summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-sheet/Excel.cpp
authorhayzel <hayzel>2004-01-07 08:08:29 (UTC)
committer hayzel <hayzel>2004-01-07 08:08:29 (UTC)
commit08bc72c34cae85e5cc6541c9daaeba121597c961 (patch) (unidiff)
treedf5b263a84099ffdf8e0b86fda9a9fe61b90d30e /noncore/apps/opie-sheet/Excel.cpp
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 (limited to 'noncore/apps/opie-sheet/Excel.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-sheet/Excel.cpp1664
1 files changed, 1664 insertions, 0 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