LibreOffice Module sc (master)  1
dpgroupdlg.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifdef SC_DLLIMPLEMENTATION
21 #undef SC_DLLIMPLEMENTATION
22 #endif
23 
24 #include <dpgroupdlg.hxx>
25 #include <globstr.hrc>
26 #include <scresid.hxx>
27 #include <editfield.hxx>
28 
29 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
30 #include <svtools/ctrlbox.hxx>
31 
32 namespace {
33 
35 const sal_Int32 spnDateParts[] =
36 {
37  css::sheet::DataPilotFieldGroupBy::SECONDS,
38  css::sheet::DataPilotFieldGroupBy::MINUTES,
39  css::sheet::DataPilotFieldGroupBy::HOURS,
40  css::sheet::DataPilotFieldGroupBy::DAYS,
41  css::sheet::DataPilotFieldGroupBy::MONTHS,
42  css::sheet::DataPilotFieldGroupBy::QUARTERS,
43  css::sheet::DataPilotFieldGroupBy::YEARS
44 };
45 
46 const char* aDatePartResIds[] =
47 {
48  STR_DPFIELD_GROUP_BY_SECONDS,
49  STR_DPFIELD_GROUP_BY_MINUTES,
50  STR_DPFIELD_GROUP_BY_HOURS,
51  STR_DPFIELD_GROUP_BY_DAYS,
52  STR_DPFIELD_GROUP_BY_MONTHS,
53  STR_DPFIELD_GROUP_BY_QUARTERS,
54  STR_DPFIELD_GROUP_BY_YEARS
55 };
56 
57 } // namespace
58 
60  : mrRbAuto(rRbAuto)
61  , mrRbMan(rRbMan)
62  , mrEdValue(rEdValue)
63 {
64  mrRbAuto.connect_toggled( LINK( this, ScDPGroupEditHelper, ToggleHdl ) );
65  mrRbMan.connect_toggled( LINK( this, ScDPGroupEditHelper, ToggleHdl ) );
66 }
67 
69 {
70  return mrRbAuto.get_active();
71 }
72 
74 {
75  double fValue;
76  if( !ImplGetValue( fValue ) )
77  fValue = 0.0;
78  return fValue;
79 }
80 
81 void ScDPGroupEditHelper::SetValue( bool bAuto, double fValue )
82 {
83  if( bAuto )
84  {
85  mrRbAuto.set_active(true);
86  ToggleHdl(mrRbAuto);
87  }
88  else
89  {
90  mrRbMan.set_active(true);
91  ToggleHdl(mrRbMan);
92  }
93  ImplSetValue( fValue );
94 }
95 
96 IMPL_LINK(ScDPGroupEditHelper, ToggleHdl, weld::Toggleable&, rButton, void)
97 {
98  if (!rButton.get_active())
99  return;
100 
101  if (mrRbAuto.get_active())
102  {
103  // disable edit field on clicking "automatic" radio button
104  mrEdValue.set_sensitive(false);
105  }
106  else if (mrRbMan.get_active())
107  {
108  // enable and set focus to edit field on clicking "manual" radio button
109  mrEdValue.set_sensitive(true);
110  mrEdValue.grab_focus();
111  }
112 }
113 
115  weld::RadioButton& rRbMan, ScDoubleField& rEdValue)
116  : ScDPGroupEditHelper(rRbAuto, rRbMan, rEdValue.get_widget())
117  , mrEdValue(rEdValue)
118 {
119 }
120 
121 bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const
122 {
123  return mrEdValue.GetValue(rfValue);
124 }
125 
127 {
128  mrEdValue.SetValue(fValue);
129 }
130 
132  SvtCalendarBox& rEdValue, const Date& rNullDate)
133  : ScDPGroupEditHelper(rRbAuto, rRbMan, rEdValue.get_button())
134  , mrEdValue(rEdValue)
135  , maNullDate(rNullDate)
136 {
137 }
138 
139 bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const
140 {
141  rfValue = mrEdValue.get_date() - maNullDate;
142  return true;
143 }
144 
146 {
147  Date aDate( maNullDate );
148  aDate.AddDays( fValue );
149  mrEdValue.set_date( aDate );
150 }
151 
153  : GenericDialogController(pParent, "modules/scalc/ui/groupbynumber.ui", "PivotTableGroupByNumber")
154  , mxRbAutoStart(m_xBuilder->weld_radio_button("auto_start"))
155  , mxRbManStart(m_xBuilder->weld_radio_button("manual_start"))
156  , mxEdStart(new ScDoubleField(m_xBuilder->weld_entry("edit_start")))
157  , mxRbAutoEnd(m_xBuilder->weld_radio_button("auto_end"))
158  , mxRbManEnd(m_xBuilder->weld_radio_button("manual_end"))
159  , mxEdEnd(new ScDoubleField(m_xBuilder->weld_entry("edit_end")))
160  , mxEdBy(new ScDoubleField(m_xBuilder->weld_entry("edit_by")))
161  , maStartHelper(*mxRbAutoStart, *mxRbManStart, *mxEdStart)
162  , maEndHelper(*mxRbAutoEnd, *mxRbManEnd, *mxEdEnd)
163 {
164  maStartHelper.SetValue( rInfo.mbAutoStart, rInfo.mfStart );
165  maEndHelper.SetValue( rInfo.mbAutoEnd, rInfo.mfEnd );
166  mxEdBy->SetValue( (rInfo.mfStep <= 0.0) ? 1.0 : rInfo.mfStep );
167 
168  /* Set the initial focus, currently it is somewhere after calling all the radio
169  button click handlers. Now the first enabled editable control is focused. */
170  if (mxEdStart->get_sensitive())
171  mxEdStart->grab_focus();
172  else if (mxEdEnd->get_sensitive())
173  mxEdEnd->grab_focus();
174  else
175  mxEdBy->grab_focus();
176 }
177 
179 {
180 }
181 
183 {
184  ScDPNumGroupInfo aInfo;
185  aInfo.mbEnable = true;
186  aInfo.mbDateValues = false;
187  aInfo.mbAutoStart = maStartHelper.IsAuto();
188  aInfo.mbAutoEnd = maEndHelper.IsAuto();
189 
190  // get values and silently auto-correct them, if they are not valid
191  // TODO: error messages in OK event?
192  aInfo.mfStart = maStartHelper.GetValue();
193  aInfo.mfEnd = maEndHelper.GetValue();
194  if( !mxEdBy->GetValue( aInfo.mfStep ) || (aInfo.mfStep <= 0.0) )
195  aInfo.mfStep = 1.0;
196  if( aInfo.mfEnd <= aInfo.mfStart )
197  aInfo.mfEnd = aInfo.mfStart + aInfo.mfStep;
198 
199  return aInfo;
200 }
201 
203  const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate)
204  : GenericDialogController(pParent, "modules/scalc/ui/groupbydate.ui", "PivotTableGroupByDate")
205  , mxRbAutoStart(m_xBuilder->weld_radio_button("auto_start"))
206  , mxRbManStart(m_xBuilder->weld_radio_button("manual_start"))
207  , mxEdStart(new SvtCalendarBox(m_xBuilder->weld_menu_button("start_date")))
208  , mxRbAutoEnd(m_xBuilder->weld_radio_button("auto_end"))
209  , mxRbManEnd(m_xBuilder->weld_radio_button("manual_end"))
210  , mxEdEnd(new SvtCalendarBox(m_xBuilder->weld_menu_button("end_date")))
211  , mxRbNumDays(m_xBuilder->weld_radio_button("days"))
212  , mxRbUnits(m_xBuilder->weld_radio_button("intervals"))
213  , mxEdNumDays(m_xBuilder->weld_spin_button("days_value"))
214  , mxLbUnits(m_xBuilder->weld_tree_view("interval_list"))
215  , mxBtnOk(m_xBuilder->weld_button("ok"))
216  , maStartHelper(*mxRbAutoStart, *mxRbManStart, *mxEdStart, rNullDate)
217  , maEndHelper(*mxRbAutoEnd, *mxRbManEnd, *mxEdEnd, rNullDate)
218 {
219  maStartHelper.SetValue( rInfo.mbAutoStart, rInfo.mfStart );
220  maEndHelper.SetValue( rInfo.mbAutoEnd, rInfo.mfEnd );
221 
222  mxLbUnits->enable_toggle_buttons(weld::ColumnToggleType::Check);
223 
224  if( nDatePart == 0 )
225  nDatePart = css::sheet::DataPilotFieldGroupBy::MONTHS;
226  for (size_t nIdx = 0; nIdx < SAL_N_ELEMENTS(aDatePartResIds); ++nIdx)
227  {
228  mxLbUnits->append();
229  mxLbUnits->set_toggle(nIdx, (nDatePart & spnDateParts[ nIdx ]) ? TRISTATE_TRUE : TRISTATE_FALSE);
230  mxLbUnits->set_text(nIdx, ScResId(aDatePartResIds[nIdx]), 0);
231  }
232 
233  if( rInfo.mbDateValues )
234  {
235  mxRbNumDays->set_active(true);
236  ToggleHdl(*mxRbNumDays );
237 
238  double fNumDays = rInfo.mfStep;
239  if( fNumDays < 1.0 )
240  fNumDays = 1.0;
241  else if( fNumDays > 32767.0 )
242  fNumDays = 32767.0;
243  mxEdNumDays->set_value(fNumDays);
244  }
245  else
246  {
247  mxRbUnits->set_active(true);
248  ToggleHdl(*mxRbUnits);
249  }
250 
251  /* Set the initial focus, currently it is somewhere after calling all the radio
252  button click handlers. Now the first enabled editable control is focused. */
253  if( mxEdStart->get_sensitive() )
254  mxEdStart->grab_focus();
255  else if( mxEdEnd->get_sensitive() )
256  mxEdEnd->grab_focus();
257  else if( mxEdNumDays->get_sensitive() )
258  mxEdNumDays->grab_focus();
259  else if( mxLbUnits->get_sensitive() )
260  mxLbUnits->grab_focus();
261 
262  mxRbNumDays->connect_toggled( LINK( this, ScDPDateGroupDlg, ToggleHdl ) );
263  mxRbUnits->connect_toggled( LINK( this, ScDPDateGroupDlg, ToggleHdl ) );
264  mxLbUnits->connect_toggled( LINK( this, ScDPDateGroupDlg, CheckHdl ) );
265 }
266 
268 {
269 }
270 
272 {
273  ScDPNumGroupInfo aInfo;
274  aInfo.mbEnable = true;
275  aInfo.mbDateValues = mxRbNumDays->get_active();
276  aInfo.mbAutoStart = maStartHelper.IsAuto();
277  aInfo.mbAutoEnd = maEndHelper.IsAuto();
278 
279  // get values and silently auto-correct them, if they are not valid
280  // TODO: error messages in OK event?
281  aInfo.mfStart = maStartHelper.GetValue();
282  aInfo.mfEnd = maEndHelper.GetValue();
283  sal_Int64 nNumDays = mxEdNumDays->get_value();
284  aInfo.mfStep = static_cast<double>( aInfo.mbDateValues ? nNumDays : 0L );
285  if( aInfo.mfEnd <= aInfo.mfStart )
286  aInfo.mfEnd = aInfo.mfStart + nNumDays;
287 
288  return aInfo;
289 }
290 
292 {
293  // return DAYS for special "number of days" mode
294  if( mxRbNumDays->get_active() )
295  return css::sheet::DataPilotFieldGroupBy::DAYS;
296 
297  // return listbox contents for "units" mode
298  sal_Int32 nDatePart = 0;
299  for (int nIdx = 0, nCount = mxLbUnits->n_children(); nIdx < nCount; ++nIdx )
300  if (mxLbUnits->get_toggle(nIdx) == TRISTATE_TRUE)
301  nDatePart |= spnDateParts[ nIdx ];
302  return nDatePart;
303 }
304 
305 IMPL_LINK(ScDPDateGroupDlg, ToggleHdl, weld::Toggleable&, rButton, void)
306 {
307  if (!rButton.get_active())
308  return;
309  if (mxRbNumDays->get_active())
310  {
311  mxLbUnits->set_sensitive(false);
312  // enable and set focus to edit field on clicking "num of days" radio button
313  mxEdNumDays->set_sensitive(true);
314  mxEdNumDays->grab_focus();
315  mxBtnOk->set_sensitive(true);
316  }
317  else if (mxRbUnits->get_active())
318  {
319  mxEdNumDays->set_sensitive(false);
320  // enable and set focus to listbox on clicking "units" radio button
321  mxLbUnits->set_sensitive(true);
322  mxLbUnits->grab_focus();
323  // disable OK button if no date part selected
324  Check();
325  }
326 }
327 
328 namespace
329 {
330  bool HasCheckedEntryCount(const weld::TreeView& rView)
331  {
332  for (int i = 0; i < rView.n_children(); ++i)
333  {
334  if (rView.get_toggle(i) == TRISTATE_TRUE)
335  return true;
336  }
337  return false;
338  }
339 }
340 
342 {
343  Check();
344 }
345 
347 {
348  // enable/disable OK button on modifying check list box
349  mxBtnOk->set_sensitive(HasCheckedEntryCount(*mxLbUnits));
350 }
351 
352 
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScDPDateGroupEditHelper maEndHelper
Definition: dpgroupdlg.hxx:135
virtual bool ImplGetValue(double &rfValue) const override
Definition: dpgroupdlg.cxx:121
virtual ~ScDPNumGroupDlg() override
Definition: dpgroupdlg.cxx:178
ScDPNumGroupInfo GetGroupInfo() const
Definition: dpgroupdlg.cxx:182
virtual ~ScDPDateGroupDlg() override
Definition: dpgroupdlg.cxx:267
ScDPNumGroupEditHelper maEndHelper
Definition: dpgroupdlg.hxx:105
ScDPNumGroupEditHelper maStartHelper
Definition: dpgroupdlg.hxx:104
bool IsAuto() const
Definition: dpgroupdlg.cxx:68
ScDoubleField & mrEdValue
Definition: dpgroupdlg.hxx:67
std::unique_ptr< ScDoubleField > mxEdStart
Definition: dpgroupdlg.hxx:99
IMPL_LINK(ScDPGroupEditHelper, ToggleHdl, weld::Toggleable &, rButton, void)
Definition: dpgroupdlg.cxx:96
ScDPDateGroupEditHelper maStartHelper
Definition: dpgroupdlg.hxx:134
ScDPNumGroupDlg(weld::Window *pParent, const ScDPNumGroupInfo &rInfo)
Definition: dpgroupdlg.cxx:152
virtual bool ImplGetValue(double &rfValue) const =0
IMPL_LINK_NOARG(ScDPDateGroupDlg, CheckHdl, const weld::TreeView::iter_col &, void)
Definition: dpgroupdlg.cxx:341
bool GetValue(double &rfValue) const
Definition: editfield.cxx:43
std::unique_ptr< weld::RadioButton > mxRbUnits
Definition: dpgroupdlg.hxx:130
Date get_date() const
ScDPDateGroupEditHelper(weld::RadioButton &rRbAuto, weld::RadioButton &rRbMan, SvtCalendarBox &rEdValue, const Date &rNullDate)
Definition: dpgroupdlg.cxx:131
TRISTATE_TRUE
std::unique_ptr< weld::SpinButton > mxEdNumDays
Definition: dpgroupdlg.hxx:131
void SetValue(bool bAuto, double fValue)
Definition: dpgroupdlg.cxx:81
virtual TriState get_toggle(int row, int col=-1) const =0
std::unique_ptr< ScDoubleField > mxEdEnd
Definition: dpgroupdlg.hxx:102
void SetValue(double fValue, sal_Int32 nDecPlaces=12)
Definition: editfield.cxx:57
ScDPDateGroupDlg(weld::Window *pParent, const ScDPNumGroupInfo &rInfo, sal_Int32 nDatePart, const Date &rNullDate)
Definition: dpgroupdlg.cxx:202
sal_Int32 GetDatePart() const
Definition: dpgroupdlg.cxx:291
std::pair< const TreeIter &, int > iter_col
int nCount
virtual int n_children() const =0
virtual void ImplSetValue(double fValue)=0
std::unique_ptr< SvtCalendarBox > mxEdStart
Definition: dpgroupdlg.hxx:125
virtual void connect_toggled(const Link< Toggleable &, void > &rLink)
#define SAL_N_ELEMENTS(arr)
weld::RadioButton & mrRbAuto
Definition: dpgroupdlg.hxx:49
ScDPGroupEditHelper(weld::RadioButton &rRbAuto, weld::RadioButton &rRbMan, weld::Widget &rEdValue)
Definition: dpgroupdlg.cxx:59
int i
ScDPNumGroupEditHelper(weld::RadioButton &rRbAuto, weld::RadioButton &rRbMan, ScDoubleField &rEdValue)
Definition: dpgroupdlg.cxx:114
void set_date(const Date &rDate)
weld::RadioButton & mrRbMan
Definition: dpgroupdlg.hxx:50
TRISTATE_FALSE
An edit control that contains a double precision floating-point value.
Definition: editfield.hxx:25
virtual void set_active(bool active)=0
void AddDays(sal_Int32 nAddDays)
std::unique_ptr< SvtCalendarBox > mxEdEnd
Definition: dpgroupdlg.hxx:128
std::unique_ptr< weld::TreeView > mxLbUnits
Definition: dpgroupdlg.hxx:132
ScDPNumGroupInfo GetGroupInfo() const
Definition: dpgroupdlg.cxx:271
virtual void ImplSetValue(double fValue) override
Definition: dpgroupdlg.cxx:145
std::unique_ptr< weld::Button > mxBtnOk
Definition: dpgroupdlg.hxx:133
std::unique_ptr< weld::RadioButton > mxRbNumDays
Definition: dpgroupdlg.hxx:129
OUString ScResId(std::string_view aId)
Definition: scdll.cxx:89
virtual bool ImplGetValue(double &rfValue) const override
Definition: dpgroupdlg.cxx:139
double GetValue() const
Definition: dpgroupdlg.cxx:73
std::unique_ptr< ScDoubleField > mxEdBy
Definition: dpgroupdlg.hxx:103
virtual void ImplSetValue(double fValue) override
Definition: dpgroupdlg.cxx:126
SvtCalendarBox & mrEdValue
Definition: dpgroupdlg.hxx:85
virtual bool get_active() const =0