1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 #ifdef SC_DLLIMPLEMENTATION 32 #undef SC_DLLIMPLEMENTATION 33 #endif 34 35 36 #include "dpgroupdlg.hxx" 37 #ifndef SC_DPGROUPDLG_HRC 38 #include "dpgroupdlg.hrc" 39 #endif 40 #include <tools/resary.hxx> 41 #include "scresid.hxx" 42 #ifndef SC_SC_HRC 43 #include "sc.hrc" 44 #endif 45 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> 46 47 // ============================================================================ 48 49 namespace { 50 51 /** Date part flags in order of the list box entries. */ 52 static const sal_Int32 spnDateParts[] = 53 { 54 com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS, 55 com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES, 56 com::sun::star::sheet::DataPilotFieldGroupBy::HOURS, 57 com::sun::star::sheet::DataPilotFieldGroupBy::DAYS, 58 com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS, 59 com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS, 60 com::sun::star::sheet::DataPilotFieldGroupBy::YEARS 61 }; 62 63 } // namespace 64 65 // ============================================================================ 66 67 ScDPGroupEditHelper::ScDPGroupEditHelper( RadioButton& rRbAuto, RadioButton& rRbMan, Edit& rEdValue ) : 68 mrRbAuto( rRbAuto ), 69 mrRbMan( rRbMan ), 70 mrEdValue( rEdValue ) 71 { 72 mrRbAuto.SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) ); 73 mrRbMan.SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) ); 74 } 75 76 bool ScDPGroupEditHelper::IsAuto() const 77 { 78 return mrRbAuto.IsChecked(); 79 } 80 81 double ScDPGroupEditHelper::GetValue() const 82 { 83 double fValue; 84 if( !ImplGetValue( fValue ) ) 85 fValue = 0.0; 86 return fValue; 87 } 88 89 void ScDPGroupEditHelper::SetValue( bool bAuto, double fValue ) 90 { 91 if( bAuto ) 92 { 93 mrRbAuto.Check(); 94 ClickHdl( &mrRbAuto ); 95 } 96 else 97 { 98 mrRbMan.Check(); 99 ClickHdl( &mrRbMan ); 100 } 101 ImplSetValue( fValue ); 102 } 103 104 IMPL_LINK( ScDPGroupEditHelper, ClickHdl, RadioButton*, pButton ) 105 { 106 if( pButton == &mrRbAuto ) 107 { 108 // disable edit field on clicking "automatic" radio button 109 mrEdValue.Disable(); 110 } 111 else if( pButton == &mrRbMan ) 112 { 113 // enable and set focus to edit field on clicking "manual" radio button 114 mrEdValue.Enable(); 115 mrEdValue.GrabFocus(); 116 } 117 return 0; 118 } 119 120 // ---------------------------------------------------------------------------- 121 122 ScDPNumGroupEditHelper::ScDPNumGroupEditHelper( 123 RadioButton& rRbAuto, RadioButton& rRbMan, ScDoubleField& rEdValue ) : 124 ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ), 125 mrEdValue( rEdValue ) 126 { 127 } 128 129 bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const 130 { 131 return mrEdValue.GetValue( rfValue ); 132 } 133 134 void ScDPNumGroupEditHelper::ImplSetValue( double fValue ) 135 { 136 mrEdValue.SetValue( fValue ); 137 } 138 139 // ---------------------------------------------------------------------------- 140 141 ScDPDateGroupEditHelper::ScDPDateGroupEditHelper( 142 RadioButton& rRbAuto, RadioButton& rRbMan, DateField& rEdValue, const Date& rNullDate ) : 143 ScDPGroupEditHelper( rRbAuto, rRbMan, rEdValue ), 144 mrEdValue( rEdValue ), 145 maNullDate( rNullDate ) 146 { 147 } 148 149 bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const 150 { 151 rfValue = mrEdValue.GetDate() - maNullDate; 152 return true; 153 } 154 155 void ScDPDateGroupEditHelper::ImplSetValue( double fValue ) 156 { 157 Date aDate( maNullDate ); 158 aDate += static_cast< sal_Int32 >( fValue ); 159 mrEdValue.SetDate( aDate ); 160 } 161 162 // ============================================================================ 163 // ============================================================================ 164 165 ScDPNumGroupDlg::ScDPNumGroupDlg( Window* pParent, const ScDPNumGroupInfo& rInfo ) : 166 ModalDialog ( pParent, ScResId( RID_SCDLG_DPNUMGROUP ) ), 167 maFlStart ( this, ScResId( FL_START ) ), 168 maRbAutoStart ( this, ScResId( RB_AUTOSTART ) ), 169 maRbManStart ( this, ScResId( RB_MANSTART ) ), 170 maEdStart ( this, ScResId( ED_START ) ), 171 maFlEnd ( this, ScResId( FL_END ) ), 172 maRbAutoEnd ( this, ScResId( RB_AUTOEND ) ), 173 maRbManEnd ( this, ScResId( RB_MANEND ) ), 174 maEdEnd ( this, ScResId( ED_END ) ), 175 maFlBy ( this, ScResId( FL_BY ) ), 176 maEdBy ( this, ScResId( ED_BY ) ), 177 maBtnOk ( this, ScResId( BTN_OK ) ), 178 maBtnCancel ( this, ScResId( BTN_CANCEL ) ), 179 maBtnHelp ( this, ScResId( BTN_HELP ) ), 180 maStartHelper ( maRbAutoStart, maRbManStart, maEdStart ), 181 maEndHelper ( maRbAutoEnd, maRbManEnd, maEdEnd ) 182 { 183 FreeResource(); 184 185 maStartHelper.SetValue( rInfo.AutoStart, rInfo.Start ); 186 maEndHelper.SetValue( rInfo.AutoEnd, rInfo.End ); 187 maEdBy.SetValue( (rInfo.Step <= 0.0) ? 1.0 : rInfo.Step ); 188 189 /* Set the initial focus, currently it is somewhere after calling all the radio 190 button click handlers. Now the first enabled editable control is focused. */ 191 if( maEdStart.IsEnabled() ) 192 maEdStart.GrabFocus(); 193 else if( maEdEnd.IsEnabled() ) 194 maEdEnd.GrabFocus(); 195 else 196 maEdBy.GrabFocus(); 197 } 198 199 ScDPNumGroupInfo ScDPNumGroupDlg::GetGroupInfo() const 200 { 201 ScDPNumGroupInfo aInfo; 202 aInfo.Enable = sal_True; 203 aInfo.DateValues = sal_False; 204 aInfo.AutoStart = maStartHelper.IsAuto(); 205 aInfo.AutoEnd = maEndHelper.IsAuto(); 206 207 // get values and silently auto-correct them, if they are not valid 208 // TODO: error messages in OK event? 209 aInfo.Start = maStartHelper.GetValue(); 210 aInfo.End = maEndHelper.GetValue(); 211 if( !maEdBy.GetValue( aInfo.Step ) || (aInfo.Step <= 0.0) ) 212 aInfo.Step = 1.0; 213 if( aInfo.End <= aInfo.Start ) 214 aInfo.End = aInfo.Start + aInfo.Step; 215 216 return aInfo; 217 } 218 219 // ============================================================================ 220 221 ScDPDateGroupDlg::ScDPDateGroupDlg( Window* pParent, 222 const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate ) : 223 ModalDialog ( pParent, ScResId( RID_SCDLG_DPDATEGROUP ) ), 224 maFlStart ( this, ScResId( FL_START ) ), 225 maRbAutoStart ( this, ScResId( RB_AUTOSTART ) ), 226 maRbManStart ( this, ScResId( RB_MANSTART ) ), 227 maEdStart ( this, ScResId( ED_START ) ), 228 maFlEnd ( this, ScResId( FL_END ) ), 229 maRbAutoEnd ( this, ScResId( RB_AUTOEND ) ), 230 maRbManEnd ( this, ScResId( RB_MANEND ) ), 231 maEdEnd ( this, ScResId( ED_END ) ), 232 maFlBy ( this, ScResId( FL_BY ) ), 233 maRbNumDays ( this, ScResId( RB_NUMDAYS ) ), 234 maRbUnits ( this, ScResId( RB_UNITS ) ), 235 maEdNumDays ( this, ScResId( ED_NUMDAYS ) ), 236 maLbUnits ( this, ScResId( LB_UNITS ) ), 237 maBtnOk ( this, ScResId( BTN_OK ) ), 238 maBtnCancel ( this, ScResId( BTN_CANCEL ) ), 239 maBtnHelp ( this, ScResId( BTN_HELP ) ), 240 maStartHelper ( maRbAutoStart, maRbManStart, maEdStart, rNullDate ), 241 maEndHelper ( maRbAutoEnd, maRbManEnd, maEdEnd, rNullDate ) 242 { 243 maLbUnits.SetHelpId( HID_SC_DPDATEGROUP_LB ); 244 ResStringArray aArr( ScResId( STR_UNITS ) ); 245 for( sal_uInt16 nIdx = 0, nCount = sal::static_int_cast<sal_uInt16>(aArr.Count()); nIdx < nCount; ++nIdx ) 246 maLbUnits.InsertEntry( aArr.GetString( nIdx ) ); 247 248 FreeResource(); 249 250 maEdStart.SetShowDateCentury( sal_True ); 251 maEdEnd.SetShowDateCentury( sal_True ); 252 253 maStartHelper.SetValue( rInfo.AutoStart, rInfo.Start ); 254 maEndHelper.SetValue( rInfo.AutoEnd, rInfo.End ); 255 256 if( nDatePart == 0 ) 257 nDatePart = com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS; 258 for( sal_uLong nIdx = 0, nCount = maLbUnits.GetEntryCount(); nIdx < nCount; ++nIdx ) 259 maLbUnits.CheckEntryPos( static_cast< sal_uInt16 >( nIdx ), (nDatePart & spnDateParts[ nIdx ]) != 0 ); 260 261 if( rInfo.DateValues ) 262 { 263 maRbNumDays.Check(); 264 ClickHdl( &maRbNumDays ); 265 266 double fNumDays = rInfo.Step; 267 if( fNumDays < 1.0 ) 268 fNumDays = 1.0; 269 else if( fNumDays > 32767.0 ) 270 fNumDays = 32767.0; 271 maEdNumDays.SetValue( static_cast< long >( fNumDays ) ); 272 } 273 else 274 { 275 maRbUnits.Check(); 276 ClickHdl( &maRbUnits ); 277 } 278 279 /* Set the initial focus, currently it is somewhere after calling all the radio 280 button click handlers. Now the first enabled editable control is focused. */ 281 if( maEdStart.IsEnabled() ) 282 maEdStart.GrabFocus(); 283 else if( maEdEnd.IsEnabled() ) 284 maEdEnd.GrabFocus(); 285 else if( maEdNumDays.IsEnabled() ) 286 maEdNumDays.GrabFocus(); 287 else if( maLbUnits.IsEnabled() ) 288 maLbUnits.GrabFocus(); 289 290 maRbNumDays.SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) ); 291 maRbUnits.SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) ); 292 maLbUnits.SetCheckButtonHdl( LINK( this, ScDPDateGroupDlg, CheckHdl ) ); 293 } 294 295 ScDPNumGroupInfo ScDPDateGroupDlg::GetGroupInfo() const 296 { 297 ScDPNumGroupInfo aInfo; 298 aInfo.Enable = sal_True; 299 aInfo.DateValues = maRbNumDays.IsChecked(); 300 aInfo.AutoStart = maStartHelper.IsAuto(); 301 aInfo.AutoEnd = maEndHelper.IsAuto(); 302 303 // get values and silently auto-correct them, if they are not valid 304 // TODO: error messages in OK event? 305 aInfo.Start = maStartHelper.GetValue(); 306 aInfo.End = maEndHelper.GetValue(); 307 sal_Int64 nNumDays = maEdNumDays.GetValue(); 308 aInfo.Step = static_cast<double>( aInfo.DateValues ? nNumDays : 0L ); 309 if( aInfo.End <= aInfo.Start ) 310 aInfo.End = aInfo.Start + nNumDays; 311 312 return aInfo; 313 } 314 315 sal_Int32 ScDPDateGroupDlg::GetDatePart() const 316 { 317 // return DAYS for special "number of days" mode 318 if( maRbNumDays.IsChecked() ) 319 return com::sun::star::sheet::DataPilotFieldGroupBy::DAYS; 320 321 // return listbox contents for "units" mode 322 sal_Int32 nDatePart = 0; 323 for( sal_uLong nIdx = 0, nCount = maLbUnits.GetEntryCount(); nIdx < nCount; ++nIdx ) 324 if( maLbUnits.IsChecked( static_cast< sal_uInt16 >( nIdx ) ) ) 325 nDatePart |= spnDateParts[ nIdx ]; 326 return nDatePart; 327 } 328 329 IMPL_LINK( ScDPDateGroupDlg, ClickHdl, RadioButton*, pButton ) 330 { 331 if( pButton == &maRbNumDays ) 332 { 333 maLbUnits.Disable(); 334 // enable and set focus to edit field on clicking "num of days" radio button 335 maEdNumDays.Enable(); 336 maEdNumDays.GrabFocus(); 337 maBtnOk.Enable(); 338 } 339 else if( pButton == &maRbUnits ) 340 { 341 maEdNumDays.Disable(); 342 // enable and set focus to listbox on clicking "units" radio button 343 maLbUnits.Enable(); 344 maLbUnits.GrabFocus(); 345 // disable OK button if no date part selected 346 CheckHdl( &maLbUnits ); 347 } 348 return 0; 349 } 350 351 IMPL_LINK( ScDPDateGroupDlg, CheckHdl, SvxCheckListBox*, pListBox ) 352 { 353 // enable/disable OK button on modifying check list box 354 if( pListBox == &maLbUnits ) 355 maBtnOk.Enable( maLbUnits.GetCheckedEntryCount() > 0 ); 356 return 0; 357 } 358 359 // ============================================================================ 360 361