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 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 83 bool ScDPGroupEditHelper::IsAuto() const 84 { 85 return mrRbAuto.IsChecked(); 86 } 87 88 double ScDPGroupEditHelper::GetValue() const 89 { 90 double fValue; 91 if( !ImplGetValue( fValue ) ) 92 fValue = 0.0; 93 return fValue; 94 } 95 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 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 129 ScDPNumGroupEditHelper::ScDPNumGroupEditHelper( 130 RadioButton& rRbAuto, RadioButton& rRbMan, ScDoubleField& rEdValue ) : 131 ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ), 132 mrEdValue( rEdValue ) 133 { 134 } 135 136 bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const 137 { 138 return mrEdValue.GetValue( rfValue ); 139 } 140 141 void ScDPNumGroupEditHelper::ImplSetValue( double fValue ) 142 { 143 mrEdValue.SetValue( fValue ); 144 } 145 146 // ---------------------------------------------------------------------------- 147 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 156 bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const 157 { 158 rfValue = mrEdValue.GetDate() - maNullDate; 159 return true; 160 } 161 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 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 206 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 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 303 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 323 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 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 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