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 : enum FDCategory
148 : {
149 : FDCat_AddIn,
150 : FDCat_DateTime,
151 : FDCat_Finance,
152 : FDCat_Inf,
153 : FDCat_Math,
154 : FDCat_Tech
155 : };
156 :
157 :
158 : struct FuncDataBase
159 : {
160 : const sal_Char* pIntName;
161 : sal_uInt16 nUINameID; // resource ID to UI name
162 : sal_uInt16 nDescrID; // resource ID to description, parameter names and ~ description
163 : sal_Bool bDouble; // name already exist in Calc
164 : sal_Bool bWithOpt; // first parameter is internal
165 : sal_uInt16 nCompListID; // resource ID to list of valid names
166 : sal_uInt16 nNumOfParams; // number of named / described parameters
167 : FDCategory eCat; // function category
168 : };
169 :
170 :
171 : class FuncData
172 : {
173 : private:
174 : OUString aIntName;
175 : sal_uInt16 nUINameID;
176 : sal_uInt16 nDescrID; // leads also to parameter descriptions!
177 : sal_Bool bDouble; // flag for names that already exist in Calc
178 : sal_Bool bWithOpt; // has internal parameter on first position
179 :
180 : sal_uInt16 nParam; // num of parameters
181 : sal_uInt16 nCompID;
182 : std::vector<OUString> aCompList; // list of all valid names
183 : FDCategory eCat; // function category
184 : public:
185 : FuncData( const FuncDataBase& rBaseData, ResMgr& );
186 : virtual ~FuncData();
187 :
188 : inline sal_uInt16 GetUINameID( void ) const;
189 : inline sal_uInt16 GetDescrID( void ) const;
190 : inline sal_Bool IsDouble( void ) const;
191 : inline sal_Bool HasIntParam( void ) const;
192 :
193 : sal_uInt16 GetStrIndex( sal_uInt16 nParamNum ) const;
194 : inline sal_Bool Is( const OUString& rCompareTo ) const;
195 :
196 : inline const std::vector<OUString> &
197 : GetCompNameList( void ) const;
198 :
199 : inline FDCategory GetCategory( void ) const;
200 : };
201 :
202 :
203 : class FuncDataList
204 : {
205 : OUString aLastName;
206 : sal_uInt32 nLast;
207 : std::vector<FuncData*> maVector;
208 : public:
209 : FuncDataList( ResMgr& );
210 : virtual ~FuncDataList();
211 :
212 : inline void Append( FuncData* pNew );
213 : inline const FuncData* Get( sal_uInt32 nIndex ) const;
214 0 : inline sal_uInt32 Count() const
215 0 : { return maVector.size(); }
216 :
217 : const FuncData* Get( const OUString& aProgrammaticName ) const;
218 : };
219 :
220 : class AnalysisResId : public ResId
221 : {
222 : public:
223 : AnalysisResId( sal_uInt16 nId, ResMgr& rResMgr );
224 : };
225 :
226 :
227 0 : class AnalysisRscStrLoader : public Resource
228 : {
229 : private:
230 : OUString aStr;
231 : public:
232 0 : AnalysisRscStrLoader( sal_uInt16 nRsc, sal_uInt16 nStrId, ResMgr& rResMgr ) :
233 : Resource( AnalysisResId( nRsc, rResMgr ) ),
234 0 : aStr( AnalysisResId( nStrId, rResMgr ) )
235 : {
236 0 : FreeResource();
237 0 : }
238 :
239 0 : const OUString& GetString() const { return aStr; }
240 :
241 : };
242 :
243 :
244 :
245 : /// sorted list with unique sal_Int32 values
246 : class SortedIndividualInt32List
247 : {
248 : private:
249 : std::vector<sal_Int32> maVector;
250 : protected:
251 : void Insert( sal_Int32 nDay );
252 : void Insert( sal_Int32 nDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend );
253 : void Insert( double fDay, sal_Int32 nNullDate, sal_Bool bInsertOnWeekend )
254 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
255 :
256 : /** @param rAnyConv must be an initialized ScaAnyConmverter
257 : @param bInsertOnWeekend insertion mode: sal_False = holidays on weekend are omitted */
258 : void InsertHolidayList(
259 : const ScaAnyConverter& rAnyConv,
260 : const css::uno::Any& rHolAny,
261 : sal_Int32 nNullDate,
262 : sal_Bool bInsertOnWeekend ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
263 :
264 : public:
265 : SortedIndividualInt32List();
266 : virtual ~SortedIndividualInt32List();
267 :
268 0 : inline sal_uInt32 Count() const
269 0 : { return maVector.size(); }
270 :
271 : /// @return element on position nIndex or 0 on invalid index
272 0 : inline sal_Int32 Get( sal_uInt32 n ) const
273 0 : { return maVector[n]; }
274 :
275 : /// @return sal_True if nVal (internal date representation) is contained
276 : sal_Bool Find( sal_Int32 nVal ) const;
277 :
278 : /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter
279 : @param bInsertOnWeekend insertion mode: sal_False = holidays on weekend are omitted */
280 : void InsertHolidayList(
281 : ScaAnyConverter& rAnyConv,
282 : const css::uno::Reference< css::beans::XPropertySet >& xOptions,
283 : const css::uno::Any& rHolAny,
284 : sal_Int32 nNullDate,
285 : sal_Bool bInsertOnWeekend ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
286 : };
287 :
288 :
289 0 : class ScaDoubleList
290 : {
291 : private:
292 : std::vector<double> maVector;
293 : protected:
294 0 : inline void ListAppend( double fValue ) { maVector.push_back(fValue); }
295 :
296 0 : inline void Append( double fValue ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException )
297 0 : { if( CheckInsert( fValue ) ) ListAppend( fValue ); }
298 :
299 : /** @param rAnyConv must be an initialized ScaAnyConmverter
300 : @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
301 : void Append(
302 : const ScaAnyConverter& rAnyConv,
303 : const css::uno::Any& rAny,
304 : sal_Bool bIgnoreEmpty ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
305 :
306 : /** @param rAnyConv must be an initialized ScaAnyConmverter
307 : @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
308 : void Append(
309 : const ScaAnyConverter& rAnyConv,
310 : const css::uno::Sequence< css::uno::Any >& rAnySeq,
311 : sal_Bool bIgnoreEmpty ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
312 :
313 : /** @param rAnyConv must be an initialized ScaAnyConmverter
314 : @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
315 : void Append(
316 : const ScaAnyConverter& rAnyConv,
317 : const css::uno::Sequence< css::uno::Sequence< css::uno::Any > >& rAnySeq,
318 : sal_Bool bIgnoreEmpty ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
319 :
320 : public:
321 0 : virtual ~ScaDoubleList() {}
322 :
323 0 : inline sal_uInt32 Count() const
324 0 : { return maVector.size(); }
325 0 : inline double Get( sal_uInt32 n ) const
326 0 : { return maVector[n]; }
327 :
328 : void Append( const css::uno::Sequence< css::uno::Sequence< double > >& rValueArr )
329 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
330 : void Append( const css::uno::Sequence< css::uno::Sequence< sal_Int32 > >& rValueArr )
331 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
332 :
333 : /** @param rAnyConv is an initialized or uninitialized ScaAnyConverter
334 : @param bIgnoreEmpty handling of empty Any's/strings: sal_False = inserted as 0.0; sal_True = omitted */
335 : void Append(
336 : ScaAnyConverter& rAnyConv,
337 : const css::uno::Reference< css::beans::XPropertySet >& xOpt,
338 : const css::uno::Sequence< css::uno::Any >& rAnySeq,
339 : sal_Bool bIgnoreEmpty = sal_True ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
340 :
341 : virtual sal_Bool CheckInsert( double fValue ) const
342 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
343 : };
344 :
345 :
346 : /// stores double values >0.0, throws exception for double values <0.0, does nothing for 0.0
347 0 : class ScaDoubleListGT0 : public ScaDoubleList
348 : {
349 : public:
350 : virtual sal_Bool CheckInsert( double fValue ) const
351 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException ) SAL_OVERRIDE;
352 : };
353 :
354 :
355 : /// stores double values >=0.0, throws exception for double values <0.0
356 0 : class ScaDoubleListGE0 : public ScaDoubleList
357 : {
358 : public:
359 : virtual sal_Bool CheckInsert( double fValue ) const
360 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException ) SAL_OVERRIDE;
361 : };
362 :
363 :
364 : class Complex
365 : {
366 : double r;
367 : double i;
368 : sal_Unicode c;
369 :
370 : public:
371 : inline Complex( double fReal, double fImag = 0.0, sal_Unicode cC = '\0' );
372 : Complex( const OUString& rComplexAsString ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
373 :
374 : inline static sal_Bool IsImagUnit( sal_Unicode c );
375 : static sal_Bool ParseString( const OUString& rComplexAsString, Complex& rReturn );
376 : OUString GetString() const throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
377 :
378 : inline double Real( void ) const;
379 : inline double Imag( void ) const;
380 :
381 : double Arg( void ) const throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
382 : inline double Abs( void ) const;
383 :
384 : // following functions change the complex number itself to avoid unnecessary copy actions!
385 : void Power( double fPower ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
386 : void Sqrt( void );
387 : void Sin( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
388 : void Cos( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
389 : void Div( const Complex& rDivisor ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
390 : void Exp( void );
391 : inline void Conjugate( void );
392 : void Ln( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
393 : void Log10( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
394 : void Log2( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
395 : inline void Mult( double fFact );
396 : inline void Mult( const Complex& rMult );
397 : inline void Sub( const Complex& rMult );
398 : inline void Add( const Complex& rAdd );
399 : void Tan( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
400 : void Sec( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
401 : void Csc( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
402 : void Cot( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
403 : void Sinh( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
404 : void Cosh( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
405 : void Sech( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
406 : void Csch( void ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
407 :
408 : };
409 :
410 :
411 : enum ComplListAppendHandl
412 : {
413 : AH_EmptyAsErr,
414 : AH_EmpyAs0,
415 : AH_IgnoreEmpty
416 : };
417 :
418 :
419 0 : class ComplexList
420 : {
421 : private:
422 : std::vector<Complex*> maVector;
423 : public:
424 : virtual ~ComplexList();
425 :
426 : inline const Complex* Get( sal_uInt32 nIndex ) const;
427 :
428 0 : inline bool empty( void ) const
429 0 : { return maVector.empty(); }
430 0 : inline sal_uInt32 Count( void ) const
431 0 : { return maVector.size(); }
432 :
433 : inline void Append( Complex* pNew );
434 : void Append( const css::uno::Sequence< css::uno::Sequence< OUString > >& rComplexNumList, ComplListAppendHandl eAH = AH_EmpyAs0 ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
435 : void Append( const css::uno::Sequence< css::uno::Any >& aMultPars,ComplListAppendHandl eAH = AH_EmpyAs0 ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
436 : };
437 :
438 :
439 : enum ConvertDataClass
440 : {
441 : CDC_Mass, CDC_Length, CDC_Time, CDC_Pressure, CDC_Force, CDC_Energy, CDC_Power, CDC_Magnetism,
442 : CDC_Temperature, CDC_Volume, CDC_Area, CDC_Speed, CDC_Information
443 : };
444 :
445 :
446 : #define INV_MATCHLEV 1764 // guess, what this is... :-)
447 :
448 :
449 : class ConvertDataList;
450 :
451 :
452 : class ConvertData
453 : {
454 : protected:
455 : friend class ConvertDataList;
456 : double fConst;
457 : OUString aName;
458 : ConvertDataClass eClass;
459 : sal_Bool bPrefixSupport;
460 : public:
461 : ConvertData(
462 : const sal_Char pUnitName[],
463 : double fConvertConstant,
464 : ConvertDataClass eClass,
465 : sal_Bool bPrefSupport = sal_False );
466 :
467 : virtual ~ConvertData();
468 :
469 : sal_Int16 GetMatchingLevel( const OUString& rRef ) const;
470 : // 0.0 = no equality
471 : // 1.0 = matches exact
472 : // rest = matches without an assumed prefix of one character
473 : // rest gives power for 10 represented by the prefix (e.g. 3 for k or -9 for n
474 :
475 : virtual double Convert( double fVal, const ConvertData& rTo,
476 : sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
477 : // converts fVal from this unit to rFrom unit
478 : // throws exception if not from same class
479 : // this implementation is for proportional cases only
480 : virtual double ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const;
481 : virtual double ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const;
482 :
483 : inline ConvertDataClass Class( void ) const;
484 : inline sal_Bool IsPrefixSupport( void ) const;
485 : };
486 :
487 :
488 : class ConvertDataLinear : public ConvertData
489 : {
490 : protected:
491 : double fOffs;
492 : public:
493 : inline ConvertDataLinear(
494 : const sal_Char pUnitName[],
495 : double fConvertConstant,
496 : double fConvertOffset,
497 : ConvertDataClass eClass,
498 : sal_Bool bPrefSupport = sal_False );
499 :
500 : virtual ~ConvertDataLinear();
501 :
502 : virtual double Convert( double fVal, const ConvertData& rTo,
503 : sal_Int16 nMatchLevelFrom, sal_Int16 nMatchLevelTo ) const throw( css::uno::RuntimeException, css::lang::IllegalArgumentException ) SAL_OVERRIDE;
504 : // for cases where f(x) = a + bx applies (e.g. Temperatures)
505 :
506 : virtual double ConvertToBase( double fVal, sal_Int16 nMatchLevel ) const SAL_OVERRIDE;
507 : virtual double ConvertFromBase( double fVal, sal_Int16 nMatchLevel ) const SAL_OVERRIDE;
508 : };
509 :
510 :
511 : class ConvertDataList
512 : {
513 : private:
514 : std::vector<ConvertData*> maVector;
515 : public:
516 : ConvertDataList( void );
517 : virtual ~ConvertDataList();
518 :
519 : double Convert( double fVal, const OUString& rFrom, const OUString& rTo ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
520 : };
521 :
522 :
523 0 : inline sal_Bool IsLeapYear( sal_uInt16 n )
524 : {
525 0 : return ( (( ( n % 4 ) == 0 ) && ( ( n % 100 ) != 0)) || ( ( n % 400 ) == 0 ) );
526 : }
527 :
528 :
529 0 : inline sal_Int32 GetDiffDate360( const css::uno::Reference< css::beans::XPropertySet >& xOpt, sal_Int32 nDate1, sal_Int32 nDate2, sal_Bool bUSAMethod )
530 : {
531 0 : return GetDiffDate360( GetNullDate( xOpt ), nDate1, nDate2, bUSAMethod );
532 : }
533 :
534 :
535 0 : inline sal_Int16 GetDayOfWeek( sal_Int32 n )
536 : { // monday = 0, ..., sunday = 6
537 0 : return static_cast< sal_Int16 >( ( n - 1 ) % 7 );
538 : }
539 :
540 :
541 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 )
542 : {
543 0 : return GetYearFrac( GetNullDate( xOpt ), nStartDate, nEndDate, nMode );
544 : }
545 :
546 :
547 : inline void AlignDate( sal_uInt16& rD, sal_uInt16 nM, sal_uInt16 nY )
548 : {
549 : sal_uInt16 nMax = DaysInMonth( nM, nY );
550 :
551 : if( rD > nMax )
552 : rD = nMax;
553 : }
554 :
555 :
556 0 : inline sal_uInt16 FuncData::GetUINameID( void ) const
557 : {
558 0 : return nUINameID;
559 : }
560 :
561 :
562 0 : inline sal_uInt16 FuncData::GetDescrID( void ) const
563 : {
564 0 : return nDescrID;
565 : }
566 :
567 :
568 0 : inline sal_Bool FuncData::IsDouble( void ) const
569 : {
570 0 : return bDouble;
571 : }
572 :
573 :
574 : inline sal_Bool FuncData::HasIntParam( void ) const
575 : {
576 : return bWithOpt;
577 : }
578 :
579 :
580 0 : inline sal_Bool FuncData::Is( const OUString& r ) const
581 : {
582 0 : return aIntName == r;
583 : }
584 :
585 :
586 0 : inline const std::vector<OUString> & FuncData::GetCompNameList( void ) const
587 : {
588 0 : return aCompList;
589 : }
590 :
591 :
592 0 : inline FDCategory FuncData::GetCategory( void ) const
593 : {
594 0 : return eCat;
595 : }
596 :
597 :
598 0 : inline void FuncDataList::Append( FuncData* p )
599 : {
600 0 : maVector.push_back( p );
601 0 : }
602 :
603 :
604 0 : inline const FuncData* FuncDataList::Get( sal_uInt32 n ) const
605 : {
606 0 : return maVector[n];
607 : }
608 :
609 :
610 0 : inline Complex::Complex( double fReal, double fImag, sal_Unicode cC ) :
611 0 : r( fReal ), i( fImag ), c( cC )
612 : {
613 0 : }
614 :
615 :
616 0 : inline double Complex::Real( void ) const
617 : {
618 0 : return r;
619 : }
620 :
621 :
622 0 : inline double Complex::Imag( void ) const
623 : {
624 0 : return i;
625 : }
626 :
627 :
628 0 : inline double Complex::Abs( void ) const
629 : {
630 0 : return sqrt( r * r + i * i );
631 : }
632 :
633 :
634 0 : void Complex::Conjugate( void )
635 : {
636 0 : i = -i;
637 0 : }
638 :
639 :
640 0 : inline void Complex::Mult( double f )
641 : {
642 0 : i *= f;
643 0 : r *= f;
644 0 : }
645 :
646 :
647 0 : inline void Complex::Mult( const Complex& rM )
648 : {
649 0 : double r_ = r;
650 0 : double i_ = i;
651 :
652 0 : r = r_ * rM.r - i_ * rM.i;
653 0 : i = r_ * rM.i + i_ * rM.r;
654 :
655 0 : if( !c ) c = rM.c;
656 0 : }
657 :
658 :
659 0 : inline void Complex::Sub( const Complex& rC )
660 : {
661 0 : r -= rC.r;
662 0 : i -= rC.i;
663 0 : if( !c ) c = rC.c;
664 0 : }
665 :
666 :
667 0 : inline void Complex::Add( const Complex& rAdd )
668 : {
669 0 : r += rAdd.r;
670 0 : i += rAdd.i;
671 0 : if( !c ) c = rAdd.c;
672 0 : }
673 :
674 :
675 0 : inline const Complex* ComplexList::Get( sal_uInt32 n ) const
676 : {
677 0 : return maVector[n];
678 : }
679 :
680 :
681 0 : inline void ComplexList::Append( Complex* p )
682 : {
683 0 : maVector.push_back(p);
684 0 : }
685 :
686 :
687 0 : inline ConvertDataClass ConvertData::Class( void ) const
688 : {
689 0 : return eClass;
690 : }
691 :
692 0 : inline sal_Bool ConvertData::IsPrefixSupport( void ) const
693 : {
694 0 : return bPrefixSupport;
695 : }
696 :
697 0 : inline ConvertDataLinear::ConvertDataLinear( const sal_Char* p, double fC, double fO, ConvertDataClass e,
698 : sal_Bool bPrefSupport ) :
699 : ConvertData( p, fC, e, bPrefSupport ),
700 0 : fOffs( fO )
701 : {
702 0 : }
703 :
704 :
705 :
706 :
707 : /// Helper class for date calculation for various financial functions
708 : class ScaDate
709 : {
710 : private:
711 : sal_uInt16 nOrigDay; /// is the day of the original date.
712 : sal_uInt16 nDay; /// is the calculated day depending on the current month/year.
713 : sal_uInt16 nMonth; /// is the current month (one-based).
714 : sal_uInt16 nYear; /// is the current year.
715 : sal_Bool bLastDayMode : 1; /// if sal_True, recalculate nDay after every calculation.
716 : sal_Bool bLastDay : 1; /// is sal_True, if original date was the last day in month.
717 : sal_Bool b30Days : 1; /// is sal_True, if every month has 30 days in calculations.
718 : sal_Bool bUSMode : 1; /// is sal_True, if the US method of 30-day-calculations is used.
719 :
720 : /// Calculates nDay from nOrigDay and current date.
721 : void setDay();
722 :
723 : /// @return count of days in current month
724 : inline sal_uInt16 getDaysInMonth() const;
725 : /// @return count of days in given month
726 : inline sal_uInt16 getDaysInMonth( sal_uInt16 _nMon ) const;
727 :
728 : /// @ return count of days in the given month range
729 : sal_Int32 getDaysInMonthRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const;
730 : /// @ return count of days in the given year range
731 : sal_Int32 getDaysInYearRange( sal_uInt16 nFrom, sal_uInt16 nTo ) const;
732 :
733 : /// Adds/subtracts the given count of years, does not adjust day.
734 : void doAddYears( sal_Int32 nYearCount ) throw( css::lang::IllegalArgumentException );
735 :
736 : public:
737 : ScaDate();
738 : /** @param nBase
739 : date handling mode (days in month / days in year):
740 : 0 = 30 days / 360 days (US NASD)
741 : 1 = exact / exact
742 : 2 = exact / 360
743 : 3 = exact / 365
744 : 4 = 30 days / 360 days (Europe)
745 : 5 = exact / exact (no last day adjustment) */
746 : ScaDate( sal_Int32 nNullDate, sal_Int32 nDate, sal_Int32 nBase );
747 : ScaDate( const ScaDate& rCopy );
748 : ScaDate& operator=( const ScaDate& rCopy );
749 :
750 : /// @return the current month.
751 0 : inline sal_uInt16 getMonth() const { return nMonth; };
752 : /// @return the current year.
753 0 : inline sal_uInt16 getYear() const { return nYear; };
754 :
755 : /// adds/subtracts the given count of months, adjusts day
756 : void addMonths( sal_Int32 nMonthCount ) throw( css::lang::IllegalArgumentException );
757 :
758 : /// sets the given year, adjusts day
759 : inline void setYear( sal_uInt16 nNewYear );
760 : /// adds/subtracts the given count of years, adjusts day
761 : inline void addYears( sal_Int32 nYearCount ) throw( css::lang::IllegalArgumentException );
762 :
763 : /// @return the internal number of the current date
764 : sal_Int32 getDate( sal_Int32 nNullDate ) const;
765 : /// @return the number of days between the two dates
766 : static sal_Int32 getDiff( const ScaDate& rFrom, const ScaDate& rTo ) throw( css::lang::IllegalArgumentException );
767 :
768 : sal_Bool operator<( const ScaDate& rCmp ) const;
769 0 : inline sal_Bool operator<=( const ScaDate& rCmp ) const { return !(rCmp < *this); }
770 0 : inline sal_Bool operator>( const ScaDate& rCmp ) const { return rCmp < *this; }
771 : inline sal_Bool operator>=( const ScaDate& rCmp ) const { return !(*this < rCmp); }
772 : };
773 :
774 0 : inline sal_uInt16 ScaDate::getDaysInMonth() const
775 : {
776 0 : return getDaysInMonth( nMonth );
777 : }
778 :
779 0 : inline sal_uInt16 ScaDate::getDaysInMonth( sal_uInt16 _nMon ) const
780 : {
781 0 : return b30Days ? 30 : DaysInMonth( _nMon, nYear );
782 : }
783 :
784 0 : inline void ScaDate::setYear( sal_uInt16 nNewYear )
785 : {
786 0 : nYear = nNewYear;
787 0 : setDay();
788 0 : }
789 :
790 0 : inline void ScaDate::addYears( sal_Int32 nYearCount ) throw( css::lang::IllegalArgumentException )
791 : {
792 0 : doAddYears( nYearCount );
793 0 : setDay();
794 0 : }
795 :
796 :
797 : /// Helper class for Any->double conversion, using current language settings
798 : class ScaAnyConverter
799 : {
800 : private:
801 : css::uno::Reference< css::util::XNumberFormatter2 > xFormatter;
802 : sal_Int32 nDefaultFormat;
803 : sal_Bool bHasValidFormat;
804 :
805 : /** Converts a string to double using the number formatter. If the formatter is not
806 : valid, ::rtl::math::stringToDouble() with english separators will be used.
807 : @throws com::sun::star::lang::IllegalArgumentException
808 : on strings not representing any double value.
809 : @return the converted double value. */
810 : double convertToDouble(
811 : const OUString& rString ) const
812 : throw( css::lang::IllegalArgumentException );
813 :
814 : public:
815 : ScaAnyConverter(
816 : const css::uno::Reference< css::uno::XComponentContext >& xContext );
817 : ~ScaAnyConverter();
818 :
819 : /// Initializing with current language settings
820 : void init(
821 : const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
822 : throw( css::uno::RuntimeException );
823 :
824 : /** Converts an Any to double (without initialization).
825 : The Any can be empty or contain a double or string.
826 : @throws com::sun::star::lang::IllegalArgumentException
827 : on other Any types or on invalid strings.
828 : @return sal_True if the Any contains a double or a non-empty valid string,
829 : sal_False if the Any is empty or the string is empty */
830 : sal_Bool getDouble(
831 : double& rfResult,
832 : const css::uno::Any& rAny ) const
833 : throw( css::lang::IllegalArgumentException );
834 :
835 : /** Converts an Any to double (with initialization).
836 : The Any can be empty or contain a double or string.
837 : @throws com::sun::star::lang::IllegalArgumentException
838 : on other Any types or on invalid strings.
839 : @return sal_True if the Any contains a double or a non-empty valid string,
840 : sal_False if the Any is empty or the string is empty */
841 : sal_Bool getDouble(
842 : double& rfResult,
843 : const css::uno::Reference< css::beans::XPropertySet >& xPropSet,
844 : const css::uno::Any& rAny )
845 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
846 :
847 : /** Converts an Any to double (with initialization).
848 : The Any can be empty or contain a double or string.
849 : @throws com::sun::star::lang::IllegalArgumentException
850 : on other Any types or on invalid strings.
851 : @return the value of the double or string or fDefault if the Any or string is empty */
852 : double getDouble(
853 : const css::uno::Reference< css::beans::XPropertySet >& xPropSet,
854 : const css::uno::Any& rAny,
855 : double fDefault )
856 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
857 :
858 : /** Converts an Any to sal_Int32 (with initialization).
859 : The Any can be empty or contain a double or string.
860 : @throws com::sun::star::lang::IllegalArgumentException
861 : on other Any types or on invalid values or strings.
862 : @return sal_True if the Any contains a double or a non-empty valid string,
863 : sal_False if the Any is empty or the string is empty */
864 : sal_Bool getInt32(
865 : sal_Int32& rnResult,
866 : const css::uno::Reference< css::beans::XPropertySet >& xPropSet,
867 : const css::uno::Any& rAny )
868 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
869 :
870 : /** Converts an Any to sal_Int32 (with initialization).
871 : The Any can be empty or contain a double or string.
872 : @throws com::sun::star::lang::IllegalArgumentException
873 : on other Any types or on invalid values or strings.
874 : @return the truncated value of the double or string or nDefault if the Any or string is empty */
875 : sal_Int32 getInt32(
876 : const css::uno::Reference< css::beans::XPropertySet >& xPropSet,
877 : const css::uno::Any& rAny,
878 : sal_Int32 nDefault )
879 : throw( css::uno::RuntimeException, css::lang::IllegalArgumentException );
880 : };
881 :
882 :
883 :
884 : #endif
885 :
886 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|