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