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