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 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 86 bool ScDPGroupEditHelper::IsAuto() const 87 { 88 return mrRbAuto.IsChecked(); 89 } 90 91 double ScDPGroupEditHelper::GetValue() const 92 { 93 double fValue; 94 if( !ImplGetValue( fValue ) ) 95 fValue = 0.0; 96 return fValue; 97 } 98 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 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 132 ScDPNumGroupEditHelper::ScDPNumGroupEditHelper( 133 RadioButton& rRbAuto, RadioButton& rRbMan, ScDoubleField& rEdValue ) : 134 ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ), 135 mrEdValue( rEdValue ) 136 { 137 } 138 139 bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const 140 { 141 return mrEdValue.GetValue( rfValue ); 142 } 143 144 void ScDPNumGroupEditHelper::ImplSetValue( double fValue ) 145 { 146 mrEdValue.SetValue( fValue ); 147 } 148 149 // ---------------------------------------------------------------------------- 150 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 159 bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const 160 { 161 rfValue = mrEdValue.GetDate() - maNullDate; 162 return true; 163 } 164 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 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 209 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 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 306 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 326 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 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 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