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 | |
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.
-rw-r--r-- | noncore/apps/opie-sheet/Excel.cpp | 1664 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/Excel.h | 205 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/cell-select.xpm | 44 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/excel16.xpm | 187 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-comma.xpm | 41 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-cross.xpm | 40 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-divide.xpm | 40 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-equal.xpm | 40 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-func.xpm | 40 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-minus.xpm | 40 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-paran-close.xpm | 41 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-paran-open.xpm | 41 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/func-plus.xpm | 40 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/mainwindow.cpp | 238 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/mainwindow.h | 14 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/opie-sheet.pro | 4 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/sheet.cpp | 2015 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/sheet.h | 93 |
18 files changed, 4434 insertions, 393 deletions
diff --git a/noncore/apps/opie-sheet/Excel.cpp b/noncore/apps/opie-sheet/Excel.cpp new file mode 100644 index 0000000..225c3e1 --- a/dev/null +++ b/noncore/apps/opie-sheet/Excel.cpp | |||
@@ -0,0 +1,1664 @@ | |||
1 | |||
2 | |||
3 | #include <stdio.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <math.h> | ||
6 | #include <time.h> | ||
7 | #include <sys/types.h> | ||
8 | #include <strings.h> | ||
9 | #include <qstring.h> | ||
10 | #include <qlist.h> | ||
11 | #include <qarray.h> | ||
12 | #include "Excel.h" | ||
13 | |||
14 | static xfrecord formatter[] = { | ||
15 | { 0xe , DATEFORMAT, "%m/%d/%y"}, | ||
16 | { 0xf , DATEFORMAT, "%d-%b-%y"}, | ||
17 | { 0x10, DATEFORMAT, "%d-%b"}, | ||
18 | { 0x11, DATEFORMAT, "%b-%y"}, | ||
19 | { 0x12, DATEFORMAT, "%I:%M %p"}, | ||
20 | { 0x13, DATEFORMAT, "%I:%M:%S %p"}, | ||
21 | { 0x14, DATEFORMAT, "%H:%M"}, | ||
22 | { 0x15, DATEFORMAT, "%H:%M:%S"}, | ||
23 | { 0x16, DATEFORMAT, "%m/%d/%y %H:%M"}, | ||
24 | { 0x2d, DATEFORMAT, "%M:%S"}, | ||
25 | { 0x2e, DATEFORMAT, "%H:%M:%S"}, | ||
26 | { 0x2f, DATEFORMAT, "%M:%S"}, | ||
27 | { 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"}, | ||
28 | { 0x1 , NUMBERFORMAT, "%.0f"}, | ||
29 | { 0x2 , NUMBERFORMAT, "%.2f"}, | ||
30 | { 0x3 , NUMBERFORMAT, "#,##%.0f"}, | ||
31 | { 0x4 , NUMBERFORMAT, "#,##%.2f"}, | ||
32 | { 0x5 , NUMBERFORMAT, "$#,##%.0f"}, | ||
33 | { 0x6 , NUMBERFORMAT, "$#,##%.0f"}, | ||
34 | { 0x7 , NUMBERFORMAT, "$#,##%.2f"}, | ||
35 | { 0x8 , NUMBERFORMAT, "$#,##%.2f"}, | ||
36 | { 0x9 , NUMBERFORMAT, "%.0f%%"}, | ||
37 | { 0xa , NUMBERFORMAT, "%.2f%%"}, | ||
38 | { 0xb , NUMBERFORMAT, "%e"}, | ||
39 | { 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, | ||
40 | { 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, | ||
41 | { 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, | ||
42 | { 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, | ||
43 | { 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"}, | ||
44 | { 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"}, | ||
45 | { 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"}, | ||
46 | { 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"}, | ||
47 | { 0x30, NUMBERFORMAT, "##0.0E0"}, | ||
48 | { 0, 0, ""} | ||
49 | }; | ||
50 | |||
51 | |||
52 | |||
53 | int ExcelBook::Integer2Byte(int b1, int b2) | ||
54 | { | ||
55 | int i1 = b1 & 0xff; | ||
56 | int i2 = b2 & 0xff; | ||
57 | int val = i2 << 8 | i1; | ||
58 | return val; | ||
59 | }; | ||
60 | |||
61 | int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4) | ||
62 | { | ||
63 | int i1 = Integer2Byte(b1, b2); | ||
64 | int i2 = Integer2Byte(b3, b4); | ||
65 | int val = i2 << 16 | i1; | ||
66 | return val; | ||
67 | }; | ||
68 | |||
69 | int ExcelBook::Integer2ByteFile(FILE *f) { | ||
70 | int i1, i2; | ||
71 | i1 = fgetc(f); | ||
72 | i2 = fgetc(f); | ||
73 | return Integer2Byte(i1,i2); | ||
74 | }; | ||
75 | |||
76 | float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4) | ||
77 | { | ||
78 | int i; | ||
79 | float f; | ||
80 | unsigned char *ieee; | ||
81 | ieee = (unsigned char *) &f; | ||
82 | for (i = 0; i < 4; i++) ieee[i] = 0; | ||
83 | ieee[0] = ((int)b4) & 0xff; | ||
84 | ieee[1] = ((int)b3) & 0xff; | ||
85 | ieee[2] = ((int)b2) & 0xff; | ||
86 | ieee[3] = ((int)b1) & 0xff; | ||
87 | return f; | ||
88 | }; | ||
89 | |||
90 | double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4) | ||
91 | { | ||
92 | long int rk; | ||
93 | double value; | ||
94 | |||
95 | rk=Integer4Byte(b1,b2,b3,b4); | ||
96 | //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4); | ||
97 | if ( (rk & 0x02) != 0) | ||
98 | { | ||
99 | long int intval = rk >> 2; //drops the 2 bits | ||
100 | printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2); | ||
101 | value = (double) intval; | ||
102 | printf("Double4Byte: VALUEINT=%f\r\n",value); | ||
103 | if ( (rk & 0x01) != 0) | ||
104 | { | ||
105 | value /= 100.0; | ||
106 | }; | ||
107 | return value; | ||
108 | }else | ||
109 | { | ||
110 | |||
111 | union { double d; unsigned long int b[2]; } dbl_byte; | ||
112 | unsigned long int valbits = (rk & 0xfffffffc); | ||
113 | #if defined(__arm__) && !defined(__vfp__) | ||
114 | dbl_byte.b[0]=valbits; | ||
115 | dbl_byte.b[1]=0; | ||
116 | #else | ||
117 | dbl_byte.b[0]=0; | ||
118 | dbl_byte.b[1]=valbits; | ||
119 | #endif | ||
120 | printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]); | ||
121 | value=dbl_byte.d; | ||
122 | printf("Double4Byte: VALUE=%f\r\n",value); | ||
123 | |||
124 | if ( (rk & 0x01) != 0) | ||
125 | { | ||
126 | value /= 100.0; | ||
127 | }; | ||
128 | return value; | ||
129 | }; | ||
130 | }; | ||
131 | |||
132 | void ExcelBook::DetectEndian(void) | ||
133 | { | ||
134 | int end; | ||
135 | long i = 0x44332211; | ||
136 | unsigned char* a = (unsigned char*) &i; | ||
137 | end = (*a != 0x11); | ||
138 | if (end == 1) { | ||
139 | endian = BIG_ENDIAN; | ||
140 | printf("BIGENDIAN!\r\n"); | ||
141 | } else { | ||
142 | endian = LITTLE_ENDIAN; | ||
143 | printf("LITTLEENDIAN!\r\n"); | ||
144 | } | ||
145 | }; | ||
146 | |||
147 | double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8) | ||
148 | { | ||
149 | int i; | ||
150 | double d; | ||
151 | unsigned char *ieee; | ||
152 | ieee = (unsigned char *)&d; | ||
153 | for (i = 0; i < 8; i++) ieee[i] = 0; | ||
154 | if (endian == BIG_ENDIAN) { | ||
155 | ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff; | ||
156 | ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff; | ||
157 | ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff; | ||
158 | ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff; | ||
159 | } else { | ||
160 | ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff; | ||
161 | ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff; | ||
162 | ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff; | ||
163 | ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff; | ||
164 | } | ||
165 | return d; | ||
166 | }; | ||
167 | |||
168 | bool ExcelBook::OpenFile(char *Filename) | ||
169 | { | ||
170 | printf("Opening excel file!\r\n"); | ||
171 | File= fopen(Filename, "r"); | ||
172 | Position=0; // first byte index in file | ||
173 | XFRecords.resize(0); | ||
174 | SharedStrings.resize(0); | ||
175 | Names.resize(0); | ||
176 | Sheets.resize(0); | ||
177 | if(File==NULL) return false; | ||
178 | printf("Opened excel file!\r\n"); | ||
179 | return true; | ||
180 | }; | ||
181 | |||
182 | bool ExcelBook::CloseFile(void) | ||
183 | { | ||
184 | int w1; | ||
185 | for(w1=0;w1<(int)XFRecords.count();w1++) | ||
186 | { | ||
187 | if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;}; | ||
188 | }; | ||
189 | for(w1=0;w1<(int)SharedStrings.count();w1++) | ||
190 | { | ||
191 | if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;}; | ||
192 | }; | ||
193 | for(w1=0;w1<(int)Names.count();w1++) | ||
194 | { | ||
195 | if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;}; | ||
196 | }; | ||
197 | for(w1=0;w1<(int)Sheets.count();w1++) | ||
198 | { | ||
199 | if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;}; | ||
200 | }; | ||
201 | XFRecords.resize(0); | ||
202 | SharedStrings.resize(0); | ||
203 | Names.resize(0); | ||
204 | Sheets.resize(0); | ||
205 | fclose(File); | ||
206 | printf("closed excel file!\r\n"); | ||
207 | if(File==NULL) return true; | ||
208 | return false; | ||
209 | }; | ||
210 | |||
211 | void ExcelBook::SeekPosition(int pos) | ||
212 | { | ||
213 | if(!feof(File)) | ||
214 | { | ||
215 | Position=pos; | ||
216 | //printf("SeekPosition:Pos:%d\r\n",Position); | ||
217 | fseek(File,pos,SEEK_SET); | ||
218 | }; | ||
219 | }; | ||
220 | |||
221 | void ExcelBook::SeekSkip(int pos) | ||
222 | { | ||
223 | if(!feof(File)) | ||
224 | { | ||
225 | Position=Position+pos; | ||
226 | //printf("SeekSkip:Pos:%d\r\n",Position); | ||
227 | fseek(File, Position, SEEK_SET); | ||
228 | }; | ||
229 | }; | ||
230 | |||
231 | int ExcelBook::FileEOF(void) | ||
232 | { | ||
233 | if(File!=NULL) return(feof(File)); else return 0; | ||
234 | //EOF is defined in stdlib as -1 | ||
235 | }; | ||
236 | |||
237 | int ExcelBook::Get2Bytes(void) | ||
238 | { | ||
239 | int i1,i2; | ||
240 | i1=0; i2=0; | ||
241 | if (!feof(File)) | ||
242 | { | ||
243 | i1=fgetc(File); | ||
244 | Position++; | ||
245 | }; | ||
246 | if (!feof(File)) | ||
247 | { | ||
248 | i2=fgetc(File); | ||
249 | Position++; | ||
250 | }; | ||
251 | return Integer2Byte(i1,i2); | ||
252 | }; | ||
253 | |||
254 | char* ExcelBook::Read(int pos, int length) | ||
255 | { | ||
256 | int i; | ||
257 | char *data; | ||
258 | data= new char[length]; | ||
259 | SeekPosition(pos); | ||
260 | for(i=0; i<length; i++) | ||
261 | { | ||
262 | if(!feof(File)) data[i]=fgetc(File); | ||
263 | }; | ||
264 | Position= Position+length; | ||
265 | return data; | ||
266 | }; | ||
267 | |||
268 | QString ExcelBook::ReadUnicodeChar(int pos, int length) | ||
269 | { | ||
270 | int i; | ||
271 | QString data; | ||
272 | int i1=' ',i2=' ',ii; | ||
273 | SeekPosition(pos); | ||
274 | for(i=0; i<length; i++) | ||
275 | { | ||
276 | if(!feof(File)) i1=fgetc(File); | ||
277 | if(!feof(File)) i2=fgetc(File); | ||
278 | ii=Integer2Byte(i1,i2); | ||
279 | data.append(ii); | ||
280 | Position+=2; | ||
281 | }; | ||
282 | return data; | ||
283 | }; | ||
284 | |||
285 | QString* ExcelBook::GetString(int num) | ||
286 | { | ||
287 | if(num>=0 && num<(int)SharedStrings.count()) | ||
288 | { | ||
289 | return SharedStrings[num]; | ||
290 | }; | ||
291 | return new QString(""); | ||
292 | }; | ||
293 | |||
294 | int ExcelBook::SeekBOF(void) | ||
295 | { | ||
296 | int opcode,version,streamtype,length,ret=0; | ||
297 | char *data; | ||
298 | while(!feof(File)) | ||
299 | { | ||
300 | opcode=Get2Bytes(); | ||
301 | if(opcode==XL_BOF) | ||
302 | { | ||
303 | length=Get2Bytes(); | ||
304 | data=Read(Position,length); | ||
305 | version=Integer2Byte(data[0], data[1]); | ||
306 | streamtype=Integer2Byte(data[2], data[3]); | ||
307 | printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version); | ||
308 | delete data; data=NULL; | ||
309 | if (version==BIFF8) ret=8; | ||
310 | else if(version==BIFF7) ret=7; | ||
311 | printf("SEEKBOF:versionBIFF%d\r\n",ret); | ||
312 | if(streamtype==WBKGLOBAL) return ret *2; | ||
313 | else if(streamtype==WRKSHEET) return ret *1; | ||
314 | return 1; | ||
315 | }; | ||
316 | }; | ||
317 | return 0; | ||
318 | }; | ||
319 | |||
320 | ExcelBREC* ExcelBook::GetBREC(void) | ||
321 | { | ||
322 | ExcelBREC* rec; | ||
323 | rec= new ExcelBREC; | ||
324 | if(FileEOF()) return NULL; | ||
325 | rec->data=NULL; | ||
326 | rec->code=Get2Bytes(); | ||
327 | rec->length=Get2Bytes(); | ||
328 | rec->position=Position; | ||
329 | SeekSkip(rec->length); | ||
330 | return rec; | ||
331 | }; | ||
332 | |||
333 | ExcelBREC* ExcelBook::PeekBREC(void) | ||
334 | { | ||
335 | int oldpos; | ||
336 | ExcelBREC* NextRec; | ||
337 | oldpos=Position; | ||
338 | NextRec=GetBREC(); | ||
339 | SeekPosition(oldpos); | ||
340 | return NextRec; | ||
341 | }; | ||
342 | |||
343 | char* ExcelBook::GetDataOfBREC(ExcelBREC* record) | ||
344 | { | ||
345 | if(record->data==NULL) | ||
346 | { | ||
347 | ConvertCharToArray(record,Read(record->position,record->length),record->length); | ||
348 | }; | ||
349 | return record->data;//new? | ||
350 | }; | ||
351 | |||
352 | void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length) | ||
353 | { | ||
354 | record->data=new char[length]; | ||
355 | for(int w1=0;w1<=length-1;w1++) | ||
356 | record->data[w1]=chars[w1]; | ||
357 | }; | ||
358 | |||
359 | |||
360 | bool ExcelSheet::InitCells() | ||
361 | { | ||
362 | int r; | ||
363 | Cells.resize(rows * cols + cols+1); | ||
364 | if(Cells.count()==0) return false; | ||
365 | for(r=0;r < Cells.count();r++) | ||
366 | { | ||
367 | Cells[r]=NULL; | ||
368 | }; | ||
369 | return true; | ||
370 | }; | ||
371 | |||
372 | void ExcelSheet::Set(int row, int col, ExcelCell* cell) | ||
373 | { | ||
374 | if(cell!=NULL&&(row*cols+col)<Cells.count()) | ||
375 | { | ||
376 | Cells[row*cols+col]=cell; | ||
377 | }; | ||
378 | }; | ||
379 | |||
380 | ExcelCell* ExcelSheet::Get(int row, int col) | ||
381 | { | ||
382 | ExcelCell* cell; | ||
383 | cell=Cells[row*cols+col]; | ||
384 | if(cell==NULL) return NULL; | ||
385 | return cell; | ||
386 | }; | ||
387 | |||
388 | int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record) | ||
389 | { | ||
390 | char* data=NULL; | ||
391 | switch (record->code) | ||
392 | { | ||
393 | case XL_DIMENSION: | ||
394 | data = GetDataOfBREC(record); | ||
395 | if (record->length == 10) | ||
396 | { | ||
397 | sheet->rows = Integer2Byte(data[2], data[3]); | ||
398 | sheet->cols = Integer2Byte(data[6], data[7]); | ||
399 | } else | ||
400 | { | ||
401 | sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]); | ||
402 | sheet->cols = Integer2Byte(data[10], data[11]); | ||
403 | } | ||
404 | sheet->InitCells(); | ||
405 | break; | ||
406 | |||
407 | case XL_LABELSST: | ||
408 | HandleLabelSST(sheet, record); | ||
409 | break; | ||
410 | |||
411 | case XL_RK: | ||
412 | case XL_RK2: | ||
413 | HandleRK(sheet, record); | ||
414 | break; | ||
415 | |||
416 | case XL_MULRK: | ||
417 | HandleMulrk(sheet, record); | ||
418 | break; | ||
419 | |||
420 | case XL_ROW: | ||
421 | break; | ||
422 | |||
423 | case XL_NUMBER: | ||
424 | HandleNumber(sheet, record); | ||
425 | break; | ||
426 | |||
427 | case XL_BOOLERR: | ||
428 | break; | ||
429 | |||
430 | case XL_CONTINUE: | ||
431 | break; | ||
432 | |||
433 | case XL_FORMULA: | ||
434 | case XL_FORMULA2: | ||
435 | HandleFormula(sheet, record); | ||
436 | break; | ||
437 | |||
438 | case XL_LABEL: | ||
439 | break; | ||
440 | |||
441 | case XL_NAME: | ||
442 | HandleName(sheet, record); | ||
443 | break; | ||
444 | |||
445 | case XL_BOF: | ||
446 | break; | ||
447 | case XL_EOF: | ||
448 | return 0; | ||
449 | default: | ||
450 | break; | ||
451 | }; | ||
452 | return 1; | ||
453 | }; | ||
454 | |||
455 | int ExcelBook::ReadSheet(ExcelSheet* sheet) | ||
456 | { | ||
457 | ExcelBREC* record; | ||
458 | int oldpos; | ||
459 | oldpos = Position; | ||
460 | SeekPosition(sheet->position); | ||
461 | record = GetBREC(); | ||
462 | while (record!=NULL) | ||
463 | { | ||
464 | if (!SheetHandleRecord(sheet, record)) break; | ||
465 | record=GetBREC(); | ||
466 | }; | ||
467 | SeekPosition(oldpos); | ||
468 | return 1; | ||
469 | }; | ||
470 | |||
471 | ExcelSheet* ExcelBook::GetSheet(void) | ||
472 | { | ||
473 | ExcelSheet* sh=NULL; | ||
474 | int type; | ||
475 | type=SeekBOF(); | ||
476 | Version=type; | ||
477 | sh=new ExcelSheet; | ||
478 | if(type) | ||
479 | { | ||
480 | sh->type=type; | ||
481 | sh->position=Position; | ||
482 | sh->name=QString(""); | ||
483 | }; | ||
484 | if(type==8||type==7) | ||
485 | { | ||
486 | ReadSheet(sh); | ||
487 | }; | ||
488 | return sh; | ||
489 | }; | ||
490 | |||
491 | void ExcelBook::ParseSheets(void) | ||
492 | { | ||
493 | int BOFs; | ||
494 | ExcelBREC* r; | ||
495 | BOFs=1; | ||
496 | r=GetBREC(); | ||
497 | while(BOFs) | ||
498 | { | ||
499 | r=GetBREC(); | ||
500 | switch(r->code) | ||
501 | { | ||
502 | case XL_SST: | ||
503 | HandleSST(r); | ||
504 | break; | ||
505 | |||
506 | case XL_TXO: | ||
507 | break; | ||
508 | case XL_NAME: | ||
509 | break; | ||
510 | case XL_ROW: | ||
511 | break; | ||
512 | |||
513 | case XL_FORMAT: | ||
514 | HandleFormat(r); | ||
515 | break; | ||
516 | |||
517 | case XL_XF: | ||
518 | HandleXF(r); | ||
519 | break; | ||
520 | |||
521 | case XL_BOUNDSHEET: | ||
522 | HandleBoundSheet(r); | ||
523 | break; | ||
524 | |||
525 | case XL_EXTSST: | ||
526 | break; | ||
527 | case XL_CONTINUE: | ||
528 | break; | ||
529 | |||
530 | case XL_EOF: | ||
531 | BOFs--; | ||
532 | break; | ||
533 | |||
534 | default: | ||
535 | break; | ||
536 | }; | ||
537 | }; | ||
538 | }; | ||
539 | |||
540 | void ExcelBook::GetSheets(void) | ||
541 | { | ||
542 | ExcelSheet* sheet; | ||
543 | Sheets.resize(0); | ||
544 | sheet=GetSheet(); | ||
545 | while (sheet->Cells.count()!= 0 ) | ||
546 | { | ||
547 | Sheets.resize(Sheets.count()+1); | ||
548 | Sheets[Sheets.count()-1]=sheet; | ||
549 | sheet->name=*Names[Sheets.count()-1]; | ||
550 | sheet=GetSheet(); | ||
551 | }; | ||
552 | }; | ||
553 | |||
554 | bool ExcelBook::ParseBook(char *file) | ||
555 | { | ||
556 | dateformat=QString(""); | ||
557 | DetectEndian(); | ||
558 | OpenFile(file); | ||
559 | SeekBOF(); | ||
560 | ParseSheets(); | ||
561 | GetSheets(); | ||
562 | return true; | ||
563 | }; | ||
564 | |||
565 | QString ExcelBook::GetASCII(char* inbytes, int pos, int chars) | ||
566 | { | ||
567 | int i; | ||
568 | QString outstr=""; | ||
569 | for (i = 0; i < chars; i++) | ||
570 | { | ||
571 | outstr.append(inbytes[i+pos]); | ||
572 | }; | ||
573 | return outstr; | ||
574 | }; | ||
575 | |||
576 | QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars) | ||
577 | { | ||
578 | QString outstr=""; | ||
579 | int i; | ||
580 | int rc; | ||
581 | for (i=0; i<chars*2; i++) | ||
582 | { | ||
583 | rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]); | ||
584 | outstr.append(QChar(rc)); | ||
585 | i++; | ||
586 | }; | ||
587 | return outstr; | ||
588 | }; | ||
589 | |||
590 | |||
591 | void ExcelBook::HandleBoundSheet(ExcelBREC* rec) | ||
592 | { | ||
593 | char* data; | ||
594 | int type; | ||
595 | int visibility; | ||
596 | int length; | ||
597 | int pos; | ||
598 | QString name; | ||
599 | pos = 8; | ||
600 | data = GetDataOfBREC(rec); | ||
601 | type = data[4]; | ||
602 | visibility = data[5]; | ||
603 | length = data[6]; | ||
604 | if(data[7]==0) | ||
605 | { | ||
606 | //ascii | ||
607 | name=GetASCII(data,pos,length); | ||
608 | }else | ||
609 | { | ||
610 | name=GetUnicode(data,pos,length); | ||
611 | }; | ||
612 | Names.resize(Names.count()+1); | ||
613 | Names[Names.count()-1]=new QString(name); | ||
614 | }; | ||
615 | |||
616 | void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec) | ||
617 | { | ||
618 | char* data; | ||
619 | QString name; | ||
620 | int length; | ||
621 | int pos; | ||
622 | pos = 15; | ||
623 | data = GetDataOfBREC(rec); | ||
624 | length = data[3]; | ||
625 | name = GetASCII(data,pos,length); | ||
626 | |||
627 | |||
628 | }; | ||
629 | |||
630 | ExcelFormat* ExcelBook::GetFormatting(int xf) | ||
631 | { | ||
632 | int i; | ||
633 | ExcelFormat* rec; | ||
634 | rec=new ExcelFormat(); | ||
635 | for (i = 0; formatter[i].code != 0; i++) | ||
636 | { | ||
637 | if (xf == formatter[i].code) break; | ||
638 | }; | ||
639 | if (formatter[i].format ==NULL) return NULL; | ||
640 | rec->code = xf; | ||
641 | rec->type = formatter[i].type; | ||
642 | rec->format = formatter[i].format; | ||
643 | return rec; | ||
644 | }; | ||
645 | |||
646 | void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes) | ||
647 | { | ||
648 | QString str=QString(""); | ||
649 | char* data; | ||
650 | int chars, pos, options, i; | ||
651 | int richstring, fareaststring, runlength=0; | ||
652 | int richruns=0,fareastsize=0; | ||
653 | int totalstrings; | ||
654 | int uniquestrings; | ||
655 | data = GetDataOfBREC(rec); | ||
656 | totalstrings = Integer4Byte(data[0], data[1], data[2], data[3]); | ||
657 | uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]); | ||
658 | pos = 8; | ||
659 | for (i = 0; i < uniquestrings; i++) | ||
660 | { | ||
661 | richruns=0; fareastsize=0; | ||
662 | chars = Integer2Byte(data[pos], data[pos+1]); | ||
663 | pos += 2; | ||
664 | options = data[pos]; | ||
665 | pos++; | ||
666 | fareaststring = ((options & 0x04) != 0); | ||
667 | richstring = ((options & 0x08) != 0); | ||
668 | if(richstring) | ||
669 | { | ||
670 | richruns= Integer2Byte(data[pos],data[pos+1]); | ||
671 | pos+=2; | ||
672 | }; | ||
673 | if(fareaststring) | ||
674 | { | ||
675 | fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]); | ||
676 | pos+=4; | ||
677 | }; | ||
678 | |||
679 | if ((options & 0x01) == 0) //8 bit chars | ||
680 | { | ||
681 | /* ascii */ | ||
682 | str = GetASCII(bytes,pos,chars); | ||
683 | pos=pos+chars; | ||
684 | if(str[0]=='=') str[0]=' '; | ||
685 | }else //16 bit chars | ||
686 | { | ||
687 | /* unicode */ | ||
688 | str = GetUnicode(bytes,pos,chars); | ||
689 | pos=pos+chars*2; | ||
690 | }; | ||
691 | // HERE TO PUT richformat handling | ||
692 | if (richstring) | ||
693 | { | ||
694 | pos += 4 * richruns; | ||
695 | }; | ||
696 | if (fareaststring) | ||
697 | { | ||
698 | pos += fareastsize; | ||
699 | }; | ||
700 | //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode()); | ||
701 | SharedStrings.resize(SharedStrings.count()+1); | ||
702 | SharedStrings[SharedStrings.count()-1]=new QString(str); | ||
703 | } | ||
704 | }; | ||
705 | |||
706 | |||
707 | char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont) | ||
708 | { | ||
709 | int i, pos; | ||
710 | int length; | ||
711 | |||
712 | char* data; | ||
713 | char* bytes; | ||
714 | length = rec->length; | ||
715 | for (i = 0; i < (int) cont->rec.count(); i++) | ||
716 | { | ||
717 | length += cont->rec[i]->length; | ||
718 | } | ||
719 | bytes = GetDataOfBREC(rec); | ||
720 | pos = rec->length; | ||
721 | for (i = 0; i < (int) cont->rec.count(); i++) | ||
722 | { | ||
723 | data = GetDataOfBREC(cont->rec[i]); | ||
724 | *bytes += pos; | ||
725 | bytes = data; | ||
726 | pos += cont->rec[i]->length; | ||
727 | } | ||
728 | return bytes; | ||
729 | }; | ||
730 | |||
731 | |||
732 | void ExcelBook::HandleSST(ExcelBREC* rec) | ||
733 | { | ||
734 | char* bytes; | ||
735 | SSTList* cont; | ||
736 | cont= new SSTList; | ||
737 | ExcelBREC* nr; | ||
738 | nr = PeekBREC(); | ||
739 | while (nr->code == XL_CONTINUE) | ||
740 | { | ||
741 | cont->rec.resize(cont->rec.count()+1); | ||
742 | cont->rec[cont->rec.count()-1]=GetBREC(); | ||
743 | nr = PeekBREC(); | ||
744 | } | ||
745 | bytes = MergeBytesFromSSTs(rec,cont); | ||
746 | HandleSetOfSST(rec, bytes); | ||
747 | for(int w1=0;w1<(int)cont->rec.count();w1++) | ||
748 | { | ||
749 | if(cont->rec[w1]!=NULL) {delete cont->rec[w1];cont->rec[w1]=NULL;}; | ||
750 | }; | ||
751 | cont->rec.resize(0); | ||
752 | }; | ||
753 | |||
754 | void ExcelBook::HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec) | ||
755 | { | ||
756 | int index, row, col; | ||
757 | char* data; | ||
758 | data = GetDataOfBREC(rec); | ||
759 | index = Integer4Byte(data[6], data[7], data[8], data[9]); | ||
760 | row = Integer2Byte(data[0], data[1]); | ||
761 | col = Integer2Byte(data[2], data[3]); | ||
762 | sheet->Set(row,col, CellLabel(row, col, *GetString(index))); | ||
763 | }; | ||
764 | |||
765 | ExcelCell* ExcelBook::CellLabel(int row, int col, QString str) | ||
766 | { | ||
767 | ExcelCell* c; | ||
768 | c= new ExcelCell; | ||
769 | c->row = row; | ||
770 | c->col = col; | ||
771 | c->type = CELL_LABEL; | ||
772 | c->valuec = str; | ||
773 | return c; | ||
774 | }; | ||
775 | |||
776 | ExcelCell* ExcelBook::CellNumber(int row, int col, int index, double d) | ||
777 | { | ||
778 | ExcelCell* c; | ||
779 | c=new ExcelCell; | ||
780 | c->row = row; | ||
781 | c->col = col; | ||
782 | c->xfindex = index; | ||
783 | c->type = CELL_NUMBER; | ||
784 | c->valued = d; | ||
785 | return c; | ||
786 | }; | ||
787 | |||
788 | QString* ExcelBook::CellDataString(ExcelSheet* sh, int row, int col) | ||
789 | { | ||
790 | time_t date; | ||
791 | struct tm *tmptr; | ||
792 | ExcelCell* c; | ||
793 | char str[128]; | ||
794 | QString format; | ||
795 | int precision; | ||
796 | int utcOffsetDays = 25569; | ||
797 | int sInADay = 24 * 60 * 60; | ||
798 | c = sh->Get(row,col); | ||
799 | if (c == NULL) return new QString(""); | ||
800 | switch (c->type) | ||
801 | { | ||
802 | case CELL_LABEL: | ||
803 | return new QString(c->valuec); | ||
804 | case CELL_NUMBER: | ||
805 | if (XFRecords[c->xfindex]->type == DATEFORMAT) | ||
806 | { | ||
807 | |||
808 | format = XFRecords[c->xfindex]->format; | ||
809 | date = (time_t) ((c->valued - utcOffsetDays) * sInADay); | ||
810 | tmptr = gmtime(&date); | ||
811 | if (dateformat) | ||
812 | { | ||
813 | strftime(str,1024,dateformat.ascii(),tmptr); | ||
814 | } else | ||
815 | { | ||
816 | strftime(str,1024,format.ascii(),tmptr); | ||
817 | }; | ||
818 | } else | ||
819 | if (XFRecords[c->xfindex]->type == NUMBERFORMAT) | ||
820 | { | ||
821 | format = XFRecords[c->xfindex]->format; | ||
822 | //sprintf(str,format.ascii(),c->valued); | ||
823 | // the real format is ignored... | ||
824 | // because there is more work to be done in the field | ||
825 | precision = CellGetPrecision(c->valued); | ||
826 | sprintf(str,"%.*f",precision,c->valued); | ||
827 | }else | ||
828 | { | ||
829 | precision = CellGetPrecision(c->valued); | ||
830 | sprintf(str,"%.*f",precision,c->valued); | ||
831 | }; | ||
832 | break; | ||
833 | case CELL_DATE: | ||
834 | break; | ||
835 | case CELL_BOOLEAN: | ||
836 | break; | ||
837 | case CELL_ERROR: | ||
838 | break; | ||
839 | } | ||
840 | return new QString(str); | ||
841 | }; | ||
842 | |||
843 | int ExcelBook::CellGetPrecision(double d) | ||
844 | { | ||
845 | double t; | ||
846 | int i,x; | ||
847 | int count; | ||
848 | if (d < 0) d *= -1; | ||
849 | i = (int)d; | ||
850 | t = d - (double)i; | ||
851 | if (t <= 0) | ||
852 | { | ||
853 | return 0; | ||
854 | }; | ||
855 | count = 0; | ||
856 | for (x = 6; x > 1; x--) | ||
857 | { | ||
858 | i = (int)d; | ||
859 | t = d - (double)i; | ||
860 | t *= pow(10,x - 2); | ||
861 | i = (int)t; | ||
862 | t = t - (double)i; | ||
863 | t *= 10; | ||
864 | i = (int)t; | ||
865 | if (i > 0) break; | ||
866 | count++; | ||
867 | }; | ||
868 | return (5 - count); | ||
869 | }; | ||
870 | |||
871 | |||
872 | void ExcelBook::CellSetDateFormat(char *d) | ||
873 | { | ||
874 | dateformat = QString(d); | ||
875 | }; | ||
876 | |||
877 | void ExcelBook::HandleMulrk(ExcelSheet* sheet, ExcelBREC* record) | ||
878 | { | ||
879 | struct mulrk mulrk; | ||
880 | char* data; | ||
881 | ExcelCell* cell; | ||
882 | int len; | ||
883 | int i; | ||
884 | len = record->length; | ||
885 | data = GetDataOfBREC(record); | ||
886 | mulrk.row = Integer2Byte(data[0],data[1]); | ||
887 | mulrk.first = Integer2Byte(data[2],data[3]); | ||
888 | mulrk.last = Integer2Byte(data[len - 2],data[len - 1]); | ||
889 | mulrk.numrks = mulrk.last - mulrk.first + 1; | ||
890 | MulrkRead(&mulrk, data); | ||
891 | for (i = 0; i < mulrk.numrks; i++) | ||
892 | { | ||
893 | cell = CellNumber(mulrk.row, mulrk.first + i, mulrk.xfindices[i], mulrk.rkdbls[i]); | ||
894 | sheet->Set(mulrk.row,mulrk.first+ i, cell); | ||
895 | //printf("handleMULRK:row=%d,col=%d,val=%f\r\n",mulrk.row,mulrk.first+i,mulrk.rkdbls[i]); | ||
896 | } | ||
897 | //delete(mulrk.xfindices); | ||
898 | //delete(mulrk.rkdbls); | ||
899 | }; | ||
900 | |||
901 | void ExcelBook::MulrkRead(struct mulrk *mulrk, char* data) | ||
902 | { | ||
903 | double d; | ||
904 | int i; | ||
905 | int pos; | ||
906 | pos = 4; | ||
907 | mulrk->xfindices.resize(mulrk->numrks); | ||
908 | mulrk->rkdbls.resize(mulrk->numrks); | ||
909 | for (i = 0; i < mulrk->numrks; i++) | ||
910 | { | ||
911 | mulrk->xfindices[i] = Integer2Byte(data[pos], data[pos+1]); | ||
912 | d=Double4Byte(data[pos+2], data[pos+3], data[pos+4], data[pos+5]); | ||
913 | //printf("double:%f\r\n",d); | ||
914 | mulrk->rkdbls[i] = d; | ||
915 | pos += 6; | ||
916 | } | ||
917 | }; | ||
918 | |||
919 | |||
920 | void ExcelBook::HandleNumber(ExcelSheet* sheet, ExcelBREC* record) | ||
921 | { | ||
922 | int xfindex, row, col; | ||
923 | char* data; | ||
924 | double d; | ||
925 | data = GetDataOfBREC(record); | ||
926 | row = Integer2Byte(data[0], data[1]); | ||
927 | col = Integer2Byte(data[2], data[3]); | ||
928 | xfindex = Integer2Byte(data[4], data[5]); | ||
929 | #if defined(__arm__) && !defined(__vfp__) | ||
930 | d=Double8Byte(data[10], data[11], data[12], data[13],data[6], data[7], data[8], data[9]); | ||
931 | #else | ||
932 | d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]); | ||
933 | #endif | ||
934 | //even if ARM is little endian... doubles are been placed as bigendian words. | ||
935 | //thanks pb_ for that. :) | ||
936 | sheet->Set(row,col, CellNumber(row,col,xfindex,d)); | ||
937 | //printf("handleNumber:row=%d,col=%d,val=%f\r\n",row,col,d); | ||
938 | }; | ||
939 | |||
940 | ExcelFormat::ExcelFormat() | ||
941 | { | ||
942 | code=0;type=0;format=""; | ||
943 | }; | ||
944 | |||
945 | ExcelFormat::ExcelFormat(int c,int t, QString s) | ||
946 | { | ||
947 | code=c;type=t;format=s; | ||
948 | }; | ||
949 | |||
950 | |||
951 | void ExcelBook::HandleFormat(ExcelBREC* rec) | ||
952 | { | ||
953 | ExcelFormat* xfrec; | ||
954 | char* data; | ||
955 | int format; | ||
956 | data = GetDataOfBREC(rec); | ||
957 | format = Integer2Byte(data[2],data[3]); | ||
958 | xfrec = GetFormatting(format); | ||
959 | /*int idx; | ||
960 | idx=XFRecords.count()-1; | ||
961 | XFRecords[idx]->code=xfrec->code; | ||
962 | XFRecords[idx]->type=xfrec->type; | ||
963 | XFRecords[idx]->format="manos"; | ||
964 | //XFRecords[XFRecords.count()-1]=xfrec; | ||
965 | printf("6\r\n");*/ | ||
966 | }; | ||
967 | |||
968 | void ExcelBook::HandleXF(ExcelBREC* rec) | ||
969 | { | ||
970 | ExcelFormat* xfrec; | ||
971 | char* data; | ||
972 | int format; | ||
973 | data = GetDataOfBREC(rec); | ||
974 | format = Integer2Byte(data[2],data[3]); | ||
975 | xfrec = GetFormatting(format); | ||
976 | XFRecords.resize(XFRecords.count()+1); | ||
977 | XFRecords[XFRecords.count()-1]=xfrec; | ||
978 | }; | ||
979 | |||
980 | |||
981 | |||
982 | void ExcelBook::HandleRK(ExcelSheet* sheet, ExcelBREC* record) | ||
983 | { | ||
984 | int xfindex, row, col; | ||
985 | char* data; | ||
986 | double d; | ||
987 | data = GetDataOfBREC(record); | ||
988 | row = Integer2Byte(data[0], data[1]); | ||
989 | col = Integer2Byte(data[2], data[3]); | ||
990 | xfindex = Integer2Byte(data[4], data[5]); | ||
991 | d=Double4Byte(data[6], data[7], data[8], data[9]); | ||
992 | sheet->Set(row,col,CellNumber(row,col,xfindex,d)); | ||
993 | //printf("handleRK:row=%d,col=%d,val=%f\r\n",row,col,d); | ||
994 | }; | ||
995 | |||
996 | |||
997 | void ExcelBook::HandleFormula(ExcelSheet* sheet, ExcelBREC* record) | ||
998 | { | ||
999 | int xfindex, row, col; | ||
1000 | char* data; | ||
1001 | double d; | ||
1002 | data = GetDataOfBREC(record); | ||
1003 | row = Integer2Byte(data[0], data[1]); | ||
1004 | col = Integer2Byte(data[2], data[3]); | ||
1005 | if (data[6] == 0 && data[12] == -1 && data[13] == -1) | ||
1006 | { | ||
1007 | // string | ||
1008 | } else | ||
1009 | if (data[6] == 1 && data[12] == -1 && data[13] == -1) | ||
1010 | { | ||
1011 | // boolean | ||
1012 | } else | ||
1013 | if ( data[6] == 2 && data[12] == -1 && data[13] == -1) | ||
1014 | { | ||
1015 | // error | ||
1016 | } | ||
1017 | else | ||
1018 | { | ||
1019 | // number | ||
1020 | xfindex = Integer2Byte(data[4], data[5]); | ||
1021 | d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]); | ||
1022 | QString s1; | ||
1023 | int sz; | ||
1024 | sz=Integer2Byte(data[20],data[21]);// size of the formula | ||
1025 | char* formuladata; | ||
1026 | formuladata=new char[sz]; | ||
1027 | for(int w1=0;w1<sz;w1++) | ||
1028 | { | ||
1029 | formuladata[w1]=data[22+w1]; | ||
1030 | }; | ||
1031 | //22 is the first 0 idx of formula data | ||
1032 | s1="="+GetFormula(row,col,sheet,formuladata,sz); | ||
1033 | //printf("GetFormula:Formula=%s\r\n",s1.ascii()); | ||
1034 | sheet->Set(row,col,CellLabel(row,col,s1)); | ||
1035 | } | ||
1036 | }; | ||
1037 | |||
1038 | |||
1039 | QString ExcelBook::GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz) | ||
1040 | { | ||
1041 | int length=sz; | ||
1042 | printf("{FormulaParser}\r\n"); | ||
1043 | printf("row=%d, col=%d, length=%d\r\n",row,col,length); | ||
1044 | int idx=0; | ||
1045 | int w1,w2,w3,w4; | ||
1046 | double d1; | ||
1047 | int token; | ||
1048 | QString s1; | ||
1049 | QList <QString> operands; | ||
1050 | operands.setAutoDelete(TRUE); | ||
1051 | QString formula; | ||
1052 | operands.clear(); | ||
1053 | while( idx<length ) | ||
1054 | { | ||
1055 | token= data[idx]; idx++; | ||
1056 | switch(token) | ||
1057 | { | ||
1058 | case 0x1E: //prtInt | ||
1059 | w1=Integer2Byte(data[idx],data[idx+1]); | ||
1060 | idx=idx+2; | ||
1061 | operands.prepend(new QString(QString::number(w1))); | ||
1062 | printf(" token:ptgInt,num=%d\r\n",w1); | ||
1063 | break; | ||
1064 | case 0x1F: //ptgNumber | ||
1065 | #if defined(__arm__) && !defined(__vfp__) | ||
1066 | d1=Double8Byte(data[idx+4],data[idx+5],data[idx+6],data[idx+7] | ||
1067 | ,data[idx],data[idx+1],data[idx+2],data[idx+3]); | ||
1068 | #else | ||
1069 | d1=Double8Byte(data[idx],data[idx+1],data[idx+2],data[idx+3] | ||
1070 | ,data[idx+4],data[idx+5],data[idx+6],data[idx+7]); | ||
1071 | #endif | ||
1072 | idx=idx+8; | ||
1073 | operands.prepend(new QString(QString::number(d1))); | ||
1074 | printf(" token:ptgNumber,num=%f\r\n",d1); | ||
1075 | break; | ||
1076 | case 0x17: //ptgStr | ||
1077 | if(Version==8) | ||
1078 | { | ||
1079 | //unicode string | ||
1080 | //w1=Integer2Byte(data[idx],data[idx+1]);idx+=2; | ||
1081 | w1=data[idx];idx++; | ||
1082 | printf("len=%d\r\n",w1); | ||
1083 | int richruns=0; int fareastsize=0; | ||
1084 | int richstring,fareaststring; | ||
1085 | int options = data[idx];idx++; | ||
1086 | fareaststring = ((options & 0x04) != 0); | ||
1087 | richstring = ((options & 0x08) != 0); | ||
1088 | if(richstring) | ||
1089 | { | ||
1090 | //containts rich string formatting. | ||
1091 | printf("STRING:richstring\r\n"); | ||
1092 | richruns= Integer2Byte(data[idx],data[idx+1]); | ||
1093 | printf("richruns:%d\r\n",richruns); | ||
1094 | idx+=2; | ||
1095 | }; | ||
1096 | if(fareaststring) | ||
1097 | { | ||
1098 | //contains far east formatting | ||
1099 | printf("STRING:fareast!\r\n"); | ||
1100 | fareastsize=Integer4Byte(data[idx], data[idx+1], | ||
1101 | data[idx+2], data[idx+3]); | ||
1102 | printf("fareastsize=%d",fareastsize); | ||
1103 | idx+=4; | ||
1104 | }; | ||
1105 | if ((options & 0x01) == 0) //8 bit chars | ||
1106 | { | ||
1107 | /* ascii */ | ||
1108 | s1 = GetASCII(data,idx,w1); | ||
1109 | idx=idx+w1; | ||
1110 | printf("STRING:ASCII=%s\r\n",s1.ascii()); | ||
1111 | }else //16 bit chars | ||
1112 | { | ||
1113 | /* unicode */ | ||
1114 | s1 = GetUnicode(data,idx,w1); | ||
1115 | idx=idx+w1*2; | ||
1116 | printf("STRING:unicode=%s\r\n",s1.ascii()); | ||
1117 | }; | ||
1118 | // HERE TO PUT richformat handling | ||
1119 | if (richstring) | ||
1120 | { | ||
1121 | idx += 4 * richruns; | ||
1122 | }; | ||
1123 | if (fareaststring) | ||
1124 | { | ||
1125 | idx += fareastsize; | ||
1126 | }; | ||
1127 | s1=QString("""")+s1+QString(""""); | ||
1128 | operands.prepend(new QString(s1)); | ||
1129 | }else | ||
1130 | { | ||
1131 | w1=data[idx];idx++; | ||
1132 | s1=GetASCII(data,idx,w1); | ||
1133 | s1=QString("""")+s1+QString(""""); | ||
1134 | idx=idx+w1; | ||
1135 | operands.prepend(new QString(s1)); | ||
1136 | }; | ||
1137 | printf(" token:ptgStr,num=%d\r\n",w1); | ||
1138 | break; | ||
1139 | case 0x25: | ||
1140 | case 0x45: | ||
1141 | case 0x65: // ptgArea | ||
1142 | if(Version==8) | ||
1143 | { | ||
1144 | w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row1 | ||
1145 | w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row2 | ||
1146 | w3=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col1 | ||
1147 | w4=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col2 | ||
1148 | }else | ||
1149 | { | ||
1150 | w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row1 | ||
1151 | w2=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row2 | ||
1152 | w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col1 | ||
1153 | w4=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col2 | ||
1154 | }; | ||
1155 | //ignores relative or absolute refs | ||
1156 | s1=FindCellName(w1,w3)+":"+FindCellName(w2,w4); | ||
1157 | printf(" token:ptgArea,ref=%s\r\n",s1.ascii()); | ||
1158 | operands.prepend(new QString(s1)); | ||
1159 | break; | ||
1160 | case 0x24: | ||
1161 | case 0x44: | ||
1162 | case 0x64://ptgRef | ||
1163 | if(Version==8) | ||
1164 | { | ||
1165 | w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row | ||
1166 | w2=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col | ||
1167 | }else | ||
1168 | { | ||
1169 | w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row | ||
1170 | w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col | ||
1171 | }; | ||
1172 | s1=FindCellName(w1,w2); | ||
1173 | printf("token:ptgRef,ref=%s\r\n",s1.ascii()); | ||
1174 | operands.prepend(new QString(s1)); | ||
1175 | break; | ||
1176 | case 0x1D: // ptgBool | ||
1177 | w1=data[idx];idx++; | ||
1178 | printf("token:ptgBool,val=%d\r\n",w1); | ||
1179 | operands.prepend(new QString(QString::number(w1))); | ||
1180 | break; | ||
1181 | case 0x16://ptg MissArg | ||
1182 | printf("token:ptgMissArg, val=' '\r\n"); | ||
1183 | operands.prepend(new QString("0")); | ||
1184 | break; | ||
1185 | case 0x12://ptgUplus== | ||
1186 | printf("token:ptgUplus\r\n"); | ||
1187 | s1=QString("+")+operands.first()->ascii(); | ||
1188 | operands.removeFirst(); | ||
1189 | operands.prepend(new QString(s1)); | ||
1190 | break; | ||
1191 | case 0x13://ptgUminus | ||
1192 | printf("token:ptgUminus\r\n"); | ||
1193 | s1=QString("-")+operands.first()->ascii(); | ||
1194 | operands.removeFirst(); | ||
1195 | operands.prepend(new QString(s1)); | ||
1196 | break; | ||
1197 | case 0x03://ptgAdd | ||
1198 | printf("token:ptgAdd\r\n"); | ||
1199 | operands.first(); | ||
1200 | s1=operands.next()->ascii() | ||
1201 | +QString("+")+operands.first()->ascii(); | ||
1202 | operands.removeFirst();operands.removeFirst(); | ||
1203 | operands.prepend(new QString(s1)); | ||
1204 | break; | ||
1205 | case 0x04://ptgSub | ||
1206 | printf("token:ptgSub\r\n"); | ||
1207 | operands.first(); | ||
1208 | s1=operands.next()->ascii() | ||
1209 | +QString("-")+operands.first()->ascii(); | ||
1210 | operands.removeFirst();operands.removeFirst(); | ||
1211 | operands.prepend(new QString(s1)); | ||
1212 | break; | ||
1213 | case 0x05://ptgMul | ||
1214 | printf("token:ptgMul\r\n"); | ||
1215 | operands.first(); | ||
1216 | s1=operands.next()->ascii() | ||
1217 | +QString("*")+operands.first()->ascii(); | ||
1218 | operands.removeFirst();operands.removeFirst(); | ||
1219 | operands.prepend(new QString(s1)); | ||
1220 | break; | ||
1221 | case 0x06://ptgDiv | ||
1222 | printf("token:ptgDiv\r\n"); | ||
1223 | operands.first(); | ||
1224 | s1=operands.next()->ascii() | ||
1225 | +QString("/")+operands.first()->ascii(); | ||
1226 | operands.removeFirst();operands.removeFirst(); | ||
1227 | operands.prepend(new QString(s1)); | ||
1228 | break; | ||
1229 | case 0x07://ptgPOWER | ||
1230 | printf("token:ptgPow\r\n"); | ||
1231 | operands.first(); | ||
1232 | s1=QString("POWER(")+operands.next()->ascii() | ||
1233 | +QString(",")+operands.first()->ascii()+QString(")"); | ||
1234 | operands.removeFirst();operands.removeFirst(); | ||
1235 | operands.prepend(new QString(s1)); | ||
1236 | break; | ||
1237 | case 0x08://ptgConcat | ||
1238 | printf("token:ptgConcat\r\n"); | ||
1239 | operands.first(); | ||
1240 | s1=QString("CONCATENATE(")+operands.next()->ascii() | ||
1241 | +QString(",")+operands.first()->ascii()+QString(")"); | ||
1242 | operands.removeFirst();operands.removeFirst(); | ||
1243 | operands.prepend(new QString(s1)); | ||
1244 | break; | ||
1245 | case 0x15://ptgParenthesis | ||
1246 | printf("token:ptgParenthesis\r\n"); | ||
1247 | s1=QString("(")+operands.first()->ascii()+QString(")"); | ||
1248 | operands.removeFirst(); | ||
1249 | operands.prepend(new QString(s1)); | ||
1250 | break; | ||
1251 | case 0x14://ptgPercent | ||
1252 | printf("token:ptgPercent\r\n"); | ||
1253 | s1=operands.first()->ascii()+QString("*0.01"); | ||
1254 | operands.removeFirst(); | ||
1255 | operands.prepend(new QString(s1)); | ||
1256 | break; | ||
1257 | case 0x9://ptgLessThan | ||
1258 | printf("token:ptgLESS\r\n"); | ||
1259 | operands.first(); | ||
1260 | s1=operands.next()->ascii() | ||
1261 | +QString("<")+operands.first()->ascii(); | ||
1262 | operands.removeFirst();operands.removeFirst(); | ||
1263 | operands.prepend(new QString(s1)); | ||
1264 | break; | ||
1265 | case 0xa://ptgLessEqual | ||
1266 | printf("token:ptgLESS_EQUAL\r\n"); | ||
1267 | operands.first(); | ||
1268 | s1=operands.next()->ascii() | ||
1269 | +QString("<=")+operands.first()->ascii(); | ||
1270 | operands.removeFirst();operands.removeFirst(); | ||
1271 | operands.prepend(new QString(s1)); | ||
1272 | break; | ||
1273 | case 0xb://ptgEQUAL | ||
1274 | printf("token:ptgEQUAL\r\n"); | ||
1275 | operands.first(); | ||
1276 | s1=operands.next()->ascii() | ||
1277 | +QString("==")+operands.first()->ascii(); | ||
1278 | operands.removeFirst();operands.removeFirst(); | ||
1279 | operands.prepend(new QString(s1)); | ||
1280 | break; | ||
1281 | case 0xc://ptgGREATER_EQUAL | ||
1282 | printf("token:ptgGREAT_EQUAL\r\n"); | ||
1283 | operands.first(); | ||
1284 | s1=operands.next()->ascii() | ||
1285 | +QString(">=")+operands.first()->ascii(); | ||
1286 | operands.removeFirst();operands.removeFirst(); | ||
1287 | operands.prepend(new QString(s1)); | ||
1288 | break; | ||
1289 | case 0xd://ptgGREAT_THAN | ||
1290 | printf("token:ptgGREAT_THAN\r\n"); | ||
1291 | operands.first(); | ||
1292 | s1=operands.next()->ascii() | ||
1293 | +QString(">")+operands.first()->ascii(); | ||
1294 | operands.removeFirst();operands.removeFirst(); | ||
1295 | operands.prepend(new QString(s1)); | ||
1296 | break; | ||
1297 | case 0xe://ptgNOT_EQUAL | ||
1298 | printf("token:ptgNOTequal\r\n"); | ||
1299 | operands.first(); | ||
1300 | s1=operands.next()->ascii() | ||
1301 | +QString("!=")+operands.first()->ascii(); | ||
1302 | operands.removeFirst();operands.removeFirst(); | ||
1303 | operands.prepend(new QString(s1)); | ||
1304 | break; | ||
1305 | case 0x19://attribute can be Sum,If,Choose | ||
1306 | w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2; | ||
1307 | idx++; | ||
1308 | printf("token:ATTRIBUTE:0x%x\r\n",w3); | ||
1309 | for(w4=idx;w4<length;w4++) | ||
1310 | printf("0x%x, ",data[w4]); | ||
1311 | if(w3&0x01)//choose | ||
1312 | { | ||
1313 | printf("token:CHOOSE\r\n"); | ||
1314 | } | ||
1315 | else if(w3&0x02)//if | ||
1316 | { | ||
1317 | printf("token:IF\r\n"); | ||
1318 | } | ||
1319 | else if(w3&0x10)//sum | ||
1320 | { | ||
1321 | printf("token:SUM\r\n"); | ||
1322 | }; | ||
1323 | |||
1324 | break; | ||
1325 | |||
1326 | |||
1327 | case 0x21: | ||
1328 | case 0x22: | ||
1329 | case 0x42: | ||
1330 | case 0x62: | ||
1331 | case 0x41: | ||
1332 | case 0x61://ptgFunction | ||
1333 | printf("token:ptgFunction\r\n"); | ||
1334 | if(token==0x22||token==0x42||token==0x62) | ||
1335 | { | ||
1336 | w2=(int)data[idx];idx++; | ||
1337 | w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2; | ||
1338 | }else | ||
1339 | { | ||
1340 | w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2; | ||
1341 | }; | ||
1342 | switch(w1) | ||
1343 | { | ||
1344 | case 0xf://SIN | ||
1345 | s1=QString("SIN(")+operands.first()->ascii()+QString(")"); | ||
1346 | operands.removeFirst(); | ||
1347 | operands.prepend(new QString(s1)); | ||
1348 | break; | ||
1349 | case 0x10://COS | ||
1350 | s1=QString("COS(")+operands.first()->ascii()+QString(")"); | ||
1351 | operands.removeFirst(); | ||
1352 | operands.prepend(new QString(s1)); | ||
1353 | break; | ||
1354 | case 0x11://tan | ||
1355 | s1=QString("TAN(")+operands.first()->ascii()+QString(")"); | ||
1356 | operands.removeFirst(); | ||
1357 | operands.prepend(new QString(s1)); | ||
1358 | break; | ||
1359 | case 0x62://asin | ||
1360 | s1=QString("ASIN(")+operands.first()->ascii()+QString(")"); | ||
1361 | operands.removeFirst(); | ||
1362 | operands.prepend(new QString(s1)); | ||
1363 | break; | ||
1364 | case 0x63://ACOS | ||
1365 | s1=QString("ACOS(")+operands.first()->ascii()+QString(")"); | ||
1366 | operands.removeFirst(); | ||
1367 | operands.prepend(new QString(s1)); | ||
1368 | break; | ||
1369 | case 0x12://ATAN | ||
1370 | s1=QString("ATAN(")+operands.first()->ascii()+QString(")"); | ||
1371 | operands.removeFirst(); | ||
1372 | operands.prepend(new QString(s1)); | ||
1373 | break; | ||
1374 | case 0xe5://SINH | ||
1375 | s1=QString("SINH(")+operands.first()->ascii()+QString(")"); | ||
1376 | operands.removeFirst(); | ||
1377 | operands.prepend(new QString(s1)); | ||
1378 | break; | ||
1379 | case 0xe6://COSH | ||
1380 | s1=QString("COSH(")+operands.first()->ascii()+QString(")"); | ||
1381 | operands.removeFirst(); | ||
1382 | operands.prepend(new QString(s1)); | ||
1383 | break; | ||
1384 | case 0xe7://TANH | ||
1385 | s1=QString("TANH(")+operands.first()->ascii()+QString(")"); | ||
1386 | operands.removeFirst(); | ||
1387 | operands.prepend(new QString(s1)); | ||
1388 | break; | ||
1389 | case 0xe8://ASINH | ||
1390 | s1=QString("ASINH(")+operands.first()->ascii()+QString(")"); | ||
1391 | operands.removeFirst(); | ||
1392 | operands.prepend(new QString(s1)); | ||
1393 | break; | ||
1394 | case 0xe9://ACOSH | ||
1395 | s1=QString("ACOSH(")+operands.first()->ascii()+QString(")"); | ||
1396 | operands.removeFirst(); | ||
1397 | operands.prepend(new QString(s1)); | ||
1398 | break; | ||
1399 | case 0xea://ATANH | ||
1400 | s1=QString("ATANH(")+operands.first()->ascii()+QString(")"); | ||
1401 | operands.removeFirst(); | ||
1402 | operands.prepend(new QString(s1)); | ||
1403 | break; | ||
1404 | case 0x13://pi | ||
1405 | s1="PI()"; | ||
1406 | operands.prepend(new QString(s1)); | ||
1407 | break; | ||
1408 | case 0x14://sqrt | ||
1409 | s1=QString("SQRT(")+operands.first()->ascii()+QString(")"); | ||
1410 | operands.removeFirst(); | ||
1411 | operands.prepend(new QString(s1)); | ||
1412 | break; | ||
1413 | case 0x15://exp | ||
1414 | s1=QString("EXP(")+operands.first()->ascii()+QString(")"); | ||
1415 | operands.removeFirst(); | ||
1416 | operands.prepend(new QString(s1)); | ||
1417 | break; | ||
1418 | case 0x16://LN | ||
1419 | s1=QString("LN(")+operands.first()->ascii()+QString(")"); | ||
1420 | operands.removeFirst(); | ||
1421 | operands.prepend(new QString(s1)); | ||
1422 | break; | ||
1423 | case 0x17://LOG10 | ||
1424 | s1=QString("LOG10(")+operands.first()->ascii()+QString(")"); | ||
1425 | operands.removeFirst(); | ||
1426 | operands.prepend(new QString(s1)); | ||
1427 | break; | ||
1428 | case 0x18://ABS | ||
1429 | s1=QString("ABS(")+operands.first()->ascii()+QString(")"); | ||
1430 | operands.removeFirst(); | ||
1431 | operands.prepend(new QString(s1)); | ||
1432 | break; | ||
1433 | case 0x19://int | ||
1434 | s1=QString("INT(")+operands.first()->ascii()+QString(")"); | ||
1435 | operands.removeFirst(); | ||
1436 | operands.prepend(new QString(s1)); | ||
1437 | break; | ||
1438 | case 0x1a://sign | ||
1439 | s1=QString("SIGN(")+operands.first()->ascii()+QString(")"); | ||
1440 | operands.removeFirst(); | ||
1441 | operands.prepend(new QString(s1)); | ||
1442 | break; | ||
1443 | case 0x1b://round | ||
1444 | operands.first(); | ||
1445 | s1=QString("ROUND(")+operands.next()->ascii() | ||
1446 | +QString(",")+operands.first()->ascii() | ||
1447 | +QString(")"); | ||
1448 | operands.removeFirst();operands.removeFirst(); | ||
1449 | operands.prepend(new QString(s1)); | ||
1450 | break; | ||
1451 | case 0x1d://index | ||
1452 | operands.first(); | ||
1453 | s1=QString("INDEX(")+operands.next()->ascii() | ||
1454 | +QString(",") | ||
1455 | +operands.first()->ascii()+QString(")"); | ||
1456 | operands.removeFirst(); | ||
1457 | operands.removeFirst(); | ||
1458 | operands.prepend(new QString(s1)); | ||
1459 | break; | ||
1460 | case 0x1: // if ATTRIBUTE | ||
1461 | operands.first();operands.next(); | ||
1462 | s1=QString("IF(")+operands.next()->ascii()+QString(","); | ||
1463 | operands.first(); | ||
1464 | s1=s1+operands.next()->ascii()+QString(","); | ||
1465 | s1=s1+operands.first()->ascii()+QString(")"); | ||
1466 | operands.removeFirst(); | ||
1467 | operands.removeFirst(); | ||
1468 | operands.removeFirst(); | ||
1469 | operands.prepend(new QString(s1)); | ||
1470 | break; | ||
1471 | case 0x81://isblank | ||
1472 | s1=QString("ISBLANK(")+operands.first()->ascii() | ||
1473 | +QString(")"); | ||
1474 | operands.removeFirst(); | ||
1475 | operands.prepend(new QString(s1)); | ||
1476 | break; | ||
1477 | case 0x80://isnumber | ||
1478 | s1=QString("ISNUMBER(")+operands.first()->ascii() | ||
1479 | +QString(")"); | ||
1480 | operands.removeFirst(); | ||
1481 | operands.prepend(new QString(s1)); | ||
1482 | break; | ||
1483 | case 0x120://ceiling | ||
1484 | operands.first(); | ||
1485 | s1=QString("CEILING(")+operands.next()->ascii() | ||
1486 | +QString(",")+operands.first()->ascii() | ||
1487 | +QString(")"); | ||
1488 | operands.removeFirst();operands.removeFirst(); | ||
1489 | operands.prepend(new QString(s1)); | ||
1490 | break; | ||
1491 | case 0x11d://floor | ||
1492 | operands.first(); | ||
1493 | s1=QString("FLOOR(")+operands.next()->ascii() | ||
1494 | +QString(",")+operands.first()->ascii() | ||
1495 | +QString(")"); | ||
1496 | operands.removeFirst();operands.removeFirst(); | ||
1497 | operands.prepend(new QString(s1)); | ||
1498 | break; | ||
1499 | case 0x157://degrees | ||
1500 | s1=QString("DEGREES(")+operands.first()->ascii() | ||
1501 | +QString(")"); | ||
1502 | operands.removeFirst(); | ||
1503 | operands.prepend(new QString(s1)); | ||
1504 | break; | ||
1505 | case 0x156://radians | ||
1506 | s1=QString("RADIANS(")+operands.first()->ascii() | ||
1507 | +QString(")"); | ||
1508 | operands.removeFirst(); | ||
1509 | operands.prepend(new QString(s1)); | ||
1510 | break; | ||
1511 | case 0xb8://fact | ||
1512 | s1=QString("FACT(")+operands.first()->ascii() | ||
1513 | +QString(")"); | ||
1514 | operands.removeFirst(); | ||
1515 | operands.prepend(new QString(s1)); | ||
1516 | break; | ||
1517 | case 0x27://MOD | ||
1518 | operands.first(); | ||
1519 | s1=QString("MOD(")+operands.next()->ascii() | ||
1520 | +QString(",")+operands.first()->ascii() | ||
1521 | +QString(")"); | ||
1522 | operands.removeFirst();operands.removeFirst(); | ||
1523 | operands.prepend(new QString(s1)); | ||
1524 | break; | ||
1525 | case 0x151://power | ||
1526 | operands.first(); | ||
1527 | s1=QString("POWER(")+operands.next()->ascii() | ||
1528 | +QString(",")+operands.first()->ascii() | ||
1529 | +QString(")"); | ||
1530 | operands.removeFirst();operands.removeFirst(); | ||
1531 | operands.prepend(new QString(s1)); | ||
1532 | break; | ||
1533 | case 0x3f://rand() | ||
1534 | s1="RAND()"; | ||
1535 | operands.prepend(new QString(s1)); | ||
1536 | break; | ||
1537 | case 0x4://sum | ||
1538 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1539 | s1=QString("SUM(")+operands.first()->ascii() | ||
1540 | +QString(")"); | ||
1541 | operands.removeFirst(); | ||
1542 | operands.prepend(new QString(s1)); | ||
1543 | break; | ||
1544 | case 0x6://min | ||
1545 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1546 | s1=QString("MIN(")+operands.first()->ascii() | ||
1547 | +QString(")"); | ||
1548 | operands.removeFirst(); | ||
1549 | operands.prepend(new QString(s1)); | ||
1550 | break; | ||
1551 | case 0x7://max | ||
1552 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1553 | s1=QString("MAX(")+operands.first()->ascii() | ||
1554 | +QString(")"); | ||
1555 | operands.removeFirst(); | ||
1556 | operands.prepend(new QString(s1)); | ||
1557 | break; | ||
1558 | case 0x5://average | ||
1559 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1560 | s1=QString("AVERAGE(")+operands.first()->ascii() | ||
1561 | +QString(")"); | ||
1562 | operands.removeFirst(); | ||
1563 | operands.prepend(new QString(s1)); | ||
1564 | break; | ||
1565 | case 0x2e://var | ||
1566 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1567 | s1=QString("VAR(")+operands.first()->ascii() | ||
1568 | +QString(")"); | ||
1569 | operands.removeFirst(); | ||
1570 | operands.prepend(new QString(s1)); | ||
1571 | break; | ||
1572 | case 0xc2://varp | ||
1573 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1574 | s1=QString("VARP(")+operands.first()->ascii() | ||
1575 | +QString(")"); | ||
1576 | operands.removeFirst(); | ||
1577 | operands.prepend(new QString(s1)); | ||
1578 | break; | ||
1579 | case 0xc://stdev | ||
1580 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1581 | s1=QString("STDEV(")+operands.first()->ascii() | ||
1582 | +QString(")"); | ||
1583 | operands.removeFirst(); | ||
1584 | operands.prepend(new QString(s1)); | ||
1585 | break; | ||
1586 | case 0xc1://stdevp | ||
1587 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1588 | s1=QString("STDEVP(")+operands.first()->ascii() | ||
1589 | +QString(")"); | ||
1590 | operands.removeFirst(); | ||
1591 | operands.prepend(new QString(s1)); | ||
1592 | break; | ||
1593 | case 0x143://skew | ||
1594 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1595 | s1=QString("SKEW(")+operands.first()->ascii() | ||
1596 | +QString(")"); | ||
1597 | operands.removeFirst(); | ||
1598 | operands.prepend(new QString(s1)); | ||
1599 | break; | ||
1600 | case 0x142://kurt | ||
1601 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1602 | s1=QString("KURT(")+operands.first()->ascii() | ||
1603 | +QString(")"); | ||
1604 | operands.removeFirst(); | ||
1605 | operands.prepend(new QString(s1)); | ||
1606 | break; | ||
1607 | case 0x0://count | ||
1608 | for(w4=1;w4<w2;w4++) operands.removeFirst(); | ||
1609 | s1=QString("COUNT(")+operands.first()->ascii() | ||
1610 | +QString(")"); | ||
1611 | operands.removeFirst(); | ||
1612 | operands.prepend(new QString(s1)); | ||
1613 | break; | ||
1614 | |||
1615 | default: | ||
1616 | printf("token:FUNCTION_UNKNOWN=0x%x\r\n",w1); | ||
1617 | return QString("FUNC_UNKNOWN"); | ||
1618 | break; | ||
1619 | |||
1620 | }; | ||
1621 | |||
1622 | break; | ||
1623 | |||
1624 | default: | ||
1625 | printf("tokenUNKNOWN=0x%x\r\n",token); | ||
1626 | return QString("TOKEN_UKNOWN"); | ||
1627 | //it is dangerous to go to idx++ and not return | ||
1628 | // because the result is unexpected. | ||
1629 | // but there is a possibility the the parser will give the correct | ||
1630 | // answer, because there are some tokens in excel formulas that can be //ignored. | ||
1631 | idx++; | ||
1632 | break; | ||
1633 | }; | ||
1634 | |||
1635 | }; | ||
1636 | |||
1637 | |||
1638 | |||
1639 | printf("{////FormulaParser}\r\n"); | ||
1640 | printf("GetFormula:::::::r=%d,c=%d,,,%s\r\n",row,col,s1.ascii()); | ||
1641 | printf("\r\n"); | ||
1642 | s1=operands.first()->ascii(); | ||
1643 | operands.clear(); | ||
1644 | return QString(s1); | ||
1645 | }; | ||
1646 | |||
1647 | QString ExcelBook::FindCellName(int row, int col) | ||
1648 | { | ||
1649 | row++;col++; | ||
1650 | QString s1=""; | ||
1651 | int i1=col % 26; | ||
1652 | int i2=col / 26; | ||
1653 | if (i2!=0) s1=(char)(i2+65); //65 =A | ||
1654 | s1=s1+(char)(i1+65-1); | ||
1655 | return (s1+QString::number(row)); | ||
1656 | }; | ||
1657 | |||
1658 | |||
1659 | |||
1660 | |||
1661 | |||
1662 | |||
1663 | |||
1664 | |||
diff --git a/noncore/apps/opie-sheet/Excel.h b/noncore/apps/opie-sheet/Excel.h new file mode 100644 index 0000000..0a581cf --- a/dev/null +++ b/noncore/apps/opie-sheet/Excel.h | |||
@@ -0,0 +1,205 @@ | |||
1 | |||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <math.h> | ||
5 | #include <time.h> | ||
6 | #include <sys/types.h> | ||
7 | #include <strings.h> | ||
8 | #include <qstring.h> | ||
9 | #include <qarray.h> | ||
10 | #include <qlist.h> | ||
11 | |||
12 | #define DATEFORMAT 0x1 | ||
13 | #define NUMBERFORMAT 0x2 | ||
14 | |||
15 | #define BIFF8 0x600 | ||
16 | #define BIFF7 0x500 | ||
17 | #define WBKGLOBAL 0x5 | ||
18 | #define WRKSHEET 0x10 | ||
19 | |||
20 | #define XL_ARRAY 0x221 | ||
21 | #define XL_BOUNDSHEET 0x85 | ||
22 | #define XL_BOF 0x809 | ||
23 | #define XL_BOOLERR 0x205 | ||
24 | #define XL_CONTINUE 0x3c | ||
25 | #define XL_DIMENSION 0x200 | ||
26 | #define XL_EOF 0x0a | ||
27 | #define XL_EXTSST 0xff | ||
28 | #define XL_FORMULA 0x406 | ||
29 | #define XL_FORMULA2 0x6 | ||
30 | #define XL_FORMAT 0x41e | ||
31 | #define XL_INDEX 0x20b | ||
32 | #define XL_LABEL 0x204 | ||
33 | #define XL_LABELSST 0xfd | ||
34 | #define XL_MULRK 0xbd | ||
35 | #define XL_NAME 0x18 | ||
36 | #define XL_NOTE 0x1c | ||
37 | #define XL_NUMBER 0x203 | ||
38 | #define XL_RK 0x7e | ||
39 | #define XL_RK2 0x27e | ||
40 | #define XL_ROW 0x208 | ||
41 | #define XL_SST 0xfc | ||
42 | #define XL_STRING 0x207 | ||
43 | #define XL_TXO 0x1b6 | ||
44 | #define XL_XF 0xe0 | ||
45 | #define XL_UNKNOWN 0xffff | ||
46 | |||
47 | #define CELL_LABEL 0x2 | ||
48 | #define CELL_NUMBER 0x3 | ||
49 | #define CELL_DATE 0x4 | ||
50 | #define CELL_BOOLEAN 0x5 | ||
51 | #define CELL_ERROR 0x6 | ||
52 | |||
53 | |||
54 | |||
55 | class ExcelFormat | ||
56 | { | ||
57 | public: | ||
58 | int code; | ||
59 | int type; | ||
60 | QString format; | ||
61 | ExcelFormat(); | ||
62 | ExcelFormat(int c,int t, QString s); | ||
63 | }; | ||
64 | |||
65 | struct xfrecord | ||
66 | { | ||
67 | int code; | ||
68 | int type; | ||
69 | QString format; | ||
70 | }; | ||
71 | |||
72 | class ExcelCell | ||
73 | { | ||
74 | public: | ||
75 | int type; | ||
76 | int row,col; | ||
77 | int xfindex; //xf format index of cell | ||
78 | int valuei; | ||
79 | double valued; | ||
80 | QString valuec; | ||
81 | |||
82 | }; | ||
83 | |||
84 | class ExcelBREC | ||
85 | { | ||
86 | public: | ||
87 | int code; | ||
88 | int length; | ||
89 | int position; | ||
90 | char* data; | ||
91 | }; | ||
92 | |||
93 | class SSTList | ||
94 | { | ||
95 | public: | ||
96 | QArray <ExcelBREC*> rec; | ||
97 | }; | ||
98 | |||
99 | class ExcelSheet | ||
100 | { | ||
101 | public: | ||
102 | QString name; | ||
103 | ExcelBREC BOFRecord; | ||
104 | int position; | ||
105 | int type; | ||
106 | int rows; | ||
107 | int cols; | ||
108 | |||
109 | int cellsize,rowalloc,cellalloc; | ||
110 | QArray <ExcelCell*> Cells; | ||
111 | bool InitCells(void); // true if ok | ||
112 | ExcelCell* Get(int row, int col); | ||
113 | void Set(int row, int col, ExcelCell* cell); | ||
114 | |||
115 | }; | ||
116 | |||
117 | struct mulrk { | ||
118 | int row; | ||
119 | int first; | ||
120 | int last; | ||
121 | int numrks; | ||
122 | QArray<int> rknumbers; | ||
123 | QArray<double> rkdbls; | ||
124 | QArray<int> xfindices; | ||
125 | }; | ||
126 | |||
127 | |||
128 | |||
129 | |||
130 | class ExcelBook | ||
131 | { | ||
132 | public: | ||
133 | FILE *File; | ||
134 | int Position; | ||
135 | //int stringcount; | ||
136 | QArray <QString*> SharedStrings; | ||
137 | //int xfcount; | ||
138 | QArray <ExcelFormat*> XFRecords; | ||
139 | //int Sheetcount; | ||
140 | QArray <ExcelSheet*> Sheets; | ||
141 | //int name count; | ||
142 | QArray <QString*> Names; | ||
143 | |||
144 | QString dateformat; | ||
145 | int Version; | ||
146 | int endian; | ||
147 | int Integer2Byte(int b1, int b2 ); | ||
148 | int Integer4Byte(int b1, int b2, int b3, int b4 ); | ||
149 | int Integer2ByteFile(FILE *f); | ||
150 | float Float4Byte(int b1, int b2, int b3, int b4); | ||
151 | double Double4Byte(int b1, int b2, int b3, int b4); | ||
152 | double Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8); | ||
153 | void DetectEndian(void); | ||
154 | |||
155 | bool OpenFile(char *Filename); // true if ok | ||
156 | bool CloseFile(void); // true if ok | ||
157 | void SeekPosition(int pos); // go to Pos | ||
158 | void SeekSkip(int pos); // skips pos bytes. | ||
159 | int FileEOF(void); //returns -1 if EOF else 0 | ||
160 | int Get2Bytes(void); //gets an int from the file | ||
161 | char* Read(int pos, int length); | ||
162 | QString ReadUnicodeChar(int pos, int length); | ||
163 | QString* GetString(int num); //gets the num string from SharedStrings; | ||
164 | int SeekBOF(void); | ||
165 | ExcelBREC* GetBREC(void); | ||
166 | ExcelBREC* PeekBREC(void); | ||
167 | char* GetDataOfBREC(ExcelBREC* record); | ||
168 | void ConvertCharToArray(ExcelBREC* record, char* chars, int length); | ||
169 | int SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record); | ||
170 | int ReadSheet(ExcelSheet* sheet); //read the sheet sheet* | ||
171 | ExcelSheet* GetSheet(void); | ||
172 | void ParseSheets(void); | ||
173 | void GetSheets(void); | ||
174 | |||
175 | bool ParseBook(char *file); // THIS IS THE MAIN PARSE FUNCTION of file | ||
176 | QString GetASCII(char* inbytes, int pos, int chars); | ||
177 | QString GetUnicode(char * inbytes, int pos, int chars); | ||
178 | void HandleBoundSheet( ExcelBREC* rec); | ||
179 | void HandleName(ExcelSheet* sheet, ExcelBREC* rec); | ||
180 | ExcelFormat* GetFormatting(int xf); | ||
181 | void HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes); | ||
182 | char* MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont); | ||
183 | void HandleSST(ExcelBREC* rec); | ||
184 | void HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec); | ||
185 | ExcelCell* CellLabel(int row, int col, QString str); | ||
186 | ExcelCell* CellNumber(int row, int col, int index, double d); | ||
187 | QString* CellDataString(ExcelSheet* sh, int row, int col); | ||
188 | int CellGetPrecision(double d); | ||
189 | void CellSetDateFormat(char *d); | ||
190 | void HandleMulrk(ExcelSheet* sheet, ExcelBREC* record); | ||
191 | void MulrkRead(struct mulrk *mulrk, char* data); | ||
192 | void HandleNumber(ExcelSheet* sheet, ExcelBREC* record); | ||
193 | void HandleFormat(ExcelBREC* rec); | ||
194 | void HandleXF(ExcelBREC* rec); | ||
195 | void HandleRK(ExcelSheet* sheet, ExcelBREC* record); | ||
196 | void HandleFormula(ExcelSheet* sheet, ExcelBREC* record); | ||
197 | QString GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz); | ||
198 | QString FindCellName(int row, int col); | ||
199 | |||
200 | |||
201 | |||
202 | |||
203 | |||
204 | }; | ||
205 | |||
diff --git a/noncore/apps/opie-sheet/cell-select.xpm b/noncore/apps/opie-sheet/cell-select.xpm index 2b0ab7e..4836c02 100644 --- a/noncore/apps/opie-sheet/cell-select.xpm +++ b/noncore/apps/opie-sheet/cell-select.xpm | |||
@@ -1,23 +1,25 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * cell_select_xpm[] = { | 2 | static const char * cell_select_xpm[] = { |
3 | "16 16 4 1", | 3 | "16 16 6 1", |
4 | " c None", | 4 | "# c None", |
5 | ".c #000000", | 5 | "c c #0058c0", |
6 | "+c #FFFFFF", | 6 | ". c #585858", |
7 | "@c #BEBEBE", | 7 | "b c #58a8ff", |
8 | ". ", | 8 | "a c #a8dcff", |
9 | ". ... ", | 9 | "d c #c0ffff", |
10 | " ... .+++. ", | 10 | ".###############", |
11 | " ..+@+++. ", | 11 | ".#####...#######", |
12 | " .+++@++@. ", | 12 | "#...#.aab.######", |
13 | " .+@+++@@++. ", | 13 | "###..acaaa.#####", |
14 | " .@++@++@+++. ", | 14 | "###.aaacabc.####", |
15 | " .@@++@@+++++. ", | 15 | "##.acaaaccab.###", |
16 | " .++@+@+++++++. ", | 16 | "#.caacabbaaa.###", |
17 | " .++@++++++++. ", | 17 | "#.ccaacbaaaaa.##", |
18 | " .++@+++++++. ", | 18 | "#.bacbcaaaadaa.#", |
19 | " .++@+++++@. ", | 19 | "##.bacbaaaddda.#", |
20 | " .++@+++@+. ", | 20 | "###.bacaaaadaa.#", |
21 | " .++@@@+. ", | 21 | "####.bacaaaaac.#", |
22 | " .++++. ", | 22 | "#####.bacaaacb.#", |
23 | " .... "}; | 23 | "######.bacccb.##", |
24 | "#######.babb.###", | ||
25 | "########....####"}; | ||
diff --git a/noncore/apps/opie-sheet/excel16.xpm b/noncore/apps/opie-sheet/excel16.xpm new file mode 100644 index 0000000..45dd96d --- a/dev/null +++ b/noncore/apps/opie-sheet/excel16.xpm | |||
@@ -0,0 +1,187 @@ | |||
1 | /* XPM */ | ||
2 | static const char *excel16_xpm[]={ | ||
3 | "16 16 168 2", | ||
4 | "aL c None", | ||
5 | "Qt c None", | ||
6 | "aK c #24440a", | ||
7 | "#y c #247d21", | ||
8 | "#B c #276d1e", | ||
9 | "aw c #284a0d", | ||
10 | "au c #2b4e10", | ||
11 | "#P c #2c6e1a", | ||
12 | "ag c #2d5114", | ||
13 | "ad c #2e541a", | ||
14 | "af c #304326", | ||
15 | "#2 c #317a1c", | ||
16 | "ae c #334f25", | ||
17 | "#5 c #335919", | ||
18 | "#F c #375d1f", | ||
19 | "#O c #3a872f", | ||
20 | "#t c #3d6324", | ||
21 | "ac c #3d7939", | ||
22 | "#Y c #3e7132", | ||
23 | "#p c #407f39", | ||
24 | "#Z c #42903e", | ||
25 | "#i c #436d28", | ||
26 | ".9 c #446e2a", | ||
27 | "aJ c #466628", | ||
28 | "av c #476430", | ||
29 | "aI c #476829", | ||
30 | ".W c #47732d", | ||
31 | "#K c #479643", | ||
32 | "#1 c #48872e", | ||
33 | "aH c #496b2d", | ||
34 | ".6 c #4a8a49", | ||
35 | "aG c #4b6e31", | ||
36 | ".z c #4b7832", | ||
37 | "#L c #4d9647", | ||
38 | "aF c #4e7336", | ||
39 | "aE c #52783b", | ||
40 | ".m c #527a3e", | ||
41 | "#x c #529c4f", | ||
42 | "#N c #549c4b", | ||
43 | "aD c #567a3f", | ||
44 | "#V c #579342", | ||
45 | "#X c #588649", | ||
46 | "aC c #598041", | ||
47 | ".T c #598955", | ||
48 | "#A c #59a354", | ||
49 | "#W c #5a8f48", | ||
50 | "aB c #5d8745", | ||
51 | "ax c #5d914d", | ||
52 | "#o c #5ea657", | ||
53 | "#C c #5f8755", | ||
54 | "aA c #5f8947", | ||
55 | ".5 c #5f9f5a", | ||
56 | "#e c #60965b", | ||
57 | "#f c #609c5b", | ||
58 | "az c #618b4a", | ||
59 | ".l c #629450", | ||
60 | "ay c #679350", | ||
61 | ".k c #689854", | ||
62 | "#U c #69a15f", | ||
63 | "ah c #6c9c59", | ||
64 | "#d c #6cae66", | ||
65 | ".R c #6da767", | ||
66 | ".S c #6ea564", | ||
67 | "#n c #6eaf67", | ||
68 | ".3 c #6fad69", | ||
69 | "#0 c #6fb067", | ||
70 | ".j c #719f5f", | ||
71 | "ab c #729a6b", | ||
72 | "#6 c #72a161", | ||
73 | ".2 c #74a270", | ||
74 | "#J c #75b56d", | ||
75 | ".i c #76a366", | ||
76 | "#l c #77ae74", | ||
77 | "#M c #78b570", | ||
78 | "#I c #79b176", | ||
79 | ".4 c #79b870", | ||
80 | "#S c #7ba66b", | ||
81 | ".N c #7bb374", | ||
82 | ".h c #7da970", | ||
83 | ".1 c #7fbd76", | ||
84 | "#G c #81ab74", | ||
85 | "#c c #81bb78", | ||
86 | ".M c #83bb7b", | ||
87 | "aa c #869782", | ||
88 | ".g c #86b079", | ||
89 | "a# c #879783", | ||
90 | "a. c #889885", | ||
91 | "#u c #88b279", | ||
92 | "#9 c #899886", | ||
93 | ".U c #89b188", | ||
94 | ".L c #89c081", | ||
95 | ".O c #8ab485", | ||
96 | ".0 c #8ac381", | ||
97 | ".f c #8eb580", | ||
98 | "#j c #8eb680", | ||
99 | ".y c #91a483", | ||
100 | "#m c #91c28a", | ||
101 | "#. c #92b885", | ||
102 | "#8 c #93ae91", | ||
103 | ".e c #93ba87", | ||
104 | "#3 c #93be91", | ||
105 | "at c #94a089", | ||
106 | "#4 c #96a18b", | ||
107 | "#z c #96c78d", | ||
108 | ".# c #97bc8a", | ||
109 | "#D c #99b598", | ||
110 | "#Q c #9abb99", | ||
111 | "#R c #9ba890", | ||
112 | ".d c #9bbf90", | ||
113 | "#E c #9ca991", | ||
114 | "#s c #9ca992", | ||
115 | "#b c #9dc895", | ||
116 | "#h c #9fac95", | ||
117 | ".c c #9fc294", | ||
118 | "#a c #a0c99b", | ||
119 | ".8 c #a2b198", | ||
120 | ".V c #a3b199", | ||
121 | ".b c #a4c699", | ||
122 | ".K c #a5b29b", | ||
123 | ".Z c #a6cf9f", | ||
124 | ".Y c #a7cda1", | ||
125 | ".a c #a9c99e", | ||
126 | ".n c #acc4a3", | ||
127 | ".x c #b2c3aa", | ||
128 | "ai c #b4c4ab", | ||
129 | ".w c #b6c7ad", | ||
130 | "#7 c #b7c7ae", | ||
131 | ".v c #b9cab1", | ||
132 | "#T c #bbcab3", | ||
133 | ".u c #bbcbb3", | ||
134 | ".Q c #bbd0ba", | ||
135 | "#H c #bccbb4", | ||
136 | ".t c #beceb7", | ||
137 | ".s c #c0d1ba", | ||
138 | "#k c #c1d1bb", | ||
139 | ".r c #c2d1bc", | ||
140 | "## c #c2d2bc", | ||
141 | ".X c #c4d5be", | ||
142 | ".q c #c6d9c1", | ||
143 | ".p c #c8d9c2", | ||
144 | ".o c #c9dac3", | ||
145 | "#q c #cdddcd", | ||
146 | "as c #d3e3d3", | ||
147 | "ar c #d4e4d4", | ||
148 | "aq c #d7e6d7", | ||
149 | "ap c #d8e7d9", | ||
150 | "ao c #dae9db", | ||
151 | ".7 c #dce8db", | ||
152 | "#r c #dce9dc", | ||
153 | "an c #ddebdd", | ||
154 | "#g c #dfecdf", | ||
155 | "am c #e1ede0", | ||
156 | "al c #e3ede3", | ||
157 | "#w c #e5efe5", | ||
158 | "ak c #e6efe6", | ||
159 | ".J c #e7f0e7", | ||
160 | "aj c #e8f0e8", | ||
161 | ".I c #eaf2ea", | ||
162 | ".P c #ebf3eb", | ||
163 | ".H c #ecf4ec", | ||
164 | ".G c #f0f5f0", | ||
165 | ".F c #f2f7f2", | ||
166 | "#v c #f3f7f3", | ||
167 | ".E c #f4f8f4", | ||
168 | ".D c #f7f9f6", | ||
169 | ".C c #f9fbf8", | ||
170 | ".B c #fafcfa", | ||
171 | ".A c #fcfdfc", | ||
172 | "QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt", | ||
173 | "Qt.#.a.b.c.d.e.f.g.h.i.j.k.l.mQt", | ||
174 | "Qt.a.n.o.p.q.r.s.t.u.v.w.x.y.zQt", | ||
175 | "Qt.b.o.A.B.C.D.E.F.G.H.I.J.K.zQt", | ||
176 | "Qt.c.p.L.M.N.O.P.Q.R.S.T.U.V.WQt", | ||
177 | "Qt.d.X.Y.Z.0.1.2.3.4.5.6.7.8.9Qt", | ||
178 | "Qt#.##.D#a#b#c#d#e#f.6.7#g#h#iQt", | ||
179 | "Qt#j#k.E.F#l#m#n#o#p#q#g#r#s#tQt", | ||
180 | "Qt#u.s#v#w#x#y#z#A#A#B#C#D#E#FQt", | ||
181 | "Qt#G#H.P#I#J#K#L#M#N#O#P#Q#R#FQt", | ||
182 | "Qt#S#T#U#V#W#X#Y#Z#0#1#2#3#4#5Qt", | ||
183 | "Qt#6#7#8#9a.a#aaabacadaeaf#4agQt", | ||
184 | "QtahaiajakalamanaoapaqarasatauQt", | ||
185 | "Qt.kavavavavavavavavavavavavawQt", | ||
186 | "QtaxayazaAaBaCaDaEaFaGaHaIaJaKQt", | ||
187 | "aLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaL"}; | ||
diff --git a/noncore/apps/opie-sheet/func-comma.xpm b/noncore/apps/opie-sheet/func-comma.xpm index 3b2bbf9..2e680d2 100644 --- a/noncore/apps/opie-sheet/func-comma.xpm +++ b/noncore/apps/opie-sheet/func-comma.xpm | |||
@@ -1,21 +1,24 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_comma_xpm[] = { | 2 | static const char * func_comma_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 5 1", |
4 | " c None", | 4 | ". c None", |
5 | ".c #000000", | 5 | "# c #000000", |
6 | " ", | 6 | "a c #0000ff", |
7 | " ", | 7 | "b c #0058c0", |
8 | " ", | 8 | "c c #0080ff", |
9 | " ... ", | 9 | "................", |
10 | " ..... ", | 10 | "................", |
11 | " ...... ", | 11 | "................", |
12 | " ...... ", | 12 | "......###.......", |
13 | " ..... ", | 13 | ".....#aaa#......", |
14 | " .. ", | 14 | ".....#bcca#.....", |
15 | " . ", | 15 | ".....#bbaa#.....", |
16 | " .. ", | 16 | "......##ba#.....", |
17 | " .. ", | 17 | "........#b#.....", |
18 | " . ", | 18 | "........#b#.....", |
19 | " ", | 19 | ".......#b#......", |
20 | " ", | 20 | "......#b#.......", |
21 | " "}; | 21 | "......##........", |
22 | "................", | ||
23 | "................", | ||
24 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/func-cross.xpm b/noncore/apps/opie-sheet/func-cross.xpm index 6f77502..3b3f3d5 100644 --- a/noncore/apps/opie-sheet/func-cross.xpm +++ b/noncore/apps/opie-sheet/func-cross.xpm | |||
@@ -1,21 +1,23 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_cross_xpm[] = { | 2 | static const char * func_cross_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 4 1", |
4 | " c None", | 4 | ". c None", |
5 | ".c #000000", | 5 | "b c #0000ff", |
6 | " ", | 6 | "a c #0058c0", |
7 | " ", | 7 | "# c #585858", |
8 | " ", | 8 | "................", |
9 | " .. ", | 9 | "................", |
10 | " .. ", | 10 | "....#......##...", |
11 | " .. ", | 11 | "...#a#....#ab#..", |
12 | " ... .. ... ", | 12 | "..#bba#..#abb#..", |
13 | " .......... ", | 13 | "...#bba##abb#...", |
14 | " ...... ", | 14 | "....#bbaabb#....", |
15 | " .... ", | 15 | ".....#bbbb#.....", |
16 | " ...... ", | 16 | ".....#bbbb#.....", |
17 | " ... ... ", | 17 | "....#bbaabb#....", |
18 | " . . ", | 18 | "...#bba##abb#...", |
19 | " ", | 19 | "..#bba#..#abb#..", |
20 | " ", | 20 | "..#ba#....#a#...", |
21 | " "}; | 21 | "...##......#....", |
22 | "................", | ||
23 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/func-divide.xpm b/noncore/apps/opie-sheet/func-divide.xpm index 1ac6a07..beb3473 100644 --- a/noncore/apps/opie-sheet/func-divide.xpm +++ b/noncore/apps/opie-sheet/func-divide.xpm | |||
@@ -1,21 +1,23 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_divide_xpm[] = { | 2 | static const char * func_divide_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 4 1", |
4 | " c None", | 4 | ". c None", |
5 | ".c #000000", | 5 | "# c #000000", |
6 | " ", | 6 | "b c #0000ff", |
7 | " ", | 7 | "a c #0058c0", |
8 | " .. ", | 8 | "................", |
9 | " .. ", | 9 | "................", |
10 | " .. ", | 10 | "...........##...", |
11 | " .. ", | 11 | "..........#ab#..", |
12 | " .. ", | 12 | ".........#aba#..", |
13 | " .. ", | 13 | "........#bba#...", |
14 | " .. ", | 14 | ".......#bba#....", |
15 | " .. ", | 15 | "......#bba#.....", |
16 | " .. ", | 16 | ".....#abb#......", |
17 | " .. ", | 17 | "....#abb#.......", |
18 | " .. ", | 18 | "...#abb#........", |
19 | " .. ", | 19 | "..#aba#.........", |
20 | " .. ", | 20 | "..#ba#..........", |
21 | " "}; | 21 | "...##...........", |
22 | "................", | ||
23 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/func-equal.xpm b/noncore/apps/opie-sheet/func-equal.xpm index 60f8710..8f34895 100644 --- a/noncore/apps/opie-sheet/func-equal.xpm +++ b/noncore/apps/opie-sheet/func-equal.xpm | |||
@@ -1,21 +1,23 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_equal_xpm[] = { | 2 | static const char * func_equal_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 4 1", |
4 | " c None", | 4 | ". c None", |
5 | ".c #000000", | 5 | "b c #0000ff", |
6 | " ", | 6 | "a c #0058c0", |
7 | " ", | 7 | "# c #585858", |
8 | " ", | 8 | "................", |
9 | " ", | 9 | "................", |
10 | " ", | 10 | "................", |
11 | " .......... ", | 11 | "...##########...", |
12 | " .......... ", | 12 | "..#aaabbbbaaa#..", |
13 | " ", | 13 | "..#bbbbbbbbbb#..", |
14 | " ", | 14 | "..############..", |
15 | " .......... ", | 15 | "................", |
16 | " .......... ", | 16 | "................", |
17 | " ", | 17 | "..############..", |
18 | " ", | 18 | "..#bbbbbbbbbb#..", |
19 | " ", | 19 | "..#aaabbbbaaa#..", |
20 | " ", | 20 | "...##########...", |
21 | " "}; | 21 | "................", |
22 | "................", | ||
23 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/func-func.xpm b/noncore/apps/opie-sheet/func-func.xpm index c1f7852..b9ec747 100644 --- a/noncore/apps/opie-sheet/func-func.xpm +++ b/noncore/apps/opie-sheet/func-func.xpm | |||
@@ -1,21 +1,23 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_func_xpm[] = { | 2 | static const char * func_func_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 4 1", |
4 | " c None", | 4 | ". c None", |
5 | ".c #000000", | 5 | "a c #0000ff", |
6 | " ", | 6 | "b c #0058c0", |
7 | " .. ", | 7 | "# c #585858", |
8 | " .. ", | 8 | "................", |
9 | " . ", | 9 | ".........#ab....", |
10 | " . ", | 10 | ".......#aa##....", |
11 | " . ", | 11 | ".......ab#......", |
12 | " ..... ", | 12 | ".......ab#......", |
13 | " . ", | 13 | "......#a#.......", |
14 | " . . . ", | 14 | "....#aaaa#......", |
15 | " . . . ", | 15 | "....bbabbb......", |
16 | " . . ", | 16 | "....##ab#a#.ba..", |
17 | " . . . ", | 17 | ".....aa##baba#..", |
18 | " . . . ", | 18 | ".....ab#.#ba#...", |
19 | " . ", | 19 | ".....ab#.baba...", |
20 | " . ", | 20 | "....#a#.ba##ba..", |
21 | " "}; | 21 | "....ab#..#..#b..", |
22 | "...#a#..........", | ||
23 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/func-minus.xpm b/noncore/apps/opie-sheet/func-minus.xpm index fa2cb4f..b747bd7 100644 --- a/noncore/apps/opie-sheet/func-minus.xpm +++ b/noncore/apps/opie-sheet/func-minus.xpm | |||
@@ -1,21 +1,23 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_minus_xpm[] = { | 2 | static const char * func_minus_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 4 1", |
4 | " c None", | 4 | ". c None", |
5 | ".c #000000", | 5 | "a c #0000ff", |
6 | " ", | 6 | "b c #0058c0", |
7 | " ", | 7 | "# c #585858", |
8 | " ", | 8 | "................", |
9 | " ", | 9 | "................", |
10 | " ", | 10 | "................", |
11 | " ", | 11 | "................", |
12 | " ", | 12 | "................", |
13 | " ....... ", | 13 | "................", |
14 | " ....... ", | 14 | "...##########...", |
15 | " ", | 15 | "...#aaaaaabb#...", |
16 | " ", | 16 | "...#bbaaaaaa#...", |
17 | " ", | 17 | "...##########...", |
18 | " ", | 18 | "................", |
19 | " ", | 19 | "................", |
20 | " ", | 20 | "................", |
21 | " "}; | 21 | "................", |
22 | "................", | ||
23 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/func-paran-close.xpm b/noncore/apps/opie-sheet/func-paran-close.xpm index 85191d5..1e9994c 100644 --- a/noncore/apps/opie-sheet/func-paran-close.xpm +++ b/noncore/apps/opie-sheet/func-paran-close.xpm | |||
@@ -1,21 +1,24 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_paran_close_xpm[] = { | 2 | static const char * func_paran_close_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 5 1", |
4 | " c None", | 4 | "c c None", |
5 | ".c #000000", | 5 | ". c None", |
6 | " ", | 6 | "b c #0000ff", |
7 | " . ", | 7 | "# c #0058c0", |
8 | " .. ", | 8 | "a c #585858", |
9 | " . ", | 9 | "......#a........", |
10 | " .. ", | 10 | "......#baa......", |
11 | " .. ", | 11 | ".......#bba.....", |
12 | " .. ", | 12 | "........#b#.....", |
13 | " .. ", | 13 | "........c##a....", |
14 | " .. ", | 14 | "........c#ba....", |
15 | " .. ", | 15 | "........c#ba....", |
16 | " .. ", | 16 | "........c#ba....", |
17 | " . ", | 17 | "........c#ba....", |
18 | " .. ", | 18 | "........c#ba....", |
19 | " . ", | 19 | "........#b#a....", |
20 | " ", | 20 | ".......abb#.....", |
21 | " "}; | 21 | ".......#bba.....", |
22 | "......#baa......", | ||
23 | "......#a........", | ||
24 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/func-paran-open.xpm b/noncore/apps/opie-sheet/func-paran-open.xpm index 3c7870b..ace24b0 100644 --- a/noncore/apps/opie-sheet/func-paran-open.xpm +++ b/noncore/apps/opie-sheet/func-paran-open.xpm | |||
@@ -1,21 +1,24 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_paran_open_xpm[] = { | 2 | static const char * func_paran_open_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 5 1", |
4 | " c None", | 4 | "c c None", |
5 | ".c #000000", | 5 | ". c None", |
6 | " ", | 6 | "b c #0000ff", |
7 | " . ", | 7 | "a c #0058c0", |
8 | " .. ", | 8 | "# c #585858", |
9 | " . ", | 9 | "........#a......", |
10 | " .. ", | 10 | "......##ba......", |
11 | " .. ", | 11 | ".....#bba.......", |
12 | " .. ", | 12 | ".....aba........", |
13 | " .. ", | 13 | "....#aacc.......", |
14 | " .. ", | 14 | "....#bacc.......", |
15 | " .. ", | 15 | "....#bacc.......", |
16 | " .. ", | 16 | "....#bacc.......", |
17 | " . ", | 17 | "....#bac........", |
18 | " .. ", | 18 | "....#bac........", |
19 | " . ", | 19 | "....#aac........", |
20 | " ", | 20 | ".....abbc.......", |
21 | " "}; | 21 | ".....#bba.......", |
22 | "......##bac.....", | ||
23 | "........#ac.....", | ||
24 | "..........c....."}; | ||
diff --git a/noncore/apps/opie-sheet/func-plus.xpm b/noncore/apps/opie-sheet/func-plus.xpm index a917c64..c779f23 100644 --- a/noncore/apps/opie-sheet/func-plus.xpm +++ b/noncore/apps/opie-sheet/func-plus.xpm | |||
@@ -1,21 +1,23 @@ | |||
1 | /* XPM */ | 1 | /* XPM */ |
2 | static const char * func_plus_xpm[] = { | 2 | static const char * func_plus_xpm[] = { |
3 | "16 16 2 1", | 3 | "16 16 4 1", |
4 | " c None", | 4 | ". c None", |
5 | ".c #000000", | 5 | "a c #0000ff", |
6 | " ", | 6 | "b c #0058c0", |
7 | " ", | 7 | "# c #585858", |
8 | " .. ", | 8 | "................", |
9 | " .. ", | 9 | "................", |
10 | " .. ", | 10 | "......####......", |
11 | " .. ", | 11 | "......#ab#......", |
12 | " .. ", | 12 | "......#ab#......", |
13 | " ............ ", | 13 | "......#ab#......", |
14 | " ............ ", | 14 | "..####babb####..", |
15 | " .. ", | 15 | "..#aaaaaabbbb#..", |
16 | " .. ", | 16 | "..#bbbbaaaaaa#..", |
17 | " .. ", | 17 | "..####bbab####..", |
18 | " .. ", | 18 | "......#ba#......", |
19 | " .. ", | 19 | "......#ba#......", |
20 | " ", | 20 | "......#ba#......", |
21 | " "}; | 21 | "......####......", |
22 | "................", | ||
23 | "................"}; | ||
diff --git a/noncore/apps/opie-sheet/mainwindow.cpp b/noncore/apps/opie-sheet/mainwindow.cpp index 78b3073..a725e31 100644 --- a/noncore/apps/opie-sheet/mainwindow.cpp +++ b/noncore/apps/opie-sheet/mainwindow.cpp | |||
@@ -38,8 +38,9 @@ | |||
38 | #include "func-func.xpm" | 38 | #include "func-func.xpm" |
39 | #include "func-equal.xpm" | 39 | #include "func-equal.xpm" |
40 | #include "cell-select.xpm" | 40 | #include "cell-select.xpm" |
41 | #include "excel16.xpm" | ||
41 | 42 | ||
42 | #define DEFAULT_NUM_ROWS 199 | 43 | #define DEFAULT_NUM_ROWS 300 |
43 | #define DEFAULT_NUM_COLS (26*3) | 44 | #define DEFAULT_NUM_COLS (26*3) |
44 | #define DEFAULT_NUM_SHEETS 3 | 45 | #define DEFAULT_NUM_SHEETS 3 |
45 | 46 | ||
@@ -52,9 +53,13 @@ MainWindow::MainWindow(QWidget *parent, const char* n, WFlags fl) | |||
52 | // construct objects | 53 | // construct objects |
53 | currentDoc=0; | 54 | currentDoc=0; |
54 | fileSelector=new FileSelector("application/sheet-qt", this, QString::null); | 55 | fileSelector=new FileSelector("application/sheet-qt", this, QString::null); |
56 | ExcelSelector=new FileSelector("application/excel",this,QString::null,FALSE); | ||
55 | connect(fileSelector, SIGNAL(closeMe()), this, SLOT(selectorHide())); | 57 | connect(fileSelector, SIGNAL(closeMe()), this, SLOT(selectorHide())); |
56 | connect(fileSelector, SIGNAL(newSelected(const DocLnk &)), this, SLOT(selectorFileNew(const DocLnk &))); | 58 | connect(fileSelector, SIGNAL(newSelected(const DocLnk &)), this, SLOT(selectorFileNew(const DocLnk &))); |
57 | connect(fileSelector, SIGNAL(fileSelected(const DocLnk &)), this, SLOT(selectorFileOpen(const DocLnk &))); | 59 | connect(fileSelector, SIGNAL(fileSelected(const DocLnk &)), this, SLOT(selectorFileOpen(const DocLnk &))); |
60 | connect(ExcelSelector,SIGNAL(fileSelected(const DocLnk &)),this,SLOT(slotImportExcel(const DocLnk &))); | ||
61 | connect(ExcelSelector,SIGNAL(closeMe()), this, SLOT(ExcelSelectorHide())); | ||
62 | |||
58 | 63 | ||
59 | listSheets.setAutoDelete(TRUE); | 64 | listSheets.setAutoDelete(TRUE); |
60 | 65 | ||
@@ -217,7 +222,7 @@ void MainWindow::selectorFileOpen(const DocLnk &lnkDoc) | |||
217 | 222 | ||
218 | if (documentModified && saveCurrentFile()==QMessageBox::Cancel) return; | 223 | if (documentModified && saveCurrentFile()==QMessageBox::Cancel) return; |
219 | if (currentDoc) delete currentDoc; | 224 | if (currentDoc) delete currentDoc; |
220 | currentDoc = new DocLnk(lnkDoc); | 225 | currentDoc = new DocLnk(); |
221 | listSheets.clear(); | 226 | listSheets.clear(); |
222 | comboSheets->clear(); | 227 | comboSheets->clear(); |
223 | 228 | ||
@@ -250,6 +255,21 @@ void MainWindow::slotFileOpen() | |||
250 | selectorShow(); | 255 | selectorShow(); |
251 | } | 256 | } |
252 | 257 | ||
258 | void MainWindow::slotImportExcelOpen() | ||
259 | { | ||
260 | sheet->hide(); | ||
261 | setCentralWidget(ExcelSelector); | ||
262 | ExcelSelector->show(); | ||
263 | ExcelSelector->reread(); | ||
264 | } | ||
265 | |||
266 | void MainWindow::ExcelSelectorHide() | ||
267 | { | ||
268 | ExcelSelector->hide(); | ||
269 | setCentralWidget(sheet); | ||
270 | sheet->show(); | ||
271 | } | ||
272 | |||
253 | void MainWindow::slotFileSave() | 273 | void MainWindow::slotFileSave() |
254 | { | 274 | { |
255 | saveCurrentFile(FALSE); | 275 | saveCurrentFile(FALSE); |
@@ -270,8 +290,11 @@ void MainWindow::initActions() | |||
270 | connect(fileSave, SIGNAL(activated()), this, SLOT(slotFileSave())); | 290 | connect(fileSave, SIGNAL(activated()), this, SLOT(slotFileSave())); |
271 | fileSaveAs=new QAction(tr("Save File As"), Resource::loadPixmap( "save" ), tr("Save &As"), 0, this); | 291 | fileSaveAs=new QAction(tr("Save File As"), Resource::loadPixmap( "save" ), tr("Save &As"), 0, this); |
272 | connect(fileSaveAs, SIGNAL(activated()), this, SLOT(slotFileSaveAs())); | 292 | connect(fileSaveAs, SIGNAL(activated()), this, SLOT(slotFileSaveAs())); |
293 | |||
273 | //fileQuit=new QAction(tr("Quit"), tr("&Quit"), 0, this); | 294 | //fileQuit=new QAction(tr("Quit"), tr("&Quit"), 0, this); |
274 | //connect(fileQuit, SIGNAL(activated()), this, SLOT(close())); | 295 | //connect(fileQuit, SIGNAL(activated()), this, SLOT(close())); |
296 | fileExcelImport=new QAction(tr("Import Excel file"),QPixmap(excel16_xpm),tr("Import E&xcel file"),0,this); | ||
297 | connect(fileExcelImport, SIGNAL(activated()), this, SLOT(slotImportExcelOpen())); | ||
275 | 298 | ||
276 | // helpGeneral=new QAction(tr("General Help"), QPixmap(help_general_xpm), tr("&General"), 0, this); | 299 | // helpGeneral=new QAction(tr("General Help"), QPixmap(help_general_xpm), tr("&General"), 0, this); |
277 | //connect(helpGeneral, SIGNAL(activated()), this, SLOT(slotHelpGeneral())); | 300 | //connect(helpGeneral, SIGNAL(activated()), this, SLOT(slotHelpGeneral())); |
@@ -370,6 +393,8 @@ void MainWindow::initMenu() | |||
370 | fileSaveAs->addTo(menuFile); | 393 | fileSaveAs->addTo(menuFile); |
371 | // menuFile->insertSeparator(); | 394 | // menuFile->insertSeparator(); |
372 | // fileQuit->addTo(menuFile); | 395 | // fileQuit->addTo(menuFile); |
396 | menuFile->insertSeparator(); | ||
397 | fileExcelImport->addTo(menuFile); | ||
373 | menu->insertItem(tr("&File"), menuFile); | 398 | menu->insertItem(tr("&File"), menuFile); |
374 | 399 | ||
375 | menuEdit=new QPopupMenu; | 400 | menuEdit=new QPopupMenu; |
@@ -428,31 +453,127 @@ void MainWindow::initMenu() | |||
428 | funcMinus->addTo(submenuFuncStd); | 453 | funcMinus->addTo(submenuFuncStd); |
429 | funcCross->addTo(submenuFuncStd); | 454 | funcCross->addTo(submenuFuncStd); |
430 | funcDivide->addTo(submenuFuncStd); | 455 | funcDivide->addTo(submenuFuncStd); |
431 | submenuFunc->insertItem(tr("&Standard"), submenuFuncStd); | 456 | submenuFunc->insertItem(tr("&Simple"), submenuFuncStd); |
432 | 457 | ||
433 | submenuFuncMath=new QPopupMenu; | 458 | |
434 | addFlyAction(tr("Summation"), tr("&Summation"), "SUM(", submenuFuncMath); | 459 | |
435 | addFlyAction(tr("Absolute Value"), tr("&Absolute"), "ABS(", submenuFuncMath); | 460 | submenuFuncStandard=new QPopupMenu; |
436 | submenuFuncMath->insertSeparator(); | 461 | addFlyAction(tr("ABS(x)"), tr("ABS(x)"), "ABS(", submenuFuncStandard); |
437 | addFlyAction(tr("Sine"), tr("Si&ne"), "SIN(", submenuFuncMath); | 462 | addFlyAction(tr("CEILING(x,acc)"), tr("CEILING(x,acc)"), "CEILING(", submenuFuncStandard); |
438 | addFlyAction(tr("Arc Sine"), tr("A&rc Sine"), "ASIN(", submenuFuncMath); | 463 | addFlyAction(tr("FACT(x)"), tr("FACT(x)"), "FACT(", submenuFuncStandard); |
439 | addFlyAction(tr("Cosine"), tr("&Cosine"), "COS(", submenuFuncMath); | 464 | addFlyAction(tr("FLOOR(x,acc)"), tr("FLOOR(x,acc)"), "FLOOR(", submenuFuncStandard); |
440 | addFlyAction(tr("ArcCosine"), tr("Arc Cos&ine"), "COS(", submenuFuncMath); | 465 | addFlyAction(tr("INT(x)"), tr("INT(x)"), "INT(", submenuFuncStandard); |
441 | addFlyAction(tr("Tangent"), tr("&Tangent"), "TAN(", submenuFuncMath); | 466 | addFlyAction(tr("MOD(x,y)"), tr("MOD(x,y)"), "MOD(", submenuFuncStandard); |
442 | addFlyAction(tr("Arc Tangent"), tr("Arc Tan&gent"), "ATAN(", submenuFuncMath); | 467 | addFlyAction(tr("ROUND(x,digits)"), tr("ROUND(x,digits)"), "ROUND(", submenuFuncStandard); |
443 | addFlyAction(tr("Arc Tangent of Coordinates"), tr("C&oor. Arc Tangent"), "ATAN2(", submenuFuncMath); | 468 | addFlyAction(tr("SIGN(x)"), tr("SIGN(x)"), "SIGN(", submenuFuncStandard); |
444 | submenuFuncMath->insertSeparator(); | 469 | submenuFuncStandard->insertSeparator(); |
445 | addFlyAction(tr("Exponential"), tr("&Exponential"), "EXP(", submenuFuncMath); | 470 | addFlyAction(tr("EXP(x)"), tr("EXP(x)"), "EXP(", submenuFuncStandard); |
446 | addFlyAction(tr("Logarithm"), tr("&Logarithm"), "LOG(", submenuFuncMath); | 471 | addFlyAction(tr("LN(x)"), tr("LN(x)"), "LN(", submenuFuncStandard); |
447 | addFlyAction(tr("Power"), tr("&Power"), "POW(", submenuFuncMath); | 472 | addFlyAction(tr("LOG(x,b)"), tr("LOG(x,b)"), "LOG(", submenuFuncStandard); |
448 | submenuFunc->insertItem(tr("&Mathematical"), submenuFuncMath); | 473 | addFlyAction(tr("LOG10(x)"), tr("LOG10(x)"), "LOG10(", submenuFuncStandard); |
474 | addFlyAction(tr("POWER(x,y)"), tr("POWER(x,y)"), "POWER(", submenuFuncStandard); | ||
475 | addFlyAction(tr("SQRT(x)"), tr("SQRT(x)"), "SQRT(", submenuFuncStandard); | ||
476 | submenuFuncStandard->insertSeparator(); | ||
477 | addFlyAction(tr("DEGREES(x)"), tr("DEGREES(x)"), "DEGREES(", submenuFuncStandard); | ||
478 | addFlyAction(tr("RADIANS(x)"), tr("RADIANS(x)"), "RADIANS(", submenuFuncStandard); | ||
479 | addFlyAction(tr("PI()"), tr("PI()"), "PI()", submenuFuncStandard); | ||
480 | addFlyAction(tr("RAND()"), tr("RAND()"), "RAND(", submenuFuncStandard); | ||
481 | addFlyAction(tr("RANDBETWEEN(a,b)"), tr("RANDBETWEEN(a,b)"), "RANDBETWEEN(", submenuFuncStandard); | ||
482 | submenuFunc->insertItem(tr("S&tandard"), submenuFuncStandard); | ||
483 | |||
484 | submenuFuncLogic=new QPopupMenu; | ||
485 | addFlyAction(tr("AND(x1,x2)"), tr("AND(x1,x2)"), "AND(", submenuFuncLogic); | ||
486 | addFlyAction(tr("NOT(x)"), tr("NOT(x)"), "NOT(", submenuFuncLogic); | ||
487 | addFlyAction(tr("OR(x1,x2)"), tr("OR(x1,x2)"), "OR(", submenuFuncLogic); | ||
488 | submenuFuncLogic->insertSeparator(); | ||
489 | addFlyAction(tr("IF(compare,val1,val2)"), tr("IF(compare,val1,val2)"), "IF(", submenuFuncLogic); | ||
490 | addFlyAction(tr("INDEX(range,index)"),tr("INDEX(range,index)"), "INDEX(", submenuFuncLogic); | ||
491 | addFlyAction(tr("ISBLANK(x)"), tr("ISBLANK(x)"), "ISBLANK(", submenuFuncLogic); | ||
492 | addFlyAction(tr("ISNUMBER(x)"), tr("ISNUMBER(x)"), "ISNUMBER(", submenuFuncLogic); | ||
493 | addFlyAction(tr("EVEN(x)"), tr("EVEN(x)"), "EVEN(", submenuFuncLogic); | ||
494 | addFlyAction(tr("ISEVEN(x)"), tr("ISEVEN(x)"), "ISEVEN(", submenuFuncLogic); | ||
495 | addFlyAction(tr("ODD(x)"), tr("ODD(x)"), "ODD(", submenuFuncLogic); | ||
496 | addFlyAction(tr("ISODD(x)"), tr("ISODD(x)"), "ISODD(", submenuFuncLogic); | ||
497 | submenuFunc->insertItem(tr("Logical-&Information"), submenuFuncLogic); | ||
498 | |||
499 | submenuFuncTrig=new QPopupMenu; | ||
500 | addFlyAction(tr("SIN(x)"), tr("SIN(x)"), "SIN(", submenuFuncTrig); | ||
501 | addFlyAction(tr("COS(x)"), tr("COS(x)"), "COS(", submenuFuncTrig); | ||
502 | addFlyAction(tr("TAN(x)"), tr("TAN(x)"), "TAN(", submenuFuncTrig); | ||
503 | addFlyAction(tr("ASIN(x)"), tr("ASIN(x)"), "ASIN(", submenuFuncTrig); | ||
504 | addFlyAction(tr("ACOS(x)"), tr("ACOS(x)"), "ACOS(", submenuFuncTrig); | ||
505 | addFlyAction(tr("ATAN(x)"), tr("ATAN(x)"), "ATAN(", submenuFuncTrig); | ||
506 | addFlyAction(tr("ATAN2(x,y)"), tr("ATAN2(x,y)"), "ATAN2(", submenuFuncTrig); | ||
507 | submenuFuncTrig->insertSeparator(); | ||
508 | addFlyAction(tr("SINH(x)"), tr("SINH(x)"), "SINH(", submenuFuncTrig); | ||
509 | addFlyAction(tr("COSH(x)"), tr("COSH(x)"), "COSH(", submenuFuncTrig); | ||
510 | addFlyAction(tr("TANH(x)"), tr("TANH(x)"), "TANH(", submenuFuncTrig); | ||
511 | addFlyAction(tr("ACOSH(x)"), tr("ACOSH(x)"), "ACOSH(", submenuFuncTrig); | ||
512 | addFlyAction(tr("ASINH(x)"), tr("ASINH(x)"), "ASINH(", submenuFuncTrig); | ||
513 | addFlyAction(tr("ATANH(x)"), tr("ATANH(x)"), "ATANH(", submenuFuncTrig); | ||
514 | submenuFunc->insertItem(tr("&Trigonometric"), submenuFuncTrig); | ||
515 | |||
516 | submenuFuncString=new QPopupMenu; | ||
517 | addFlyAction(tr("LEN(s)"), tr("LEN(s)"), "LEN(",submenuFuncString); | ||
518 | addFlyAction(tr("LEFT(s,num)"), tr("LEFT(s,num)"), "LEFT(",submenuFuncString); | ||
519 | addFlyAction(tr("RIGHT(s,num)"), tr("RIGHT(s,num)"), "RIGHT(",submenuFuncString); | ||
520 | addFlyAction(tr("MID(s,pos,len)"), tr("MID(s,pos,len)"), "MID(",submenuFuncString); | ||
521 | submenuFuncString->insertSeparator(); | ||
522 | addFlyAction(tr("CONCATENATE(s1,s2..)"), tr("CONCATENATE(s1,s2..)"), "CONCATENATE(",submenuFuncString); | ||
523 | addFlyAction(tr("EXACT(s1,s2)"), tr("EXACT(s1,s2)"), "EXACT(",submenuFuncString); | ||
524 | addFlyAction(tr("FIND(what,where,pos)"), | ||
525 | tr("FIND(what,where,pos)"), "FIND(",submenuFuncString); | ||
526 | addFlyAction(tr("REPLACE(s,pos,len,ns)"), tr("REPLACE(s,pos,len,ns)"), "REPLACE(",submenuFuncString); | ||
527 | addFlyAction(tr("REPT(s,n)"), tr("REPT(s,n)"), "REPT(",submenuFuncString); | ||
528 | submenuFuncString->insertSeparator(); | ||
529 | addFlyAction(tr("UPPER(s)"), tr("UPPER(s)"), "UPPER(",submenuFuncString); | ||
530 | addFlyAction(tr("LOWER(s)"), tr("LOWER(s)"), "LOWER(",submenuFuncString); | ||
531 | submenuFunc->insertItem(tr("&Strings"), submenuFuncString); | ||
449 | 532 | ||
450 | submenuFuncStat=new QPopupMenu; | 533 | submenuFuncStat=new QPopupMenu; |
451 | addFlyAction(tr("Average"), tr("&Average"), "AVG(", submenuFuncStat); | 534 | addFlyAction(tr("AVERAGE(range)"), tr("AVERAGE(range)"), "AVERAGE(",submenuFuncStat); |
452 | addFlyAction(tr("Maximum"), tr("Ma&ximum"), "MAX(", submenuFuncStat); | 535 | addFlyAction(tr("COUNT(range)"), tr("COUNT(range)"), "COUNT(",submenuFuncStat); |
453 | addFlyAction(tr("Minimum"), tr("&Minimum"), "MIN(", submenuFuncStat); | 536 | addFlyAction(tr("COUNTIF(range,eqls)"), tr("COUNTIF(range,eqls)"), "COUNTIF(",submenuFuncStat); |
454 | addFlyAction(tr("Count"), tr("&Count"), "COUNT(", submenuFuncStat); | 537 | addFlyAction(tr("MAX(range)"), tr("MAX(range)"), "MAX(",submenuFuncStat); |
455 | submenuFunc->insertItem(tr("&Statistical"), submenuFuncStat); | 538 | addFlyAction(tr("MIN(range)"), tr("MIN(range)"), "MIN(",submenuFuncStat); |
539 | addFlyAction(tr("SUM(range)"), tr("SUM(range)"), "SUM(",submenuFuncStat); | ||
540 | addFlyAction(tr("SUMSQ(range)"), tr("SUMSQ(range)"), "SUMSQ(",submenuFuncStat); | ||
541 | submenuFuncStat->insertSeparator(); | ||
542 | addFlyAction(tr("AVERAGE(range)"), tr("AVERAGE(range)"), "AVERAGE(",submenuFuncStat); | ||
543 | addFlyAction(tr("VAR(range)"), tr("VAR(range)"), "VAR(",submenuFuncStat); | ||
544 | addFlyAction(tr("VARP(range)"), tr("VARP(range)"), "VARP(",submenuFuncStat); | ||
545 | addFlyAction(tr("STDEV(range)"), tr("STDEV(range)"), "STDEV(",submenuFuncStat); | ||
546 | addFlyAction(tr("STDEVP(range)"), tr("STDEVP(range)"), "STDEVP(",submenuFuncStat); | ||
547 | addFlyAction(tr("SKEW(range)"), tr("SKEW(range)"), "SKEW(",submenuFuncStat); | ||
548 | addFlyAction(tr("KURT(range)"), tr("KURT(range)"), "KURT(",submenuFuncStat); | ||
549 | submenuFunc->insertItem(tr("Sta&tistical"), submenuFuncStat); | ||
550 | |||
551 | submenuFuncScientific=new QPopupMenu; | ||
552 | addFlyAction(tr("BESSELI(x,n)"), tr("BESSELI(x,n)"), "BESSELI(",submenuFuncScientific); | ||
553 | addFlyAction(tr("BESSELJ(x,n)"), tr("BESSELJ(x,n)"), "BESSELJ(",submenuFuncScientific); | ||
554 | addFlyAction(tr("BESSELK(x,n)"), tr("BESSELK(x,n)"), "BESSELK(",submenuFuncScientific); | ||
555 | addFlyAction(tr("BESSELY(x,n)"), tr("BESSELY(x,n)"), "BESSELY(",submenuFuncScientific); | ||
556 | submenuFuncScientific->insertSeparator(); | ||
557 | addFlyAction(tr("BETAI(x,a,b)"), tr("BETAI(x,a,b)"), "BETAI(",submenuFuncScientific); | ||
558 | addFlyAction(tr("ERF(a,b)"), tr("ERF(a,b)"), "ERF(",submenuFuncScientific); | ||
559 | addFlyAction(tr("ERFC(a,b)"), tr("ERFC(a,b)"), "ERFC(",submenuFuncScientific); | ||
560 | addFlyAction(tr("GAMMALN(x)"), tr("GAMMALN(x)"), "GAMMALN(",submenuFuncScientific); | ||
561 | addFlyAction(tr("GAMMAP(x,a)"), tr("GAMMAP(x,a)"), "GAMMAP(",submenuFuncScientific); | ||
562 | addFlyAction(tr("GAMMAQ(x,a)"), tr("GAMMAQ(x,a)"), "GAMMAQ(",submenuFuncScientific); | ||
563 | submenuFunc->insertItem(tr("Scienti&fic"), submenuFuncScientific); | ||
564 | |||
565 | submenuFuncDistr=new QPopupMenu; | ||
566 | addFlyAction(tr("BETADIST(z,a,b,Q?)"), tr("BETADIST(z,a,b,Q?)"), "BETADIST(",submenuFuncDistr); | ||
567 | addFlyAction(tr("CHI2DIST(x,n,Q?)"), tr("CHI2DIST(x,n,Q?)"), "CHI2DIST(",submenuFuncDistr); | ||
568 | addFlyAction(tr("CHIDIST(x,n,Q?)"), tr("CHIDIST(x,n,Q?)"), "CHIDIST(",submenuFuncDistr); | ||
569 | addFlyAction(tr("FDIST(z,deg1,deg2,Q?)"), tr("FDIST(z,deg1,deg2,Q?)"), "FDIST(",submenuFuncDistr); | ||
570 | addFlyAction(tr("GAMMADIST(x,a,b,Q?)"), tr("GAMMADIST(x,a,b,Q?)"), "GAMMADIST(",submenuFuncDistr); | ||
571 | addFlyAction(tr("NORMALDIST(x,m,s,Q?)"), tr("NORMALDIST(x,m,s,Q?)"), "NORMALDIST(",submenuFuncDistr); | ||
572 | addFlyAction(tr("PHI(x,Q?)"), tr("PHI(x,Q?)"), "PHI(",submenuFuncDistr); | ||
573 | addFlyAction(tr("POISSON(x,n,Q?)"), tr("POISSON(x,n,Q?)"), "POISSON(",submenuFuncDistr); | ||
574 | submenuFunc->insertItem(tr("&Distributions"), submenuFuncDistr); | ||
575 | |||
576 | |||
456 | 577 | ||
457 | menuInsert->insertSeparator(); | 578 | menuInsert->insertSeparator(); |
458 | insertCells->addTo(menuInsert); | 579 | insertCells->addTo(menuInsert); |
@@ -597,7 +718,7 @@ void MainWindow::slotCellClicked(const QString &cell) | |||
597 | typeSheet *MainWindow::createNewSheet() | 718 | typeSheet *MainWindow::createNewSheet() |
598 | { | 719 | { |
599 | typeSheet *newSheet=new typeSheet; | 720 | typeSheet *newSheet=new typeSheet; |
600 | int currentNo=1, tempNo; | 721 | int currentNo=1, tempNo=0; |
601 | bool ok; | 722 | bool ok; |
602 | 723 | ||
603 | for (typeSheet *tempSheet=listSheets.first(); tempSheet; tempSheet=listSheets.next()) | 724 | for (typeSheet *tempSheet=listSheets.first(); tempSheet; tempSheet=listSheets.next()) |
@@ -625,6 +746,7 @@ void MainWindow::slotSheetChanged(const QString &name) | |||
625 | sheet->copySheetData(&findSheet(sheet->getName())->data); | 746 | sheet->copySheetData(&findSheet(sheet->getName())->data); |
626 | sheet->setName(name); | 747 | sheet->setName(name); |
627 | sheet->setSheetData(&findSheet(name)->data); | 748 | sheet->setSheetData(&findSheet(name)->data); |
749 | sheet->ReCalc(); | ||
628 | } | 750 | } |
629 | 751 | ||
630 | void MainWindow::addFlyAction(const QString &text, const QString &menuText, const QString &tip, QWidget *w) | 752 | void MainWindow::addFlyAction(const QString &text, const QString &menuText, const QString &tip, QWidget *w) |
@@ -745,6 +867,70 @@ void MainWindow::slotFileSaveAs() | |||
745 | documentSave(currentDoc); | 867 | documentSave(currentDoc); |
746 | } | 868 | } |
747 | 869 | ||
870 | void MainWindow::slotImportExcel(const DocLnk &lnkDoc) | ||
871 | { | ||
872 | ExcelBook file1; | ||
873 | file1.ParseBook((char *)lnkDoc.file().ascii()); | ||
874 | int NumOfSheets=file1.Sheets.count(); | ||
875 | printf("OpieSheet::NumberOfSheets:%d\r\n",NumOfSheets); | ||
876 | if (documentModified && saveCurrentFile()==QMessageBox::Cancel) return; | ||
877 | if (currentDoc) delete currentDoc; | ||
878 | currentDoc = new DocLnk(); | ||
879 | listSheets.clear(); | ||
880 | comboSheets->clear(); | ||
881 | int w1,r,c; | ||
882 | ExcelSheet* sh1; | ||
883 | typeSheet* newSheet; | ||
884 | QString* str; | ||
885 | typeCellData* newCell; | ||
886 | for(w1=1;w1<=NumOfSheets;w1++) | ||
887 | { | ||
888 | sh1=file1.Sheets[w1-1]; | ||
889 | printf("OpieSheet:newSheet:%x,r=%d,c=%d\r\n",sh1,sh1->rows,sh1->cols); | ||
890 | newSheet=new typeSheet; | ||
891 | newSheet->data.setAutoDelete(TRUE); | ||
892 | newSheet->name=sh1->name; | ||
893 | printf("OpieSheet:Sheetname:%s\r\n",sh1->name.ascii()); | ||
894 | comboSheets->insertItem(newSheet->name); | ||
895 | for(r=1; r <= sh1->rows; r++) | ||
896 | { | ||
897 | for(c=1;c <= sh1->cols; c++) | ||
898 | { | ||
899 | str=file1.CellDataString(sh1,r-1,c-1); | ||
900 | if(str!=NULL && r<DEFAULT_NUM_ROWS && c<DEFAULT_NUM_COLS) | ||
901 | { | ||
902 | newCell=new typeCellData; | ||
903 | newCell->row=r-1; | ||
904 | newCell->col=c-1; | ||
905 | if(str!=NULL) newCell->data=QString(*str); else newCell->data=QString(""); | ||
906 | newCell->background=QBrush(Qt::white, Qt::SolidPattern); | ||
907 | newCell->alignment=(Qt::AlignmentFlags)(Qt::AlignLeft | Qt::AlignTop); | ||
908 | newCell->fontColor=Qt::black; | ||
909 | newCell->font=font(); | ||
910 | newCell->borders.right=QPen(Qt::gray, 1, Qt::SolidLine); | ||
911 | newCell->borders.bottom=QPen(Qt::gray, 1, Qt::SolidLine); | ||
912 | newSheet->data.append(newCell); | ||
913 | //there is no format parsing at the moment or style parsing | ||
914 | //printf("OpieSheetNumber:row=%d,col=%d,val=%s\r\n",r,c,str->latin1()); | ||
915 | }; | ||
916 | }; | ||
917 | }; | ||
918 | listSheets.append(newSheet); | ||
919 | if (w1==1)//if i==0 link sheet1 with sheetview | ||
920 | { | ||
921 | sheet->setName(newSheet->name); | ||
922 | sheet->setSheetData(&newSheet->data); | ||
923 | sheet->ReCalc(); | ||
924 | }; | ||
925 | |||
926 | }; | ||
927 | file1.CloseFile(); | ||
928 | printf("Excel FILE read OK\r\n"); | ||
929 | documentModified=TRUE; | ||
930 | |||
931 | |||
932 | } | ||
933 | |||
748 | void MainWindow::slotSheetRename() | 934 | void MainWindow::slotSheetRename() |
749 | { | 935 | { |
750 | TextDialog dialogText(this); | 936 | TextDialog dialogText(this); |
diff --git a/noncore/apps/opie-sheet/mainwindow.h b/noncore/apps/opie-sheet/mainwindow.h index bd99c36..eacbe36 100644 --- a/noncore/apps/opie-sheet/mainwindow.h +++ b/noncore/apps/opie-sheet/mainwindow.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <qbutton.h> | 25 | #include <qbutton.h> |
26 | #include <qcombobox.h> | 26 | #include <qcombobox.h> |
27 | #include <qtoolbutton.h> | 27 | #include <qtoolbutton.h> |
28 | 28 | #include "Excel.h" | |
29 | #include "sheet.h" | 29 | #include "sheet.h" |
30 | 30 | ||
31 | typedef struct typeSheet | 31 | typedef struct typeSheet |
@@ -43,12 +43,15 @@ class MainWindow: public QMainWindow | |||
43 | QMenuBar *menu; | 43 | QMenuBar *menu; |
44 | QToolBar *toolbarFunctions, *toolbarEdit, *toolbarStandard; | 44 | QToolBar *toolbarFunctions, *toolbarEdit, *toolbarStandard; |
45 | FileSelector *fileSelector; | 45 | FileSelector *fileSelector; |
46 | FileSelector *ExcelSelector; | ||
46 | 47 | ||
47 | // QT objects | 48 | // QT objects |
48 | QPopupMenu *menuFile, *menuEdit, *menuInsert, *menuFormat, *menuData, *menuHelp, | 49 | QPopupMenu *menuFile, *menuEdit, *menuInsert, *menuFormat, *menuData, *menuHelp, |
49 | *submenuFunc, *submenuFuncStd, *submenuFuncMath, *submenuFuncStat, | 50 | *submenuFunc, *submenuFuncStd, *submenuFuncStandard, *submenuFuncLogic, |
51 | *submenuFuncTrig, *submenuFuncString, *submenuFuncScientific, *submenuFuncDistr, | ||
52 | *submenuFuncStat, | ||
50 | *submenuRow, *submenuCol, *submenuSheet; | 53 | *submenuRow, *submenuCol, *submenuSheet; |
51 | QAction *fileNew, *fileOpen, *fileSave, *fileSaveAs, *fileQuit, *helpAbout, *editAccept, *editCancel, *formatCells, | 54 | QAction *fileNew, *fileOpen, *fileSave, *fileSaveAs, *fileExcelImport, *fileQuit, *helpAbout, *editAccept, *editCancel, *formatCells, |
52 | *funcPlus, *funcMinus, *funcCross, *funcDivide, *funcParanOpen, *funcParanClose, *funcComma, *funcEqual, | 55 | *funcPlus, *funcMinus, *funcCross, *funcDivide, *funcParanOpen, *funcParanClose, *funcComma, *funcEqual, |
53 | *editCut, *editCopy, *editPaste, *editPasteContents, *editClear, *insertCols, *insertRows, *insertSheets, *insertCells, | 56 | *editCut, *editCopy, *editPaste, *editPasteContents, *editClear, *insertCols, *insertRows, *insertSheets, *insertCells, |
54 | *rowHeight, *rowShow, *rowHide, *rowAdjust, *colWidth, *colShow, *colHide, *colAdjust, *sheetRename, *sheetRemove, | 57 | *rowHeight, *rowShow, *rowHide, *rowAdjust, *colWidth, *colShow, *colHide, *colAdjust, *sheetRename, *sheetRemove, |
@@ -87,6 +90,11 @@ class MainWindow: public QMainWindow | |||
87 | void slotFileOpen(); | 90 | void slotFileOpen(); |
88 | void slotFileSave(); | 91 | void slotFileSave(); |
89 | void slotFileSaveAs(); | 92 | void slotFileSaveAs(); |
93 | |||
94 | void slotImportExcel(const DocLnk &lnkDoc); | ||
95 | void slotImportExcelOpen(); | ||
96 | void ExcelSelectorHide(); | ||
97 | |||
90 | void slotHelpAbout(); | 98 | void slotHelpAbout(); |
91 | void slotEditAccept(); | 99 | void slotEditAccept(); |
92 | void slotEditCancel(); | 100 | void slotEditCancel(); |
diff --git a/noncore/apps/opie-sheet/opie-sheet.pro b/noncore/apps/opie-sheet/opie-sheet.pro index 81a3366..334a221 100644 --- a/noncore/apps/opie-sheet/opie-sheet.pro +++ b/noncore/apps/opie-sheet/opie-sheet.pro | |||
@@ -1,6 +1,6 @@ | |||
1 | CONFIG = qt warn_on release quick-app | 1 | CONFIG = qt warn_on release quick-app |
2 | HEADERS = mainwindow.h sheet.h cellformat.h finddlg.h numberdlg.h sortdlg.h textdlg.h | 2 | HEADERS = mainwindow.h sheet.h cellformat.h finddlg.h numberdlg.h sortdlg.h textdlg.h Excel.h |
3 | SOURCES = main.cpp mainwindow.cpp sheet.cpp cellformat.cpp finddlg.cpp numberdlg.cpp sortdlg.cpp textdlg.cpp | 3 | SOURCES = main.cpp mainwindow.cpp sheet.cpp cellformat.cpp finddlg.cpp numberdlg.cpp sortdlg.cpp textdlg.cpp Excel.cpp |
4 | INCLUDEPATH+= $(OPIEDIR)/include | 4 | INCLUDEPATH+= $(OPIEDIR)/include |
5 | DEPENDPATH+= $(OPIEDIR)/include | 5 | DEPENDPATH+= $(OPIEDIR)/include |
6 | LIBS += -lqpe | 6 | LIBS += -lqpe |
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 | |||
@@ -17,6 +17,9 @@ | |||
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 | ||
@@ -40,6 +43,7 @@ Sheet::Sheet(int numRows, int numCols, QWidget *parent) | |||
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 | } |
@@ -52,8 +56,9 @@ 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 | ||
@@ -61,8 +66,9 @@ 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 | ||
@@ -88,10 +94,38 @@ void Sheet::slotCellChanged(int row, int 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); |
@@ -118,7 +152,8 @@ QString Sheet::getParameter(const QString ¶meters, int paramNo, bool giveErr | |||
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 | } |
@@ -130,7 +165,7 @@ QString Sheet::getParameter(const QString ¶meters, int paramNo, bool giveErr | |||
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; |
@@ -159,40 +194,621 @@ bool Sheet::findRowColumn(const QString &variable, int *row, int *col, bool give | |||
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); | ||
220 | } | ||
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; | ||
170 | } | 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 | |||
171 | 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 | } |
706 | if(count1>0) result=result/double(count1); else result=0.0; | ||
707 | return result; | ||
708 | }; | ||
185 | 709 | ||
710 | double Sheet::functionVariance(const QString ¶m1, const QString ¶m2) | ||
711 | { | ||
712 | int row1, col1, row2, col2, row, col; | ||
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; | ||
186 | return result; | 725 | return result; |
726 | }; | ||
727 | |||
728 | double Sheet::functionSkew(const QString ¶m1, const QString ¶m2) | ||
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; | ||
738 | for (row=row1; row<=row2; ++row) | ||
739 | for (col=col1; col<=col2; ++col) | ||
740 | { | ||
741 | tempResult=text(row, col).toDouble(&ok); | ||
742 | if (ok) | ||
743 | { | ||
744 | result=result + (tempResult - avg1)*(tempResult - avg1)*(tempResult - avg1)/(var1*var1*var1); | ||
745 | count1++; | ||
746 | }; | ||
187 | } | 747 | } |
748 | if(count1>0) result=result/double(count1); else result=0.0; | ||
749 | return result; | ||
750 | }; | ||
188 | 751 | ||
189 | double Sheet::functionMin(const QString ¶m1, const QString ¶m2) | 752 | double Sheet::functionKurt(const QString ¶m1, const QString ¶m2) |
190 | { | 753 | { |
191 | int row1, col1, row2, col2, row, col; | 754 | int row1, col1, row2, col2, row, col; |
192 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | 755 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; |
756 | double avg1=functionAvg(param1,param2); | ||
757 | double var1=sqrt(functionVariancePopulation(param1,param2)); | ||
758 | if(var1==0.0) return 0.0; | ||
759 | double result=0, tempResult; | ||
760 | int count1=0; | ||
761 | bool ok; | ||
762 | for (row=row1; row<=row2; ++row) | ||
763 | for (col=col1; col<=col2; ++col) | ||
764 | { | ||
765 | tempResult=text(row, col).toDouble(&ok); | ||
766 | if (ok) | ||
767 | { | ||
768 | result=result + (tempResult - avg1)*(tempResult - avg1)* | ||
769 | (tempResult - avg1)*(tempResult - avg1)/(var1*var1*var1*var1); | ||
770 | count1++; | ||
771 | }; | ||
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 | } | ||
193 | 802 | ||
803 | |||
804 | |||
805 | double Sheet::functionMin(const QString ¶m1, const QString ¶m2) | ||
806 | { | ||
807 | int row1, col1, row2, col2, row, col; | ||
194 | double min=0, tempMin; | 808 | double min=0, tempMin; |
195 | bool ok, init=FALSE; | 809 | bool ok, init=FALSE; |
810 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
811 | { | ||
196 | for (row=row1; row<=row2; ++row) | 812 | for (row=row1; row<=row2; ++row) |
197 | for (col=col1; col<=col2; ++col) | 813 | for (col=col1; col<=col2; ++col) |
198 | { | 814 | { |
@@ -203,17 +819,24 @@ double Sheet::functionMin(const QString ¶m1, const QString ¶m2) | |||
203 | init=TRUE; | 819 | init=TRUE; |
204 | } | 820 | } |
205 | } | 821 | } |
206 | |||
207 | return min; | 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; | ||
208 | } | 831 | } |
209 | 832 | ||
210 | double Sheet::functionMax(const QString ¶m1, const QString ¶m2) | 833 | double Sheet::functionMax(const QString ¶m1, const QString ¶m2) |
211 | { | 834 | { |
212 | int row1, col1, row2, col2, row, col; | 835 | int row1, col1, row2, col2, row, col; |
213 | if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0; | ||
214 | |||
215 | double max=0, tempMax; | 836 | double max=0, tempMax; |
216 | bool ok, init=FALSE; | 837 | bool ok, init=FALSE; |
838 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
839 | { | ||
217 | for (row=row1; row<=row2; ++row) | 840 | for (row=row1; row<=row2; ++row) |
218 | for (col=col1; col<=col2; ++col) | 841 | for (col=col1; col<=col2; ++col) |
219 | { | 842 | { |
@@ -223,9 +846,16 @@ double Sheet::functionMax(const QString ¶m1, const QString ¶m2) | |||
223 | max=tempMax; | 846 | max=tempMax; |
224 | init=TRUE; | 847 | init=TRUE; |
225 | } | 848 | } |
226 | } | 849 | }; |
227 | |||
228 | return max; | 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) |
@@ -237,188 +867,955 @@ double Sheet::functionAvg(const QString ¶m1, const QString ¶m2) | |||
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; | ||
241 | |||
242 | int divider=0; | 870 | int divider=0; |
243 | bool ok; | 871 | bool ok; |
872 | if (findRange(param1, param2, &row1, &col1, &row2, &col2)) | ||
873 | { | ||
244 | for (row=row1; row<=row2; ++row) | 874 | for (row=row1; row<=row2; ++row) |
245 | for (col=col1; col<=col2; ++col) | 875 | for (col=col1; col<=col2; ++col) |
246 | { | 876 | { |
247 | text(row, col).toDouble(&ok); | 877 | text(row, col).toDouble(&ok); |
248 | if (ok) ++divider; | 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; | ||
249 | } | 891 | } |
250 | 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 | ||
898 | int divider=0; | ||
899 | QString s2; | ||
900 | bool ok; | ||
901 | s2=calculateVariable(param3); | ||
902 | for (row=row1; row<=row2; ++row) | ||
903 | for (col=col1; col<=col2; ++col) | ||
904 | { | ||
905 | text(row, col).toDouble(&ok); | ||
906 | if (ok && (s2==text(row,col)) ) ++divider; | ||
907 | } | ||
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)); | 944 | { |
264 | if (function=="SUM") | 945 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); |
265 | return functionSum(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | 946 | val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok); |
266 | if (function=="COUNT") | 947 | if(val2==0.0) return QString("Err101"); |
267 | return functionCount(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | 948 | val1=val1/val2; |
268 | if (function=="MIN") | 949 | return QString::number(val1); |
269 | return functionMin(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | 950 | }; |
270 | if (function=="MAX") | 951 | if (function==">") |
271 | return functionMax(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | 952 | { |
272 | if (function=="AVG") | 953 | val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok); |
273 | return functionAvg(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function)); | 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 | ||
274 | if (function=="ABS") | 1046 | if (function=="ABS") |
275 | return fabs(calculateVariable(getParameter(parameters, 0, TRUE, function))); | 1047 | { |
276 | if (function=="SIN") | 1048 | val1=fabs(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
277 | return sin(calculateVariable(getParameter(parameters, 0, TRUE, function))); | 1049 | return QString::number(val1); |
278 | if (function=="COS") | 1050 | }; |
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") | 1051 | 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 | { | 1052 | { |
301 | switch (oper) | 1053 | val1=acos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
1054 | return QString::number(val1); | ||
1055 | }; | ||
1056 | if (function=="ACOSH") | ||
302 | { | 1057 | { |
303 | case '+': | 1058 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); |
304 | case '-': | 1059 | if(val1<1.0) return QString::number(0); |
305 | return 1; | 1060 | val1=acosh(val1); |
306 | 1061 | return QString::number(val1); | |
307 | case '*': | 1062 | }; |
308 | case '/': | 1063 | if (function=="ASIN") |
309 | return 2; | ||
310 | } | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | void Sheet::pushCharStack(QStack<QChar> *stackChars, const QChar &character) | ||
315 | { | 1064 | { |
316 | QChar *temp=new QChar(character); | 1065 | val1=asin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
317 | stackChars->push(temp); | 1066 | return QString::number(val1); |
318 | } | 1067 | }; |
319 | 1068 | if (function=="ASINH") | |
320 | void Sheet::pushStringStack(QStack<QString> *stackStrings, const QString &string) | ||
321 | { | 1069 | { |
322 | QString *temp=new QString(string); | 1070 | val1=asinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
323 | stackStrings->push(temp); | 1071 | return QString::number(val1); |
324 | } | 1072 | }; |
325 | 1073 | if (function=="ATAN") | |
326 | QChar Sheet::popCharStack(QStack<QChar> *stackChars) | ||
327 | { | 1074 | { |
328 | if (stackChars->isEmpty()) | 1075 | val1=atan(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
1076 | return QString::number(val1); | ||
1077 | }; | ||
1078 | if (function=="ATAN2") | ||
329 | { | 1079 | { |
330 | QMessageBox::critical(this, tr("Error"), tr("Syntax error!")); | 1080 | val1=atan2(calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok), |
331 | return '0'; | 1081 | calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
332 | } | 1082 | return QString::number(val1); |
333 | 1083 | }; | |
334 | QChar *temp=stackChars->pop(); | 1084 | if (function=="ATANH") |
335 | QChar temp2(*temp); | 1085 | { |
336 | delete temp; | 1086 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); |
337 | return temp2; | 1087 | if(val1<=-1.0 || val1>=1.0) return QString("Err101"); |
338 | } | 1088 | val1=atanh(val1); |
339 | 1089 | return QString::number(val1); | |
340 | QString Sheet::popStringStack(QStack<QString> *stackStrings) | 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") | ||
341 | { | 1101 | { |
342 | if (stackStrings->isEmpty()) | 1102 | val1=cos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
1103 | return QString::number(val1); | ||
1104 | }; | ||
1105 | if (function=="COSH") | ||
343 | { | 1106 | { |
344 | QMessageBox::critical(this, tr("Error"), tr("Syntax error!")); | 1107 | val1=cosh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
345 | return "0"; | 1108 | return QString::number(val1); |
346 | } | 1109 | }; |
347 | 1110 | if (function=="DEGREES") | |
348 | QString *temp=stackStrings->pop(); | ||
349 | QString temp2(*temp); | ||
350 | delete temp; | ||
351 | return temp2; | ||
352 | } | ||
353 | |||
354 | QString Sheet::dataParserHelper(const QString &data) | ||
355 | { | 1111 | { |
356 | QStack<QString> stackElements; | 1112 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)*180.0/M_PI; |
357 | QStack<QChar> stackOperators; | 1113 | return QString::number(val1); |
358 | QString tempElement(""), temp2Element, firstElement, secondElement; | 1114 | }; |
359 | int paranCount; | 1115 | if (function=="EXP") |
360 | |||
361 | for (unsigned int i=0; i<data.length(); ++i) | ||
362 | { | 1116 | { |
363 | if (data[i]=='+' || data[i]=='-' || data[i]=='*' || data[i]=='/') | 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") | ||
364 | { | 1186 | { |
365 | pushStringStack(&stackElements, tempElement); | 1187 | // return the base-param2 logarithm of param1 |
366 | tempElement=""; | 1188 | val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok); |
367 | if (!stackOperators.isEmpty() && getOperatorPriority(*stackOperators.top())>getOperatorPriority(data[i])) | 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") | ||
368 | { | 1259 | { |
369 | secondElement=popStringStack(&stackElements); | 1260 | val1=sin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
370 | firstElement=popStringStack(&stackElements); | 1261 | return QString::number(val1); |
371 | pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement))); | 1262 | }; |
372 | } | 1263 | if (function=="SINH") |
373 | pushCharStack(&stackOperators, data[i]); | ||
374 | } | ||
375 | else | ||
376 | if (data[i]==',') | ||
377 | { | 1264 | { |
378 | if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement); | 1265 | val1=sinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
379 | while (!stackOperators.isEmpty()) | 1266 | return QString::number(val1); |
1267 | }; | ||
1268 | if (function=="TAN") | ||
380 | { | 1269 | { |
381 | secondElement=popStringStack(&stackElements); | 1270 | val1=tan(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
382 | firstElement=popStringStack(&stackElements); | 1271 | return QString::number(val1); |
383 | pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement))); | 1272 | }; |
384 | } | 1273 | if (function=="TANH") |
385 | tempElement=""; | 1274 | { |
386 | } | 1275 | val1=tanh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)); |
387 | else | 1276 | return QString::number(val1); |
388 | if (data[i]=='(') | 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") | ||
389 | { | 1398 | { |
390 | paranCount=1; | 1399 | //NumOfParams |
391 | temp2Element=""; | 1400 | val2=0.0; |
392 | for (++i; paranCount>0; ++i) | 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") | ||
393 | { | 1434 | { |
394 | temp2Element+=data[i]; | 1435 | //NumOfParams |
395 | if (data[i]=='(') ++paranCount; | 1436 | val2=0.0; |
396 | if (data[i]==')') --paranCount; | 1437 | for(w1=1;w1<=(NumOfParams/2);w1++) |
397 | } | 1438 | { |
398 | temp2Element=dataParserHelper(temp2Element.left(temp2Element.length()-1)); | 1439 | val1=functionCount(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function)); |
399 | if (tempElement.isEmpty()) | 1440 | val2=val2+val1; |
400 | tempElement=temp2Element; | 1441 | }; |
401 | else | 1442 | if(NumOfParams%2==1) |
402 | tempElement.setNum(calculateFunction(tempElement, temp2Element)); | 1443 | { |
403 | --i; | 1444 | val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok); |
404 | } | 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); | ||
405 | else | 1655 | else |
406 | tempElement+=data[i]; | 1656 | return QString::number(GammaP(val2,val1/val3)); |
407 | } | 1657 | }else //density |
408 | if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement); | 1658 | { |
409 | while (!stackOperators.isEmpty()) | 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 | */ | ||
1747 | |||
1748 | |||
1749 | |||
1750 | return 0; | ||
1751 | }; | ||
1752 | |||
1753 | |||
1754 | |||
1755 | |||
1756 | QString Sheet::dataParserHelper(const QString &data) | ||
410 | { | 1757 | { |
411 | secondElement=popStringStack(&stackElements); | 1758 | if(data.left(1)=="""" && data.right(1)=="""") return QString(data); |
412 | firstElement=popStringStack(&stackElements); | 1759 | Expression exp1(data); |
413 | pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement))); | 1760 | exp1.Parse(); |
414 | } | 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 | }; | ||
1817 | |||
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 | { |
@@ -427,13 +1824,14 @@ QString Sheet::dataParser(const QString &cell, const QString &data) | |||
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()); |
@@ -441,6 +1839,7 @@ QString Sheet::dataParser(const QString &cell, const QString &data) | |||
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); |
@@ -482,6 +1881,7 @@ void Sheet::paintCell(QPainter *p, int row, int col, const QRect & cr, bool sele | |||
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 | ||
@@ -870,3 +2270,296 @@ int Sheet::getHeaderColumn(const QString §ion) | |||
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 | |||
diff --git a/noncore/apps/opie-sheet/sheet.h b/noncore/apps/opie-sheet/sheet.h index f4e9d38..41f1b86 100644 --- a/noncore/apps/opie-sheet/sheet.h +++ b/noncore/apps/opie-sheet/sheet.h | |||
@@ -34,6 +34,52 @@ typedef struct typeCellData | |||
34 | QString data; | 34 | QString data; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | |||
38 | #define NONE_TOKEN 0 | ||
39 | #define NUMBER_TOKEN 1 | ||
40 | #define VARIABLE_TOKEN 2 | ||
41 | #define FUNCTION_TOKEN 3 | ||
42 | #define SYMBOL_TOKEN 4 | ||
43 | #define STRING_TOKEN 5 | ||
44 | |||
45 | class Expression | ||
46 | { | ||
47 | public: | ||
48 | QString Body; | ||
49 | QList<QString> CompiledBody; | ||
50 | QList<int> CompiledBodyType; | ||
51 | QString SYMBOL; | ||
52 | QString MATHSYMBOL; | ||
53 | QArray<int> ArgsOfFunc; | ||
54 | int FuncDepth; | ||
55 | bool ErrorFound; | ||
56 | int n; // holds the current parser position | ||
57 | QString chunk; // the piece in the parser we are on | ||
58 | int SymbGroup; // the current type | ||
59 | |||
60 | QString InExpr; | ||
61 | |||
62 | QChar chunk0(void); // retunrs the first char of expression; | ||
63 | Expression(QString expr1);// constructor | ||
64 | |||
65 | bool isSymbol(QChar ch); | ||
66 | bool isMathSymbol(QChar ch); | ||
67 | void GetNext(); | ||
68 | void First(); | ||
69 | void Third(); | ||
70 | void Fourth(); | ||
71 | void Fifth(); | ||
72 | void Sixth(); | ||
73 | void Seventh(); | ||
74 | void Eighth(); | ||
75 | void Ninth(); | ||
76 | |||
77 | bool Expression::Parse(); //parses the expression in RPN format; | ||
78 | |||
79 | }; | ||
80 | |||
81 | |||
82 | |||
37 | class Sheet: public QTable | 83 | class Sheet: public QTable |
38 | { | 84 | { |
39 | Q_OBJECT | 85 | Q_OBJECT |
@@ -50,21 +96,50 @@ class Sheet: public QTable | |||
50 | QStringList listDataParser; | 96 | QStringList listDataParser; |
51 | 97 | ||
52 | // Private functions | 98 | // Private functions |
53 | int getOperatorPriority(char oper); | ||
54 | bool findRowColumn(const QString &variable, int *row, int *col, bool giveError=FALSE); | 99 | bool findRowColumn(const QString &variable, int *row, int *col, bool giveError=FALSE); |
55 | QString findCellName(int row, int col); | 100 | QString findCellName(int row, int col); |
56 | bool findRange(const QString &variable1, const QString &variable2, int *row1, int *col1, int *row2, int *col2); | 101 | bool findRange(const QString &variable1, const QString &variable2, int *row1, int *col1, int *row2, int *col2); |
57 | double calculateVariable(const QString &variable); | 102 | QString calculateVariable(const QString &variable); |
58 | double calculateFunction(const QString &function, const QString ¶meters); | 103 | QString calculateFunction(const QString &function, const QString ¶meters, int NumOfParams); |
59 | QChar popCharStack(QStack<QChar> *stackChars); | ||
60 | QString popStringStack(QStack<QString> *stackStrings); | ||
61 | QString getParameter(const QString ¶meters, int paramNo, bool giveError=FALSE, const QString funcName=""); | 104 | QString getParameter(const QString ¶meters, int paramNo, bool giveError=FALSE, const QString funcName=""); |
62 | QString dataParser(const QString &cell, const QString &data); | 105 | QString dataParser(const QString &cell, const QString &data); |
63 | QString dataParserHelper(const QString &data); | 106 | QString dataParserHelper(const QString &data); |
64 | typeCellData *createCellData(int row, int col); | 107 | typeCellData *createCellData(int row, int col); |
65 | typeCellData *findCellData(int row, int col); | 108 | typeCellData *findCellData(int row, int col); |
66 | void pushCharStack(QStack<QChar> *stackChars, const QChar &character); | 109 | |
67 | void pushStringStack(QStack<QString> *stackStrings, const QString &string); | 110 | |
111 | //LOGICAL / INFO | ||
112 | double functionCountIf(const QString ¶m1, const QString ¶m2, const QString ¶m3); | ||
113 | double functionSumSQ(const QString ¶m1, const QString ¶m2); //sum of squares | ||
114 | QString functionIndex(const QString ¶m1, const QString ¶m2, int indx); | ||
115 | //math functions computations | ||
116 | double BesselI0(double x); | ||
117 | double BesselI(int n, double x); | ||
118 | double BesselK0(double x); | ||
119 | double BesselI1(double x); | ||
120 | double BesselK1(double x); | ||
121 | double BesselK(int n, double x); | ||
122 | double BesselJ0(double x); | ||
123 | double BesselY0(double x); | ||
124 | double BesselJ1(double x); | ||
125 | double BesselY1(double x); | ||
126 | double BesselY(int n, double x); | ||
127 | double BesselJ(int n, double x); | ||
128 | double GammaLn(double xx); | ||
129 | double Factorial(double n); | ||
130 | double GammaP(double a, double x); | ||
131 | double GammaQ(double a,double x); | ||
132 | void GammaSeries(double *gamser, double a, double x, double *gln); | ||
133 | void GammaContinuedFraction(double *gammcf, double a, double x, double *gln); | ||
134 | double ErrorFunction(double x); | ||
135 | double ErrorFunctionComplementary(double x); | ||
136 | double Beta(double z, double w); | ||
137 | double BetaContinuedFraction(double a, double b, double x); | ||
138 | double BetaIncomplete(double a, double b, double x); | ||
139 | double functionVariance(const QString ¶m1, const QString ¶m2); | ||
140 | double functionVariancePopulation(const QString ¶m1, const QString ¶m2); | ||
141 | double functionSkew(const QString ¶m1, const QString ¶m2); | ||
142 | double functionKurt(const QString ¶m1, const QString ¶m2); | ||
68 | 143 | ||
69 | // Sheet/Qt parser functions | 144 | // Sheet/Qt parser functions |
70 | double functionSum(const QString ¶m1, const QString ¶m2); | 145 | double functionSum(const QString ¶m1, const QString ¶m2); |
@@ -79,14 +154,14 @@ class Sheet: public QTable | |||
79 | void viewportMouseMoveEvent(QMouseEvent *e); | 154 | void viewportMouseMoveEvent(QMouseEvent *e); |
80 | void viewportMouseReleaseEvent(QMouseEvent *e); | 155 | void viewportMouseReleaseEvent(QMouseEvent *e); |
81 | 156 | ||
82 | private slots: | 157 | public slots: |
83 | void slotCellSelected(int row, int col); | 158 | void slotCellSelected(int row, int col); |
84 | void slotCellChanged(int row, int col); | 159 | void slotCellChanged(int row, int col); |
85 | 160 | ||
86 | public: | 161 | public: |
87 | Sheet(int numRows, int numCols, QWidget *parent); | 162 | Sheet(int numRows, int numCols, QWidget *parent); |
88 | ~Sheet(); | 163 | ~Sheet(); |
89 | 164 | void ReCalc(void); | |
90 | void setData(const QString &data); | 165 | void setData(const QString &data); |
91 | QString getData(); | 166 | QString getData(); |
92 | 167 | ||