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