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