author | hayzel <hayzel> | 2004-01-07 08:08:29 (UTC) |
---|---|---|
committer | hayzel <hayzel> | 2004-01-07 08:08:29 (UTC) |
commit | 08bc72c34cae85e5cc6541c9daaeba121597c961 (patch) (unidiff) | |
tree | df5b263a84099ffdf8e0b86fda9a9fe61b90d30e /noncore/apps/opie-sheet/sheet.cpp | |
parent | 656e80e7b35c4aefd49ffe7756d895f4e7370de1 (diff) | |
download | opie-08bc72c34cae85e5cc6541c9daaeba121597c961.zip opie-08bc72c34cae85e5cc6541c9daaeba121597c961.tar.gz opie-08bc72c34cae85e5cc6541c9daaeba121597c961.tar.bz2 |
January 7, 2004
* Release by hayzel (koppermind@panafonet.gr)
This version has many valuable changes, though It may have some annoying bugs. Please if you are interested in opie-sheet try it hard, so I can fix some of them. Also If you want some other functions that must be here and are missing feel free to ask them. (no financial functions please. :) I really hate them )
-Fixed a bug with non closed parenthesis editing&recalculation infinite loop.
-Added support for functions that can parse parameters not ONLY as numbers but also as strings.
-Added many functions that cover many computational topics rendering opie-sheet a computational tool-spreadsheet at last. (total 90 functions!)
-Maintained compatibility with the opie-fileformat.
-New icons.
-Found that the DataParser was not a real RPN compiler of the expressions. In fact it was returning faulty results in calculations, in both binary or unary operations. A1-A2-A3 was parsed as A1-(A2-A3). A1 was parsed as A1.
-Added new class "Expression" a general Parser for spreadsheet-expression. Imported from an old C# project of mine.
-Now can also parse <>=!%&^|"" in expressions.
-Added experimental Excel File format import!. The opie-sheet can import any excel file in BIFF7/BIFF8 format. These formats are used in Excel XP,2000,95. The Excel Importer class is in a good coding level.. BUT it is not complete. Only strings,numbers,formulas are imported. Not formatting rules. Not all the functions are converted in the functions of opie-sheet. Infact FEW functions are converted.
-Fixed a bug with Sheet Recalculation. Added ReCalc() function. Opie-sheet was calculating wrong the values of expression in opening/importing. if a value needed was not loaded yet in the time of calculation. Solved with ReCalc() each time the active sheet is changing.
*known issues:
-if someone enters directly text as parameter to a string function the text renders as uppercase due to the calculation engine that uppercases all the parsing sentence.
-randbetween return only integer part random... if both limit numbers are integers.
-skew and kurt function give different results compared to kspread-oofice equivalents.
-unstable parser Excel Class
-string vars and string functions are not correctly handled by excel importer.
-unicode strings are converted FINE in QString unicode format, but cannot be rendered fine if a suitable unicode font is not setuped as the default string. So the string is junked in the opie-sheet and may crash the parser.
*TODOs:
-surelly a much full-stable excel importer.
-Cell Manipulation of many Data is really slow.... must change the QList data type. To a structure more efficient.
-maybe some more functions.
-maybe some kind of charts drawing?
-maybe kspread or ooffice files import/export.
Diffstat (limited to 'noncore/apps/opie-sheet/sheet.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-sheet/sheet.cpp | 2069 |
1 files changed, 1881 insertions, 188 deletions
diff --git a/noncore/apps/opie-sheet/sheet.cpp b/noncore/apps/opie-sheet/sheet.cpp index c2563c2..103b83b 100644 --- a/noncore/apps/opie-sheet/sheet.cpp +++ b/noncore/apps/opie-sheet/sheet.cpp | |||
@@ -14,12 +14,15 @@ | |||
14 | 14 | ||
15 | #include "sheet.h" | 15 | #include "sheet.h" |
16 | 16 | ||
17 | #include <qmainwindow.h> | 17 | #include <qmainwindow.h> |
18 | #include <qmessagebox.h> | 18 | #include <qmessagebox.h> |
19 | #include <math.h> | 19 | #include <math.h> |
20 | #include <stdlib.h> | ||
21 | #include <stdio.h> | ||
22 | #include <time.h> | ||
20 | 23 | ||
21 | #define DEFAULT_COL_WIDTH 50 | 24 | #define DEFAULT_COL_WIDTH 50 |
22 | 25 | ||
23 | Sheet::Sheet(int numRows, int numCols, QWidget *parent) | 26 | Sheet::Sheet(int numRows, int numCols, QWidget *parent) |
24 | :QTable(numRows, numCols, parent) | 27 | :QTable(numRows, numCols, parent) |
25 | { | 28 | { |
@@ -37,35 +40,38 @@ Sheet::Sheet(int numRows, int numCols, QWidget *parent) | |||
37 | 40 | ||
38 | sheetData.setAutoDelete(TRUE); | 41 | sheetData.setAutoDelete(TRUE); |
39 | clipboardData.setAutoDelete(TRUE); | 42 | clipboardData.setAutoDelete(TRUE); |
40 | for (int i=0; i<numCols; ++i) | 43 | for (int i=0; i<numCols; ++i) |
41 | horizontalHeader()->setLabel(i, getHeaderString(i+1), DEFAULT_COL_WIDTH); | 44 | horizontalHeader()->setLabel(i, getHeaderString(i+1), DEFAULT_COL_WIDTH); |
42 | 45 | ||
46 | |||
43 | connect(this, SIGNAL(currentChanged(int, int)), this, SLOT(slotCellSelected(int, int))); | 47 | connect(this, SIGNAL(currentChanged(int, int)), this, SLOT(slotCellSelected(int, int))); |
44 | connect(this, SIGNAL(valueChanged(int, int)), this, SLOT(slotCellChanged(int, int))); | 48 | connect(this, SIGNAL(valueChanged(int, int)), this, SLOT(slotCellChanged(int, int))); |
45 | } | 49 | } |
46 | 50 | ||
47 | Sheet::~Sheet() | 51 | Sheet::~Sheet() |
48 | { | 52 | { |
49 | } | 53 | } |
50 | 54 | ||
51 | typeCellData *Sheet::findCellData(int row, int col) | 55 | typeCellData *Sheet::findCellData(int row, int col) |
52 | { | 56 | { |
53 | typeCellData *tempCellData; | 57 | typeCellData *tempCellData; |
54 | for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next()) | 58 | for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next()) |
55 | if (tempCellData->row==row && tempCellData->col==col) | 59 | { |
56 | return tempCellData; | 60 | if (tempCellData->row==row && tempCellData->col==col) return tempCellData; |
61 | } | ||
57 | return NULL; | 62 | return NULL; |
58 | } | 63 | } |
59 | 64 | ||
60 | void Sheet::slotCellSelected(int row, int col) | 65 | void Sheet::slotCellSelected(int row, int col) |
61 | { | 66 | { |
62 | typeCellData *cellData=findCellData(row, col); | 67 | typeCellData *cellData=findCellData(row, col); |
63 | if (cellData) | 68 | if (cellData) |
69 | { | ||
64 | emit currentDataChanged(cellData->data); | 70 | emit currentDataChanged(cellData->data); |
65 | else | 71 | }else |
66 | emit currentDataChanged(""); | 72 | emit currentDataChanged(""); |
67 | } | 73 | } |
68 | 74 | ||
69 | typeCellData *Sheet::createCellData(int row, int col) | 75 | typeCellData *Sheet::createCellData(int row, int col) |
70 | { | 76 | { |
71 | if (row<0 || col<0) return NULL; | 77 | if (row<0 || col<0) return NULL; |
@@ -85,16 +91,44 @@ typeCellData *Sheet::createCellData(int row, int col) | |||
85 | void Sheet::slotCellChanged(int row, int col) | 91 | void Sheet::slotCellChanged(int row, int col) |
86 | { | 92 | { |
87 | typeCellData *cellData=findCellData(row, col); | 93 | typeCellData *cellData=findCellData(row, col); |
88 | if (!cellData) cellData=createCellData(row, col); | 94 | if (!cellData) cellData=createCellData(row, col); |
89 | if (cellData) cellData->data=text(row, col); | 95 | if (cellData) cellData->data=text(row, col); |
90 | for (cellData=sheetData.first(); cellData; cellData=sheetData.next()) | 96 | for (cellData=sheetData.first(); cellData; cellData=sheetData.next()) |
91 | setText(cellData->row, cellData->col, dataParser(findCellName(cellData->row, cellData->col), cellData->data)); | 97 | { |
98 | // modified by Toussis Manolis koppermind@panafonet.gr | ||
99 | // the parser was crashing if there were no closed parenthesis. | ||
100 | int w1,ii=0; | ||
101 | for(w1=0;w1<=(int)text(row, col).length();w1++) | ||
102 | { | ||
103 | if(text(row,col)[w1]=='(') ii++; | ||
104 | if(text(row,col)[w1]==')') ii--; | ||
105 | }; | ||
106 | if(ii==0) setText(cellData->row, cellData->col, dataParser(findCellName(cellData->row, cellData->col), cellData->data)); | ||
107 | //end of modification | ||
108 | // old was plain: | ||
109 | //setText(cellData->row, cellData->col, dataParser(findCellName(cellData->row, cellData->col), cellData->data)); | ||
110 | }; | ||
92 | emit sheetModified(); | 111 | emit sheetModified(); |
93 | } | 112 | } |
94 | 113 | ||
114 | |||
115 | void Sheet::ReCalc(void) | ||
116 | { | ||
117 | typeCellData* cellData; | ||
118 | for (cellData=sheetData.first(); cellData; cellData=sheetData.next()) | ||
119 | { | ||
120 | //printf("cellchanged:%d, %d\r\n",cellData->row,cellData->col); | ||
121 | |||
122 | slotCellChanged(cellData->row,cellData->col); | ||
123 | }; | ||
124 | }; | ||
125 | |||
126 | |||
127 | |||
128 | |||
95 | void Sheet::swapCells(int row1, int col1, int row2, int col2) | 129 | void Sheet::swapCells(int row1, int col1, int row2, int col2) |
96 | { | 130 | { |
97 | typeCellData *cellData1=findCellData(row1, col1), *cellData2=findCellData(row2, col2); | 131 | typeCellData *cellData1=findCellData(row1, col1), *cellData2=findCellData(row2, col2); |
98 | if (!cellData1) cellData1=createCellData(row1, col1); | 132 | if (!cellData1) cellData1=createCellData(row1, col1); |
99 | if (!cellData2) cellData2=createCellData(row2, col2); | 133 | if (!cellData2) cellData2=createCellData(row2, col2); |
100 | if (cellData1 && cellData2) | 134 | if (cellData1 && cellData2) |
@@ -115,25 +149,26 @@ QString Sheet::getParameter(const QString ¶meters, int paramNo, bool giveErr | |||
115 | for (int i=0; i<paramNo; ++i) | 149 | for (int i=0; i<paramNo; ++i) |
116 | { | 150 | { |
117 | position=params.find(','); | 151 | position=params.find(','); |
118 | if (position<0) | 152 | if (position<0) |
119 | { | 153 | { |
120 | if (giveError) QMessageBox::critical(this, tr("Error"), tr("Too few arguments to function '"+funcName+'\'')); | 154 | if (giveError) QMessageBox::critical(this, tr("Error"), tr("Too few arguments to function '"+funcName+'\'')); |
121 | return QString(); | 155 | //printf("params:%s\r\n",parameters.ascii()); |
156 | return QString(NULL); | ||
122 | } | 157 | } |
123 | params=params.mid(position+1); | 158 | params=params.mid(position+1); |
124 | } | 159 | } |
125 | position=params.find(','); | 160 | position=params.find(','); |
126 | if (position<0) return params; | 161 | if (position<0) return params; |
127 | return params.left(position); | 162 | return params.left(position); |
128 | } | 163 | } |
129 | 164 | ||
130 | bool Sheet::findRange(const QString &variable1, const QString &variable2, int *row1, int *col1, int *row2, int *col2) | 165 | bool Sheet::findRange(const QString &variable1, const QString &variable2, int *row1, int *col1, int *row2, int *col2) |
131 | { | 166 | { |
132 | int row, col; | 167 | int row, col; |
133 | if (!findRowColumn(variable1, row1, col1, TRUE) || !findRowColumn(variable2, row2, col2, TRUE)) return FALSE; | 168 | if (!findRowColumn(variable1, row1, col1, FALSE) || !findRowColumn(variable2, row2, col2, FALSE)) return FALSE; |
134 | if (*row1>*row2) | 169 | if (*row1>*row2) |
135 | { | 170 | { |
136 | row=*row1; | 171 | row=*row1; |
137 | *row1=*row2; | 172 | *row1=*row2; |
138 | *row2=row; | 173 | *row2=row; |
139 | } | 174 | } |
@@ -156,294 +191,1658 @@ bool Sheet::findRowColumn(const QString &variable, int *row, int *col, bool give | |||
156 | } | 191 | } |
157 | *row=variable.mid(position).toInt()-1; | 192 | *row=variable.mid(position).toInt()-1; |
158 | *col=getHeaderColumn(variable.left(position))-1; | 193 | *col=getHeaderColumn(variable.left(position))-1; |
159 | return TRUE; | 194 | return TRUE; |
160 | } | 195 | } |
161 | 196 | ||
162 | double Sheet::calculateVariable(const QString &variable) | 197 | QString Sheet::calculateVariable(const QString &variable) |
163 | { | 198 | { |
164 | bool ok; | 199 | bool ok; |
200 | printf("calculateVariable=%s,len=%d\r\n",variable.ascii(),variable.length()); | ||
201 | if(variable.left(1)=="\"") return QString(variable.mid(1,variable.length()-2)); | ||
165 | double tempResult=variable.toDouble(&ok); | 202 | double tempResult=variable.toDouble(&ok); |
166 | if (ok) return tempResult; | 203 | if (ok) |
204 | { | ||
205 | if(tempResult!=0.0) | ||
206 | { | ||
207 | return QString::number(tempResult); | ||
208 | } | ||
209 | else | ||
210 | { | ||
211 | if(variable!="0" || variable!="0.0") return QString(variable); // hereis a string variable | ||
212 | return QString::number(tempResult); | ||
213 | }; | ||
214 | }; | ||
167 | 215 | ||
168 | int row, col; | 216 | int row, col; |
169 | return (findRowColumn(variable, &row, &col, TRUE) ? dataParser(variable, text(row, col)).toDouble() : 0); | 217 | if(findRowColumn(variable, &row, &col, FALSE)) return dataParser(variable, text(row,col)); |
218 | //return (findRowColumn(variable, &row, &col, TRUE) ? dataParser(variable, text(row, col)) : 0); | ||
219 | return QString(variable); | ||
170 | } | 220 | } |
171 | 221 | ||
222 | double Sheet::BesselI0(double x) | ||
223 | { | ||
224 | //Returns the modi ed Bessel function I0(x) for any real x. | ||
225 | double ax,ans; | ||
226 | double y; | ||
227 | if ((ax=fabs(x)) < 3.75) | ||
228 | { | ||
229 | y=x/3.75; | ||
230 | y*=y; | ||
231 | ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); | ||
232 | }else | ||
233 | { | ||
234 | y=3.75/ax; | ||
235 | ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 +y*0.392377e-2)))))))); | ||
236 | } | ||
237 | return ans; | ||
238 | }; | ||
239 | |||
240 | double Sheet::BesselI1(double x) | ||
241 | { | ||
242 | double ax,ans; | ||
243 | double y; | ||
244 | if ((ax=fabs(x)) < 3.75) | ||
245 | { | ||
246 | y=x/3.75; | ||
247 | y*=y; | ||
248 | ans=ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3)))))); | ||
249 | } else | ||
250 | { | ||
251 | y=3.75/ax; | ||
252 | ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1 -y*0.420059e-2)); ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans)))); | ||
253 | ans *= (exp(ax)/sqrt(ax)); | ||
254 | } | ||
255 | return x < 0.0 ? -ans : ans; | ||
256 | }; | ||
257 | |||
258 | double Sheet::BesselI(int n, double x) | ||
259 | { | ||
260 | double ACC=40.0; | ||
261 | double BIGNO=1.0e10; | ||
262 | double BIGNI=1.0e-10; | ||
263 | int j; | ||
264 | double bi,bim,bip,tox,ans; | ||
265 | if (n < 2) return 0.0; | ||
266 | if (x == 0.0) return 0.0; else | ||
267 | { | ||
268 | tox=2.0/fabs(x); | ||
269 | bip=ans=0.0; | ||
270 | bi=1.0; | ||
271 | for (j=2*(n+(int) sqrt(ACC*n));j>0;j--) | ||
272 | { | ||
273 | bim=bip+j*tox*bi; | ||
274 | bip=bi; | ||
275 | bi=bim; | ||
276 | if (fabs(bi) > BIGNO) | ||
277 | { | ||
278 | ans *= BIGNI; | ||
279 | bi *= BIGNI; | ||
280 | bip *= BIGNI; | ||
281 | } | ||
282 | if (j == n) ans=bip; | ||
283 | } | ||
284 | ans *= BesselI0(x)/bi; | ||
285 | return x < 0.0 && (n & 1) ? -ans : ans; | ||
286 | } | ||
287 | }; | ||
288 | |||
289 | double Sheet::BesselK0(double x) | ||
290 | { | ||
291 | double y,ans; | ||
292 | if (x <= 2.0) | ||
293 | { | ||
294 | y=x*x/4.0; | ||
295 | ans=(-log(x/2.0)*BesselI0(x))+(-0.57721566+y*(0.42278420 +y*(0.23069756+y*(0.3488590e-1+y*(0.262698e-2 +y*(0.10750e-3+y*0.74e-5)))))); | ||
296 | } else | ||
297 | { | ||
298 | y=2.0/x; | ||
299 | ans=(exp(-x)/sqrt(x))*(1.25331414+y*(-0.7832358e-1 +y*(0.2189568e-1+y*(-0.1062446e-1+y*(0.587872e-2 +y*(-0.251540e-2+y*0.53208e-3)))))); | ||
300 | } | ||
301 | return ans; | ||
302 | }; | ||
303 | |||
304 | double Sheet::BesselK1(double x) | ||
305 | { | ||
306 | double y,ans; | ||
307 | if (x <= 2.0) | ||
308 | { | ||
309 | y=x*x/4.0; | ||
310 | ans=(log(x/2.0)*BesselI1(x))+(1.0/x)*(1.0+y*(0.15443144 +y*(-0.67278579+y*(-0.18156897+y*(-0.1919402e-1 +y*(-0.110404e-2+y*(-0.4686e-4))))))); | ||
311 | } else | ||
312 | { | ||
313 | y=2.0/x; | ||
314 | ans=(exp(-x)/sqrt(x))*(1.25331414+y*(0.23498619 +y*(-0.3655620e-1+y*(0.1504268e-1+y*(-0.780353e-2 +y*(0.325614e-2+y*(-0.68245e-3))))))); | ||
315 | } | ||
316 | return ans; | ||
317 | }; | ||
318 | |||
319 | double Sheet::BesselK(int n, double x) | ||
320 | { | ||
321 | int j; | ||
322 | double bk,bkm,bkp,tox; | ||
323 | if (n < 2) return 0.0; | ||
324 | tox=2.0/x; | ||
325 | bkm=BesselK0(x); | ||
326 | bk=BesselK1(x); | ||
327 | for (j=1;j<n;j++) | ||
328 | { | ||
329 | bkp=bkm+j*tox*bk; | ||
330 | bkm=bk; | ||
331 | bk=bkp; | ||
332 | } | ||
333 | return bk; | ||
334 | }; | ||
335 | |||
336 | double Sheet::BesselJ0(double x) | ||
337 | { | ||
338 | double ax,z; | ||
339 | double xx,y,ans,ans1,ans2; | ||
340 | if ((ax=fabs(x)) < 8.0) | ||
341 | { | ||
342 | y=x*x; | ||
343 | ans1=57568490574.0+y*(-13362590354.0+y*(651619640.7 +y*(-11214424.18+y*(77392.33017+y*(-184.9052456))))); | ||
344 | ans2=57568490411.0+y*(1029532985.0+y*(9494680.718 +y*(59272.64853+y*(267.8532712+y*1.0)))); | ||
345 | ans=ans1/ans2; | ||
346 | } else | ||
347 | { | ||
348 | z=8.0/ax; | ||
349 | y=z*z; | ||
350 | xx=ax-0.785398164; | ||
351 | ans1=1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 +y*(-0.2073370639e-5+y*0.2093887211e-6))); | ||
352 | ans2 = -0.1562499995e-1+y*(0.1430488765e-3 +y*(-0.6911147651e-5+y*(0.7621095161e-6 -y*0.934935152e-7))); | ||
353 | ans=sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); | ||
354 | } | ||
355 | return ans; | ||
356 | }; | ||
357 | |||
358 | double Sheet::BesselY0(double x) | ||
359 | { | ||
360 | double z; | ||
361 | double xx,y,ans,ans1,ans2; | ||
362 | if (x < 8.0) | ||
363 | { | ||
364 | y=x*x; | ||
365 | ans1 = -2957821389.0+y*(7062834065.0+y*(-512359803.6 +y*(10879881.29+y*(-86327.92757+y*228.4622733)))); | ||
366 | ans2=40076544269.0+y*(745249964.8+y*(7189466.438 +y*(47447.26470+y*(226.1030244+y*1.0)))); | ||
367 | ans=(ans1/ans2)+0.636619772*BesselJ0(x)*log(x); | ||
368 | } else | ||
369 | { | ||
370 | z=8.0/x; | ||
371 | y=z*z; | ||
372 | xx=x-0.785398164; | ||
373 | ans1=1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 +y*(-0.2073370639e-5+y*0.2093887211e-6))); | ||
374 | ans2 = -0.1562499995e-1+y*(0.1430488765e-3 +y*(-0.6911147651e-5+y*(0.7621095161e-6 +y*(-0.934945152e-7)))); | ||
375 | ans=sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); | ||
376 | } | ||
377 | return ans; | ||
378 | }; | ||
379 | |||
380 | double Sheet::BesselJ1(double x) | ||
381 | { | ||
382 | double ax,z; | ||
383 | double xx,y,ans,ans1,ans2; | ||
384 | if ((ax=fabs(x)) < 8.0) | ||
385 | { | ||
386 | y=x*x; | ||
387 | ans1=x*(72362614232.0+y*(-7895059235.0+y*(242396853.1 +y*(-2972611.439+y*(15704.48260+y*(-30.16036606)))))); | ||
388 | ans2=144725228442.0+y*(2300535178.0+y*(18583304.74 +y*(99447.43394+y*(376.9991397+y*1.0)))); | ||
389 | ans=ans1/ans2; | ||
390 | } else | ||
391 | { | ||
392 | z=8.0/ax; y=z*z; xx=ax-2.356194491; | ||
393 | ans1=1.0+y*(0.183105e-2+y*(-0.3516396496e-4 +y*(0.2457520174e-5+y*(-0.240337019e-6)))); | ||
394 | ans2=0.04687499995+y*(-0.2002690873e-3 +y*(0.8449199096e-5+y*(-0.88228987e-6 +y*0.105787412e-6))); | ||
395 | ans=sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2); | ||
396 | if (x < 0.0) ans = -ans; | ||
397 | } | ||
398 | return ans; | ||
399 | }; | ||
400 | |||
401 | double Sheet::BesselY1(double x) | ||
402 | { | ||
403 | double z; | ||
404 | double xx,y,ans,ans1,ans2; | ||
405 | if (x < 8.0) | ||
406 | { | ||
407 | y=x*x; | ||
408 | ans1=x*(-0.4900604943e13+y*(0.1275274390e13 +y*(-0.5153438139e11+y*(0.7349264551e9 +y*(-0.4237922726e7+y*0.8511937935e4))))); | ||
409 | ans2=0.2499580570e14+y*(0.4244419664e12 +y*(0.3733650367e10+y*(0.2245904002e8 +y*(0.1020426050e6+y*(0.3549632885e3+y))))); | ||
410 | ans=(ans1/ans2)+0.636619772*(BesselJ1(x)*log(x)-1.0/x); | ||
411 | } else | ||
412 | { | ||
413 | z=8.0/x; | ||
414 | y=z*z; | ||
415 | xx=x-2.356194491; | ||
416 | ans1=1.0+y*(0.183105e-2+y*(-0.3516396496e-4 +y*(0.2457520174e-5+y*(-0.240337019e-6)))); | ||
417 | ans2=0.04687499995+y*(-0.2002690873e-3 +y*(0.8449199096e-5+y*(-0.88228987e-6 +y*0.105787412e-6))); | ||
418 | ans=sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2); | ||
419 | } | ||
420 | return ans; | ||
421 | }; | ||
422 | |||
423 | double Sheet::BesselY(int n, double x) | ||
424 | { | ||
425 | int j; | ||
426 | double by,bym,byp,tox; | ||
427 | if (n < 2) return 0.0; | ||
428 | tox=2.0/x; | ||
429 | by=BesselY1(x); | ||
430 | bym=BesselY0(x); | ||
431 | for (j=1;j<n;j++) | ||
432 | { | ||
433 | byp=j*tox*by-bym; | ||
434 | bym=by; | ||
435 | by=byp; | ||
436 | } | ||
437 | return by; | ||
438 | }; | ||
439 | |||
440 | double Sheet::BesselJ(int n, double x) | ||
441 | { | ||
442 | double ACC=40.0; | ||
443 | double BIGNO=1.0e10; | ||
444 | double BIGNI=1.0e-10; | ||
445 | int j,jsum,m; | ||
446 | double ax,bj,bjm,bjp,sum,tox,ans; | ||
447 | if (n < 2) return 0.0; | ||
448 | ax=fabs(x); | ||
449 | if (ax == 0.0) return 0.0; | ||
450 | else if (ax > (double) n) | ||
451 | { | ||
452 | tox=2.0/ax; | ||
453 | bjm=BesselJ0(ax); | ||
454 | bj=BesselJ1(ax); | ||
455 | for (j=1;j<n;j++) | ||
456 | { | ||
457 | bjp=j*tox*bj-bjm; | ||
458 | bjm=bj; | ||
459 | bj=bjp; | ||
460 | } | ||
461 | ans=bj; | ||
462 | } else | ||
463 | { | ||
464 | tox=2.0/ax; | ||
465 | m=2*((n+(int) sqrt(ACC*n))/2); | ||
466 | jsum=0; | ||
467 | bjp=ans=sum=0.0; | ||
468 | bj=1.0; | ||
469 | for (j=m;j>0;j--) | ||
470 | { | ||
471 | bjm=j*tox*bj-bjp; | ||
472 | bjp=bj; | ||
473 | bj=bjm; | ||
474 | if (fabs(bj) > BIGNO) | ||
475 | { | ||
476 | bj *= BIGNI; | ||
477 | bjp *= BIGNI; | ||
478 | ans *= BIGNI; | ||
479 | sum *= BIGNI; | ||
480 | } | ||
481 | if (jsum) sum += bj; | ||
482 | jsum=!jsum; | ||
483 | if (j == n) ans=bjp; | ||
484 | } | ||
485 | sum=2.0*sum-bj; | ||
486 | ans /= sum; | ||
487 | } | ||
488 | return x < 0.0 && (n & 1) ? -ans : ans; | ||
489 | }; | ||
490 | |||
491 | double Sheet::GammaLn(double xx) | ||
492 | { | ||
493 | double x,y,tmp,ser; | ||
494 | static double cof[6]={76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5}; | ||
495 | int j; | ||
496 | y=x=xx; | ||
497 | tmp=x+5.5; | ||
498 | tmp -= (x+0.5)*log(tmp); | ||
499 | ser=1.000000000190015; | ||
500 | for (j=0;j<=5;j++) ser += cof[j]/++y; | ||
501 | return -tmp+log(2.5066282746310005*ser/x); | ||
502 | }; | ||
503 | |||
504 | double Sheet::Factorial(double n) | ||
505 | { | ||
506 | if (n < 0) return 0.0; | ||
507 | if (n > 100) return 0.0; | ||
508 | return exp(GammaLn(n+1.0)); | ||
509 | }; | ||
510 | |||
511 | double Sheet::GammaP(double a, double x) | ||
512 | { | ||
513 | // returns GammaP(a,x) | ||
514 | //void gcf(float *gammcf, float a, float x, float *gln); | ||
515 | //void gser(float *gamser, float a, float x, float *gln); | ||
516 | double gamser,gammcf,gln; | ||
517 | if (x < 0.0 || a <= 0.0) return 0.0;//error | ||
518 | if (x < (a+1.0)) | ||
519 | { | ||
520 | GammaSeries(&gamser,a,x,&gln); | ||
521 | return gamser; | ||
522 | }else | ||
523 | { | ||
524 | GammaContinuedFraction(&gammcf,a,x,&gln); | ||
525 | return 1.0-gammcf; | ||
526 | } | ||
527 | }; | ||
528 | |||
529 | double Sheet::GammaQ(double a,double x) | ||
530 | { | ||
531 | //returns GammaQ(a,x)=1.0 - GammaP(a,x); | ||
532 | return (1.0-GammaP(a,x)); | ||
533 | }; | ||
534 | |||
535 | |||
536 | void Sheet::GammaSeries(double *gamser, double a, double x, double *gln) | ||
537 | { | ||
538 | double EPS=3.0e-7; | ||
539 | int ITMAX=100; | ||
540 | int n; | ||
541 | double sum,del,ap; | ||
542 | *gln=GammaLn(a); | ||
543 | if (x <= 0.0) | ||
544 | { | ||
545 | if (x < 0.0) return;//error | ||
546 | *gamser=0.0; | ||
547 | return; | ||
548 | } else | ||
549 | { | ||
550 | ap=a; | ||
551 | del=sum=1.0/a; | ||
552 | for (n=1;n<=ITMAX;n++) | ||
553 | { | ||
554 | ++ap; | ||
555 | del *= x/ap; | ||
556 | sum += del; | ||
557 | if (fabs(del) < fabs(sum)*EPS) | ||
558 | { | ||
559 | *gamser=sum*exp(-x+a*log(x)-(*gln)); | ||
560 | return; | ||
561 | } | ||
562 | } return; | ||
563 | return; | ||
564 | } | ||
565 | }; | ||
566 | |||
567 | |||
568 | void Sheet::GammaContinuedFraction(double *gammcf, double a, double x, double *gln) | ||
569 | { | ||
570 | double EPS=3.0e-7; | ||
571 | double FPMIN=1.0e-30; | ||
572 | int ITMAX=100; | ||
573 | int i; | ||
574 | double an,b,c,d,del,h; | ||
575 | *gln=GammaLn(a); | ||
576 | b=x+1.0-a; | ||
577 | c=1.0/FPMIN; | ||
578 | d=1.0/b; h=d; | ||
579 | for (i=1;i<=ITMAX;i++) | ||
580 | { | ||
581 | an = -i*(i-a); | ||
582 | b += 2.0; d=an*d+b; | ||
583 | if (fabs(d) < FPMIN) d=FPMIN; | ||
584 | c=b+an/c; | ||
585 | if (fabs(c) < FPMIN) c=FPMIN; | ||
586 | d=1.0/d; del=d*c; h *= del; | ||
587 | if (fabs(del-1.0) < EPS) break; | ||
588 | } | ||
589 | if (i > ITMAX) return; | ||
590 | *gammcf=exp(-x+a*log(x)-(*gln))*h; | ||
591 | }; | ||
592 | |||
593 | double Sheet::ErrorFunction(double x) | ||
594 | { | ||
595 | return x < 0.0 ? -GammaP(0.5,x*x) : GammaP(0.5,x*x); | ||
596 | }; | ||
597 | |||
598 | double Sheet::ErrorFunctionComplementary(double x) | ||
599 | { | ||
600 | return x < 0.0 ? 1.0+GammaP(0.5,x*x) : GammaQ(0.5,x*x); | ||
601 | }; | ||
602 | |||
603 | double Sheet::Beta(double z, double w) | ||
604 | { | ||
605 | return exp(GammaLn(z)+GammaLn(w)-GammaLn(z+w)); | ||
606 | }; | ||
607 | |||
608 | |||
609 | double Sheet::BetaContinuedFraction(double a, double b, double x) | ||
610 | { | ||
611 | int MAXIT=100; | ||
612 | double EPS=3.0e-7; | ||
613 | double FPMIN=1.0e-30; | ||
614 | int m,m2; | ||
615 | double aa,c,d,del,h,qab,qam,qap; | ||
616 | qab=a+b; | ||
617 | qap=a+1.0; qam=a-1.0; c=1.0; | ||
618 | d=1.0-qab*x/qap; | ||
619 | if (fabs(d) < FPMIN) d=FPMIN; | ||
620 | d=1.0/d; h=d; | ||
621 | for (m=1;m<=MAXIT;m++) | ||
622 | { | ||
623 | m2=2*m; aa=m*(b-m)*x/((qam+m2)*(a+m2)); | ||
624 | d=1.0+aa*d; | ||
625 | if (fabs(d) < FPMIN) d=FPMIN; | ||
626 | c=1.0+aa/c; | ||
627 | if (fabs(c) < FPMIN) c=FPMIN; | ||
628 | d=1.0/d; h *= d*c; | ||
629 | aa = -(a+m)*(qab+m)*x/((a+m2)*(qap+m2)); d=1.0+aa*d; | ||
630 | if (fabs(d) < FPMIN) d=FPMIN; | ||
631 | c=1.0+aa/c; | ||
632 | if (fabs(c) < FPMIN) c=FPMIN; d=1.0/d; | ||
633 | del=d*c; h *= del; | ||
634 | if (fabs(del-1.0) < EPS) break; | ||
635 | } | ||
636 | if (m > MAXIT) return 0.0; | ||
637 | return h; | ||
638 | }; | ||
639 | |||
640 | double Sheet::BetaIncomplete(double a, double b, double x) | ||
641 | { | ||
642 | double bt; | ||
643 | if (x < 0.0 || x > 1.0) return 0.0; | ||
644 | if (x == 0.0 || x == 1.0) bt=0.0; else | ||
645 | bt=exp(GammaLn(a+b)-GammaLn(a)-GammaLn(b)+a*log(x)+b*log(1.0-x)); | ||
646 | if (x < (a+1.0)/(a+b+2.0)) return bt*BetaContinuedFraction(a,b,x)/a; else | ||
647 | return 1.0-bt*BetaContinuedFraction(b,a,1.0-x)/b; | ||
648 | }; | ||
649 | |||
650 | |||
651 | |||
172 | double Sheet::functionSum(const QString ¶m1, const QString ¶m2) | 652 | double Sheet::functionSum(const QString ¶m1, const QString ¶m2) |
173 | { | 653 | { |
174 | int row1, col1, row2, col2, row, col; | 654 | int row1, col1, row2, col2, row, col; |
655 | double result=0, tempResult; | ||
656 | bool ok; | ||
657 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
658 | { | ||
659 | for (row=row1; row<=row2; ++row) | ||
660 | for (col=col1; col<=col2; ++col) | ||
661 | { | ||
662 | tempResult=text(row, col).toDouble(&ok); | ||
663 | if (ok) result+=tempResult; | ||
664 | } | ||
665 | return result; | ||
666 | }else | ||
667 | { | ||
668 | double d1=0,d2=0; | ||
669 | d1=calculateVariable(param1).toDouble(&ok); | ||
670 | d2=calculateVariable(param2).toDouble(&ok); | ||
671 | return(d1+d2); | ||
672 | }; | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | QString Sheet::functionIndex(const QString ¶m1, const QString ¶m2, int indx) | ||
677 | { | ||
678 | int row1, col1, row2, col2, row, col; | ||
175 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | 679 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; |
680 | int ii=1; | ||
681 | for (col=col1; col<=col2; ++col) | ||
682 | for (row=row1; row<=row2; ++row) | ||
683 | { | ||
684 | if(ii==indx) return text(row,col); | ||
685 | ii++; | ||
686 | } | ||
687 | return QString(""); | ||
688 | } | ||
689 | |||
690 | |||
176 | 691 | ||
692 | double Sheet::functionVariancePopulation(const QString ¶m1, const QString ¶m2) | ||
693 | { | ||
694 | int row1, col1, row2, col2, row, col; | ||
695 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | ||
696 | double avg1=functionAvg(param1,param2); | ||
177 | double result=0, tempResult; | 697 | double result=0, tempResult; |
698 | int count1=0; | ||
178 | bool ok; | 699 | bool ok; |
179 | for (row=row1; row<=row2; ++row) | 700 | for (row=row1; row<=row2; ++row) |
180 | for (col=col1; col<=col2; ++col) | 701 | for (col=col1; col<=col2; ++col) |
181 | { | 702 | { |
182 | tempResult=text(row, col).toDouble(&ok); | 703 | tempResult=text(row, col).toDouble(&ok); |
183 | if (ok) result+=tempResult; | 704 | if (ok) { result=result + (tempResult - avg1)*(tempResult - avg1); count1++;}; |
184 | } | 705 | } |
185 | 706 | if(count1>0) result=result/double(count1); else result=0.0; | |
186 | return result; | 707 | return result; |
187 | } | 708 | }; |
188 | 709 | ||
189 | double Sheet::functionMin(const QString ¶m1, const QString ¶m2) | 710 | double Sheet::functionVariance(const QString ¶m1, const QString ¶m2) |
190 | { | 711 | { |
191 | int row1, col1, row2, col2, row, col; | 712 | int row1, col1, row2, col2, row, col; |
192 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | 713 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; |
714 | double avg1=functionAvg(param1,param2); | ||
715 | double result=0, tempResult; | ||
716 | int count1=0; | ||
717 | bool ok; | ||
718 | for (row=row1; row<=row2; ++row) | ||
719 | for (col=col1; col<=col2; ++col) | ||
720 | { | ||
721 | tempResult=text(row, col).toDouble(&ok); | ||
722 | if (ok) { result=result + (tempResult - avg1)*(tempResult - avg1); count1++;}; | ||
723 | } | ||
724 | if(count1>1) result=result/double(count1-1); else result=0.0; | ||
725 | return result; | ||
726 | }; | ||
193 | 727 | ||
194 | double min=0, tempMin; | 728 | double Sheet::functionSkew(const QString ¶m1, const QString ¶m2) |
195 | bool ok, init=FALSE; | 729 | { |
730 | int row1, col1, row2, col2, row, col; | ||
731 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | ||
732 | double avg1=functionAvg(param1,param2); | ||
733 | double var1=sqrt(functionVariancePopulation(param1,param2)); | ||
734 | if(var1==0.0) return 0.0; | ||
735 | double result=0, tempResult; | ||
736 | int count1=0; | ||
737 | bool ok; | ||
196 | for (row=row1; row<=row2; ++row) | 738 | for (row=row1; row<=row2; ++row) |
197 | for (col=col1; col<=col2; ++col) | 739 | for (col=col1; col<=col2; ++col) |
198 | { | 740 | { |
199 | tempMin=text(row, col).toDouble(&ok); | 741 | tempResult=text(row, col).toDouble(&ok); |
200 | if (ok && (!init || tempMin<min)) | 742 | if (ok) |
201 | { | 743 | { |
202 | min=tempMin; | 744 | result=result + (tempResult - avg1)*(tempResult - avg1)*(tempResult - avg1)/(var1*var1*var1); |
203 | init=TRUE; | 745 | count1++; |
204 | } | 746 | }; |
205 | } | 747 | } |
748 | if(count1>0) result=result/double(count1); else result=0.0; | ||
749 | return result; | ||
750 | }; | ||
206 | 751 | ||
207 | return min; | 752 | double Sheet::functionKurt(const QString ¶m1, const QString ¶m2) |
208 | } | ||
209 | |||
210 | double Sheet::functionMax(const QString ¶m1, const QString ¶m2) | ||
211 | { | 753 | { |
212 | int row1, col1, row2, col2, row, col; | 754 | int row1, col1, row2, col2, row, col; |
213 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | 755 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; |
214 | 756 | double avg1=functionAvg(param1,param2); | |
215 | double max=0, tempMax; | 757 | double var1=sqrt(functionVariancePopulation(param1,param2)); |
216 | bool ok, init=FALSE; | 758 | if(var1==0.0) return 0.0; |
759 | double result=0, tempResult; | ||
760 | int count1=0; | ||
761 | bool ok; | ||
217 | for (row=row1; row<=row2; ++row) | 762 | for (row=row1; row<=row2; ++row) |
218 | for (col=col1; col<=col2; ++col) | 763 | for (col=col1; col<=col2; ++col) |
219 | { | 764 | { |
220 | tempMax=text(row, col).toDouble(&ok); | 765 | tempResult=text(row, col).toDouble(&ok); |
221 | if (ok && (!init || tempMax>max)) | 766 | if (ok) |
222 | { | 767 | { |
223 | max=tempMax; | 768 | result=result + (tempResult - avg1)*(tempResult - avg1)* |
224 | init=TRUE; | 769 | (tempResult - avg1)*(tempResult - avg1)/(var1*var1*var1*var1); |
225 | } | 770 | count1++; |
771 | }; | ||
226 | } | 772 | } |
773 | if(count1>0) result=result/double(count1)-3.0; else result=0.0; | ||
774 | return result; | ||
775 | }; | ||
776 | |||
777 | |||
778 | |||
779 | double Sheet::functionSumSQ(const QString ¶m1, const QString ¶m2) | ||
780 | { | ||
781 | int row1, col1, row2, col2, row, col; | ||
782 | double result=0, tempResult; | ||
783 | bool ok; | ||
784 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
785 | { | ||
786 | for (row=row1; row<=row2; ++row) | ||
787 | for (col=col1; col<=col2; ++col) | ||
788 | { | ||
789 | tempResult=text(row, col).toDouble(&ok); | ||
790 | if (ok) result+=tempResult*tempResult; | ||
791 | } | ||
792 | return result; | ||
793 | }else | ||
794 | { | ||
795 | double d1=0,d2=0; | ||
796 | d1=calculateVariable(param1).toDouble(&ok); | ||
797 | d2=calculateVariable(param2).toDouble(&ok); | ||
798 | return(d1*d1+d2*d2); | ||
799 | }; | ||
800 | return 0; | ||
801 | } | ||
802 | |||
227 | 803 | ||
228 | return max; | 804 | |
805 | double Sheet::functionMin(const QString ¶m1, const QString ¶m2) | ||
806 | { | ||
807 | int row1, col1, row2, col2, row, col; | ||
808 | double min=0, tempMin; | ||
809 | bool ok, init=FALSE; | ||
810 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
811 | { | ||
812 | for (row=row1; row<=row2; ++row) | ||
813 | for (col=col1; col<=col2; ++col) | ||
814 | { | ||
815 | tempMin=text(row, col).toDouble(&ok); | ||
816 | if (ok && (!init || tempMin<min)) | ||
817 | { | ||
818 | min=tempMin; | ||
819 | init=TRUE; | ||
820 | } | ||
821 | } | ||
822 | return min; | ||
823 | }else | ||
824 | { | ||
825 | double d1=0,d2=0; | ||
826 | d1=calculateVariable(param1).toDouble(&ok); | ||
827 | d2=calculateVariable(param2).toDouble(&ok); | ||
828 | if(d1<d2) return(d1); else return(d2); | ||
829 | }; | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | double Sheet::functionMax(const QString ¶m1, const QString ¶m2) | ||
834 | { | ||
835 | int row1, col1, row2, col2, row, col; | ||
836 | double max=0, tempMax; | ||
837 | bool ok, init=FALSE; | ||
838 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
839 | { | ||
840 | for (row=row1; row<=row2; ++row) | ||
841 | for (col=col1; col<=col2; ++col) | ||
842 | { | ||
843 | tempMax=text(row, col).toDouble(&ok); | ||
844 | if (ok && (!init || tempMax>max)) | ||
845 | { | ||
846 | max=tempMax; | ||
847 | init=TRUE; | ||
848 | } | ||
849 | }; | ||
850 | return max; | ||
851 | }else | ||
852 | { | ||
853 | double d1=0,d2=0; | ||
854 | d1=calculateVariable(param1).toDouble(&ok); | ||
855 | d2=calculateVariable(param2).toDouble(&ok); | ||
856 | if(d1>d2) return(d1); else return(d2); | ||
857 | }; | ||
858 | return 0; | ||
229 | } | 859 | } |
230 | 860 | ||
231 | double Sheet::functionAvg(const QString ¶m1, const QString ¶m2) | 861 | double Sheet::functionAvg(const QString ¶m1, const QString ¶m2) |
232 | { | 862 | { |
233 | double resultSum=functionSum(param1, param2), resultCount=functionCount(param1, param2); | 863 | double resultSum=functionSum(param1, param2), resultCount=functionCount(param1, param2); |
234 | return (resultCount>0 ? resultSum/resultCount : 0); | 864 | return (resultCount>0 ? resultSum/resultCount : 0); |
235 | } | 865 | } |
236 | 866 | ||
237 | double Sheet::functionCount(const QString ¶m1, const QString ¶m2) | 867 | double Sheet::functionCount(const QString ¶m1, const QString ¶m2) |
238 | { | 868 | { |
239 | int row1, col1, row2, col2, row, col; | 869 | int row1, col1, row2, col2, row, col; |
240 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | 870 | int divider=0; |
871 | bool ok; | ||
872 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
873 | { | ||
874 | for (row=row1; row<=row2; ++row) | ||
875 | for (col=col1; col<=col2; ++col) | ||
876 | { | ||
877 | text(row, col).toDouble(&ok); | ||
878 | if (ok) ++divider; | ||
879 | }; | ||
880 | return divider; | ||
881 | }else | ||
882 | { | ||
883 | double d1=0,d2=0;int ii=0; | ||
884 | d1=calculateVariable(param1).toDouble(&ok); | ||
885 | if (ok) ii++; | ||
886 | d2=calculateVariable(param2).toDouble(&ok); | ||
887 | if (ok) ii++; | ||
888 | return(ii); | ||
889 | }; | ||
890 | return 0; | ||
891 | } | ||
241 | 892 | ||
893 | double Sheet::functionCountIf(const QString ¶m1, const QString ¶m2, const QString ¶m3) | ||
894 | { | ||
895 | int row1, col1, row2, col2, row, col; | ||
896 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | ||
897 | //same as count except check if each field is equal to param3 | ||
242 | int divider=0; | 898 | int divider=0; |
899 | QString s2; | ||
243 | bool ok; | 900 | bool ok; |
901 | s2=calculateVariable(param3); | ||
244 | for (row=row1; row<=row2; ++row) | 902 | for (row=row1; row<=row2; ++row) |
245 | for (col=col1; col<=col2; ++col) | 903 | for (col=col1; col<=col2; ++col) |
246 | { | 904 | { |
247 | text(row, col).toDouble(&ok); | 905 | text(row, col).toDouble(&ok); |
248 | if (ok) ++divider; | 906 | if (ok && (s2==text(row,col)) ) ++divider; |
249 | } | 907 | } |
250 | |||
251 | return divider; | 908 | return divider; |
252 | } | 909 | } |
253 | 910 | ||
254 | double Sheet::calculateFunction(const QString &function, const QString ¶meters) | 911 | |
912 | QString Sheet::calculateFunction(const QString &function, const QString ¶meters, int NumOfParams) | ||
255 | { | 913 | { |
914 | bool ok; | ||
915 | double val1=0.0,val2=0.0,val3=0.0; | ||
916 | long int vali=0; | ||
917 | int w1,w2; | ||
918 | int row,col; | ||
919 | QString s1,s2; | ||
920 | //basic functions | ||
256 | if (function=="+") | 921 | if (function=="+") |
257 | return calculateVariable(getParameter(parameters, 0))+calculateVariable(getParameter(parameters, 1)); | 922 | { |
923 | s1=calculateVariable(getParameter(parameters, 0)); | ||
924 | s2=calculateVariable(getParameter(parameters, 1)); | ||
925 | val1=s1.toDouble(&ok)+s2.toDouble(&ok); | ||
926 | return QString::number(val1); | ||
927 | |||
928 | }; | ||
258 | if (function=="-") | 929 | if (function=="-") |
259 | return calculateVariable(getParameter(parameters, 0))-calculateVariable(getParameter(parameters, 1)); | 930 | { |
931 | s1=calculateVariable(getParameter(parameters, 0)); | ||
932 | s2=calculateVariable(getParameter(parameters, 1)); | ||
933 | val1=s1.toDouble(&ok)-s2.toDouble(&ok); | ||
934 | return QString::number(val1); | ||
935 | }; | ||
260 | if (function=="*") | 936 | if (function=="*") |
261 | return calculateVariable(getParameter(parameters, 0))*calculateVariable(getParameter(parameters, 1)); | 937 | { |
938 | val1=calculateVariable( | ||
939 | getParameter(parameters, 0)).toDouble(&ok) | ||
940 | *calculateVariable(getParameter(parameters, 1)).toDouble(&ok); | ||
941 | return QString::number(val1); | ||
942 | }; | ||
262 | if (function=="/") | 943 | if (function=="/") |
263 | return calculateVariable(getParameter(parameters, 0))/calculateVariable(getParameter(parameters, 1)); | ||
264 | if (function=="SUM") | ||
265 | return functionSum(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
266 | if (function=="COUNT") | ||
267 | return functionCount(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
268 | if (function=="MIN") | ||
269 | return functionMin(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
270 | if (function=="MAX") | ||
271 | return functionMax(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
272 | if (function=="AVG") | ||
273 | return functionAvg(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
274 | if (function=="ABS") | ||
275 | return fabs(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
276 | if (function=="SIN") | ||
277 | return sin(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
278 | if (function=="COS") | ||
279 | return cos(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
280 | if (function=="TAN") | ||
281 | return tan(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
282 | if (function=="ATAN") | ||
283 | return atan(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
284 | if (function=="ATAN2") | ||
285 | return atan2(calculateVariable(getParameter(parameters, 0, TRUE, function)), calculateVariable(getParameter(parameters, 1, TRUE, function))); | ||
286 | if (function=="ASIN") | ||
287 | return asin(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
288 | if (function=="ACOS") | ||
289 | return acos(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
290 | if (function=="EXP") | ||
291 | return exp(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
292 | if (function=="LOG") | ||
293 | return log(calculateVariable(getParameter(parameters, 0, TRUE, function))); | ||
294 | if (function=="POW") | ||
295 | return pow(calculateVariable(getParameter(parameters, 0, TRUE, function)), calculateVariable(getParameter(parameters, 1, TRUE, function))); | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | int Sheet::getOperatorPriority(char oper) | ||
300 | { | ||
301 | switch (oper) | ||
302 | { | 944 | { |
303 | case '+': | 945 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); |
304 | case '-': | 946 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); |
305 | return 1; | 947 | if(val2==0.0) return QString("Err101"); |
306 | 948 | val1=val1/val2; | |
307 | case '*': | 949 | return QString::number(val1); |
308 | case '/': | 950 | }; |
309 | return 2; | 951 | if (function==">") |
310 | } | 952 | { |
311 | return 0; | 953 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); |
312 | } | 954 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); |
955 | if(val1>val2) return QString::number(1); else return QString::number(0); | ||
956 | }; | ||
957 | if (function=="<") | ||
958 | { | ||
959 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); | ||
960 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); | ||
961 | if(val1<val2) return QString::number(1); else return QString::number(0); | ||
962 | }; | ||
963 | if (function==">=") | ||
964 | { | ||
965 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); | ||
966 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); | ||
967 | if(val1>=val2) return QString::number(1); else return QString::number(0); | ||
968 | }; | ||
969 | if (function=="<=") | ||
970 | { | ||
971 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); | ||
972 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); | ||
973 | if(val1<=val2) return QString::number(1); else return QString::number(0); | ||
974 | }; | ||
975 | if (function=="!=") | ||
976 | { | ||
977 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); | ||
978 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); | ||
979 | if(val1!=val2) return QString::number(1); else return QString::number(0); | ||
980 | }; | ||
981 | if (function=="=="||function=="=") | ||
982 | { | ||
983 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); | ||
984 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); | ||
985 | if(val1==val2) return QString::number(1); else return QString::number(0); | ||
986 | }; | ||
987 | |||
988 | //LOGICAL / INFO | ||
989 | if (function=="ISBLANK") | ||
990 | { | ||
991 | if(findRowColumn(getParameter(parameters, 0), &row, &col, FALSE)) | ||
992 | { | ||
993 | if(text(row,col).length()==0) val1=1; else val1=0; | ||
994 | }else | ||
995 | { | ||
996 | if(findRowColumn(calculateVariable(getParameter(parameters, 0)), &row,&col, FALSE)) | ||
997 | { | ||
998 | if(text(row,col).length()==0) val1=1; else val1=0; | ||
999 | }else | ||
1000 | { | ||
1001 | val1=0; | ||
1002 | }; | ||
1003 | }; | ||
1004 | return QString::number(val1); | ||
1005 | }; | ||
1006 | |||
1007 | |||
1008 | if (function=="ISNUMBER") | ||
1009 | { | ||
1010 | if(findRowColumn(getParameter(parameters, 0, TRUE, function), &row, &col, FALSE)) | ||
1011 | { | ||
1012 | val1=text(row,col).toDouble(&ok); | ||
1013 | if(ok) val1=1; else val1=0; | ||
1014 | }else | ||
1015 | { | ||
1016 | if(findRowColumn(calculateVariable(getParameter(parameters, 0, TRUE, function)), &row,&col, FALSE)) | ||
1017 | { | ||
1018 | val1=text(row,col).toDouble(&ok); | ||
1019 | if(ok) val1=1; else val1=0; | ||
1020 | }else | ||
1021 | { | ||
1022 | val1=0; | ||
1023 | }; | ||
1024 | }; | ||
1025 | return QString::number(val1); | ||
1026 | }; | ||
1027 | if (function=="AND") | ||
1028 | { | ||
1029 | vali=calculateVariable(getParameter(parameters, 0, TRUE, function)).toInt(&ok) | ||
1030 | & calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1031 | return QString::number(vali); | ||
1032 | }; | ||
1033 | if (function=="OR") | ||
1034 | { | ||
1035 | vali=calculateVariable(getParameter(parameters, 0, TRUE, function)).toInt(&ok) | ||
1036 | | calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1037 | return QString::number(vali); | ||
1038 | }; | ||
1039 | if (function=="NOT") | ||
1040 | { | ||
1041 | vali=!calculateVariable(getParameter(parameters, 0, TRUE, function)).toInt(&ok); | ||
1042 | return QString::number(vali); | ||
1043 | }; | ||
1044 | |||
1045 | // MATHEMATICAL FUNCTIONS | ||
1046 | if (function=="ABS") | ||
1047 | { | ||
1048 | val1=fabs(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1049 | return QString::number(val1); | ||
1050 | }; | ||
1051 | if (function=="ACOS") | ||
1052 | { | ||
1053 | val1=acos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1054 | return QString::number(val1); | ||
1055 | }; | ||
1056 | if (function=="ACOSH") | ||
1057 | { | ||
1058 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1059 | if(val1<1.0) return QString::number(0); | ||
1060 | val1=acosh(val1); | ||
1061 | return QString::number(val1); | ||
1062 | }; | ||
1063 | if (function=="ASIN") | ||
1064 | { | ||
1065 | val1=asin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1066 | return QString::number(val1); | ||
1067 | }; | ||
1068 | if (function=="ASINH") | ||
1069 | { | ||
1070 | val1=asinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1071 | return QString::number(val1); | ||
1072 | }; | ||
1073 | if (function=="ATAN") | ||
1074 | { | ||
1075 | val1=atan(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1076 | return QString::number(val1); | ||
1077 | }; | ||
1078 | if (function=="ATAN2") | ||
1079 | { | ||
1080 | val1=atan2(calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok), | ||
1081 | calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1082 | return QString::number(val1); | ||
1083 | }; | ||
1084 | if (function=="ATANH") | ||
1085 | { | ||
1086 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1087 | if(val1<=-1.0 || val1>=1.0) return QString("Err101"); | ||
1088 | val1=atanh(val1); | ||
1089 | return QString::number(val1); | ||
1090 | }; | ||
1091 | if (function=="CEILING") | ||
1092 | { | ||
1093 | // rounds up param1 to specified accuracy param2 | ||
1094 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1095 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1096 | if(val2==0.0) return QString::number(val1); | ||
1097 | val1=ceil(val1/val2)*val2; | ||
1098 | return QString::number(val1); | ||
1099 | }; | ||
1100 | if (function=="COS") | ||
1101 | { | ||
1102 | val1=cos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1103 | return QString::number(val1); | ||
1104 | }; | ||
1105 | if (function=="COSH") | ||
1106 | { | ||
1107 | val1=cosh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1108 | return QString::number(val1); | ||
1109 | }; | ||
1110 | if (function=="DEGREES") | ||
1111 | { | ||
1112 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)*180.0/M_PI; | ||
1113 | return QString::number(val1); | ||
1114 | }; | ||
1115 | if (function=="EXP") | ||
1116 | { | ||
1117 | val1=exp(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1118 | return QString::number(val1); | ||
1119 | }; | ||
1120 | if (function=="FACT") | ||
1121 | { | ||
1122 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1123 | val2=Factorial(val1); | ||
1124 | return QString::number(val2); | ||
1125 | }; | ||
1126 | if (function=="FLOOR") | ||
1127 | { | ||
1128 | // rounds down param1 to specified accuracy param2 | ||
1129 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1130 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1131 | if(val2==0.0) return QString::number(val1); | ||
1132 | val1=floor(val1/val2)*val2; | ||
1133 | return QString::number(val1); | ||
1134 | }; | ||
1135 | if (function=="INT") | ||
1136 | { | ||
1137 | // rounds down param1 | ||
1138 | val1=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1139 | return QString::number(val1); | ||
1140 | }; | ||
1141 | if (function=="EVEN") | ||
1142 | { | ||
1143 | //converts param1 to even | ||
1144 | vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1145 | if(vali % 2 !=0) val1=vali+1; else val1=vali; | ||
1146 | return QString::number(val1); | ||
1147 | }; | ||
1148 | if (function=="ODD") | ||
1149 | { | ||
1150 | //converts param1 to odd | ||
1151 | vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1152 | if(vali % 2 !=0) val1=vali; else val1=vali+1; | ||
1153 | return QString::number(val1); | ||
1154 | }; | ||
1155 | if (function=="ISEVEN") | ||
1156 | { | ||
1157 | //Is Even param1? | ||
1158 | vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1159 | if(vali % 2 == 0) val1=1; else val1=0; | ||
1160 | return QString::number(val1); | ||
1161 | }; | ||
1162 | if (function=="ISODD") | ||
1163 | { | ||
1164 | //Is odd param1? | ||
1165 | vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1166 | if(vali % 2 == 0) val1=0; else val1=1; | ||
1167 | return QString::number(val1); | ||
1168 | }; | ||
1169 | if (function=="LN") | ||
1170 | { | ||
1171 | // returns the natural logarithm of param1 | ||
1172 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1173 | if(val1<=0.0) return QString("Err101"); | ||
1174 | val1=log(val1); | ||
1175 | return QString::number(val1); | ||
1176 | }; | ||
1177 | if (function=="LOG10") | ||
1178 | { | ||
1179 | // returns the base-10 logarithm of param1 | ||
1180 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1181 | if(val1<=0.0) return QString("Err101"); | ||
1182 | val1=log10(val1); | ||
1183 | return QString::number(val1); | ||
1184 | }; | ||
1185 | if (function=="LOG") | ||
1186 | { | ||
1187 | // return the base-param2 logarithm of param1 | ||
1188 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1189 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1190 | if(val1<=0.0 || val2<=0.0 ) return QString("Err101"); | ||
1191 | val1=log(val1)/log(val2); | ||
1192 | return QString::number(val1); | ||
1193 | }; | ||
1194 | if (function=="MOD") | ||
1195 | { | ||
1196 | // return the modulus of param1/param2 | ||
1197 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1198 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1199 | if(val2==0.0) return QString("Err101"); | ||
1200 | val1=(int(val1) % int(val2)); | ||
1201 | return QString::number(val1); | ||
1202 | }; | ||
1203 | if (function=="POWER") | ||
1204 | { | ||
1205 | // return the param1^param2 | ||
1206 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1207 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1208 | if(val1<0.0 && (floor(val2)!=val2)) return QString("Err101"); | ||
1209 | val1=pow(val1,val2); | ||
1210 | return QString::number(val1); | ||
1211 | }; | ||
1212 | if (function=="PI") | ||
1213 | { | ||
1214 | return QString::number(M_PI); | ||
1215 | }; | ||
1216 | if (function=="RADIANS") | ||
1217 | { | ||
1218 | // param1 deg->rad | ||
1219 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)*M_PI/180.0; | ||
1220 | return QString::number(val1); | ||
1221 | }; | ||
1222 | if (function=="RAND") | ||
1223 | { | ||
1224 | // retuns random number 0>x>1 | ||
1225 | srand((unsigned int)time((time_t *)NULL)); | ||
1226 | val1=double(rand())/double(RAND_MAX); | ||
1227 | return QString::number(val1); | ||
1228 | }; | ||
1229 | if (function=="RANDBETWEEN") | ||
1230 | { | ||
1231 | // returns random number between param1>x>param2 | ||
1232 | //TOFIX: this is not ok because I think results is always int related. | ||
1233 | srand((unsigned int)time((time_t *)NULL)); | ||
1234 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1235 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1236 | val1=fmod(double(rand()),(val2-val1))+val1; | ||
1237 | return QString::number(val1); | ||
1238 | }; | ||
1239 | if (function=="ROUND") | ||
1240 | { | ||
1241 | // rounds down param1 to specified digits param2 (positive decimal digits) | ||
1242 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1243 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1244 | val2=pow(10.0,-val2); | ||
1245 | val1=floor(val1/val2)*val2; | ||
1246 | return QString::number(val1); | ||
1247 | }; | ||
1248 | if (function=="SIGN") | ||
1249 | { | ||
1250 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1251 | if(val1>=0.0) return QString::number(1.0); else return QString::number(-1.0); | ||
1252 | }; | ||
1253 | if (function=="CHGSGN")//changes sign (for unary operator) | ||
1254 | { | ||
1255 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1256 | return QString::number((-1.0)*val1); | ||
1257 | }; | ||
1258 | if (function=="SIN") | ||
1259 | { | ||
1260 | val1=sin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1261 | return QString::number(val1); | ||
1262 | }; | ||
1263 | if (function=="SINH") | ||
1264 | { | ||
1265 | val1=sinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1266 | return QString::number(val1); | ||
1267 | }; | ||
1268 | if (function=="TAN") | ||
1269 | { | ||
1270 | val1=tan(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1271 | return QString::number(val1); | ||
1272 | }; | ||
1273 | if (function=="TANH") | ||
1274 | { | ||
1275 | val1=tanh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1276 | return QString::number(val1); | ||
1277 | }; | ||
1278 | if (function=="SQRT") | ||
1279 | { | ||
1280 | val1=sqrt(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); | ||
1281 | return QString::number(val1); | ||
1282 | }; | ||
1283 | |||
1284 | |||
1285 | // STRING FUNCTIONS | ||
1286 | if (function=="CONCATENATE") | ||
1287 | { | ||
1288 | // concatenates strings together | ||
1289 | w1=0; | ||
1290 | s1=""; | ||
1291 | while(getParameter(parameters, w1, FALSE, function)!="") //parse all params; | ||
1292 | { | ||
1293 | s1=s1+calculateVariable(getParameter(parameters, w1)); | ||
1294 | w1++; | ||
1295 | }; | ||
1296 | return QString(s1); | ||
1297 | }; | ||
1298 | if (function=="EXACT") | ||
1299 | { | ||
1300 | // compare two string if they are exactly the same | ||
1301 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1302 | s2=calculateVariable(getParameter(parameters, 1, TRUE, function)); | ||
1303 | if(s1==s2) return QString::number(1); else return QString::number(0); | ||
1304 | }; | ||
1305 | if (function=="FIND") | ||
1306 | { | ||
1307 | // finds param1 in param2 from pos param3 and after | ||
1308 | // returns -1 if not found | ||
1309 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1310 | s2=calculateVariable(getParameter(parameters, 1, TRUE, function)); | ||
1311 | vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok); | ||
1312 | val1=s2.find(s1,vali); | ||
1313 | return QString::number(val1); | ||
1314 | }; | ||
1315 | if (function=="LEFT") | ||
1316 | { | ||
1317 | // returns the param2 left chars from param1 string | ||
1318 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1319 | vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1320 | s2=s1.left(vali); | ||
1321 | return QString(s2); | ||
1322 | }; | ||
1323 | if (function=="LEN") | ||
1324 | { | ||
1325 | // return the length of a string(param1) | ||
1326 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1327 | return QString::number(s1.length()); | ||
1328 | }; | ||
1329 | if (function=="MID") | ||
1330 | { | ||
1331 | // returns the mid word of string param1 with start param2 and len param3 | ||
1332 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1333 | w1=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1334 | w2=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok); | ||
1335 | s2=s1.mid(w1,w2); | ||
1336 | return QString(s2); | ||
1337 | }; | ||
1338 | if (function=="REPLACE") | ||
1339 | { | ||
1340 | //replace in param1 text in pos param2 and length param3 to newtext param4 | ||
1341 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1342 | w1=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1343 | w2=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok); | ||
1344 | s2=calculateVariable(getParameter(parameters, 3, TRUE, function)); | ||
1345 | if(w1<0 || w2<0) return QString(s1); | ||
1346 | s1=s1.left(w2-1)+s2+s1.right(s1.length()-w1-w2); | ||
1347 | return QString(s1); | ||
1348 | }; | ||
1349 | if (function=="REPT") | ||
1350 | { | ||
1351 | //repeats param1 string param2 times | ||
1352 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1353 | w1=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1354 | for(w2=1;w2<=w1;w2++) | ||
1355 | { | ||
1356 | s2=s2.append(s1); | ||
1357 | }; | ||
1358 | return QString(s2); | ||
1359 | }; | ||
1360 | if (function=="RIGHT") | ||
1361 | { | ||
1362 | // returns the param2 right chars from param1 string | ||
1363 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1364 | vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1365 | s2=s1.right(vali); | ||
1366 | return QString(s2); | ||
1367 | }; | ||
1368 | if (function=="UPPER") | ||
1369 | { | ||
1370 | // returns the upper param1 string | ||
1371 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1372 | s1=s1.upper(); | ||
1373 | return QString(s1); | ||
1374 | }; | ||
1375 | if (function=="LOWER") | ||
1376 | { | ||
1377 | // returns the lower param1 string | ||
1378 | s1=calculateVariable(getParameter(parameters, 0, TRUE, function)); | ||
1379 | s1=s1.lower(); | ||
1380 | return QString(s1); | ||
1381 | }; | ||
1382 | if (function=="IF") | ||
1383 | { | ||
1384 | //usage: IF(param1,param2,param3) | ||
1385 | //returns param4 if true(param1)/ param5 if false(param1) | ||
1386 | val1=getParameter(parameters, 0, TRUE, function).toDouble(&ok); | ||
1387 | if(val1==1.0) | ||
1388 | { | ||
1389 | s1=calculateVariable(getParameter(parameters, 1, TRUE, function)); | ||
1390 | return QString(s1); | ||
1391 | }else | ||
1392 | { | ||
1393 | s1=calculateVariable(getParameter(parameters, 2, TRUE, function)); | ||
1394 | return QString(s1); | ||
1395 | }; | ||
1396 | }; | ||
1397 | if (function=="SUM") | ||
1398 | { | ||
1399 | //NumOfParams | ||
1400 | val2=0.0; | ||
1401 | for(w1=1;w1<=(NumOfParams/2);w1++) | ||
1402 | { | ||
1403 | val1=functionSum(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function)); | ||
1404 | val2=val2+val1; | ||
1405 | }; | ||
1406 | if(NumOfParams%2==1) | ||
1407 | { | ||
1408 | val2=val2+calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok); | ||
1409 | }; | ||
1410 | return QString::number(val2); | ||
1411 | }; | ||
1412 | if (function=="INDEX") | ||
1413 | { | ||
1414 | s1=functionIndex(getParameter(parameters,0,TRUE,function), getParameter(parameters, 1, TRUE, function), getParameter(parameters,2,TRUE,function).toInt(&ok)); | ||
1415 | return QString(s1); | ||
1416 | }; | ||
1417 | if (function=="SUMSQ") | ||
1418 | { | ||
1419 | //NumOfParams | ||
1420 | val2=0.0; | ||
1421 | for(w1=1;w1<=(NumOfParams/2);w1++) | ||
1422 | { | ||
1423 | val1=functionSumSQ(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function)); | ||
1424 | val2=val2+val1; | ||
1425 | }; | ||
1426 | if(NumOfParams%2==1) | ||
1427 | { | ||
1428 | val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok); | ||
1429 | val2=val2+val1*val1; | ||
1430 | }; | ||
1431 | return QString::number(val2); | ||
1432 | }; | ||
1433 | if (function=="COUNT") | ||
1434 | { | ||
1435 | //NumOfParams | ||
1436 | val2=0.0; | ||
1437 | for(w1=1;w1<=(NumOfParams/2);w1++) | ||
1438 | { | ||
1439 | val1=functionCount(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function)); | ||
1440 | val2=val2+val1; | ||
1441 | }; | ||
1442 | if(NumOfParams%2==1) | ||
1443 | { | ||
1444 | val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok); | ||
1445 | if(ok) val2=val2+1; | ||
1446 | }; | ||
1447 | return QString::number(val2); | ||
1448 | }; | ||
1449 | if (function=="COUNTIF") | ||
1450 | { | ||
1451 | //NumOfParams | ||
1452 | val1=functionCountIf(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function), getParameter(parameters, 2, TRUE, function)); | ||
1453 | return QString::number(val1); | ||
1454 | }; | ||
1455 | if (function=="MIN") | ||
1456 | { | ||
1457 | //NumOfParams | ||
1458 | val2=0.0; | ||
1459 | for(w1=1;w1<=(NumOfParams/2);w1++) | ||
1460 | { | ||
1461 | val1=functionMin(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function)); | ||
1462 | val2=val1; | ||
1463 | }; | ||
1464 | if(NumOfParams%2==1) | ||
1465 | { | ||
1466 | val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok); | ||
1467 | if(val1<val2) val2=val1; | ||
1468 | }; | ||
1469 | return QString::number(val2); | ||
1470 | }; | ||
1471 | if (function=="MAX") | ||
1472 | { | ||
1473 | //NumOfParams | ||
1474 | val2=0.0; | ||
1475 | for(w1=1;w1<=(NumOfParams/2);w1++) | ||
1476 | { | ||
1477 | val1=functionMax(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function)); | ||
1478 | val2=val1; | ||
1479 | }; | ||
1480 | if(NumOfParams%2==1) | ||
1481 | { | ||
1482 | val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok); | ||
1483 | if(val1>val2) val2=val1; | ||
1484 | }; | ||
1485 | return QString::number(val2); | ||
1486 | }; | ||
1487 | if (function=="AVERAGE") | ||
1488 | { | ||
1489 | val1=functionAvg(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
1490 | return QString::number(val1); | ||
1491 | }; | ||
1492 | |||
1493 | if(function=="BESSELI") | ||
1494 | { | ||
1495 | // BesselI (x,n) | ||
1496 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1497 | vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1498 | val2=BesselI(vali,val1); | ||
1499 | return QString::number(val2); | ||
1500 | }; | ||
1501 | if(function=="BESSELJ") | ||
1502 | { | ||
1503 | // BesselJ (x,n) | ||
1504 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1505 | vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1506 | val2=BesselJ(vali,val1); | ||
1507 | return QString::number(val2); | ||
1508 | }; | ||
1509 | if(function=="BESSELK") | ||
1510 | { | ||
1511 | // BesselK (x,n) | ||
1512 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1513 | vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1514 | val2=BesselK(vali,val1); | ||
1515 | return QString::number(val2); | ||
1516 | }; | ||
1517 | if(function=="BESSELY") | ||
1518 | { | ||
1519 | // BesselY (x,n) | ||
1520 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1521 | vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1522 | val2=BesselY(vali,val1); | ||
1523 | return QString::number(val2); | ||
1524 | }; | ||
1525 | if(function=="GAMMALN") | ||
1526 | { | ||
1527 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1528 | val2=GammaLn(val1); | ||
1529 | return QString::number(val2); | ||
1530 | }; | ||
1531 | if(function=="ERF") | ||
1532 | { | ||
1533 | // ERF (a,b) | ||
1534 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1535 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1536 | return QString::number(ErrorFunction(val2)-ErrorFunction(val1)); | ||
1537 | }; | ||
1538 | if(function=="ERFC") | ||
1539 | { | ||
1540 | // ERFC (a,b) | ||
1541 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1542 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1543 | return QString::number(ErrorFunctionComplementary(val2)-ErrorFunctionComplementary(val1)); | ||
1544 | }; | ||
1545 | if(function=="POISSON") | ||
1546 | { | ||
1547 | // POISSON DISTR(x,n,distr/desnt) | ||
1548 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1549 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1550 | vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok); | ||
1551 | if(vali==1) | ||
1552 | { | ||
1553 | return QString::number(GammaQ(floor(val1)+1, val2)); | ||
1554 | }else | ||
1555 | { | ||
1556 | return QString::number(exp(-val2)*pow(val2,val1)/exp(GammaLn(val1+1.0))); | ||
1557 | }; | ||
1558 | }; | ||
1559 | if(function=="CHIDIST") | ||
1560 | { | ||
1561 | // POISSON CHIDIST(x,n,distr/density) | ||
1562 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1563 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1564 | vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok); | ||
1565 | if(vali==1) | ||
1566 | { | ||
1567 | return QString::number(GammaP(val2/2.0,val1*val1/2.0)); | ||
1568 | } else | ||
1569 | { | ||
1570 | return QString::number( | ||
1571 | pow(val1,val2-1.0)*exp(-val1*val1/2)/ ( pow(2,val2/2.0-1.0)*exp(GammaLn(val2/2.0))) | ||
1572 | ); | ||
1573 | }; | ||
1574 | }; | ||
1575 | if(function=="CHI2DIST") | ||
1576 | { | ||
1577 | // POISSON CHISQUAREDIST(x,n,distr/density) | ||
1578 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1579 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1580 | vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok); | ||
1581 | if(vali==1) | ||
1582 | { | ||
1583 | return QString::number(GammaP(val2/2.0,val1/2.0)); | ||
1584 | } else | ||
1585 | { | ||
1586 | return QString::number( | ||
1587 | pow(val1,val2/2.0-1.0)/(exp(val1/2.0)*pow(sqrt(2.0),val2)*exp(GammaLn(val2/2.0))) | ||
1588 | ); | ||
1589 | }; | ||
1590 | }; | ||
1591 | if(function=="BETAI") | ||
1592 | { | ||
1593 | // BETA INCOMPLETE BETA(x,a,b) | ||
1594 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1595 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1596 | val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok); | ||
1597 | return QString::number(BetaIncomplete(val2,val3,val1)); | ||
1598 | }; | ||
1599 | if(function=="GAMMAP") | ||
1600 | { | ||
1601 | // GammaP (x,a) | ||
1602 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1603 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1604 | return QString::number(GammaP(val2,val1)); | ||
1605 | }; | ||
1606 | if(function=="GAMMAQ") | ||
1607 | { | ||
1608 | // GammaQ (x,a) | ||
1609 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1610 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1611 | return QString::number(GammaQ(val2,val1)); | ||
1612 | }; | ||
1613 | if (function=="VAR") | ||
1614 | { | ||
1615 | val1=functionVariance(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
1616 | return QString::number(val1); | ||
1617 | }; | ||
1618 | if (function=="VARP") | ||
1619 | { | ||
1620 | val1=functionVariancePopulation(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
1621 | return QString::number(val1); | ||
1622 | }; | ||
1623 | if (function=="STDEV") | ||
1624 | { | ||
1625 | val1=functionVariance(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
1626 | if(val1<=0.0) return QString::number(0.0); | ||
1627 | return QString::number(sqrt(val1)); | ||
1628 | }; | ||
1629 | if (function=="STDEVP") | ||
1630 | { | ||
1631 | val1=functionVariancePopulation(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
1632 | if(val1<=0.0) return QString::number(0.0); | ||
1633 | return QString::number(sqrt(val1)); | ||
1634 | }; | ||
1635 | if (function=="SKEW") | ||
1636 | { | ||
1637 | val1=functionSkew(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
1638 | return QString::number(val1); | ||
1639 | }; | ||
1640 | if (function=="KURT") | ||
1641 | { | ||
1642 | val1=functionKurt(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | ||
1643 | return QString::number(val1); | ||
1644 | }; | ||
1645 | if(function=="GAMMADIST") | ||
1646 | { | ||
1647 | // GAMMADIST (x,alpha,beta,distribution?density1:0) | ||
1648 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1649 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1650 | val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok); | ||
1651 | vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok); | ||
1652 | if(vali==1)//distribution | ||
1653 | { | ||
1654 | if(val3==0.0) return QString::number(0.0); | ||
1655 | else | ||
1656 | return QString::number(GammaP(val2,val1/val3)); | ||
1657 | }else //density | ||
1658 | { | ||
1659 | return QString::number( | ||
1660 | pow(val1,val2-1.0)*exp(-val1/val3) / (pow(val3,val2)*exp(GammaLn(val2))) | ||
1661 | ); | ||
1662 | }; | ||
1663 | }; | ||
1664 | if(function=="BETADIST") | ||
1665 | { | ||
1666 | // BETADIST (z,alpha,beta,distribution?density1:0) | ||
1667 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1668 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1669 | val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok); | ||
1670 | vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok); | ||
1671 | if(vali==1)//distribution | ||
1672 | { | ||
1673 | return QString::number(BetaIncomplete(val2,val3,val1)); | ||
1674 | }else //density | ||
1675 | { | ||
1676 | return QString::number( | ||
1677 | pow(val1,val2-1.0)*pow(1.0-val1,val3-1.0) / Beta(val2,val3) | ||
1678 | ); | ||
1679 | }; | ||
1680 | }; | ||
1681 | if(function=="FDIST") | ||
1682 | { | ||
1683 | // FDIST (z,d1,d2,distribution?density1:0) | ||
1684 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1685 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1686 | val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok); | ||
1687 | vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok); | ||
1688 | if(vali==1)//distribution | ||
1689 | { | ||
1690 | return QString::number( | ||
1691 | -BetaIncomplete(val3/2,val2/2,val3/(val3+val2*val1)) | ||
1692 | +BetaIncomplete(val3/2,val2/2,1) | ||
1693 | ); | ||
1694 | }else //density | ||
1695 | { | ||
1696 | return QString::number( | ||
1697 | pow(val2,val2/2)*pow(val3,val3/2)*pow(val1,val2/2-1)/ | ||
1698 | (pow(val3+val2*val1,(val2+val3)/2)*Beta(val2/2,val3/2)) | ||
1699 | ); | ||
1700 | }; | ||
1701 | }; | ||
1702 | if(function=="NORMALDIST") | ||
1703 | { | ||
1704 | // NORMALDIST (x,m,s,distribution?density1:0) | ||
1705 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1706 | val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok); | ||
1707 | val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok); | ||
1708 | vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok); | ||
1709 | if(vali==1)//distribution | ||
1710 | { | ||
1711 | return QString::number( | ||
1712 | (ErrorFunction((val1-val2)/(sqrt(2)*val3))+1)/2.0 | ||
1713 | ); | ||
1714 | }else //density | ||
1715 | { | ||
1716 | return QString::number( | ||
1717 | exp(-pow(((val1-val2)/val3),2)/2)/(val3*sqrt(2*M_PI)) | ||
1718 | ); | ||
1719 | }; | ||
1720 | }; | ||
1721 | if(function=="PHI") | ||
1722 | { | ||
1723 | // NORMALDIST (x,distribution?density1:0) with mean=0 s=1.0 | ||
1724 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); | ||
1725 | vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok); | ||
1726 | if(vali==1)//distribution | ||
1727 | { | ||
1728 | return QString::number( | ||
1729 | (ErrorFunction(val1/(sqrt(2)))+1)/2.0 | ||
1730 | ); | ||
1731 | }else //density | ||
1732 | { | ||
1733 | return QString::number( | ||
1734 | exp(-pow(val1,2)/2)/(sqrt(2*M_PI)) | ||
1735 | ); | ||
1736 | }; | ||
1737 | }; | ||
1738 | /* | ||
1739 | StudentTDistribution/: PDF[StudentTDistribution[n_], x_] := | ||
1740 | 1/(Sqrt[n] Beta[n/2, 1/2]) Sqrt[n/(n+x^2)]^(n+1) /; | ||
1741 | ParameterQ[StudentTDistribution[n]] | ||
1742 | |||
1743 | StudentTDistribution/: CDF[StudentTDistribution[n_], x_] := | ||
1744 | (1 + Sign[x] BetaRegularized[n/(n+x^2), 1, n/2, 1/2])/2 /; | ||
1745 | ParameterQ[StudentTDistribution[n]] | ||
1746 | */ | ||
313 | 1747 | ||
314 | void Sheet::pushCharStack(QStack<QChar> *stackChars, const QChar &character) | ||
315 | { | ||
316 | QChar *temp=new QChar(character); | ||
317 | stackChars->push(temp); | ||
318 | } | ||
319 | 1748 | ||
320 | void Sheet::pushStringStack(QStack<QString> *stackStrings, const QString &string) | ||
321 | { | ||
322 | QString *temp=new QString(string); | ||
323 | stackStrings->push(temp); | ||
324 | } | ||
325 | 1749 | ||
326 | QChar Sheet::popCharStack(QStack<QChar> *stackChars) | 1750 | return 0; |
327 | { | 1751 | }; |
328 | if (stackChars->isEmpty()) | ||
329 | { | ||
330 | QMessageBox::critical(this, tr("Error"), tr("Syntax error!")); | ||
331 | return '0'; | ||
332 | } | ||
333 | 1752 | ||
334 | QChar *temp=stackChars->pop(); | ||
335 | QChar temp2(*temp); | ||
336 | delete temp; | ||
337 | return temp2; | ||
338 | } | ||
339 | 1753 | ||
340 | QString Sheet::popStringStack(QStack<QString> *stackStrings) | ||
341 | { | ||
342 | if (stackStrings->isEmpty()) | ||
343 | { | ||
344 | QMessageBox::critical(this, tr("Error"), tr("Syntax error!")); | ||
345 | return "0"; | ||
346 | } | ||
347 | 1754 | ||
348 | QString *temp=stackStrings->pop(); | ||
349 | QString temp2(*temp); | ||
350 | delete temp; | ||
351 | return temp2; | ||
352 | } | ||
353 | 1755 | ||
354 | QString Sheet::dataParserHelper(const QString &data) | 1756 | QString Sheet::dataParserHelper(const QString &data) |
355 | { | 1757 | { |
356 | QStack<QString> stackElements; | 1758 | if(data.left(1)=="""" && data.right(1)=="""") return QString(data); |
357 | QStack<QChar> stackOperators; | 1759 | Expression exp1(data); |
358 | QString tempElement(""), temp2Element, firstElement, secondElement; | 1760 | exp1.Parse(); |
359 | int paranCount; | 1761 | QStack<QString> stack1; |
1762 | stack1.setAutoDelete(TRUE); | ||
1763 | int i=0; | ||
1764 | QString* s1; | ||
1765 | QString* s2=NULL; | ||
1766 | int* i1; | ||
1767 | int args,tokentype; | ||
1768 | QString tempval; | ||
1769 | s1=exp1.CompiledBody.first();i1=exp1.CompiledBodyType.first(); | ||
1770 | while(i<=(int)exp1.CompiledBody.count()-1) | ||
1771 | { | ||
1772 | args= ((*i1) & 0xFF00)>>8; tokentype=(*i1) & 0x00FF; | ||
1773 | if(tokentype==NUMBER_TOKEN) | ||
1774 | { | ||
1775 | stack1.push(new QString(*s1)); | ||
1776 | //printf("Parse:Number=%s\r\n",s1->latin1()); | ||
1777 | } | ||
1778 | else if(tokentype==VARIABLE_TOKEN) | ||
1779 | { | ||
1780 | stack1.push(new QString(*s1)); | ||
1781 | //printf("Parse:Var=%s\r\n",s1->latin1()); | ||
1782 | //here to put implementation of other types of variables except cell. | ||
1783 | //for example names | ||
1784 | } | ||
1785 | else if(tokentype==STRING_TOKEN) | ||
1786 | { | ||
1787 | stack1.push(new QString(*s1)); | ||
1788 | //printf("Parse:String=%s\r\n",s1->ascii()); | ||
1789 | } | ||
1790 | else if(tokentype==FUNCTION_TOKEN) | ||
1791 | { | ||
1792 | QString params=""; | ||
1793 | for(int w1=1;w1<=args;w1++) | ||
1794 | { | ||
1795 | if((int)stack1.count()!=0) s2=stack1.pop(); | ||
1796 | params=*s2+params;//args in reverse order | ||
1797 | params=","+params; | ||
1798 | }; | ||
1799 | params=params.mid(1); | ||
1800 | if(params==NULL) params="0"; | ||
1801 | //printf("Parse:Func=%s, params=%s, stackcount=%d,args=%d\r\n" | ||
1802 | //,s1->latin1(),params.latin1(),stack1.count(),args); | ||
1803 | tempval=calculateFunction(*s1,params,args); | ||
1804 | tempval=tempval.upper(); | ||
1805 | stack1.push(new QString(tempval)); | ||
1806 | }; | ||
1807 | |||
1808 | //loops to next token | ||
1809 | if(exp1.CompiledBody.next()!=NULL) s1=exp1.CompiledBody.current(); else break; | ||
1810 | if(exp1.CompiledBodyType.next()!=NULL) i1=exp1.CompiledBodyType.current(); else break; | ||
1811 | i++; | ||
1812 | }; | ||
1813 | if((int)stack1.count()!=0)s2=stack1.pop(); else s2=new QString("!ERROR"); | ||
1814 | tempval=*s2; | ||
1815 | return(tempval); | ||
1816 | }; | ||
360 | 1817 | ||
361 | for (unsigned int i=0; i<data.length(); ++i) | ||
362 | { | ||
363 | if (data[i]=='+' || data[i]=='-' || data[i]=='*' || data[i]=='/') | ||
364 | { | ||
365 | pushStringStack(&stackElements, tempElement); | ||
366 | tempElement=""; | ||
367 | if (!stackOperators.isEmpty() && getOperatorPriority(*stackOperators.top())>getOperatorPriority(data[i])) | ||
368 | { | ||
369 | secondElement=popStringStack(&stackElements); | ||
370 | firstElement=popStringStack(&stackElements); | ||
371 | pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement))); | ||
372 | } | ||
373 | pushCharStack(&stackOperators, data[i]); | ||
374 | } | ||
375 | else | ||
376 | if (data[i]==',') | ||
377 | { | ||
378 | if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement); | ||
379 | while (!stackOperators.isEmpty()) | ||
380 | { | ||
381 | secondElement=popStringStack(&stackElements); | ||
382 | firstElement=popStringStack(&stackElements); | ||
383 | pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement))); | ||
384 | } | ||
385 | tempElement=""; | ||
386 | } | ||
387 | else | ||
388 | if (data[i]=='(') | ||
389 | { | ||
390 | paranCount=1; | ||
391 | temp2Element=""; | ||
392 | for (++i; paranCount>0; ++i) | ||
393 | { | ||
394 | temp2Element+=data[i]; | ||
395 | if (data[i]=='(') ++paranCount; | ||
396 | if (data[i]==')') --paranCount; | ||
397 | } | ||
398 | temp2Element=dataParserHelper(temp2Element.left(temp2Element.length()-1)); | ||
399 | if (tempElement.isEmpty()) | ||
400 | tempElement=temp2Element; | ||
401 | else | ||
402 | tempElement.setNum(calculateFunction(tempElement, temp2Element)); | ||
403 | --i; | ||
404 | } | ||
405 | else | ||
406 | tempElement+=data[i]; | ||
407 | } | ||
408 | if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement); | ||
409 | while (!stackOperators.isEmpty()) | ||
410 | { | ||
411 | secondElement=popStringStack(&stackElements); | ||
412 | firstElement=popStringStack(&stackElements); | ||
413 | pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement))); | ||
414 | } | ||
415 | 1818 | ||
416 | if (!stackElements.isEmpty()) | ||
417 | tempElement=popStringStack(&stackElements); | ||
418 | while (!stackElements.isEmpty()) | ||
419 | tempElement.prepend(popStringStack(&stackElements)+","); | ||
420 | return tempElement; | ||
421 | } | ||
422 | 1819 | ||
423 | QString Sheet::dataParser(const QString &cell, const QString &data) | 1820 | QString Sheet::dataParser(const QString &cell, const QString &data) |
424 | { | 1821 | { |
425 | QString strippedData(data); | 1822 | QString strippedData(data); |
426 | strippedData.replace(QRegExp("\\s"), ""); | 1823 | strippedData.replace(QRegExp("\\s"), ""); |
427 | if (strippedData.isEmpty() || strippedData[0]!='=') return data; | 1824 | if (strippedData.isEmpty() || strippedData[0]!='=') return data; |
428 | if (listDataParser.find(cell)!=listDataParser.end()) return "0"; | 1825 | if (listDataParser.find(cell)!=listDataParser.end()) return "0"; |
429 | listDataParser.append(cell); | 1826 | listDataParser.append(cell); |
1827 | // printf("DATAPARSER: data=%s, cell=%s\r\n",data.ascii(),cell.ascii()); | ||
430 | strippedData=dataParserHelper(strippedData.remove(0, 1).upper().replace(QRegExp(":"), ",")); | 1828 | strippedData=dataParserHelper(strippedData.remove(0, 1).upper().replace(QRegExp(":"), ",")); |
431 | 1829 | ||
432 | int i=0; | 1830 | int i=0; |
433 | QString tempParameter(getParameter(strippedData, i)), result=""; | 1831 | QString tempParameter(getParameter(strippedData, i)), result=""; |
434 | do | 1832 | do |
435 | { | 1833 | { |
436 | result+=","+QString::number(calculateVariable(tempParameter)); | 1834 | result+=","+calculateVariable(tempParameter); |
437 | tempParameter=getParameter(strippedData, ++i); | 1835 | tempParameter=getParameter(strippedData, ++i); |
438 | } | 1836 | } |
439 | while (!tempParameter.isNull()); | 1837 | while (!tempParameter.isNull()); |
440 | listDataParser.remove(cell); | 1838 | listDataParser.remove(cell); |
441 | return result.mid(1); | 1839 | return result.mid(1); |
442 | } | 1840 | } |
443 | 1841 | ||
1842 | |||
444 | void Sheet::setData(const QString &data) | 1843 | void Sheet::setData(const QString &data) |
445 | { | 1844 | { |
446 | setText(currentRow(), currentColumn(), data); | 1845 | setText(currentRow(), currentColumn(), data); |
447 | slotCellChanged(currentRow(), currentColumn()); | 1846 | slotCellChanged(currentRow(), currentColumn()); |
448 | activateNextCell(); | 1847 | activateNextCell(); |
449 | } | 1848 | } |
@@ -479,12 +1878,13 @@ void Sheet::paintCell(QPainter *p, int row, int col, const QRect & cr, bool sele | |||
479 | 1878 | ||
480 | QTableItem *cellItem=item(row, col); | 1879 | QTableItem *cellItem=item(row, col); |
481 | if (cellItem) | 1880 | if (cellItem) |
482 | { | 1881 | { |
483 | p->setPen(selected ? colorGroup().highlightedText() : cellData->fontColor); | 1882 | p->setPen(selected ? colorGroup().highlightedText() : cellData->fontColor); |
484 | p->setFont(cellData->font); | 1883 | p->setFont(cellData->font); |
1884 | QString str=cellItem->text(); | ||
485 | p->drawText(2, 2, cr.width()-4, cr.height()-4, cellData->alignment, cellItem->text()); | 1885 | p->drawText(2, 2, cr.width()-4, cr.height()-4, cellData->alignment, cellItem->text()); |
486 | } | 1886 | } |
487 | 1887 | ||
488 | int rx=cr.width()-1, ry=cr.height()-1; | 1888 | int rx=cr.width()-1, ry=cr.height()-1; |
489 | QPen pen(p->pen()); | 1889 | QPen pen(p->pen()); |
490 | p->setPen(cellData->borders.right); | 1890 | p->setPen(cellData->borders.right); |
@@ -867,6 +2267,299 @@ QString Sheet::getHeaderString(int section) | |||
867 | 2267 | ||
868 | int Sheet::getHeaderColumn(const QString §ion) | 2268 | int Sheet::getHeaderColumn(const QString §ion) |
869 | { | 2269 | { |
870 | if (section.isEmpty()) return 0; | 2270 | if (section.isEmpty()) return 0; |
871 | return (section[section.length()-1]-'A'+1)+getHeaderColumn(section.left(section.length()-1))*26; | 2271 | return (section[section.length()-1]-'A'+1)+getHeaderColumn(section.left(section.length()-1))*26; |
872 | } | 2272 | } |
2273 | |||
2274 | |||
2275 | //Expression Parser Class Definition | ||
2276 | |||
2277 | |||
2278 | QChar Expression::chunk0(void) | ||
2279 | { | ||
2280 | if(chunk.length()>0) return(chunk[0]); else return('\0'); | ||
2281 | }; | ||
2282 | |||
2283 | Expression::Expression(QString expr1)// constructor | ||
2284 | { | ||
2285 | Body=expr1; | ||
2286 | SYMBOL="+-*/%^=()<>&|!,"; | ||
2287 | MATHSYMBOL="+-*/%^=<>&|!,"; | ||
2288 | // lnlim=1.0e-36; // Smallest number allowed | ||
2289 | // loglim=1.0e-10 ; // Smallest number allowed in call to log10() * | ||
2290 | ErrorFound=TRUE; | ||
2291 | n=0;chunk="";SymbGroup=NONE_TOKEN;InExpr=Body; | ||
2292 | ArgsOfFunc=0; | ||
2293 | CompiledBody.setAutoDelete(TRUE); | ||
2294 | CompiledBodyType.setAutoDelete(TRUE); | ||
2295 | //CompiledBody=QStringList(0); | ||
2296 | }; | ||
2297 | |||
2298 | bool Expression::isSymbol(QChar ch) | ||
2299 | { | ||
2300 | int j = 0; | ||
2301 | while (j<=((int)SYMBOL.length()-1) && ch!=SYMBOL[j]) j++; | ||
2302 | if(j<((int)SYMBOL.length())) return true; else return false; | ||
2303 | }; | ||
2304 | |||
2305 | bool Expression::isMathSymbol(QChar ch) | ||
2306 | { | ||
2307 | int j = 0; | ||
2308 | while (j<=((int)MATHSYMBOL.length()-1) && ch!=MATHSYMBOL[j]) j++; | ||
2309 | if(j<((int)MATHSYMBOL.length())) return true; else return false; | ||
2310 | }; | ||
2311 | |||
2312 | void Expression::GetNext() | ||
2313 | { | ||
2314 | chunk=""; | ||
2315 | if(n>=(int)InExpr.length()) return; | ||
2316 | while (InExpr[n]==' ') n++; | ||
2317 | if(InExpr[n]=='\"') | ||
2318 | { | ||
2319 | while ( (n<(int)InExpr.length()) && (InExpr[n+1]!='\"') ) | ||
2320 | { | ||
2321 | printf("chunk=%s\r\n",chunk.latin1()); | ||
2322 | chunk+=InExpr[n]; | ||
2323 | n++; | ||
2324 | }; | ||
2325 | chunk+=InExpr[n]; | ||
2326 | printf("2\r\n"); | ||
2327 | SymbGroup=STRING_TOKEN; | ||
2328 | } | ||
2329 | else if (isSymbol(InExpr[n])) | ||
2330 | { | ||
2331 | SymbGroup=SYMBOL_TOKEN; | ||
2332 | chunk+=InExpr[n]; | ||
2333 | n++; | ||
2334 | if( (n<(int)InExpr.length()) && | ||
2335 | isMathSymbol(InExpr[n-1]) && | ||
2336 | isMathSymbol(InExpr[n]) ) | ||
2337 | { | ||
2338 | SymbGroup=SYMBOL_TOKEN; | ||
2339 | chunk+=InExpr[n]; | ||
2340 | n++; | ||
2341 | }; | ||
2342 | } | ||
2343 | else if ((InExpr[n].isLetter())||(InExpr[n]=='#')) | ||
2344 | { | ||
2345 | while ( (n<(int)InExpr.length()) && !isSymbol(InExpr[n]) ) | ||
2346 | { | ||
2347 | if (!(InExpr[n]==' ')) chunk+=InExpr[n]; | ||
2348 | n++; | ||
2349 | }; | ||
2350 | if (InExpr[n]=='(') SymbGroup=FUNCTION_TOKEN; // function TOKEN | ||
2351 | else SymbGroup=VARIABLE_TOKEN; | ||
2352 | } | ||
2353 | else if((n<(int)InExpr.length()) && | ||
2354 | ((InExpr[n].isDigit()) || (InExpr[n]=='.'))) | ||
2355 | { | ||
2356 | while( n<(int)InExpr.length() ) | ||
2357 | { | ||
2358 | if((InExpr[n].isDigit()) || InExpr[n]=='.') | ||
2359 | { | ||
2360 | chunk+=InExpr[n]; | ||
2361 | SymbGroup=NUMBER_TOKEN; | ||
2362 | n++; | ||
2363 | } | ||
2364 | else if(InExpr[n]=='e') | ||
2365 | { | ||
2366 | if((n+1)<(int)InExpr.length()) | ||
2367 | { | ||
2368 | if(InExpr[n+1]=='-' || InExpr[n+1]=='+' || InExpr[n+1].isDigit()) | ||
2369 | { | ||
2370 | chunk+=InExpr[n]; | ||
2371 | chunk+=InExpr[n+1]; | ||
2372 | SymbGroup=NUMBER_TOKEN; | ||
2373 | n+=2; | ||
2374 | } | ||
2375 | } | ||
2376 | else | ||
2377 | { | ||
2378 | break; | ||
2379 | } | ||
2380 | } | ||
2381 | else | ||
2382 | { | ||
2383 | break; | ||
2384 | } | ||
2385 | }//while | ||
2386 | }//else if | ||
2387 | };//end function | ||
2388 | |||
2389 | |||
2390 | void Expression::First() | ||
2391 | { | ||
2392 | GetNext(); | ||
2393 | if (!(chunk=="") && !ErrorFound) Third(); | ||
2394 | else ErrorFound = true; | ||
2395 | }; | ||
2396 | |||
2397 | void Expression::Third() | ||
2398 | { | ||
2399 | QChar sign, secS='\0'; | ||
2400 | Fourth(); | ||
2401 | sign = chunk0(); | ||
2402 | if((int)chunk.length()>1) secS=chunk[1]; | ||
2403 | while( sign == '+' || sign == '-'|| | ||
2404 | sign == '<' || sign == '>'|| sign == '%'|| | ||
2405 | sign == '&' || sign == '|' || sign == '!' || sign == '=' | ||
2406 | ) | ||
2407 | { | ||
2408 | GetNext(); | ||
2409 | Fourth(); | ||
2410 | QString name; | ||
2411 | if( sign == '+' ) name= "+" ; | ||
2412 | else if(sign=='-') name= "-" ; | ||
2413 | else if(sign=='>' && secS=='\0') name= ">" ; | ||
2414 | else if(sign=='<' && secS=='\0') name= "<" ; | ||
2415 | else if(sign=='=' && secS=='=') name= "==" ; | ||
2416 | else if(sign=='!' && secS=='=') name= "!=" ; | ||
2417 | else if(sign=='>' && secS=='=') name= ">=" ; | ||
2418 | else if(sign=='<' && secS=='=') name= "<=" ; | ||
2419 | else if(sign=='&' && secS=='&') name= "AND" ; | ||
2420 | else if(sign=='|' && secS=='|') name= "OR" ; | ||
2421 | else if(sign=='%') name= "MOD" ; | ||
2422 | CompiledBody.append(new QString(name)); // not sure if pushed in the back. | ||
2423 | CompiledBodyType.append(new int(FUNCTION_TOKEN | 2<<8)); //2 argument functions | ||
2424 | sign = chunk0(); | ||
2425 | } | ||
2426 | }; | ||
2427 | |||
2428 | void Expression::Fourth() | ||
2429 | { | ||
2430 | QChar sign; | ||
2431 | Fifth(); | ||
2432 | sign = chunk0(); | ||
2433 | while( sign == '*' || sign == '/' ) | ||
2434 | { | ||
2435 | GetNext(); | ||
2436 | Fifth(); | ||
2437 | QString name; | ||
2438 | if( sign == '*' ) name= "*" ; | ||
2439 | else name= "/" ; | ||
2440 | CompiledBody.append(new QString(name)); | ||
2441 | CompiledBodyType.append(new int(FUNCTION_TOKEN | 2<<8)); //2 arguments functions | ||
2442 | sign = chunk0(); | ||
2443 | } | ||
2444 | }; | ||
2445 | |||
2446 | void Expression::Fifth() | ||
2447 | { | ||
2448 | Sixth(); | ||
2449 | //if(chunk.Length==0) return; | ||
2450 | if( chunk0() == '^' ) | ||
2451 | { | ||
2452 | GetNext(); | ||
2453 | Fifth(); | ||
2454 | CompiledBody.append(new QString("POWER")); | ||
2455 | CompiledBodyType.append(new int(FUNCTION_TOKEN | 2<<8)); // 2 argument functions | ||
2456 | } | ||
2457 | }; | ||
2458 | |||
2459 | void Expression::Sixth() | ||
2460 | { | ||
2461 | char sign; | ||
2462 | sign = ' '; | ||
2463 | if(SymbGroup== SYMBOL_TOKEN && | ||
2464 | chunk0() == '+' || chunk0() == '-' | chunk0() == '!') | ||
2465 | { | ||
2466 | sign = chunk0(); | ||
2467 | GetNext(); | ||
2468 | } | ||
2469 | Seventh(); | ||
2470 | if( sign == '-' ) | ||
2471 | { | ||
2472 | CompiledBody.append(new QString("CHGSGN")); // unary minus | ||
2473 | CompiledBodyType.append(new int(FUNCTION_TOKEN | 1<<8)); //1 argument | ||
2474 | } | ||
2475 | if( sign == '!' ) | ||
2476 | { | ||
2477 | CompiledBody.append(new QString("NOT")); // unary minus | ||
2478 | CompiledBodyType.append(new int(FUNCTION_TOKEN | 1<<8)); //1 argument | ||
2479 | } | ||
2480 | }; | ||
2481 | |||
2482 | |||
2483 | void Expression::Seventh() | ||
2484 | { | ||
2485 | if( chunk0() == '(' && SymbGroup==SYMBOL_TOKEN) | ||
2486 | { | ||
2487 | GetNext(); | ||
2488 | Third(); //parse the insides until we get a ')' | ||
2489 | if (chunk0() != ')') ErrorFound = true; | ||
2490 | GetNext(); | ||
2491 | } | ||
2492 | else Eighth(); | ||
2493 | }; | ||
2494 | |||
2495 | void Expression::Eighth() | ||
2496 | { | ||
2497 | if ( SymbGroup== NUMBER_TOKEN ) | ||
2498 | { | ||
2499 | CompiledBody.append(new QString(chunk)); | ||
2500 | CompiledBodyType.append(new int(NUMBER_TOKEN)); | ||
2501 | GetNext(); | ||
2502 | } | ||
2503 | else if ( SymbGroup== VARIABLE_TOKEN ) | ||
2504 | { | ||
2505 | CompiledBody.append(new QString(chunk)); | ||
2506 | CompiledBodyType.append(new int(VARIABLE_TOKEN)); | ||
2507 | GetNext(); | ||
2508 | } | ||
2509 | else if (SymbGroup== STRING_TOKEN ) | ||
2510 | { | ||
2511 | CompiledBody.append(new QString(chunk+QString("\""))); | ||
2512 | CompiledBodyType.append(new int(STRING_TOKEN)); | ||
2513 | GetNext(); | ||
2514 | } | ||
2515 | else Ninth(); | ||
2516 | }; | ||
2517 | |||
2518 | void Expression::Ninth() | ||
2519 | { | ||
2520 | if ( SymbGroup== FUNCTION_TOKEN ) | ||
2521 | { | ||
2522 | QString TempFunk = chunk ; | ||
2523 | GetNext(); | ||
2524 | if(chunk0() == '(' ) | ||
2525 | { | ||
2526 | FuncDepth++; | ||
2527 | ArgsOfFunc.resize(FuncDepth+1); | ||
2528 | ArgsOfFunc[FuncDepth]=1; | ||
2529 | //ArgsOfFunc=1; | ||
2530 | GetNext(); | ||
2531 | Third(); | ||
2532 | while(chunk0()==',') //function arguments separator | ||
2533 | { | ||
2534 | //ArgsOfFunc++; | ||
2535 | ArgsOfFunc[FuncDepth]++; | ||
2536 | GetNext(); | ||
2537 | Third(); | ||
2538 | }; | ||
2539 | if (chunk0() != ')') ErrorFound = true; | ||
2540 | |||
2541 | CompiledBody.append(new QString(TempFunk)); | ||
2542 | if (TempFunk=="PI") ArgsOfFunc[FuncDepth]=0; | ||
2543 | // couldn't find a better way to parse function PI() with 0 args. :) | ||
2544 | CompiledBodyType.append(new int(FUNCTION_TOKEN | (ArgsOfFunc[FuncDepth]<<8) )); | ||
2545 | //the mask &FF00 gives the arguments of the functions passed. | ||
2546 | FuncDepth--; | ||
2547 | ArgsOfFunc.resize(FuncDepth+1); | ||
2548 | GetNext(); | ||
2549 | } | ||
2550 | } | ||
2551 | else | ||
2552 | ErrorFound = true; | ||
2553 | }; | ||
2554 | |||
2555 | bool Expression::Parse() | ||
2556 | { | ||
2557 | CompiledBody.clear(); | ||
2558 | ErrorFound = false; | ||
2559 | n = 0;ArgsOfFunc.resize(0);FuncDepth=0; | ||
2560 | InExpr=Body; | ||
2561 | First(); | ||
2562 | return(!ErrorFound); | ||
2563 | }; | ||
2564 | |||
2565 | |||