1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27 #ifdef SC_DLLIMPLEMENTATION
28 #undef SC_DLLIMPLEMENTATION
29 #endif
30
31
32 #include "dpgroupdlg.hxx"
33 #ifndef SC_DPGROUPDLG_HRC
34 #include "dpgroupdlg.hrc"
35 #endif
36
37 #include "scresid.hxx"
38 #ifndef SC_SC_HRC
39 #include "sc.hrc"
40 #endif
41
42 #include "globstr.hrc"
43
44 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
45
46 // ============================================================================
47
48 namespace {
49
50 /** Date part flags in order of the list box entries. */
51 static const sal_Int32 spnDateParts[] =
52 {
53 com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS,
54 com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES,
55 com::sun::star::sheet::DataPilotFieldGroupBy::HOURS,
56 com::sun::star::sheet::DataPilotFieldGroupBy::DAYS,
57 com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS,
58 com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS,
59 com::sun::star::sheet::DataPilotFieldGroupBy::YEARS
60 };
61
62 static const sal_uInt16 nDatePartResIds[] =
63 {
64 STR_DPFIELD_GROUP_BY_SECONDS,
65 STR_DPFIELD_GROUP_BY_MINUTES,
66 STR_DPFIELD_GROUP_BY_HOURS,
67 STR_DPFIELD_GROUP_BY_DAYS,
68 STR_DPFIELD_GROUP_BY_MONTHS,
69 STR_DPFIELD_GROUP_BY_QUARTERS,
70 STR_DPFIELD_GROUP_BY_YEARS
71 };
72
73 } // namespace
74
75 // ============================================================================
76
ScDPGroupEditHelper(RadioButton & rRbAuto,RadioButton & rRbMan,Edit & rEdValue)77 ScDPGroupEditHelper::ScDPGroupEditHelper( RadioButton& rRbAuto, RadioButton& rRbMan, Edit& rEdValue ) :
78 mrRbAuto( rRbAuto ),
79 mrRbMan( rRbMan ),
80 mrEdValue( rEdValue )
81 {
82 mrRbAuto.SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
83 mrRbMan.SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
84 }
85
IsAuto() const86 bool ScDPGroupEditHelper::IsAuto() const
87 {
88 return mrRbAuto.IsChecked();
89 }
90
GetValue() const91 double ScDPGroupEditHelper::GetValue() const
92 {
93 double fValue;
94 if( !ImplGetValue( fValue ) )
95 fValue = 0.0;
96 return fValue;
97 }
98
SetValue(bool bAuto,double fValue)99 void ScDPGroupEditHelper::SetValue( bool bAuto, double fValue )
100 {
101 if( bAuto )
102 {
103 mrRbAuto.Check();
104 ClickHdl( &mrRbAuto );
105 }
106 else
107 {
108 mrRbMan.Check();
109 ClickHdl( &mrRbMan );
110 }
111 ImplSetValue( fValue );
112 }
113
IMPL_LINK(ScDPGroupEditHelper,ClickHdl,RadioButton *,pButton)114 IMPL_LINK( ScDPGroupEditHelper, ClickHdl, RadioButton*, pButton )
115 {
116 if( pButton == &mrRbAuto )
117 {
118 // disable edit field on clicking "automatic" radio button
119 mrEdValue.Disable();
120 }
121 else if( pButton == &mrRbMan )
122 {
123 // enable and set focus to edit field on clicking "manual" radio button
124 mrEdValue.Enable();
125 mrEdValue.GrabFocus();
126 }
127 return 0;
128 }
129
130 // ----------------------------------------------------------------------------
131
ScDPNumGroupEditHelper(RadioButton & rRbAuto,RadioButton & rRbMan,ScDoubleField & rEdValue)132 ScDPNumGroupEditHelper::ScDPNumGroupEditHelper(
133 RadioButton& rRbAuto, RadioButton& rRbMan, ScDoubleField& rEdValue ) :
134 ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ),
135 mrEdValue( rEdValue )
136 {
137 }
138
ImplGetValue(double & rfValue) const139 bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const
140 {
141 return mrEdValue.GetValue( rfValue );
142 }
143
ImplSetValue(double fValue)144 void ScDPNumGroupEditHelper::ImplSetValue( double fValue )
145 {
146 mrEdValue.SetValue( fValue );
147 }
148
149 // ----------------------------------------------------------------------------
150
ScDPDateGroupEditHelper(RadioButton & rRbAuto,RadioButton & rRbMan,DateField & rEdValue,const Date & rNullDate)151 ScDPDateGroupEditHelper::ScDPDateGroupEditHelper(
152 RadioButton& rRbAuto, RadioButton& rRbMan, DateField& rEdValue, const Date& rNullDate ) :
153 ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ),
154 mrEdValue( rEdValue ),
155 maNullDate( rNullDate )
156 {
157 }
158
ImplGetValue(double & rfValue) const159 bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const
160 {
161 rfValue = mrEdValue.GetDate() - maNullDate;
162 return true;
163 }
164
ImplSetValue(double fValue)165 void ScDPDateGroupEditHelper::ImplSetValue( double fValue )
166 {
167 Date aDate( maNullDate );
168 aDate += static_cast< sal_Int32 >( fValue );
169 mrEdValue.SetDate( aDate );
170 }
171
172 // ============================================================================
173 // ============================================================================
174
ScDPNumGroupDlg(Window * pParent,const ScDPNumGroupInfo & rInfo)175 ScDPNumGroupDlg::ScDPNumGroupDlg( Window* pParent, const ScDPNumGroupInfo& rInfo ) :
176 ModalDialog ( pParent, ScResId( RID_SCDLG_DPNUMGROUP ) ),
177 maFlStart ( this, ScResId( FL_START ) ),
178 maRbAutoStart ( this, ScResId( RB_AUTOSTART ) ),
179 maRbManStart ( this, ScResId( RB_MANSTART ) ),
180 maEdStart ( this, ScResId( ED_START ) ),
181 maFlEnd ( this, ScResId( FL_END ) ),
182 maRbAutoEnd ( this, ScResId( RB_AUTOEND ) ),
183 maRbManEnd ( this, ScResId( RB_MANEND ) ),
184 maEdEnd ( this, ScResId( ED_END ) ),
185 maFlBy ( this, ScResId( FL_BY ) ),
186 maEdBy ( this, ScResId( ED_BY ) ),
187 maBtnOk ( this, ScResId( BTN_OK ) ),
188 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
189 maBtnHelp ( this, ScResId( BTN_HELP ) ),
190 maStartHelper ( maRbAutoStart, maRbManStart, maEdStart ),
191 maEndHelper ( maRbAutoEnd, maRbManEnd, maEdEnd )
192 {
193 FreeResource();
194
195 maStartHelper.SetValue( rInfo.AutoStart, rInfo.Start );
196 maEndHelper.SetValue( rInfo.AutoEnd, rInfo.End );
197 maEdBy.SetValue( (rInfo.Step <= 0.0) ? 1.0 : rInfo.Step );
198
199 /* Set the initial focus, currently it is somewhere after calling all the radio
200 button click handlers. Now the first enabled editable control is focused. */
201 if( maEdStart.IsEnabled() )
202 maEdStart.GrabFocus();
203 else if( maEdEnd.IsEnabled() )
204 maEdEnd.GrabFocus();
205 else
206 maEdBy.GrabFocus();
207 }
208
GetGroupInfo() const209 ScDPNumGroupInfo ScDPNumGroupDlg::GetGroupInfo() const
210 {
211 ScDPNumGroupInfo aInfo;
212 aInfo.Enable = sal_True;
213 aInfo.DateValues = sal_False;
214 aInfo.AutoStart = maStartHelper.IsAuto();
215 aInfo.AutoEnd = maEndHelper.IsAuto();
216
217 // get values and silently auto-correct them, if they are not valid
218 // TODO: error messages in OK event?
219 aInfo.Start = maStartHelper.GetValue();
220 aInfo.End = maEndHelper.GetValue();
221 if( !maEdBy.GetValue( aInfo.Step ) || (aInfo.Step <= 0.0) )
222 aInfo.Step = 1.0;
223 if( aInfo.End <= aInfo.Start )
224 aInfo.End = aInfo.Start + aInfo.Step;
225
226 return aInfo;
227 }
228
229 // ============================================================================
230
ScDPDateGroupDlg(Window * pParent,const ScDPNumGroupInfo & rInfo,sal_Int32 nDatePart,const Date & rNullDate)231 ScDPDateGroupDlg::ScDPDateGroupDlg( Window* pParent,
232 const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate ) :
233 ModalDialog ( pParent, ScResId( RID_SCDLG_DPDATEGROUP ) ),
234 maFlStart ( this, ScResId( FL_START ) ),
235 maRbAutoStart ( this, ScResId( RB_AUTOSTART ) ),
236 maRbManStart ( this, ScResId( RB_MANSTART ) ),
237 maEdStart ( this, ScResId( ED_START ) ),
238 maFlEnd ( this, ScResId( FL_END ) ),
239 maRbAutoEnd ( this, ScResId( RB_AUTOEND ) ),
240 maRbManEnd ( this, ScResId( RB_MANEND ) ),
241 maEdEnd ( this, ScResId( ED_END ) ),
242 maFlBy ( this, ScResId( FL_BY ) ),
243 maRbNumDays ( this, ScResId( RB_NUMDAYS ) ),
244 maRbUnits ( this, ScResId( RB_UNITS ) ),
245 maEdNumDays ( this, ScResId( ED_NUMDAYS ) ),
246 maLbUnits ( this, ScResId( LB_UNITS ) ),
247 maBtnOk ( this, ScResId( BTN_OK ) ),
248 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
249 maBtnHelp ( this, ScResId( BTN_HELP ) ),
250 maStartHelper ( maRbAutoStart, maRbManStart, maEdStart, rNullDate ),
251 maEndHelper ( maRbAutoEnd, maRbManEnd, maEdEnd, rNullDate )
252 {
253 FreeResource();
254
255 maLbUnits.SetHelpId( HID_SC_DPDATEGROUP_LB );
256
257 static const size_t nCount = sizeof( nDatePartResIds ) / sizeof( nDatePartResIds[0] );
258 for( size_t nIdx = 0 ; nIdx < nCount; ++nIdx )
259 maLbUnits.InsertEntry( ScGlobal::GetRscString( nDatePartResIds[nIdx] ) );
260
261 maEdStart.SetShowDateCentury( sal_True );
262 maEdEnd.SetShowDateCentury( sal_True );
263
264 maStartHelper.SetValue( rInfo.AutoStart, rInfo.Start );
265 maEndHelper.SetValue( rInfo.AutoEnd, rInfo.End );
266
267 if( nDatePart == 0 )
268 nDatePart = com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS;
269 for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
270 maLbUnits.CheckEntryPos( static_cast< sal_uInt16 >( nIdx ), (nDatePart & spnDateParts[ nIdx ]) != 0 );
271
272 if( rInfo.DateValues )
273 {
274 maRbNumDays.Check();
275 ClickHdl( &maRbNumDays );
276
277 double fNumDays = rInfo.Step;
278 if( fNumDays < 1.0 )
279 fNumDays = 1.0;
280 else if( fNumDays > 32767.0 )
281 fNumDays = 32767.0;
282 maEdNumDays.SetValue( static_cast< long >( fNumDays ) );
283 }
284 else
285 {
286 maRbUnits.Check();
287 ClickHdl( &maRbUnits );
288 }
289
290 /* Set the initial focus, currently it is somewhere after calling all the radio
291 button click handlers. Now the first enabled editable control is focused. */
292 if( maEdStart.IsEnabled() )
293 maEdStart.GrabFocus();
294 else if( maEdEnd.IsEnabled() )
295 maEdEnd.GrabFocus();
296 else if( maEdNumDays.IsEnabled() )
297 maEdNumDays.GrabFocus();
298 else if( maLbUnits.IsEnabled() )
299 maLbUnits.GrabFocus();
300
301 maRbNumDays.SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
302 maRbUnits.SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
303 maLbUnits.SetCheckButtonHdl( LINK( this, ScDPDateGroupDlg, CheckHdl ) );
304 }
305
GetGroupInfo() const306 ScDPNumGroupInfo ScDPDateGroupDlg::GetGroupInfo() const
307 {
308 ScDPNumGroupInfo aInfo;
309 aInfo.Enable = sal_True;
310 aInfo.DateValues = maRbNumDays.IsChecked();
311 aInfo.AutoStart = maStartHelper.IsAuto();
312 aInfo.AutoEnd = maEndHelper.IsAuto();
313
314 // get values and silently auto-correct them, if they are not valid
315 // TODO: error messages in OK event?
316 aInfo.Start = maStartHelper.GetValue();
317 aInfo.End = maEndHelper.GetValue();
318 sal_Int64 nNumDays = maEdNumDays.GetValue();
319 aInfo.Step = static_cast<double>( aInfo.DateValues ? nNumDays : 0L );
320 if( aInfo.End <= aInfo.Start )
321 aInfo.End = aInfo.Start + nNumDays;
322
323 return aInfo;
324 }
325
GetDatePart() const326 sal_Int32 ScDPDateGroupDlg::GetDatePart() const
327 {
328 // return DAYS for special "number of days" mode
329 if( maRbNumDays.IsChecked() )
330 return com::sun::star::sheet::DataPilotFieldGroupBy::DAYS;
331
332 // return listbox contents for "units" mode
333 sal_Int32 nDatePart = 0;
334 for( sal_uLong nIdx = 0, nCount = maLbUnits.GetEntryCount(); nIdx < nCount; ++nIdx )
335 if( maLbUnits.IsChecked( static_cast< sal_uInt16 >( nIdx ) ) )
336 nDatePart |= spnDateParts[ nIdx ];
337 return nDatePart;
338 }
339
IMPL_LINK(ScDPDateGroupDlg,ClickHdl,RadioButton *,pButton)340 IMPL_LINK( ScDPDateGroupDlg, ClickHdl, RadioButton*, pButton )
341 {
342 if( pButton == &maRbNumDays )
343 {
344 maLbUnits.Disable();
345 // enable and set focus to edit field on clicking "num of days" radio button
346 maEdNumDays.Enable();
347 maEdNumDays.GrabFocus();
348 maBtnOk.Enable();
349 }
350 else if( pButton == &maRbUnits )
351 {
352 maEdNumDays.Disable();
353 // enable and set focus to listbox on clicking "units" radio button
354 maLbUnits.Enable();
355 maLbUnits.GrabFocus();
356 // disable OK button if no date part selected
357 CheckHdl( &maLbUnits );
358 }
359 return 0;
360 }
361
IMPL_LINK(ScDPDateGroupDlg,CheckHdl,SvxCheckListBox *,pListBox)362 IMPL_LINK( ScDPDateGroupDlg, CheckHdl, SvxCheckListBox*, pListBox )
363 {
364 // enable/disable OK button on modifying check list box
365 if( pListBox == &maLbUnits )
366 maBtnOk.Enable( maLbUnits.GetCheckedEntryCount() > 0 );
367 return 0;
368 }
369
370 // ============================================================================
371
372