summaryrefslogtreecommitdiff
authorhayzel <hayzel>2004-01-07 08:08:29 (UTC)
committer hayzel <hayzel>2004-01-07 08:08:29 (UTC)
commit08bc72c34cae85e5cc6541c9daaeba121597c961 (patch) (unidiff)
treedf5b263a84099ffdf8e0b86fda9a9fe61b90d30e
parent656e80e7b35c4aefd49ffe7756d895f4e7370de1 (diff)
downloadopie-08bc72c34cae85e5cc6541c9daaeba121597c961.zip
opie-08bc72c34cae85e5cc6541c9daaeba121597c961.tar.gz
opie-08bc72c34cae85e5cc6541c9daaeba121597c961.tar.bz2
January 7, 2004
* Release by hayzel (koppermind@panafonet.gr) This version has many valuable changes, though It may have some annoying bugs. Please if you are interested in opie-sheet try it hard, so I can fix some of them. Also If you want some other functions that must be here and are missing feel free to ask them. (no financial functions please. :) I really hate them ) -Fixed a bug with non closed parenthesis editing&recalculation infinite loop. -Added support for functions that can parse parameters not ONLY as numbers but also as strings. -Added many functions that cover many computational topics rendering opie-sheet a computational tool-spreadsheet at last. (total 90 functions!) -Maintained compatibility with the opie-fileformat. -New icons. -Found that the DataParser was not a real RPN compiler of the expressions. In fact it was returning faulty results in calculations, in both binary or unary operations. A1-A2-A3 was parsed as A1-(A2-A3). A1 was parsed as A1. -Added new class "Expression" a general Parser for spreadsheet-expression. Imported from an old C# project of mine. -Now can also parse <>=!%&^|"" in expressions. -Added experimental Excel File format import!. The opie-sheet can import any excel file in BIFF7/BIFF8 format. These formats are used in Excel XP,2000,95. The Excel Importer class is in a good coding level.. BUT it is not complete. Only strings,numbers,formulas are imported. Not formatting rules. Not all the functions are converted in the functions of opie-sheet. Infact FEW functions are converted. -Fixed a bug with Sheet Recalculation. Added ReCalc() function. Opie-sheet was calculating wrong the values of expression in opening/importing. if a value needed was not loaded yet in the time of calculation. Solved with ReCalc() each time the active sheet is changing. *known issues: -if someone enters directly text as parameter to a string function the text renders as uppercase due to the calculation engine that uppercases all the parsing sentence. -randbetween return only integer part random... if both limit numbers are integers. -skew and kurt function give different results compared to kspread-oofice equivalents. -unstable parser Excel Class -string vars and string functions are not correctly handled by excel importer. -unicode strings are converted FINE in QString unicode format, but cannot be rendered fine if a suitable unicode font is not setuped as the default string. So the string is junked in the opie-sheet and may crash the parser. *TODOs: -surelly a much full-stable excel importer. -Cell Manipulation of many Data is really slow.... must change the QList data type. To a structure more efficient. -maybe some more functions. -maybe some kind of charts drawing? -maybe kspread or ooffice files import/export.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-sheet/Excel.cpp1664
-rw-r--r--noncore/apps/opie-sheet/Excel.h205
-rw-r--r--noncore/apps/opie-sheet/cell-select.xpm44
-rw-r--r--noncore/apps/opie-sheet/excel16.xpm187
-rw-r--r--noncore/apps/opie-sheet/func-comma.xpm41
-rw-r--r--noncore/apps/opie-sheet/func-cross.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-divide.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-equal.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-func.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-minus.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-paran-close.xpm41
-rw-r--r--noncore/apps/opie-sheet/func-paran-open.xpm41
-rw-r--r--noncore/apps/opie-sheet/func-plus.xpm40
-rw-r--r--noncore/apps/opie-sheet/mainwindow.cpp238
-rw-r--r--noncore/apps/opie-sheet/mainwindow.h14
-rw-r--r--noncore/apps/opie-sheet/opie-sheet.pro4
-rw-r--r--noncore/apps/opie-sheet/sheet.cpp2015
-rw-r--r--noncore/apps/opie-sheet/sheet.h93
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
14static 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
53int 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
61int 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
69int ExcelBook::Integer2ByteFile(FILE *f) {
70 int i1, i2;
71 i1 = fgetc(f);
72 i2 = fgetc(f);
73 return Integer2Byte(i1,i2);
74};
75
76float 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
90double 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
132void 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
147double 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
168bool 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
182bool 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
211void 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
221void 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
231int ExcelBook::FileEOF(void)
232{
233 if(File!=NULL) return(feof(File)); else return 0;
234 //EOF is defined in stdlib as -1
235};
236
237int 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
254char* 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
268QString 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
285QString* 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
294int 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
320ExcelBREC* 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
333ExcelBREC* ExcelBook::PeekBREC(void)
334{
335 int oldpos;
336 ExcelBREC* NextRec;
337 oldpos=Position;
338 NextRec=GetBREC();
339 SeekPosition(oldpos);
340 return NextRec;
341};
342
343char* 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
352void 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
360bool 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
372void 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
380ExcelCell* 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
388int 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
455int 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
471ExcelSheet* 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
491void 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
540void 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
554bool ExcelBook::ParseBook(char *file)
555{
556 dateformat=QString("");
557 DetectEndian();
558 OpenFile(file);
559 SeekBOF();
560 ParseSheets();
561 GetSheets();
562 return true;
563};
564
565QString 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
576QString 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
591void 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
616void 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
630ExcelFormat* 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
646void 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
707char* 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
732void 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
754void 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
765ExcelCell* 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
776ExcelCell* 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
788QString* 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
843int 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
872void ExcelBook::CellSetDateFormat(char *d)
873{
874 dateformat = QString(d);
875};
876
877void 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
901void 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
920void 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
940ExcelFormat::ExcelFormat()
941{
942code=0;type=0;format="";
943};
944
945ExcelFormat::ExcelFormat(int c,int t, QString s)
946{
947 code=c;type=t;format=s;
948};
949
950
951void 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
968void 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
982void 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
997void 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
1039QString 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();
1644return QString(s1);
1645};
1646
1647QString 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
55class ExcelFormat
56{
57public:
58int code;
59int type;
60QString format;
61ExcelFormat();
62ExcelFormat(int c,int t, QString s);
63};
64
65struct xfrecord
66{
67int code;
68int type;
69QString format;
70};
71
72class ExcelCell
73{
74public:
75int type;
76int row,col;
77int xfindex; //xf format index of cell
78int valuei;
79double valued;
80QString valuec;
81
82};
83
84class ExcelBREC
85{
86public:
87 int code;
88 int length;
89 int position;
90 char* data;
91};
92
93class SSTList
94{
95public:
96 QArray <ExcelBREC*> rec;
97};
98
99class ExcelSheet
100{
101public:
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
117struct 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
130class ExcelBook
131{
132public:
133FILE *File;
134int Position;
135//int stringcount;
136QArray <QString*> SharedStrings;
137//int xfcount;
138QArray <ExcelFormat*> XFRecords;
139//int Sheetcount;
140QArray <ExcelSheet*> Sheets;
141//int name count;
142QArray <QString*> Names;
143
144QString dateformat;
145int Version;
146int endian;
147int Integer2Byte(int b1, int b2 );
148int Integer4Byte(int b1, int b2, int b3, int b4 );
149int Integer2ByteFile(FILE *f);
150float Float4Byte(int b1, int b2, int b3, int b4);
151double Double4Byte(int b1, int b2, int b3, int b4);
152double Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8);
153void DetectEndian(void);
154
155bool OpenFile(char *Filename); // true if ok
156bool CloseFile(void); // true if ok
157void SeekPosition(int pos); // go to Pos
158void SeekSkip(int pos); // skips pos bytes.
159int FileEOF(void); //returns -1 if EOF else 0
160int Get2Bytes(void); //gets an int from the file
161char* Read(int pos, int length);
162QString ReadUnicodeChar(int pos, int length);
163QString* GetString(int num); //gets the num string from SharedStrings;
164int SeekBOF(void);
165ExcelBREC* GetBREC(void);
166ExcelBREC* PeekBREC(void);
167char* GetDataOfBREC(ExcelBREC* record);
168void ConvertCharToArray(ExcelBREC* record, char* chars, int length);
169int SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record);
170int ReadSheet(ExcelSheet* sheet); //read the sheet sheet*
171ExcelSheet* GetSheet(void);
172void ParseSheets(void);
173void GetSheets(void);
174
175bool ParseBook(char *file); // THIS IS THE MAIN PARSE FUNCTION of file
176QString GetASCII(char* inbytes, int pos, int chars);
177QString GetUnicode(char * inbytes, int pos, int chars);
178void HandleBoundSheet( ExcelBREC* rec);
179void HandleName(ExcelSheet* sheet, ExcelBREC* rec);
180ExcelFormat* GetFormatting(int xf);
181void HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes);
182char* MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont);
183void HandleSST(ExcelBREC* rec);
184void HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec);
185ExcelCell* CellLabel(int row, int col, QString str);
186ExcelCell* CellNumber(int row, int col, int index, double d);
187QString* CellDataString(ExcelSheet* sh, int row, int col);
188int CellGetPrecision(double d);
189void CellSetDateFormat(char *d);
190void HandleMulrk(ExcelSheet* sheet, ExcelBREC* record);
191void MulrkRead(struct mulrk *mulrk, char* data);
192void HandleNumber(ExcelSheet* sheet, ExcelBREC* record);
193void HandleFormat(ExcelBREC* rec);
194void HandleXF(ExcelBREC* rec);
195void HandleRK(ExcelSheet* sheet, ExcelBREC* record);
196void HandleFormula(ExcelSheet* sheet, ExcelBREC* record);
197QString GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz);
198QString 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 */
2static const char * cell_select_xpm[] = { 2static 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 */
2static 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 */
2static const char * func_comma_xpm[] = { 2static 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 */
2static const char * func_cross_xpm[] = { 2static 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 */
2static const char * func_divide_xpm[] = { 2static 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 */
2static const char * func_equal_xpm[] = { 2static 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 */
2static const char * func_func_xpm[] = { 2static 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 */
2static const char * func_minus_xpm[] = { 2static 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 */
2static const char * func_paran_close_xpm[] = { 2static 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 */
2static const char * func_paran_open_xpm[] = { 2static 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 */
2static const char * func_plus_xpm[] = { 2static 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
258void MainWindow::slotImportExcelOpen()
259{
260 sheet->hide();
261 setCentralWidget(ExcelSelector);
262 ExcelSelector->show();
263 ExcelSelector->reread();
264}
265
266void MainWindow::ExcelSelectorHide()
267{
268 ExcelSelector->hide();
269 setCentralWidget(sheet);
270 sheet->show();
271}
272
253void MainWindow::slotFileSave() 273void 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)
597typeSheet *MainWindow::createNewSheet() 718typeSheet *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
630void MainWindow::addFlyAction(const QString &text, const QString &menuText, const QString &tip, QWidget *w) 752void 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
870void 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
748void MainWindow::slotSheetRename() 934void 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
31typedef struct typeSheet 31typedef 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
6LIBS += -lqpe 6LIBS += -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
115void 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
95void Sheet::swapCells(int row1, int col1, int row2, int col2) 129void 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 &parameters, 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 &parameters, int paramNo, bool giveErr
130bool Sheet::findRange(const QString &variable1, const QString &variable2, int *row1, int *col1, int *row2, int *col2) 165bool 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
162double Sheet::calculateVariable(const QString &variable) 197QString 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
222double 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
240double 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
258double 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
289double 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 }
301return ans;
302};
303
304double 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
319double 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
336double 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
358double 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
380double 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
401double 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
423double 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
440double 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
491double 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
504double 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
511double 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
529double 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
536void 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
568void 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
593double Sheet::ErrorFunction(double x)
594{
595 return x < 0.0 ? -GammaP(0.5,x*x) : GammaP(0.5,x*x);
596};
597
598double Sheet::ErrorFunctionComplementary(double x)
599{
600 return x < 0.0 ? 1.0+GammaP(0.5,x*x) : GammaQ(0.5,x*x);
601};
602
603double Sheet::Beta(double z, double w)
604{
605 return exp(GammaLn(z)+GammaLn(w)-GammaLn(z+w));
606};
607
608
609double 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
640double 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
172double Sheet::functionSum(const QString &param1, const QString &param2) 652double Sheet::functionSum(const QString &param1, const QString &param2)
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
676QString Sheet::functionIndex(const QString &param1, const QString &param2, 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
692double Sheet::functionVariancePopulation(const QString &param1, const QString &param2)
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
710double Sheet::functionVariance(const QString &param1, const QString &param2)
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
728double Sheet::functionSkew(const QString &param1, const QString &param2)
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
189double Sheet::functionMin(const QString &param1, const QString &param2) 752double Sheet::functionKurt(const QString &param1, const QString &param2)
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
779double Sheet::functionSumSQ(const QString &param1, const QString &param2)
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
805double Sheet::functionMin(const QString &param1, const QString &param2)
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 &param1, const QString &param2)
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
210double Sheet::functionMax(const QString &param1, const QString &param2) 833double Sheet::functionMax(const QString &param1, const QString &param2)
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 &param1, const QString &param2)
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
231double Sheet::functionAvg(const QString &param1, const QString &param2) 861double Sheet::functionAvg(const QString &param1, const QString &param2)
@@ -237,188 +867,955 @@ double Sheet::functionAvg(const QString &param1, const QString &param2)
237double Sheet::functionCount(const QString &param1, const QString &param2) 867double Sheet::functionCount(const QString &param1, const QString &param2)
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
893double Sheet::functionCountIf(const QString &param1, const QString &param2, const QString &param3)
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
254double Sheet::calculateFunction(const QString &function, const QString &parameters) 911
912QString Sheet::calculateFunction(const QString &function, const QString &parameters, 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
299int 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
314void 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")
320void 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")
326QChar 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);
340QString 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
354QString 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
1756QString 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
423QString Sheet::dataParser(const QString &cell, const QString &data) 1820QString 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
444void Sheet::setData(const QString &data) 1843void 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 &section)
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
2278QChar Expression::chunk0(void)
2279{
2280 if(chunk.length()>0) return(chunk[0]); else return('\0');
2281};
2282
2283Expression::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
2298bool 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
2305bool 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
2312void 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
2390void Expression::First()
2391{
2392 GetNext();
2393 if (!(chunk=="") && !ErrorFound) Third();
2394 else ErrorFound = true;
2395};
2396
2397void 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
2428void 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
2446void 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
2459void 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
2483void 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
2495void 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
2518void 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
2555bool 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
45class Expression
46{
47public:
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
37class Sheet: public QTable 83class 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 &parameters); 103 QString calculateFunction(const QString &function, const QString &parameters, int NumOfParams);
59 QChar popCharStack(QStack<QChar> *stackChars);
60 QString popStringStack(QStack<QString> *stackStrings);
61 QString getParameter(const QString &parameters, int paramNo, bool giveError=FALSE, const QString funcName=""); 104 QString getParameter(const QString &parameters, 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 &param1, const QString &param2, const QString &param3);
113 double functionSumSQ(const QString &param1, const QString &param2); //sum of squares
114 QString functionIndex(const QString &param1, const QString &param2, 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 &param1, const QString &param2);
140 double functionVariancePopulation(const QString &param1, const QString &param2);
141 double functionSkew(const QString &param1, const QString &param2);
142 double functionKurt(const QString &param1, const QString &param2);
68 143
69 // Sheet/Qt parser functions 144 // Sheet/Qt parser functions
70 double functionSum(const QString &param1, const QString &param2); 145 double functionSum(const QString &param1, const QString &param2);
@@ -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