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