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 28 29 #include <vcl/svapp.hxx> 30 #include <svl/zforlist.hxx> 31 32 #include <com/sun/star/uno/Any.hxx> 33 #include <com/sun/star/uno/Sequence.hxx> 34 35 #include "cfgids.hxx" 36 #include "docoptio.hxx" 37 #include "rechead.hxx" 38 #include "scresid.hxx" 39 #include "sc.hrc" 40 #include "miscuno.hxx" 41 42 using namespace utl; 43 using namespace rtl; 44 using namespace com::sun::star::uno; 45 46 //------------------------------------------------------------------------ 47 48 #define SC_VERSION ((sal_uInt16)251) 49 50 TYPEINIT1(ScTpCalcItem, SfxPoolItem); 51 52 //------------------------------------------------------------------------ 53 54 //! these functions should be moved to some header file 55 inline long TwipsToHMM(long nTwips) { return (nTwips * 127 + 36) / 72; } 56 inline long HMMToTwips(long nHMM) { return (nHMM * 72 + 63) / 127; } 57 58 inline long TwipsToEvenHMM(long nTwips) { return ( (nTwips * 127 + 72) / 144 ) * 2; } 59 60 //------------------------------------------------------------------------ 61 62 sal_uInt16 lcl_GetDefaultTabDist() 63 { 64 if ( ScOptionsUtil::IsMetricSystem() ) 65 return 709; // 1,25 cm 66 else 67 return 720; // 1/2" 68 } 69 70 //======================================================================== 71 // ScDocOptions - Dokument-Optionen 72 //======================================================================== 73 74 ScDocOptions::ScDocOptions() 75 { 76 ResetDocOptions(); 77 } 78 79 //------------------------------------------------------------------------ 80 81 ScDocOptions::ScDocOptions( const ScDocOptions& rCpy ) 82 : fIterEps( rCpy.fIterEps ), 83 nIterCount( rCpy.nIterCount ), 84 nPrecStandardFormat( rCpy.nPrecStandardFormat ), 85 nDay( rCpy.nDay ), 86 nMonth( rCpy.nMonth ), 87 nYear( rCpy.nYear ), 88 nYear2000( rCpy.nYear2000 ), 89 nTabDistance( rCpy.nTabDistance ), 90 bIsIgnoreCase( rCpy.bIsIgnoreCase ), 91 bIsIter( rCpy.bIsIter ), 92 bCalcAsShown( rCpy.bCalcAsShown ), 93 bMatchWholeCell( rCpy.bMatchWholeCell ), 94 bDoAutoSpell( rCpy.bDoAutoSpell ), 95 bLookUpColRowNames( rCpy.bLookUpColRowNames ), 96 bFormulaRegexEnabled( rCpy.bFormulaRegexEnabled ) 97 { 98 } 99 100 //------------------------------------------------------------------------ 101 102 ScDocOptions::~ScDocOptions() 103 { 104 } 105 106 //------------------------------------------------------------------------ 107 108 void ScDocOptions::ResetDocOptions() 109 { 110 bIsIgnoreCase = sal_False; 111 bIsIter = sal_False; 112 nIterCount = 100; 113 fIterEps = 1.0E-3; 114 nPrecStandardFormat = SvNumberFormatter::UNLIMITED_PRECISION; 115 nDay = 30; 116 nMonth = 12; 117 nYear = 1899; 118 nYear2000 = SvNumberFormatter::GetYear2000Default(); 119 nTabDistance = lcl_GetDefaultTabDist(); 120 bCalcAsShown = sal_False; 121 bMatchWholeCell = sal_True; 122 bDoAutoSpell = sal_False; 123 bLookUpColRowNames = sal_True; 124 bFormulaRegexEnabled= sal_True; 125 } 126 127 //======================================================================== 128 // ScTpCalcItem - Daten fuer die CalcOptions-TabPage 129 //======================================================================== 130 131 //UNUSED2008-05 ScTpCalcItem::ScTpCalcItem( sal_uInt16 nWhichP ) : SfxPoolItem( nWhichP ) 132 //UNUSED2008-05 { 133 //UNUSED2008-05 } 134 135 //------------------------------------------------------------------------ 136 137 ScTpCalcItem::ScTpCalcItem( sal_uInt16 nWhichP, const ScDocOptions& rOpt ) 138 : SfxPoolItem ( nWhichP ), 139 theOptions ( rOpt ) 140 { 141 } 142 143 //------------------------------------------------------------------------ 144 145 ScTpCalcItem::ScTpCalcItem( const ScTpCalcItem& rItem ) 146 : SfxPoolItem ( rItem ), 147 theOptions ( rItem.theOptions ) 148 { 149 } 150 151 //------------------------------------------------------------------------ 152 153 __EXPORT ScTpCalcItem::~ScTpCalcItem() 154 { 155 } 156 157 //------------------------------------------------------------------------ 158 159 String __EXPORT ScTpCalcItem::GetValueText() const 160 { 161 return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("ScTpCalcItem") ); 162 } 163 164 //------------------------------------------------------------------------ 165 166 int __EXPORT ScTpCalcItem::operator==( const SfxPoolItem& rItem ) const 167 { 168 DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal Which or Type" ); 169 170 const ScTpCalcItem& rPItem = (const ScTpCalcItem&)rItem; 171 172 return ( theOptions == rPItem.theOptions ); 173 } 174 175 //------------------------------------------------------------------------ 176 177 SfxPoolItem* __EXPORT ScTpCalcItem::Clone( SfxItemPool * ) const 178 { 179 return new ScTpCalcItem( *this ); 180 } 181 182 //================================================================== 183 // Config Item containing document options 184 //================================================================== 185 186 #define CFGPATH_CALC "Office.Calc/Calculate" 187 188 #define SCCALCOPT_ITER_ITER 0 189 #define SCCALCOPT_ITER_STEPS 1 190 #define SCCALCOPT_ITER_MINCHG 2 191 #define SCCALCOPT_DATE_DAY 3 192 #define SCCALCOPT_DATE_MONTH 4 193 #define SCCALCOPT_DATE_YEAR 5 194 #define SCCALCOPT_DECIMALS 6 195 #define SCCALCOPT_CASESENSITIVE 7 196 #define SCCALCOPT_PRECISION 8 197 #define SCCALCOPT_SEARCHCRIT 9 198 #define SCCALCOPT_FINDLABEL 10 199 #define SCCALCOPT_REGEX 11 200 #define SCCALCOPT_COUNT 12 201 202 #define CFGPATH_DOCLAYOUT "Office.Calc/Layout/Other" 203 204 #define SCDOCLAYOUTOPT_TABSTOP 0 205 #define SCDOCLAYOUTOPT_COUNT 1 206 207 208 Sequence<OUString> ScDocCfg::GetCalcPropertyNames() 209 { 210 static const char* aPropNames[] = 211 { 212 "IterativeReference/Iteration", // SCCALCOPT_ITER_ITER 213 "IterativeReference/Steps", // SCCALCOPT_ITER_STEPS 214 "IterativeReference/MinimumChange", // SCCALCOPT_ITER_MINCHG 215 "Other/Date/DD", // SCCALCOPT_DATE_DAY 216 "Other/Date/MM", // SCCALCOPT_DATE_MONTH 217 "Other/Date/YY", // SCCALCOPT_DATE_YEAR 218 "Other/DecimalPlaces", // SCCALCOPT_DECIMALS 219 "Other/CaseSensitive", // SCCALCOPT_CASESENSITIVE 220 "Other/Precision", // SCCALCOPT_PRECISION 221 "Other/SearchCriteria", // SCCALCOPT_SEARCHCRIT 222 "Other/FindLabel", // SCCALCOPT_FINDLABEL 223 "Other/RegularExpressions" // SCCALCOPT_REGEX 224 }; 225 Sequence<OUString> aNames(SCCALCOPT_COUNT); 226 OUString* pNames = aNames.getArray(); 227 for(int i = 0; i < SCCALCOPT_COUNT; i++) 228 pNames[i] = OUString::createFromAscii(aPropNames[i]); 229 230 return aNames; 231 } 232 233 Sequence<OUString> ScDocCfg::GetLayoutPropertyNames() 234 { 235 static const char* aPropNames[] = 236 { 237 "TabStop/NonMetric" // SCDOCLAYOUTOPT_TABSTOP 238 }; 239 Sequence<OUString> aNames(SCDOCLAYOUTOPT_COUNT); 240 OUString* pNames = aNames.getArray(); 241 for(int i = 0; i < SCDOCLAYOUTOPT_COUNT; i++) 242 pNames[i] = OUString::createFromAscii(aPropNames[i]); 243 244 // adjust for metric system 245 if (ScOptionsUtil::IsMetricSystem()) 246 pNames[SCDOCLAYOUTOPT_TABSTOP] = OUString::createFromAscii( "TabStop/Metric" ); 247 248 return aNames; 249 } 250 251 ScDocCfg::ScDocCfg() : 252 aCalcItem( OUString::createFromAscii( CFGPATH_CALC ) ), 253 aLayoutItem( OUString::createFromAscii( CFGPATH_DOCLAYOUT ) ) 254 { 255 sal_Int32 nIntVal = 0; 256 double fDoubleVal = 0; 257 258 Sequence<OUString> aNames; 259 Sequence<Any> aValues; 260 const Any* pValues = NULL; 261 262 sal_uInt16 nDateDay, nDateMonth, nDateYear; 263 GetDate( nDateDay, nDateMonth, nDateYear ); 264 265 aNames = GetCalcPropertyNames(); 266 aValues = aCalcItem.GetProperties(aNames); 267 aCalcItem.EnableNotification(aNames); 268 pValues = aValues.getConstArray(); 269 DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); 270 if(aValues.getLength() == aNames.getLength()) 271 { 272 for(int nProp = 0; nProp < aNames.getLength(); nProp++) 273 { 274 DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); 275 if(pValues[nProp].hasValue()) 276 { 277 switch(nProp) 278 { 279 case SCCALCOPT_ITER_ITER: 280 SetIter( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); 281 break; 282 case SCCALCOPT_ITER_STEPS: 283 if (pValues[nProp] >>= nIntVal) SetIterCount( (sal_uInt16) nIntVal ); 284 break; 285 case SCCALCOPT_ITER_MINCHG: 286 if (pValues[nProp] >>= fDoubleVal) SetIterEps( fDoubleVal ); 287 break; 288 case SCCALCOPT_DATE_DAY: 289 if (pValues[nProp] >>= nIntVal) nDateDay = (sal_uInt16) nIntVal; 290 break; 291 case SCCALCOPT_DATE_MONTH: 292 if (pValues[nProp] >>= nIntVal) nDateMonth = (sal_uInt16) nIntVal; 293 break; 294 case SCCALCOPT_DATE_YEAR: 295 if (pValues[nProp] >>= nIntVal) nDateYear = (sal_uInt16) nIntVal; 296 break; 297 case SCCALCOPT_DECIMALS: 298 if (pValues[nProp] >>= nIntVal) SetStdPrecision( (sal_uInt16) nIntVal ); 299 break; 300 case SCCALCOPT_CASESENSITIVE: 301 // content is reversed 302 SetIgnoreCase( !ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); 303 break; 304 case SCCALCOPT_PRECISION: 305 SetCalcAsShown( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); 306 break; 307 case SCCALCOPT_SEARCHCRIT: 308 SetMatchWholeCell( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); 309 break; 310 case SCCALCOPT_FINDLABEL: 311 SetLookUpColRowNames( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); 312 break; 313 case SCCALCOPT_REGEX : 314 SetFormulaRegexEnabled( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) ); 315 break; 316 } 317 } 318 } 319 } 320 aCalcItem.SetCommitLink( LINK( this, ScDocCfg, CalcCommitHdl ) ); 321 322 SetDate( nDateDay, nDateMonth, nDateYear ); 323 324 aNames = GetLayoutPropertyNames(); 325 aValues = aLayoutItem.GetProperties(aNames); 326 aLayoutItem.EnableNotification(aNames); 327 pValues = aValues.getConstArray(); 328 DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); 329 if(aValues.getLength() == aNames.getLength()) 330 { 331 for(int nProp = 0; nProp < aNames.getLength(); nProp++) 332 { 333 DBG_ASSERT(pValues[nProp].hasValue(), "property value missing"); 334 if(pValues[nProp].hasValue()) 335 { 336 switch(nProp) 337 { 338 case SCDOCLAYOUTOPT_TABSTOP: 339 // TabDistance in ScDocOptions is in twips 340 if (pValues[nProp] >>= nIntVal) 341 SetTabDistance( (sal_uInt16) HMMToTwips( nIntVal ) ); 342 break; 343 } 344 } 345 } 346 } 347 aLayoutItem.SetCommitLink( LINK( this, ScDocCfg, LayoutCommitHdl ) ); 348 } 349 350 IMPL_LINK( ScDocCfg, CalcCommitHdl, void *, EMPTYARG ) 351 { 352 Sequence<OUString> aNames = GetCalcPropertyNames(); 353 Sequence<Any> aValues(aNames.getLength()); 354 Any* pValues = aValues.getArray(); 355 356 sal_uInt16 nDateDay, nDateMonth, nDateYear; 357 GetDate( nDateDay, nDateMonth, nDateYear ); 358 359 for(int nProp = 0; nProp < aNames.getLength(); nProp++) 360 { 361 switch(nProp) 362 { 363 case SCCALCOPT_ITER_ITER: 364 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsIter() ); 365 break; 366 case SCCALCOPT_ITER_STEPS: 367 pValues[nProp] <<= (sal_Int32) GetIterCount(); 368 break; 369 case SCCALCOPT_ITER_MINCHG: 370 pValues[nProp] <<= (double) GetIterEps(); 371 break; 372 case SCCALCOPT_DATE_DAY: 373 pValues[nProp] <<= (sal_Int32) nDateDay; 374 break; 375 case SCCALCOPT_DATE_MONTH: 376 pValues[nProp] <<= (sal_Int32) nDateMonth; 377 break; 378 case SCCALCOPT_DATE_YEAR: 379 pValues[nProp] <<= (sal_Int32) nDateYear; 380 break; 381 case SCCALCOPT_DECIMALS: 382 pValues[nProp] <<= (sal_Int32) GetStdPrecision(); 383 break; 384 case SCCALCOPT_CASESENSITIVE: 385 // content is reversed 386 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], !IsIgnoreCase() ); 387 break; 388 case SCCALCOPT_PRECISION: 389 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsCalcAsShown() ); 390 break; 391 case SCCALCOPT_SEARCHCRIT: 392 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsMatchWholeCell() ); 393 break; 394 case SCCALCOPT_FINDLABEL: 395 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsLookUpColRowNames() ); 396 break; 397 case SCCALCOPT_REGEX : 398 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], IsFormulaRegexEnabled() ); 399 } 400 } 401 aCalcItem.PutProperties(aNames, aValues); 402 403 return 0; 404 } 405 406 IMPL_LINK( ScDocCfg, LayoutCommitHdl, void *, EMPTYARG ) 407 { 408 Sequence<OUString> aNames = GetLayoutPropertyNames(); 409 Sequence<Any> aValues(aNames.getLength()); 410 Any* pValues = aValues.getArray(); 411 412 for(int nProp = 0; nProp < aNames.getLength(); nProp++) 413 { 414 switch(nProp) 415 { 416 case SCDOCLAYOUTOPT_TABSTOP: 417 // TabDistance in ScDocOptions is in twips 418 // use only even numbers, so defaults don't get changed 419 // by modifying other settings in the same config item 420 pValues[nProp] <<= (sal_Int32) TwipsToEvenHMM( GetTabDistance() ); 421 break; 422 } 423 } 424 aLayoutItem.PutProperties(aNames, aValues); 425 426 return 0; 427 } 428 429 430 void ScDocCfg::SetOptions( const ScDocOptions& rNew ) 431 { 432 *(ScDocOptions*)this = rNew; 433 434 aCalcItem.SetModified(); 435 aLayoutItem.SetModified(); 436 } 437 438 439