1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifdef SC_DLLIMPLEMENTATION
21 #undef SC_DLLIMPLEMENTATION
24 #include <dpgroupdlg.hxx>
25 #include <globstr.hrc>
26 #include <scresid.hxx>
27 #include <editfield.hxx>
29 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
30 #include <svtools/ctrlbox.hxx>
34 /** Date part flags in order of the list box entries. */
35 const sal_Int32 spnDateParts
[] =
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
46 const TranslateId aDatePartResIds
[] =
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
59 ScDPGroupEditHelper::ScDPGroupEditHelper(weld::RadioButton
& rRbAuto
, weld::RadioButton
& rRbMan
, weld::Widget
& rEdValue
)
64 mrRbAuto
.connect_toggled( LINK( this, ScDPGroupEditHelper
, ToggleHdl
) );
65 mrRbMan
.connect_toggled( LINK( this, ScDPGroupEditHelper
, ToggleHdl
) );
68 bool ScDPGroupEditHelper::IsAuto() const
70 return mrRbAuto
.get_active();
73 double ScDPGroupEditHelper::GetValue() const
76 if( !ImplGetValue( fValue
) )
81 void ScDPGroupEditHelper::SetValue( bool bAuto
, double fValue
)
85 mrRbAuto
.set_active(true);
90 mrRbMan
.set_active(true);
93 ImplSetValue( fValue
);
96 IMPL_LINK(ScDPGroupEditHelper
, ToggleHdl
, weld::Toggleable
&, rButton
, void)
98 if (!rButton
.get_active())
101 if (mrRbAuto
.get_active())
103 // disable edit field on clicking "automatic" radio button
104 mrEdValue
.set_sensitive(false);
106 else if (mrRbMan
.get_active())
108 // enable and set focus to edit field on clicking "manual" radio button
109 mrEdValue
.set_sensitive(true);
110 mrEdValue
.grab_focus();
114 ScDPNumGroupEditHelper::ScDPNumGroupEditHelper(weld::RadioButton
& rRbAuto
,
115 weld::RadioButton
& rRbMan
, ScDoubleField
& rEdValue
)
116 : ScDPGroupEditHelper(rRbAuto
, rRbMan
, rEdValue
.get_widget())
117 , mrEdValue(rEdValue
)
121 bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue
) const
123 return mrEdValue
.GetValue(rfValue
);
126 void ScDPNumGroupEditHelper::ImplSetValue( double fValue
)
128 mrEdValue
.SetValue(fValue
);
131 ScDPDateGroupEditHelper::ScDPDateGroupEditHelper(weld::RadioButton
& rRbAuto
, weld::RadioButton
& rRbMan
,
132 SvtCalendarBox
& rEdValue
, const Date
& rNullDate
)
133 : ScDPGroupEditHelper(rRbAuto
, rRbMan
, rEdValue
.get_button())
134 , mrEdValue(rEdValue
)
135 , maNullDate(rNullDate
)
139 bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue
) const
141 rfValue
= mrEdValue
.get_date() - maNullDate
;
145 void ScDPDateGroupEditHelper::ImplSetValue( double fValue
)
147 Date
aDate( maNullDate
);
148 aDate
.AddDays( fValue
);
149 mrEdValue
.set_date( aDate
);
152 ScDPNumGroupDlg::ScDPNumGroupDlg(weld::Window
* pParent
, const ScDPNumGroupInfo
& rInfo
)
153 : GenericDialogController(pParent
, u
"modules/scalc/ui/groupbynumber.ui"_ustr
, u
"PivotTableGroupByNumber"_ustr
)
154 , mxRbAutoStart(m_xBuilder
->weld_radio_button(u
"auto_start"_ustr
))
155 , mxRbManStart(m_xBuilder
->weld_radio_button(u
"manual_start"_ustr
))
156 , mxEdStart(new ScDoubleField(m_xBuilder
->weld_entry(u
"edit_start"_ustr
)))
157 , mxRbAutoEnd(m_xBuilder
->weld_radio_button(u
"auto_end"_ustr
))
158 , mxRbManEnd(m_xBuilder
->weld_radio_button(u
"manual_end"_ustr
))
159 , mxEdEnd(new ScDoubleField(m_xBuilder
->weld_entry(u
"edit_end"_ustr
)))
160 , mxEdBy(new ScDoubleField(m_xBuilder
->weld_entry(u
"edit_by"_ustr
)))
161 , maStartHelper(*mxRbAutoStart
, *mxRbManStart
, *mxEdStart
)
162 , maEndHelper(*mxRbAutoEnd
, *mxRbManEnd
, *mxEdEnd
)
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
);
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();
175 mxEdBy
->grab_focus();
178 ScDPNumGroupDlg::~ScDPNumGroupDlg()
182 ScDPNumGroupInfo
ScDPNumGroupDlg::GetGroupInfo() const
184 ScDPNumGroupInfo aInfo
;
185 aInfo
.mbEnable
= true;
186 aInfo
.mbDateValues
= false;
187 aInfo
.mbAutoStart
= maStartHelper
.IsAuto();
188 aInfo
.mbAutoEnd
= maEndHelper
.IsAuto();
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) )
196 if( aInfo
.mfEnd
<= aInfo
.mfStart
)
197 aInfo
.mfEnd
= aInfo
.mfStart
+ aInfo
.mfStep
;
202 ScDPDateGroupDlg::ScDPDateGroupDlg(weld::Window
* pParent
,
203 const ScDPNumGroupInfo
& rInfo
, sal_Int32 nDatePart
, const Date
& rNullDate
)
204 : GenericDialogController(pParent
, u
"modules/scalc/ui/groupbydate.ui"_ustr
, u
"PivotTableGroupByDate"_ustr
)
205 , mxRbAutoStart(m_xBuilder
->weld_radio_button(u
"auto_start"_ustr
))
206 , mxRbManStart(m_xBuilder
->weld_radio_button(u
"manual_start"_ustr
))
207 , mxEdStart(new SvtCalendarBox(m_xBuilder
->weld_menu_button(u
"start_date"_ustr
)))
208 , mxRbAutoEnd(m_xBuilder
->weld_radio_button(u
"auto_end"_ustr
))
209 , mxRbManEnd(m_xBuilder
->weld_radio_button(u
"manual_end"_ustr
))
210 , mxEdEnd(new SvtCalendarBox(m_xBuilder
->weld_menu_button(u
"end_date"_ustr
)))
211 , mxRbNumDays(m_xBuilder
->weld_radio_button(u
"days"_ustr
))
212 , mxRbUnits(m_xBuilder
->weld_radio_button(u
"intervals"_ustr
))
213 , mxEdNumDays(m_xBuilder
->weld_spin_button(u
"days_value"_ustr
))
214 , mxLbUnits(m_xBuilder
->weld_tree_view(u
"interval_list"_ustr
))
215 , mxBtnOk(m_xBuilder
->weld_button(u
"ok"_ustr
))
216 , maStartHelper(*mxRbAutoStart
, *mxRbManStart
, *mxEdStart
, rNullDate
)
217 , maEndHelper(*mxRbAutoEnd
, *mxRbManEnd
, *mxEdEnd
, rNullDate
)
219 maStartHelper
.SetValue( rInfo
.mbAutoStart
, rInfo
.mfStart
);
220 maEndHelper
.SetValue( rInfo
.mbAutoEnd
, rInfo
.mfEnd
);
222 mxLbUnits
->enable_toggle_buttons(weld::ColumnToggleType::Check
);
225 nDatePart
= css::sheet::DataPilotFieldGroupBy::MONTHS
;
226 for (size_t nIdx
= 0; nIdx
< SAL_N_ELEMENTS(aDatePartResIds
); ++nIdx
)
229 mxLbUnits
->set_toggle(nIdx
, (nDatePart
& spnDateParts
[ nIdx
]) ? TRISTATE_TRUE
: TRISTATE_FALSE
);
230 mxLbUnits
->set_text(nIdx
, ScResId(aDatePartResIds
[nIdx
]), 0);
233 if( rInfo
.mbDateValues
)
235 mxRbNumDays
->set_active(true);
236 ToggleHdl(*mxRbNumDays
);
238 double fNumDays
= rInfo
.mfStep
;
241 else if( fNumDays
> 32767.0 )
243 mxEdNumDays
->set_value(fNumDays
);
247 mxRbUnits
->set_active(true);
248 ToggleHdl(*mxRbUnits
);
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();
262 mxRbNumDays
->connect_toggled( LINK( this, ScDPDateGroupDlg
, ToggleHdl
) );
263 mxRbUnits
->connect_toggled( LINK( this, ScDPDateGroupDlg
, ToggleHdl
) );
264 mxLbUnits
->connect_toggled( LINK( this, ScDPDateGroupDlg
, CheckHdl
) );
267 ScDPDateGroupDlg::~ScDPDateGroupDlg()
271 ScDPNumGroupInfo
ScDPDateGroupDlg::GetGroupInfo() const
273 ScDPNumGroupInfo aInfo
;
274 aInfo
.mbEnable
= true;
275 aInfo
.mbDateValues
= mxRbNumDays
->get_active();
276 aInfo
.mbAutoStart
= maStartHelper
.IsAuto();
277 aInfo
.mbAutoEnd
= maEndHelper
.IsAuto();
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
;
291 sal_Int32
ScDPDateGroupDlg::GetDatePart() const
293 // return DAYS for special "number of days" mode
294 if( mxRbNumDays
->get_active() )
295 return css::sheet::DataPilotFieldGroupBy::DAYS
;
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
];
305 IMPL_LINK(ScDPDateGroupDlg
, ToggleHdl
, weld::Toggleable
&, rButton
, void)
307 if (!rButton
.get_active())
309 if (mxRbNumDays
->get_active())
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);
317 else if (mxRbUnits
->get_active())
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
330 bool HasCheckedEntryCount(const weld::TreeView
& rView
)
332 for (int i
= 0; i
< rView
.n_children(); ++i
)
334 if (rView
.get_toggle(i
) == TRISTATE_TRUE
)
341 IMPL_LINK_NOARG(ScDPDateGroupDlg
, CheckHdl
, const weld::TreeView::iter_col
&, void)
346 void ScDPDateGroupDlg::Check()
348 // enable/disable OK button on modifying check list box
349 mxBtnOk
->set_sensitive(HasCheckedEntryCount(*mxLbUnits
));
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */