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