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