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