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 #ifndef ANALYSISHELPER_HXX 24 #define ANALYSISHELPER_HXX 25 26 27 #include <com/sun/star/lang/XServiceName.hpp> 28 #include <com/sun/star/lang/XServiceInfo.hpp> 29 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 30 #include <com/sun/star/util/Date.hpp> 31 #include <com/sun/star/util/XNumberFormatter.hpp> 32 #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 33 #include <com/sun/star/sheet/XAddIn.hpp> 34 #include <com/sun/star/sheet/addin/XAnalysis.hpp> 35 36 #include <math.h> 37 38 #include <tools/resid.hxx> 39 #include <tools/rc.hxx> 40 41 #include "analysisdefs.hxx" 42 43 44 class ResMgr; 45 class SortedIndividualInt32List; 46 class ScaAnyConverter; 47 48 49 #define PI 3.1415926535897932 50 #define PI_2 (PI/2.0) 51 //#define EULER 2.7182818284590452 52 #define EOL ( ( const sal_Char* ) 1 ) 53 #define EOE ( ( const sal_Char* ) 2 ) 54 55 56 //double _Test( sal_Int32 nMode, double f1, double f2, double f3 ); 57 inline sal_Bool IsLeapYear( sal_uInt16 nYear ); 58 sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear ); 59 sal_Int32 DateToDays( sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear ); 60 void DaysToDate( sal_Int32 nDays, sal_uInt16& rDay, sal_uInt16& rMonth, sal_uInt16& rYear ) throw( ::com::sun::star::lang::IllegalArgumentException ); 61 sal_Int32 GetNullDate( const REF( CSS::beans::XPropertySet )& xOptions ) THROWDEF_RTE; 62 sal_Int32 GetDiffDate360( 63 sal_uInt16 nDay1, sal_uInt16 nMonth1, sal_uInt16 nYear1, sal_Bool bLeapYear1, 64 sal_uInt16 nDay2, sal_uInt16 nMonth2, sal_uInt16 nYear2, 65 sal_Bool bUSAMethod ); 66 inline sal_Int32 GetDiffDate360( constREFXPS& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod ); 67 sal_Int32 GetDiffDate360( sal_Int32 nNullDate, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod ); 68 69 sal_Int32 GetDaysInYears( sal_uInt16 nYear1, sal_uInt16 nYear2 ); 70 inline sal_Int16 GetDayOfWeek( sal_Int32 nDate ); 71 void GetDiffParam( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode, 72 sal_uInt16& rYears, sal_Int32& rDayDiffPart, sal_Int32& rDaysInYear ) THROWDEF_RTE_IAE; 73 // rYears = full num of years 74 // rDayDiffPart = num of days for last year 75 // rDaysInYear = num of days in first year 76 sal_Int32 GetDiffDate( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode, 77 sal_Int32* pOptDaysIn1stYear = NULL ) THROWDEF_RTE_IAE; 78 double GetYearDiff( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) 79 THROWDEF_RTE_IAE; 80 sal_Int32 GetDaysInYear( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nMode ) THROWDEF_RTE_IAE; 81 double GetYearFrac( sal_Int32 nNullDate, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) 82 THROWDEF_RTE_IAE; 83 inline double GetYearFrac( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) 84 THROWDEF_RTE_IAE; 85 inline void AlignDate( sal_uInt16& rDay, sal_uInt16 nMonth, sal_uInt16 nYear ); 86 87 double Fak( sal_Int32 n ); 88 double GetGcd( double f1, double f2 ); 89 double ConvertToDec( const STRING& rFromNum, sal_uInt16 nBaseFrom, sal_uInt16 nCharLim ) THROWDEF_RTE_IAE; 90 STRING ConvertFromDec( 91 double fNum, double fMin, double fMax, sal_uInt16 nBase, 92 sal_Int32 nPlaces, sal_Int32 nMaxPlaces, sal_Bool bUsePlaces ) THROWDEF_RTE_IAE; 93 double Erf( double fX ); 94 double Erfc( double fX ); 95 sal_Bool ParseDouble( const sal_Unicode*& rpDoubleAsString, double& rReturn ); 96 STRING GetString( double fNumber, sal_Bool bLeadingSign = sal_False, sal_uInt16 nMaxNumOfDigits = 15 ); 97 inline double Exp10( sal_Int16 nPower ); // 10 ^ nPower 98 99 double GetAmordegrc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, 100 double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE; 101 double GetAmorlinc( sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, 102 double fRestVal, double fPer, double fRate, sal_Int32 nBase ) THROWDEF_RTE_IAE; 103 double GetDuration( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, 104 double fYield, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 105 double GetYieldmat( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, 106 double fRate, double fPrice, sal_Int32 nBase ) THROWDEF_RTE_IAE; 107 double GetOddfprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, 108 sal_Int32 nFirstCoup, double fRate, double fYield, double fRedemp, 109 sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 110 double getYield_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice, 111 double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 112 double getPrice_( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield, 113 double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 114 double GetOddfyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, 115 sal_Int32 nFirstCoup, double fRate, double fPrice, double fRedemp, 116 sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 117 double GetOddlprice( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest, 118 double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 119 double GetOddlyield( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest, 120 double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 121 double GetRmz( double fZins, double fZzr, double fBw, double fZw, sal_Int32 nF ); 122 double GetZw( double fZins, double fZzr, double fRmz, double fBw, sal_Int32 nF ); 123 //double TBillYield( constREFXPS& xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice )THROWDEF_RTE_IAE; 124 125 double GetCouppcd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, 126 sal_Int32 nBase ) THROWDEF_RTE_IAE; 127 double GetCoupncd( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, 128 sal_Int32 nBase ) THROWDEF_RTE_IAE; 129 double GetCoupdaybs( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, 130 sal_Int32 nBase ) THROWDEF_RTE_IAE; 131 double GetCoupdaysnc( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, 132 sal_Int32 nBase ) THROWDEF_RTE_IAE; 133 134 double GetCoupnum( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, 135 sal_Int32 nFreq, sal_Int32 nBase ) THROWDEF_RTE_IAE; 136 double GetCoupdays( sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, 137 sal_Int32 nBase ) THROWDEF_RTE_IAE; 138 139 140 141 142 //----------------------------------------------------------------------------- 143 144 145 146 class MyList 147 { 148 private: 149 static const sal_uInt32 nStartSize; 150 static const sal_uInt32 nIncrSize; 151 152 void** pData; // pointer array 153 sal_uInt32 nSize; // array size 154 sal_uInt32 nNew; // next index to be inserted at 155 sal_uInt32 nAct; // actual for iterations 156 157 void _Grow( void ); 158 inline void Grow( void ); 159 protected: 160 public: 161 MyList( void ); 162 virtual ~MyList(); 163 164 inline const void* GetObject( sal_uInt32 nIndex ) const; 165 inline const void* First( void ); 166 inline const void* Next( void ); 167 168 inline void Append( void* pNewElement ); 169 void Insert( void* pNewLement, sal_uInt32 nPlace ); 170 171 inline sal_uInt32 Count( void ) const; 172 }; 173 174 175 176 177 class StringList : protected MyList 178 { 179 public: 180 virtual ~StringList(); 181 182 inline const STRING* First( void ); 183 inline const STRING* Next( void ); 184 inline const STRING* Get( sal_uInt32 nIndex ) const; 185 186 using MyList::Append; 187 inline void Append( STRING* pNew ); 188 inline void Append( const STRING& rNew ); 189 190 using MyList::Count; 191 }; 192 193 194 195 196 enum FDCategory 197 { 198 FDCat_AddIn, 199 FDCat_DateTime, 200 FDCat_Finance, 201 FDCat_Inf, 202 FDCat_Math, 203 FDCat_Tech 204 }; 205 206 207 struct FuncDataBase 208 { 209 const sal_Char* pIntName; 210 sal_uInt16 nUINameID; // resource ID to UI name 211 sal_uInt16 nDescrID; // resource ID to description, parameter names and ~ description 212 sal_Bool bDouble; // name already exist in Calc 213 sal_Bool bWithOpt; // first parameter is internal 214 sal_uInt16 nCompListID; // resource ID to list of valid names 215 sal_uInt16 nNumOfParams; // number of named / described parameters 216 FDCategory eCat; // function category 217 }; 218 219 220 221 222 class FuncData 223 { 224 private: 225 ::rtl::OUString aIntName; 226 sal_uInt16 nUINameID; 227 sal_uInt16 nDescrID; // leads also to parameter descriptions! 228 sal_Bool bDouble; // flag for names, wich already exist in Calc 229 sal_Bool bWithOpt; // has internal parameter on first position 230 231 sal_uInt16 nParam; // num of parameters 232 sal_uInt16 nCompID; 233 StringList aCompList; // list of all valid names 234 FDCategory eCat; // function category 235 public: 236 FuncData( const FuncDataBase& rBaseData, ResMgr& ); 237 virtual ~FuncData(); 238 239 inline sal_uInt16 GetUINameID( void ) const; 240 inline sal_uInt16 GetDescrID( void ) const; 241 inline sal_Bool IsDouble( void ) const; 242 inline sal_Bool HasIntParam( void ) const; 243 244 sal_uInt16 GetStrIndex( sal_uInt16 nParamNum ) const; 245 inline sal_Bool Is( const ::rtl::OUString& rCompareTo ) const; 246 247 inline const StringList& GetCompNameList( void ) const; 248 249 inline FDCategory GetCategory( void ) const; 250 }; 251 252 253 254 255 class CStrList : private MyList 256 { 257 public: 258 using MyList::Append; 259 inline void Append( const sal_Char* pNew ); 260 inline const sal_Char* Get( sal_uInt32 nIndex ) const; 261 using MyList::Count; 262 }; 263 264 265 266 267 class FuncDataList : private MyList 268 { 269 ::rtl::OUString aLastName; 270 sal_uInt32 nLast; 271 public: 272 FuncDataList( ResMgr& ); 273 virtual ~FuncDataList(); 274 using MyList::Append; 275 inline void Append( FuncData* pNew ); 276 inline const FuncData* Get( sal_uInt32 nIndex ) const; 277 using MyList::Count; 278 279 const FuncData* Get( const ::rtl::OUString& aProgrammaticName ) const; 280 }; 281 282 283 284 class AnalysisResId : public ResId 285 { 286 public: 287 AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr ); 288 }; 289 290 291 292 293 class AnalysisRscStrLoader : public Resource 294 { 295 private: 296 String aStr; 297 public: 298 AnalysisRscStrLoader( sal_uInt16 nRsc, sal_uInt16 nStrId, ResMgr& rResMgr ) : 299 Resource( AnalysisResId( nRsc, rResMgr ) ), 300 aStr( AnalysisResId( nStrId, rResMgr ) ) 301 { 302 FreeResource(); 303 } 304 305 const String& GetString() const { return aStr; } 306 307 }; 308 309 310 311 //----------------------------------------------------------------------------- 312 313 /// sorted list with unique sal_Int32 values 314 class SortedIndividualInt32List : private MyList 315 { 316 protected: 317 using MyList::Insert; 318 void Insert( sal_Int32 nDay ); 319 void Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend ); 320 void Insert( double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend ) 321 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 322 323 /** @param rAnyConv must be an initialized ScaAnyConmverter 324 @param bInsertOnWeekend insertion mode: sal_False = holidays on weekend are omitted */ 325 void InsertHolidayList( 326 const ScaAnyConverter& rAnyConv, 327 const CSS::uno::Any& rHolAny, 328 sal_Int32 nNullDate, 329 sal_Bool bInsertOnWeekend ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 330 331 public: 332 SortedIndividualInt32List(); 333 virtual ~SortedIndividualInt32List(); 334 335 using MyList::Count; 336 337 /// @return element on position nIndex or 0 on invalid index 338 inline sal_Int32 Get( sal_uInt32 nIndex ) const 339 { return (sal_Int32)(sal_IntPtr) MyList::GetObject( nIndex ); } 340 341 /// @return sal_True if nVal (internal date representation) is contained 342 sal_Bool Find( sal_Int32 nVal ) const; 343 344 /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter 345 @param bInsertOnWeekend insertion mode: sal_False = holidays on weekend are omitted */ 346 void InsertHolidayList( 347 ScaAnyConverter& rAnyConv, 348 const CSS::uno::Reference< CSS::beans::XPropertySet >& xOptions, 349 const CSS::uno::Any& rHolAny, 350 sal_Int32 nNullDate, 351 sal_Bool bInsertOnWeekend ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 352 }; 353 354 355 //----------------------------------------------------------------------------- 356 357 class ScaDoubleList : protected MyList 358 { 359 protected: 360 inline void ListAppend( double fValue ) { MyList::Append( new double( fValue ) ); } 361 362 using MyList::Append; 363 inline void Append( double fValue ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ) 364 { if( CheckInsert( fValue ) ) ListAppend( fValue ); } 365 366 /** @param rAnyConv must be an initialized ScaAnyConmverter 367 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */ 368 void Append( 369 const ScaAnyConverter& rAnyConv, 370 const CSS::uno::Any& rAny, 371 sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 372 373 /** @param rAnyConv must be an initialized ScaAnyConmverter 374 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */ 375 void Append( 376 const ScaAnyConverter& rAnyConv, 377 const CSS::uno::Sequence< CSS::uno::Any >& rAnySeq, 378 sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 379 380 /** @param rAnyConv must be an initialized ScaAnyConmverter 381 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */ 382 void Append( 383 const ScaAnyConverter& rAnyConv, 384 const CSS::uno::Sequence< CSS::uno::Sequence< CSS::uno::Any > >& rAnySeq, 385 sal_Bool bIgnoreEmpty ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 386 387 public: 388 virtual ~ScaDoubleList(); 389 390 using MyList::Count; 391 inline const double* Get( sal_uInt32 nIndex ) const 392 { return static_cast< const double* >( MyList::GetObject( nIndex ) ); } 393 394 inline const double* First() { return static_cast< const double* >( MyList::First() ); } 395 inline const double* Next() { return static_cast< const double* >( MyList::Next() ); } 396 397 void Append( const CSS::uno::Sequence< CSS::uno::Sequence< double > >& rValueArr ) 398 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 399 void Append( const CSS::uno::Sequence< CSS::uno::Sequence< sal_Int32 > >& rValueArr ) 400 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 401 402 /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter 403 @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */ 404 void Append( 405 ScaAnyConverter& rAnyConv, 406 const CSS::uno::Reference< CSS::beans::XPropertySet >& xOpt, 407 const CSS::uno::Sequence< CSS::uno::Any >& rAnySeq, 408 sal_Bool bIgnoreEmpty = sal_True ) throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 409 410 virtual sal_Bool CheckInsert( double fValue ) const 411 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 412 }; 413 414 415 //----------------------------------------------------------------------------- 416 417 /// stores double values >0.0, throws exception for double values <0.0, does nothing for 0.0 418 class ScaDoubleListGT0 : public ScaDoubleList 419 { 420 public: 421 virtual sal_Bool CheckInsert( double fValue ) const 422 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 423 }; 424 425 426 //----------------------------------------------------------------------------- 427 428 /// stores double values >=0.0, throws exception for double values <0.0 429 class ScaDoubleListGE0 : public ScaDoubleList 430 { 431 public: 432 virtual sal_Bool CheckInsert( double fValue ) const 433 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 434 }; 435 436 437 //----------------------------------------------------------------------------- 438 439 class Complex 440 { 441 double r; 442 double i; 443 sal_Unicode c; 444 445 public: 446 inline Complex( double fReal, double fImag = 0.0, sal_Char cC = '\0' ); 447 Complex( const STRING& rComplexAsString ) THROWDEF_RTE_IAE; 448 449 inline static sal_Bool IsImagUnit( sal_Unicode c ); 450 static sal_Bool ParseString( const STRING& rComplexAsString, Complex& rReturn ); 451 STRING GetString() const THROWDEF_RTE_IAE; 452 453 inline double Real( void ) const; 454 inline double Imag( void ) const; 455 456 double Arg( void ) const THROWDEF_RTE_IAE; 457 inline double Abs( void ) const; 458 459 // following functions change the complex number itself to avoid unnecessary copy actions! 460 void Power( double fPower ) THROWDEF_RTE_IAE; 461 void Sqrt( void ); 462 void Sin( void ) THROWDEF_RTE_IAE; 463 void Cos( void ) THROWDEF_RTE_IAE; 464 void Div( const Complex& rDivisor ) THROWDEF_RTE_IAE; 465 void Exp( void ); 466 inline void Conjugate( void ); 467 void Ln( void ) THROWDEF_RTE_IAE; 468 void Log10( void ) THROWDEF_RTE_IAE; 469 void Log2( void ) THROWDEF_RTE_IAE; 470 inline void Mult( double fFact ); 471 inline void Mult( const Complex& rMult ); 472 inline void Sub( const Complex& rMult ); 473 inline void Add( const Complex& rAdd ); 474 }; 475 476 477 478 479 enum ComplListAppendHandl 480 { 481 AH_EmptyAsErr, 482 AH_EmpyAs0, 483 AH_IgnoreEmpty 484 }; 485 486 487 class ComplexList : protected MyList 488 { 489 public: 490 virtual ~ComplexList(); 491 492 inline const Complex* Get( sal_uInt32 nIndex ) const; 493 inline const Complex* First( void ); 494 inline const Complex* Next( void ); 495 496 using MyList::Count; 497 498 using MyList::Append; 499 inline void Append( Complex* pNew ); 500 void Append( const SEQSEQ( STRING )& rComplexNumList, ComplListAppendHandl eAH = AH_EmpyAs0 ) THROWDEF_RTE_IAE; 501 void Append( const SEQ( ANY )& aMultPars,ComplListAppendHandl eAH = AH_EmpyAs0 ) THROWDEF_RTE_IAE; 502 }; 503 504 505 506 507 enum ConvertDataClass 508 { 509 CDC_Mass, CDC_Length, CDC_Time, CDC_Pressure, CDC_Force, CDC_Energy, CDC_Power, CDC_Magnetism, 510 CDC_Temperature, CDC_Volume, CDC_Area, CDC_Speed, CDC_Information 511 }; 512 513 514 #define INV_MATCHLEV 1764 // guess, what this is... :-) 515 516 517 class ConvertDataList; 518 519 520 521 522 class ConvertData 523 { 524 protected: 525 friend class ConvertDataList; 526 double fConst; 527 STRING aName; 528 ConvertDataClass eClass; 529 sal_Bool bPrefixSupport; 530 public: 531 ConvertData( 532 const sal_Char pUnitName[], 533 double fConvertConstant, 534 ConvertDataClass eClass, 535 sal_Bool bPrefSupport = sal_False ); 536 537 virtual ~ConvertData(); 538 539 sal_Int16 GetMatchingLevel( const STRING& rRef ) const; 540 // 0.0 = no equality 541 // 1.0 = matches exact 542 // rest = matches without an assumed prefix of one character 543 // rest gives power for 10 represented by the prefix (e.g. 3 for k or -9 for n 544 545 virtual double Convert( double fVal, const ConvertData& rTo, 546 sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const THROWDEF_RTE_IAE; 547 // converts fVal from this unit to rFrom unit 548 // throws exception if not from same class 549 // this implementation is for proportional cases only 550 virtual double ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const; 551 virtual double ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const; 552 553 inline ConvertDataClass Class( void ) const; 554 inline sal_Bool IsPrefixSupport( void ) const; 555 }; 556 557 558 559 560 class ConvertDataLinear : public ConvertData 561 { 562 protected: 563 double fOffs; 564 public: 565 inline ConvertDataLinear( 566 const sal_Char pUnitName[], 567 double fConvertConstant, 568 double fConvertOffset, 569 ConvertDataClass eClass, 570 sal_Bool bPrefSupport = sal_False ); 571 572 virtual ~ConvertDataLinear(); 573 574 virtual double Convert( double fVal, const ConvertData& rTo, 575 sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const THROWDEF_RTE_IAE; 576 // for cases where f(x) = a + bx applies (e.g. Temperatures) 577 578 virtual double ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const; 579 virtual double ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const; 580 }; 581 582 583 584 585 class ConvertDataList : protected MyList 586 { 587 private: 588 protected: 589 inline ConvertData* First( void ); 590 inline ConvertData* Next( void ); 591 public: 592 ConvertDataList( void ); 593 virtual ~ConvertDataList(); 594 595 double Convert( double fVal, const STRING& rFrom, const STRING& rTo ) THROWDEF_RTE_IAE; 596 }; 597 598 599 600 601 inline sal_Bool IsLeapYear( sal_uInt16 n ) 602 { 603 return ( (( ( n % 4 ) == 0 ) && ( ( n % 100 ) != 0)) || ( ( n % 400 ) == 0 ) ); 604 } 605 606 607 inline sal_Int32 GetDiffDate360( constREFXPS& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod ) 608 { 609 return GetDiffDate360( GetNullDate( xOpt ), nDate1, nDate2, bUSAMethod ); 610 } 611 612 613 inline sal_Int16 GetDayOfWeek( sal_Int32 n ) 614 { // monday = 0, ..., sunday = 6 615 return static_cast< sal_Int16 >( ( n - 1 ) % 7 ); 616 } 617 618 619 inline double GetYearFrac( constREFXPS& xOpt, sal_Int32 nStartDate, sal_Int32 nEndDate, sal_Int32 nMode ) THROWDEF_RTE_IAE 620 { 621 return GetYearFrac( GetNullDate( xOpt ), nStartDate, nEndDate, nMode ); 622 } 623 624 625 inline void AlignDate( sal_uInt16& rD, sal_uInt16 nM, sal_uInt16 nY ) 626 { 627 sal_uInt16 nMax = DaysInMonth( nM, nY ); 628 629 if( rD > nMax ) 630 rD = nMax; 631 } 632 633 634 inline void MyList::Grow( void ) 635 { 636 if( nNew >= nSize ) 637 _Grow(); 638 } 639 640 641 inline const void* MyList::GetObject( sal_uInt32 n ) const 642 { 643 if( n < nNew ) 644 return pData[ n ]; 645 else 646 return NULL; 647 } 648 649 650 inline const void* MyList::First( void ) 651 { 652 nAct = 0; 653 if( nNew ) 654 return pData[ 0 ]; 655 else 656 return NULL; 657 } 658 659 660 inline const void* MyList::Next( void ) 661 { 662 nAct++; 663 if( nAct < nNew ) 664 return pData[ nAct ]; 665 else 666 { 667 nAct--; 668 return NULL; 669 } 670 } 671 672 673 inline void MyList::Append( void* p ) 674 { 675 Grow(); 676 pData[ nNew ] = p; 677 nNew++; 678 } 679 680 681 inline sal_uInt32 MyList::Count( void ) const 682 { 683 return nNew; 684 } 685 686 687 688 689 inline const STRING* StringList::First( void ) 690 { 691 return ( const STRING* ) MyList::First(); 692 } 693 694 695 inline const STRING* StringList::Next( void ) 696 { 697 return ( const STRING* ) MyList::Next(); 698 } 699 700 701 inline const STRING* StringList::Get( sal_uInt32 n ) const 702 { 703 return ( const STRING* ) MyList::GetObject( n ); 704 } 705 706 707 inline void StringList::Append( STRING* p ) 708 { 709 MyList::Append( p ); 710 } 711 712 713 inline void StringList::Append( const STRING& r ) 714 { 715 MyList::Append( new STRING( r ) ); 716 } 717 718 719 720 721 inline sal_uInt16 FuncData::GetUINameID( void ) const 722 { 723 return nUINameID; 724 } 725 726 727 inline sal_uInt16 FuncData::GetDescrID( void ) const 728 { 729 return nDescrID; 730 } 731 732 733 inline sal_Bool FuncData::IsDouble( void ) const 734 { 735 return bDouble; 736 } 737 738 739 inline sal_Bool FuncData::HasIntParam( void ) const 740 { 741 return bWithOpt; 742 } 743 744 745 inline sal_Bool FuncData::Is( const ::rtl::OUString& r ) const 746 { 747 return aIntName == r; 748 } 749 750 751 inline const StringList& FuncData::GetCompNameList( void ) const 752 { 753 return aCompList; 754 } 755 756 757 inline FDCategory FuncData::GetCategory( void ) const 758 { 759 return eCat; 760 } 761 762 763 764 765 inline void CStrList::Append( const sal_Char* p ) 766 { 767 MyList::Append( ( void* ) p ); 768 } 769 770 771 inline const sal_Char* CStrList::Get( sal_uInt32 n ) const 772 { 773 return ( const sal_Char* ) MyList::GetObject( n ); 774 } 775 776 777 778 779 inline void FuncDataList::Append( FuncData* p ) 780 { 781 MyList::Append( p ); 782 } 783 784 785 inline const FuncData* FuncDataList::Get( sal_uInt32 n ) const 786 { 787 return ( const FuncData* ) MyList::GetObject( n ); 788 } 789 790 791 inline Complex::Complex( double fReal, double fImag, sal_Char cC ) : 792 r( fReal ), i( fImag ), c( cC ) 793 { 794 } 795 796 797 inline double Complex::Real( void ) const 798 { 799 return r; 800 } 801 802 803 inline double Complex::Imag( void ) const 804 { 805 return i; 806 } 807 808 809 inline double Complex::Abs( void ) const 810 { 811 return sqrt( r * r + i * i ); 812 } 813 814 815 void Complex::Conjugate( void ) 816 { 817 i = -i; 818 } 819 820 821 inline void Complex::Mult( double f ) 822 { 823 i *= f; 824 r *= f; 825 } 826 827 828 inline void Complex::Mult( const Complex& rM ) 829 { 830 double r_ = r; 831 double i_ = i; 832 833 r = r_ * rM.r - i_ * rM.i; 834 i = r_ * rM.i + i_ * rM.r; 835 836 if( !c ) c = rM.c; 837 } 838 839 840 inline void Complex::Sub( const Complex& rC ) 841 { 842 r -= rC.r; 843 i -= rC.i; 844 if( !c ) c = rC.c; 845 } 846 847 848 inline void Complex::Add( const Complex& rAdd ) 849 { 850 r += rAdd.r; 851 i += rAdd.i; 852 if( !c ) c = rAdd.c; 853 } 854 855 856 857 858 inline const Complex* ComplexList::Get( sal_uInt32 n ) const 859 { 860 return ( const Complex* ) MyList::GetObject( n ); 861 } 862 863 864 inline const Complex* ComplexList::First( void ) 865 { 866 return ( const Complex* ) MyList::First(); 867 } 868 869 870 inline const Complex* ComplexList::Next( void ) 871 { 872 return ( const Complex* ) MyList::Next(); 873 } 874 875 876 inline void ComplexList::Append( Complex* p ) 877 { 878 MyList::Append( p ); 879 } 880 881 882 883 884 inline ConvertDataClass ConvertData::Class( void ) const 885 { 886 return eClass; 887 } 888 889 890 891 inline sal_Bool ConvertData::IsPrefixSupport( void ) const 892 { 893 return bPrefixSupport; 894 } 895 896 inline ConvertDataLinear::ConvertDataLinear( const sal_Char* p, double fC, double fO, ConvertDataClass e, 897 sal_Bool bPrefSupport ) : 898 ConvertData( p, fC, e, bPrefSupport ), 899 fOffs( fO ) 900 { 901 } 902 903 904 905 906 inline ConvertData* ConvertDataList::First( void ) 907 { 908 return ( ConvertData* ) MyList::First(); 909 } 910 911 912 inline ConvertData* ConvertDataList::Next( void ) 913 { 914 return ( ConvertData* ) MyList::Next(); 915 } 916 917 //----------------------------------------------------------------------------- 918 919 /// Helper class for date calculation for various financial functions 920 class ScaDate 921 { 922 private: 923 sal_uInt16 nOrigDay; /// is the day of the original date. 924 sal_uInt16 nDay; /// is the calculated day depending on the current month/year. 925 sal_uInt16 nMonth; /// is the current month (one-based). 926 sal_uInt16 nYear; /// is the current year. 927 sal_Bool bLastDayMode : 1; /// if sal_True, recalculate nDay after every calculation. 928 sal_Bool bLastDay : 1; /// is sal_True, if original date was the last day in month. 929 sal_Bool b30Days : 1; /// is sal_True, if every month has 30 days in calculations. 930 sal_Bool bUSMode : 1; /// is sal_True, if the US method of 30-day-calculations is used. 931 932 /// Calculates nDay from nOrigDay and current date. 933 void setDay(); 934 935 /// @return count of days in current month 936 inline sal_uInt16 getDaysInMonth() const; 937 /// @return count of days in given month 938 inline sal_uInt16 getDaysInMonth( sal_uInt16 _nMon ) const; 939 940 /// @ return count of days in the given month range 941 sal_Int32 getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const; 942 /// @ return count of days in the given year range 943 sal_Int32 getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const; 944 945 /// Adds/subtracts the given count of years, does not adjust day. 946 void doAddYears( sal_Int32 nYearCount ) throw( CSS::lang::IllegalArgumentException ); 947 948 public: 949 ScaDate(); 950 /** @param nBase 951 date handling mode (days in month / days in year): 952 0 = 30 days / 360 days (US NASD) 953 1 = exact / exact 954 2 = exact / 360 955 3 = exact / 365 956 4 = 30 days / 360 days (Europe) 957 5 = exact / exact (no last day adjustment) */ 958 ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase ); 959 ScaDate( const ScaDate& rCopy ); 960 ScaDate& operator=( const ScaDate& rCopy ); 961 962 /// @return the current month. 963 inline sal_uInt16 getMonth() const { return nMonth; }; 964 /// @return the current year. 965 inline sal_uInt16 getYear() const { return nYear; }; 966 967 /// adds/subtracts the given count of months, adjusts day 968 void addMonths( sal_Int32 nMonthCount ) throw( CSS::lang::IllegalArgumentException ); 969 970 /// sets the given year, adjusts day 971 inline void setYear( sal_uInt16 nNewYear ); 972 /// adds/subtracts the given count of years, adjusts day 973 inline void addYears( sal_Int32 nYearCount ) throw( CSS::lang::IllegalArgumentException ); 974 975 /// @return the internal number of the current date 976 sal_Int32 getDate( sal_Int32 nNullDate ) const; 977 /// @return the number of days between the two dates 978 static sal_Int32 getDiff( const ScaDate& rFrom, const ScaDate& rTo ) throw( CSS::lang::IllegalArgumentException ); 979 980 sal_Bool operator<( const ScaDate& rCmp ) const; 981 inline sal_Bool operator<=( const ScaDate& rCmp ) const { return !(rCmp < *this); } 982 inline sal_Bool operator>( const ScaDate& rCmp ) const { return rCmp < *this; } 983 inline sal_Bool operator>=( const ScaDate& rCmp ) const { return !(*this < rCmp); } 984 }; 985 986 inline sal_uInt16 ScaDate::getDaysInMonth() const 987 { 988 return getDaysInMonth( nMonth ); 989 } 990 991 inline sal_uInt16 ScaDate::getDaysInMonth( sal_uInt16 _nMon ) const 992 { 993 return b30Days ? 30 : DaysInMonth( _nMon, nYear ); 994 } 995 996 inline void ScaDate::setYear( sal_uInt16 nNewYear ) 997 { 998 nYear = nNewYear; 999 setDay(); 1000 } 1001 1002 inline void ScaDate::addYears( sal_Int32 nYearCount ) throw( CSS::lang::IllegalArgumentException ) 1003 { 1004 doAddYears( nYearCount ); 1005 setDay(); 1006 } 1007 1008 1009 //----------------------------------------------------------------------------- 1010 1011 /// Helper class for Any->double conversion, using current language settings 1012 class ScaAnyConverter 1013 { 1014 private: 1015 CSS::uno::Reference< CSS::util::XNumberFormatter > xFormatter; 1016 sal_Int32 nDefaultFormat; 1017 sal_Bool bHasValidFormat; 1018 1019 /** Converts a string to double using the number formatter. If the formatter is not 1020 valid, ::rtl::math::stringToDouble() with english separators will be used. 1021 @throws com::sun::star::lang::IllegalArgumentException 1022 on strings not representing any double value. 1023 @return the converted double value. */ 1024 double convertToDouble( 1025 const ::rtl::OUString& rString ) const 1026 throw( CSS::lang::IllegalArgumentException ); 1027 1028 public: 1029 ScaAnyConverter( 1030 const CSS::uno::Reference< CSS::lang::XMultiServiceFactory >& xServiceFact ); 1031 ~ScaAnyConverter(); 1032 1033 /// Initializing with current language settings 1034 void init( 1035 const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet ) 1036 throw( CSS::uno::RuntimeException ); 1037 1038 /** Converts an Any to double (without initialization). 1039 The Any can be empty or contain a double or string. 1040 @throws com::sun::star::lang::IllegalArgumentException 1041 on other Any types or on invalid strings. 1042 @return sal_True if the Any contains a double or a non-empty valid string, 1043 sal_False if the Any is empty or the string is empty */ 1044 sal_Bool getDouble( 1045 double& rfResult, 1046 const CSS::uno::Any& rAny ) const 1047 throw( CSS::lang::IllegalArgumentException ); 1048 1049 /** Converts an Any to double (with initialization). 1050 The Any can be empty or contain a double or string. 1051 @throws com::sun::star::lang::IllegalArgumentException 1052 on other Any types or on invalid strings. 1053 @return sal_True if the Any contains a double or a non-empty valid string, 1054 sal_False if the Any is empty or the string is empty */ 1055 sal_Bool getDouble( 1056 double& rfResult, 1057 const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet, 1058 const CSS::uno::Any& rAny ) 1059 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 1060 1061 /** Converts an Any to double (with initialization). 1062 The Any can be empty or contain a double or string. 1063 @throws com::sun::star::lang::IllegalArgumentException 1064 on other Any types or on invalid strings. 1065 @return the value of the double or string or fDefault if the Any or string is empty */ 1066 double getDouble( 1067 const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet, 1068 const CSS::uno::Any& rAny, 1069 double fDefault ) 1070 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 1071 1072 /** Converts an Any to sal_Int32 (with initialization). 1073 The Any can be empty or contain a double or string. 1074 @throws com::sun::star::lang::IllegalArgumentException 1075 on other Any types or on invalid values or strings. 1076 @return sal_True if the Any contains a double or a non-empty valid string, 1077 sal_False if the Any is empty or the string is empty */ 1078 sal_Bool getInt32( 1079 sal_Int32& rnResult, 1080 const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet, 1081 const CSS::uno::Any& rAny ) 1082 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 1083 1084 /** Converts an Any to sal_Int32 (with initialization). 1085 The Any can be empty or contain a double or string. 1086 @throws com::sun::star::lang::IllegalArgumentException 1087 on other Any types or on invalid values or strings. 1088 @return the truncated value of the double or string or nDefault if the Any or string is empty */ 1089 sal_Int32 getInt32( 1090 const CSS::uno::Reference< CSS::beans::XPropertySet >& xPropSet, 1091 const CSS::uno::Any& rAny, 1092 sal_Int32 nDefault ) 1093 throw( CSS::uno::RuntimeException, CSS::lang::IllegalArgumentException ); 1094 }; 1095 1096 1097 //----------------------------------------------------------------------------- 1098 1099 1100 #endif 1101 1102