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:
AnalysisRscStrLoader(sal_uInt16 nRsc,sal_uInt16 nStrId,ResMgr & rResMgr)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
GetString() const307 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
Get(sal_uInt32 nIndex) const339 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:
ListAppend(double fValue)361 inline void ListAppend( double fValue ) { MyList::Append( new double( fValue ) ); }
362
363 using MyList::Append;
Append(double fValue)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;
Get(sal_uInt32 nIndex) const392 inline const double* Get( sal_uInt32 nIndex ) const
393 { return static_cast< const double* >( MyList::GetObject( nIndex ) ); }
394
First()395 inline const double* First() { return static_cast< const double* >( MyList::First() ); }
Next()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
IsLeapYear(sal_uInt16 n)606 inline sal_Bool IsLeapYear( sal_uInt16 n )
607 {
608 return ( (( ( n % 4 ) == 0 ) && ( ( n % 100 ) != 0)) || ( ( n % 400 ) == 0 ) );
609 }
610
611
GetDiffDate360(constREFXPS & xOpt,sal_Int32 nDate1,sal_Int32 nDate2,sal_Bool bUSAMethod)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
GetDayOfWeek(sal_Int32 n)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
GetYearFrac(constREFXPS & xOpt,sal_Int32 nStartDate,sal_Int32 nEndDate,sal_Int32 nMode)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
AlignDate(sal_uInt16 & rD,sal_uInt16 nM,sal_uInt16 nY)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
Grow(void)639 inline void MyList::Grow( void )
640 {
641 if( nNew >= nSize )
642 _Grow();
643 }
644
645
GetObject(sal_uInt32 n) const646 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
First(void)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
Next(void)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
Append(void * p)678 inline void MyList::Append( void* p )
679 {
680 Grow();
681 pData[ nNew ] = p;
682 nNew++;
683 }
684
685
Count(void) const686 inline sal_uInt32 MyList::Count( void ) const
687 {
688 return nNew;
689 }
690
691
692
693
First(void)694 inline const STRING* StringList::First( void )
695 {
696 return ( const STRING* ) MyList::First();
697 }
698
699
Next(void)700 inline const STRING* StringList::Next( void )
701 {
702 return ( const STRING* ) MyList::Next();
703 }
704
705
Get(sal_uInt32 n) const706 inline const STRING* StringList::Get( sal_uInt32 n ) const
707 {
708 return ( const STRING* ) MyList::GetObject( n );
709 }
710
711
Append(STRING * p)712 inline void StringList::Append( STRING* p )
713 {
714 MyList::Append( p );
715 }
716
717
Append(const STRING & r)718 inline void StringList::Append( const STRING& r )
719 {
720 MyList::Append( new STRING( r ) );
721 }
722
723
724
725
GetUINameID(void) const726 inline sal_uInt16 FuncData::GetUINameID( void ) const
727 {
728 return nUINameID;
729 }
730
731
GetDescrID(void) const732 inline sal_uInt16 FuncData::GetDescrID( void ) const
733 {
734 return nDescrID;
735 }
736
737
IsDouble(void) const738 inline sal_Bool FuncData::IsDouble( void ) const
739 {
740 return bDouble;
741 }
742
743
HasIntParam(void) const744 inline sal_Bool FuncData::HasIntParam( void ) const
745 {
746 return bWithOpt;
747 }
748
749
Is(const::rtl::OUString & r) const750 inline sal_Bool FuncData::Is( const ::rtl::OUString& r ) const
751 {
752 return aIntName == r;
753 }
754
755
GetCompNameList(void) const756 inline const StringList& FuncData::GetCompNameList( void ) const
757 {
758 return aCompList;
759 }
760
761
GetCategory(void) const762 inline FDCategory FuncData::GetCategory( void ) const
763 {
764 return eCat;
765 }
766
767
768
769
Append(const sal_Char * p)770 inline void CStrList::Append( const sal_Char* p )
771 {
772 MyList::Append( ( void* ) p );
773 }
774
775
Get(sal_uInt32 n) const776 inline const sal_Char* CStrList::Get( sal_uInt32 n ) const
777 {
778 return ( const sal_Char* ) MyList::GetObject( n );
779 }
780
781
782
783
Append(FuncData * p)784 inline void FuncDataList::Append( FuncData* p )
785 {
786 MyList::Append( p );
787 }
788
789
Get(sal_uInt32 n) const790 inline const FuncData* FuncDataList::Get( sal_uInt32 n ) const
791 {
792 return ( const FuncData* ) MyList::GetObject( n );
793 }
794
795
Complex(double fReal,double fImag,sal_Unicode cC)796 inline Complex::Complex( double fReal, double fImag, sal_Unicode cC ) :
797 Num( fReal, fImag ), c( cC )
798 {
799 }
800
801
Real(void) const802 inline double Complex::Real( void ) const
803 {
804 return Num.real();
805 }
806
807
Imag(void) const808 inline double Complex::Imag( void ) const
809 {
810 return Num.imag();
811 }
812
813
Abs(void) const814 inline double Complex::Abs( void ) const
815 {
816 return std::abs( Num );
817 }
818
819
Conjugate(void)820 void Complex::Conjugate( void )
821 {
822 Num = std::conj( Num );
823 }
824
825
Mult(double f)826 inline void Complex::Mult( double f )
827 {
828 Num = f * Num;
829 }
830
831
Mult(const Complex & rM)832 inline void Complex::Mult( const Complex& rM )
833 {
834 Num = Num * rM.Num;
835
836 if( !c ) c = rM.c;
837 }
838
839
Sub(const Complex & rC)840 inline void Complex::Sub( const Complex& rC )
841 {
842 Num -= rC.Num;
843
844 if( !c ) c = rC.c;
845 }
846
847
Add(const Complex & rAdd)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
Get(sal_uInt32 n) const858 inline const Complex* ComplexList::Get( sal_uInt32 n ) const
859 {
860 return ( const Complex* ) MyList::GetObject( n );
861 }
862
863
First(void)864 inline const Complex* ComplexList::First( void )
865 {
866 return ( const Complex* ) MyList::First();
867 }
868
869
Next(void)870 inline const Complex* ComplexList::Next( void )
871 {
872 return ( const Complex* ) MyList::Next();
873 }
874
875
Append(Complex * p)876 inline void ComplexList::Append( Complex* p )
877 {
878 MyList::Append( p );
879 }
880
881
882
883
Class(void) const884 inline ConvertDataClass ConvertData::Class( void ) const
885 {
886 return eClass;
887 }
888
889
890
IsPrefixSupport(void) const891 inline sal_Bool ConvertData::IsPrefixSupport( void ) const
892 {
893 return bPrefixSupport;
894 }
895
ConvertDataLinear(const sal_Char * p,double fC,double fO,ConvertDataClass e,sal_Bool bPrefSupport)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
First(void)906 inline ConvertData* ConvertDataList::First( void )
907 {
908 return ( ConvertData* ) MyList::First();
909 }
910
911
Next(void)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.
getMonth() const963 inline sal_uInt16 getMonth() const { return nMonth; };
964 /// @return the current year.
getYear() const965 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;
operator <=(const ScaDate & rCmp) const981 inline sal_Bool operator<=( const ScaDate& rCmp ) const { return !(rCmp < *this); }
operator >(const ScaDate & rCmp) const982 inline sal_Bool operator>( const ScaDate& rCmp ) const { return rCmp < *this; }
operator >=(const ScaDate & rCmp) const983 inline sal_Bool operator>=( const ScaDate& rCmp ) const { return !(*this < rCmp); }
984 };
985
getDaysInMonth() const986 inline sal_uInt16 ScaDate::getDaysInMonth() const
987 {
988 return getDaysInMonth( nMonth );
989 }
990
getDaysInMonth(sal_uInt16 _nMon) const991 inline sal_uInt16 ScaDate::getDaysInMonth( sal_uInt16 _nMon ) const
992 {
993 return b30Days ? 30 : DaysInMonth( _nMon, nYear );
994 }
995
setYear(sal_uInt16 nNewYear)996 inline void ScaDate::setYear( sal_uInt16 nNewYear )
997 {
998 nYear = nNewYear;
999 setDay();
1000 }
1001
addYears(sal_Int32 nYearCount)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