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 :
20 : #ifndef INCLUDED_SW_INC_CALC_HXX
21 : #define INCLUDED_SW_INC_CALC_HXX
22 :
23 : #include <vector>
24 : #include <basic/sbxvar.hxx>
25 : #include <unotools/syslocale.hxx>
26 : #include "swdllapi.h"
27 :
28 : class CharClass;
29 : class LocaleDataWrapper;
30 : class SwFieldType;
31 : class SwDoc;
32 : class SwUserFieldType;
33 :
34 : #define TBLSZ 47 // should be a prime, because of hash table
35 :
36 : const sal_Unicode cListDelim = '|';
37 :
38 : enum SwCalcOper
39 : {
40 : CALC_NAME, CALC_NUMBER, CALC_ENDCALC,
41 : CALC_PLUS='+', CALC_MINUS='-', CALC_MUL='*',
42 : CALC_DIV='/', CALC_PRINT=';', CALC_ASSIGN='=',
43 : CALC_LP='(', CALC_RP=')', CALC_PHD='%',
44 : CALC_POW='^',
45 : CALC_LISTOP = cListDelim,
46 : CALC_NOT=256, CALC_AND=257, CALC_OR=258,
47 : CALC_XOR=259, CALC_EQ=260, CALC_NEQ=261,
48 : CALC_LEQ=262, CALC_GEQ=263, CALC_LES=264,
49 : CALC_GRE=265, CALC_SUM=266, CALC_MEAN=267,
50 : CALC_SQRT=268, CALC_MIN=269, CALC_MIN_IN=270,
51 : CALC_MAX=271, CALC_MAX_IN=272, CALC_SIN=273,
52 : CALC_COS=274, CALC_TAN=275, CALC_ASIN=276,
53 : CALC_ACOS=278, CALC_ATAN=279, CALC_TDIF=280,
54 : CALC_ROUND=281, CALC_DATE=282, CALC_MONTH=283,
55 : CALC_DAY=284
56 : };
57 :
58 : // Calculate Operations Strings
59 : extern const sal_Char sCalc_Add[];
60 : extern const sal_Char sCalc_Sub[];
61 : extern const sal_Char sCalc_Mul[];
62 : extern const sal_Char sCalc_Div[];
63 : extern const sal_Char sCalc_Phd[];
64 : extern const sal_Char sCalc_Sqrt[];
65 : extern const sal_Char sCalc_Pow[];
66 : extern const sal_Char sCalc_Or[];
67 : extern const sal_Char sCalc_Xor[];
68 : extern const sal_Char sCalc_And[];
69 : extern const sal_Char sCalc_Not[];
70 : extern const sal_Char sCalc_Eq[];
71 : extern const sal_Char sCalc_Neq[];
72 : extern const sal_Char sCalc_Leq[];
73 : extern const sal_Char sCalc_Geq[];
74 : extern const sal_Char sCalc_L[];
75 : extern const sal_Char sCalc_G[];
76 : extern const sal_Char sCalc_Sum[];
77 : extern const sal_Char sCalc_Mean[];
78 : extern const sal_Char sCalc_Min[];
79 : extern const sal_Char sCalc_Max[];
80 : extern const sal_Char sCalc_Sin[];
81 : extern const sal_Char sCalc_Cos[];
82 : extern const sal_Char sCalc_Tan[];
83 : extern const sal_Char sCalc_Asin[];
84 : extern const sal_Char sCalc_Acos[];
85 : extern const sal_Char sCalc_Atan[];
86 : extern const sal_Char sCalc_Tdif[];
87 : extern const sal_Char sCalc_Round[];
88 : extern const sal_Char sCalc_Date[];
89 :
90 : // Calculate ErrorCodes
91 : enum SwCalcError
92 : {
93 : CALC_NOERR=0,
94 : CALC_SYNTAX, // syntax error
95 : CALC_ZERODIV, // division by zero
96 : CALC_BRACK, // faulty brackets
97 : CALC_POWERR, // overflow in power function
98 : CALC_VARNFND, // variable was not found
99 : CALC_OVERFLOW, // overflow
100 : CALC_WRONGTIME // wrong time format
101 : };
102 :
103 182 : class SwSbxValue : public SbxValue
104 : {
105 : bool bVoid;
106 : public:
107 : // always default to a number. otherwise it will become a SbxEMPTY
108 318 : SwSbxValue( long n = 0 ) : bVoid(false) { PutLong( n ); }
109 28 : SwSbxValue( const double& rD ) : bVoid(false) { PutDouble( rD ); }
110 1208 : SwSbxValue( const SwSbxValue& rVal ) :
111 : SvRefBase( rVal ),
112 : SbxValue( rVal ),
113 1208 : bVoid(rVal.bVoid)
114 1208 : {}
115 : virtual ~SwSbxValue();
116 :
117 : bool GetBool() const;
118 : double GetDouble() const;
119 : SwSbxValue& MakeDouble();
120 :
121 18 : bool IsVoidValue() {return bVoid;}
122 58 : void SetVoidValue(bool bSet) {bVoid = bSet;}
123 : };
124 :
125 : // Calculate HashTables for VarTable und Operations
126 : struct SwHash
127 : {
128 : SwHash( const OUString& rStr );
129 : virtual ~SwHash();
130 : OUString aStr;
131 : SwHash *pNext;
132 : };
133 :
134 2310 : struct SwCalcExp : public SwHash
135 : {
136 : SwSbxValue nValue;
137 : const SwFieldType* pFldType;
138 :
139 : SwCalcExp( const OUString& rStr, const SwSbxValue& rVal,
140 : const SwFieldType* pFldType = 0 );
141 : };
142 :
143 : SwHash* Find( const OUString& rSrch, SwHash** ppTable,
144 : sal_uInt16 nTblSize, sal_uInt16* pPos = 0 );
145 :
146 : void DeleteHashTable( SwHash** ppTable, sal_uInt16 nTblSize );
147 :
148 : // if _CalcOp != 0, this is a valid operator
149 : struct _CalcOp;
150 : _CalcOp* FindOperator( const OUString& rSearch );
151 :
152 : class SwCalc
153 : {
154 : SwHash* VarTable[ TBLSZ ];
155 : OUString aVarName, sCurrSym;
156 : OUString sCommand;
157 : std::vector<const SwUserFieldType*> aRekurStk;
158 : SwSbxValue nLastLeft;
159 : SwSbxValue nNumberValue;
160 : SwCalcExp aErrExpr;
161 : sal_Int32 nCommandPos;
162 :
163 : SwDoc& rDoc;
164 : SvtSysLocale m_aSysLocale;
165 : const LocaleDataWrapper* pLclData;
166 : CharClass* pCharClass;
167 :
168 : sal_uInt16 nListPor;
169 : SwCalcOper eCurrOper;
170 : SwCalcOper eCurrListOper;
171 : SwCalcError eError;
172 :
173 : SwCalcOper GetToken();
174 : SwSbxValue Expr();
175 : SwSbxValue Term();
176 : SwSbxValue Prim();
177 :
178 : bool ParseTime( sal_uInt16*, sal_uInt16*, sal_uInt16* );
179 :
180 : OUString GetColumnName( const OUString& rName );
181 : OUString GetDBName( const OUString& rName );
182 :
183 : // dont call this methods
184 : SwCalc( const SwCalc& );
185 : SwCalc& operator=( const SwCalc& );
186 :
187 : public:
188 : SwCalc( SwDoc& rD );
189 : ~SwCalc();
190 :
191 : SwSbxValue Calculate( const OUString &rStr );
192 : OUString GetStrResult( const SwSbxValue& rValue, bool bRound = true );
193 : OUString GetStrResult( double, bool bRound = true );
194 :
195 : SwCalcExp* VarInsert( const OUString& r );
196 : SwCalcExp* VarLook( const OUString &rStr, sal_uInt16 ins = 0 );
197 : void VarChange( const OUString& rStr, const SwSbxValue& rValue );
198 : void VarChange( const OUString& rStr, double );
199 0 : SwHash** GetVarTable() { return VarTable; }
200 :
201 : bool Push(const SwUserFieldType* pUserFieldType);
202 : void Pop();
203 :
204 0 : void SetCalcError( SwCalcError eErr ) { eError = eErr; }
205 0 : bool IsCalcError() const { return 0 != eError; }
206 :
207 : static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
208 : double& rVal,
209 : LocaleDataWrapper const*const pData = 0 );
210 : static bool Str2Double( const OUString& rStr, sal_Int32& rPos,
211 : double& rVal, SwDoc *const pDoc );
212 :
213 : SW_DLLPUBLIC static bool IsValidVarName( const OUString& rStr,
214 : OUString* pValidName = 0 );
215 : };
216 :
217 : #endif
218 :
219 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|