Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Excel.cpp

Go to the documentation of this file.
00001 /*
00002                =.            This file is part of the Opie Project
00003              .=l.            Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org>
00004            .>+-=
00005  _;:,     .>    :=|.         This program is free software; you can
00006 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00007 :`=1 )Y*s>-.--   :           the terms of the GNU General Public
00008 .="- .-=="i,     .._         License as published by the Free Software
00009  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00010      ._= =}       :          or (at your option) any later version.
00011     .%`+i>       _;_.
00012     .i_,=:_.      -<s.       This program is distributed in the hope that
00013      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00014     : ..    .:,     . . .    without even the implied warranty of
00015     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00016   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00017 ..}^=.=       =       ;      Library General Public License for more
00018 ++=   -.     .`     .:       details.
00019  :     =  ...= . :.=-
00020  -.   .:....=;==+<;          You should have received a copy of the GNU
00021   -_. . .   )=.  =           Library General Public License along with
00022     --        :-=`           this library; see the file COPYING.LIB.
00023                              If not, write to the Free Software Foundation,
00024                              Inc., 59 Temple Place - Suite 330,
00025                              Boston, MA 02111-1307, USA.
00026 
00027 */
00028 
00029 #include "Excel.h"
00030 
00031 /* STD */
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <math.h>
00035 #include <time.h>
00036 #include <sys/types.h>
00037 #include <strings.h>
00038 
00039 static xfrecord formatter[] = {
00040                                   { 0xe , DATEFORMAT, "%m/%d/%y"},
00041                                   { 0xf , DATEFORMAT, "%d-%b-%y"},
00042                                   { 0x10, DATEFORMAT, "%d-%b"},
00043                                   { 0x11, DATEFORMAT, "%b-%y"},
00044                                   { 0x12, DATEFORMAT, "%I:%M %p"},
00045                                   { 0x13, DATEFORMAT, "%I:%M:%S %p"},
00046                                   { 0x14, DATEFORMAT, "%H:%M"},
00047                                   { 0x15, DATEFORMAT, "%H:%M:%S"},
00048                                   { 0x16, DATEFORMAT, "%m/%d/%y %H:%M"},
00049                                   { 0x2d, DATEFORMAT, "%M:%S"},
00050                                   { 0x2e, DATEFORMAT, "%H:%M:%S"},
00051                                   { 0x2f, DATEFORMAT, "%M:%S"},
00052                                   { 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"},
00053                                   { 0x1 , NUMBERFORMAT, "%.0f"},
00054                                   { 0x2 , NUMBERFORMAT, "%.2f"},
00055                                   { 0x3 , NUMBERFORMAT, "#,##%.0f"},
00056                                   { 0x4 , NUMBERFORMAT, "#,##%.2f"},
00057                                   { 0x5 , NUMBERFORMAT, "$#,##%.0f"},
00058                                   { 0x6 , NUMBERFORMAT, "$#,##%.0f"},
00059                                   { 0x7 , NUMBERFORMAT, "$#,##%.2f"},
00060                                   { 0x8 , NUMBERFORMAT, "$#,##%.2f"},
00061                                   { 0x9 , NUMBERFORMAT, "%.0f%%"},
00062                                   { 0xa , NUMBERFORMAT, "%.2f%%"},
00063                                   { 0xb , NUMBERFORMAT, "%e"},
00064                                   { 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
00065                                   { 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
00066                                   { 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
00067                                   { 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
00068                                   { 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
00069                                   { 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"},
00070                                   { 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
00071                                   { 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"},
00072                                   { 0x30, NUMBERFORMAT, "##0.0E0"},
00073                                   { 0, 0, ""}
00074                               };
00075 
00076 
00077 
00078 int ExcelBook::Integer2Byte(int b1, int b2)
00079 {
00080     int i1 = b1 & 0xff;
00081     int i2 = b2 & 0xff;
00082     int val = i2 << 8 | i1;
00083     return val;
00084 };
00085 
00086 int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4)
00087 {
00088     int i1 = Integer2Byte(b1, b2);
00089     int i2 = Integer2Byte(b3, b4);
00090     int val = i2 << 16 | i1;
00091     return val;
00092 };
00093 
00094 int ExcelBook::Integer2ByteFile(FILE *f)
00095 {
00096     int i1, i2;
00097     i1 = fgetc(f);
00098     i2 = fgetc(f);
00099     return Integer2Byte(i1,i2);
00100 };
00101 
00102 float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4)
00103 {
00104     int i;
00105     float f;
00106     unsigned char *ieee;
00107     ieee = (unsigned char *) &f;
00108     for (i = 0; i < 4; i++) ieee[i] = 0;
00109     ieee[0] = ((int)b4) & 0xff;
00110     ieee[1] = ((int)b3) & 0xff;
00111     ieee[2] = ((int)b2) & 0xff;
00112     ieee[3] = ((int)b1) & 0xff;
00113     return f;
00114 };
00115 
00116 double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4)
00117 {
00118     long int rk;
00119     double value;
00120 
00121     rk=Integer4Byte(b1,b2,b3,b4);
00122     //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4);
00123     if ( (rk & 0x02) != 0)
00124     {
00125         long int intval = rk >> 2; //drops the 2 bits
00126         printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2);
00127         value = (double) intval;
00128         printf("Double4Byte: VALUEINT=%f\r\n",value);
00129         if ( (rk & 0x01) != 0)
00130         {
00131             value /= 100.0;
00132         };
00133         return value;
00134     }
00135     else
00136     {
00137 
00138         union { double d; unsigned long int b[2]; } dbl_byte;
00139         unsigned long int valbits = (rk & 0xfffffffc);
00140 #if defined(__arm__) && !defined(__vfp__)
00141         dbl_byte.b[0]=valbits;
00142         dbl_byte.b[1]=0;
00143 #else
00144         dbl_byte.b[0]=0;
00145         dbl_byte.b[1]=valbits;
00146 #endif
00147         printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]);
00148         value=dbl_byte.d;
00149         printf("Double4Byte: VALUE=%f\r\n",value);
00150 
00151         if ( (rk & 0x01) != 0)
00152         {
00153             value /= 100.0;
00154         };
00155         return value;
00156     };
00157 };
00158 
00159 void ExcelBook::DetectEndian(void)
00160 {
00161     int end;
00162     long i = 0x44332211;
00163     unsigned char* a = (unsigned char*) &i;
00164     end = (*a != 0x11);
00165     if (end == 1)
00166     {
00167         endian = BIG_ENDIAN;
00168         printf("BIGENDIAN!\r\n");
00169     }
00170     else
00171     {
00172         endian = LITTLE_ENDIAN;
00173         printf("LITTLEENDIAN!\r\n");
00174     }
00175 };
00176 
00177 double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8)
00178 {
00179     int i;
00180     double d;
00181     unsigned char *ieee;
00182     ieee = (unsigned char *)&d;
00183     for (i = 0; i < 8; i++) ieee[i] = 0;
00184     if (endian == BIG_ENDIAN)
00185     {
00186         ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff;
00187         ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff;
00188         ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff;
00189         ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff;
00190     }
00191     else
00192     {
00193         ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff;
00194         ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff;
00195         ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff;
00196         ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff;
00197     }
00198     return d;
00199 };
00200 
00201 bool ExcelBook::OpenFile(char *Filename)
00202 {
00203     printf("Opening excel file!\r\n");
00204     File= fopen(Filename, "r");
00205     Position=0; // first byte index in file
00206     XFRecords.resize(0);
00207     SharedStrings.resize(0);
00208     Names.resize(0);
00209     Sheets.resize(0);
00210     if(File==NULL) return false;
00211     printf("Opened excel file!\r\n");
00212     return true;
00213 };
00214 
00215 bool ExcelBook::CloseFile(void)
00216 {
00217     int w1;
00218     for(w1=0;w1<(int)XFRecords.count();w1++)
00219     {
00220         if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;};
00221     };
00222     for(w1=0;w1<(int)SharedStrings.count();w1++)
00223     {
00224         if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;};
00225     };
00226     for(w1=0;w1<(int)Names.count();w1++)
00227     {
00228         if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;};
00229     };
00230     for(w1=0;w1<(int)Sheets.count();w1++)
00231     {
00232         if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;};
00233     };
00234     XFRecords.resize(0);
00235     SharedStrings.resize(0);
00236     Names.resize(0);
00237     Sheets.resize(0);
00238     fclose(File);
00239     printf("closed excel file!\r\n");
00240     if(File==NULL) return true;
00241     return false;
00242 };
00243 
00244 void ExcelBook::SeekPosition(int pos)
00245 {
00246     if(!feof(File))
00247     {
00248         Position=pos;
00249         //printf("SeekPosition:Pos:%d\r\n",Position);
00250         fseek(File,pos,SEEK_SET);
00251     };
00252 };
00253 
00254 void ExcelBook::SeekSkip(int pos)
00255 {
00256     if(!feof(File))
00257     {
00258         Position=Position+pos;
00259         //printf("SeekSkip:Pos:%d\r\n",Position);
00260         fseek(File, Position, SEEK_SET);
00261     };
00262 };
00263 
00264 int ExcelBook::FileEOF(void)
00265 {
00266     if(File!=NULL) return(feof(File)); else return 0;
00267     //EOF is defined in stdlib as -1
00268 };
00269 
00270 int ExcelBook::Get2Bytes(void)
00271 {
00272     int i1,i2;
00273     i1=0; i2=0;
00274     if (!feof(File))
00275     {
00276         i1=fgetc(File);
00277         Position++;
00278     };
00279     if (!feof(File))
00280     {
00281         i2=fgetc(File);
00282         Position++;
00283     };
00284     return Integer2Byte(i1,i2);
00285 };
00286 
00287 char* ExcelBook::Read(int pos, int length)
00288 {
00289     int i;
00290     char *data;
00291     data= new char[length];
00292     SeekPosition(pos);
00293     for(i=0; i<length; i++)
00294     {
00295         if(!feof(File)) data[i]=fgetc(File);
00296     };
00297     Position= Position+length;
00298     return data;
00299 };
00300 
00301 QString ExcelBook::ReadUnicodeChar(int pos, int length)
00302 {
00303     int i;
00304     QString data;
00305     int i1=' ',i2=' ',ii;
00306     SeekPosition(pos);
00307     for(i=0; i<length; i++)
00308     {
00309         if(!feof(File)) i1=fgetc(File);
00310         if(!feof(File)) i2=fgetc(File);
00311         ii=Integer2Byte(i1,i2);
00312         data.append(ii);
00313         Position+=2;
00314     };
00315     return data;
00316 };
00317 
00318 QString* ExcelBook::GetString(int num)
00319 {
00320     if(num>=0 && num<(int)SharedStrings.count())
00321     {
00322         return SharedStrings[num];
00323     };
00324     return new QString("");
00325 };
00326 
00327 int ExcelBook::SeekBOF(void)
00328 {
00329     int opcode,version,streamtype,length,ret=0;
00330     char *data;
00331     while(!feof(File))
00332     {
00333         opcode=Get2Bytes();
00334         if(opcode==XL_BOF)
00335         {
00336             length=Get2Bytes();
00337             data=Read(Position,length);
00338             version=Integer2Byte(data[0], data[1]);
00339             streamtype=Integer2Byte(data[2], data[3]);
00340             printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version);
00341             delete data; data=NULL;
00342             if (version==BIFF8) ret=8;
00343             else if(version==BIFF7) ret=7;
00344             printf("SEEKBOF:versionBIFF%d\r\n",ret);
00345             if(streamtype==WBKGLOBAL) return ret *2;
00346             else if(streamtype==WRKSHEET) return ret *1;
00347             return 1;
00348         };
00349     };
00350     return 0;
00351 };
00352 
00353 ExcelBREC* ExcelBook::GetBREC(void)
00354 {
00355     ExcelBREC* rec;
00356     rec= new ExcelBREC;
00357     if(FileEOF()) return NULL;
00358     rec->data=NULL;
00359     rec->code=Get2Bytes();
00360     rec->length=Get2Bytes();
00361     rec->position=Position;
00362     SeekSkip(rec->length);
00363     return rec;
00364 };
00365 
00366 ExcelBREC* ExcelBook::PeekBREC(void)
00367 {
00368     int oldpos;
00369     ExcelBREC* NextRec;
00370     oldpos=Position;
00371     NextRec=GetBREC();
00372     SeekPosition(oldpos);
00373     return NextRec;
00374 };
00375 
00376 char* ExcelBook::GetDataOfBREC(ExcelBREC* record)
00377 {
00378     if(record->data==NULL)
00379     {
00380         ConvertCharToArray(record,Read(record->position,record->length),record->length);
00381     };
00382     return record->data;//new?
00383 };
00384 
00385 void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length)
00386 {
00387     record->data=new char[length];
00388     for(int w1=0;w1<=length-1;w1++)
00389         record->data[w1]=chars[w1];
00390 };
00391 
00392 
00393 bool ExcelSheet::InitCells()
00394 {
00395     int r;
00396     Cells.resize(rows * cols + cols+1);
00397     if(Cells.count()==0) return false;
00398     for(r=0;r < Cells.count();r++)
00399     {
00400         Cells[r]=NULL;
00401     };
00402     return true;
00403 };
00404 
00405 void ExcelSheet::Set(int row, int col, ExcelCell* cell)
00406 {
00407     if(cell!=NULL&&(row*cols+col)<Cells.count())
00408     {
00409         Cells[row*cols+col]=cell;
00410     };
00411 };
00412 
00413 ExcelCell* ExcelSheet::Get(int row, int col)
00414 {
00415     ExcelCell* cell;
00416     cell=Cells[row*cols+col];
00417     if(cell==NULL) return NULL;
00418     return cell;
00419 };
00420 
00421 int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record)
00422 {
00423     char* data=NULL;
00424     switch (record->code)
00425     {
00426     case XL_DIMENSION:
00427         data = GetDataOfBREC(record);
00428         if (record->length == 10)
00429         {
00430             sheet->rows = Integer2Byte(data[2], data[3]);
00431             sheet->cols = Integer2Byte(data[6], data[7]);
00432         }
00433         else
00434         {
00435             sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]);
00436             sheet->cols = Integer2Byte(data[10], data[11]);
00437         }
00438         sheet->InitCells();
00439         break;
00440 
00441     case XL_LABELSST:
00442         HandleLabelSST(sheet, record);
00443         break;
00444 
00445     case XL_RK:
00446     case XL_RK2:
00447         HandleRK(sheet, record);
00448         break;
00449 
00450     case XL_MULRK:
00451         HandleMulrk(sheet, record);
00452         break;
00453 
00454     case XL_ROW:
00455         break;
00456 
00457     case XL_NUMBER:
00458         HandleNumber(sheet, record);
00459         break;
00460 
00461     case XL_BOOLERR:
00462         break;
00463 
00464     case XL_CONTINUE:
00465         break;
00466 
00467     case XL_FORMULA:
00468     case XL_FORMULA2:
00469         HandleFormula(sheet, record);
00470         break;
00471 
00472     case XL_LABEL:
00473         break;
00474 
00475     case XL_NAME:
00476         HandleName(sheet, record);
00477         break;
00478 
00479     case XL_BOF:
00480         break;
00481     case XL_EOF:
00482         return 0;
00483     default:
00484         break;
00485     };
00486     return 1;
00487 };
00488 
00489 int ExcelBook::ReadSheet(ExcelSheet* sheet)
00490 {
00491     ExcelBREC* record;
00492     int oldpos;
00493     oldpos = Position;
00494     SeekPosition(sheet->position);
00495     record = GetBREC();
00496     while (record!=NULL)
00497     {
00498         if (!SheetHandleRecord(sheet, record)) break;
00499         record=GetBREC();
00500     };
00501     SeekPosition(oldpos);
00502     return 1;
00503 };
00504 
00505 ExcelSheet* ExcelBook::GetSheet(void)
00506 {
00507     ExcelSheet* sh=NULL;
00508     int type;
00509     type=SeekBOF();
00510     Version=type;
00511     sh=new ExcelSheet;
00512     if(type)
00513     {
00514         sh->type=type;
00515         sh->position=Position;
00516         sh->name=QString("");
00517     };
00518     if(type==8||type==7)
00519     {
00520         ReadSheet(sh);
00521     };
00522     return sh;
00523 };
00524 
00525 void ExcelBook::ParseSheets(void)
00526 {
00527     int BOFs;
00528     ExcelBREC* r;
00529     BOFs=1;
00530     r=GetBREC();
00531     while(BOFs)
00532     {
00533         r=GetBREC();
00534         switch(r->code)
00535         {
00536         case XL_SST:
00537             HandleSST(r);
00538             break;
00539 
00540         case XL_TXO:
00541             break;
00542         case XL_NAME:
00543             break;
00544         case XL_ROW:
00545             break;
00546 
00547         case XL_FORMAT:
00548             HandleFormat(r);
00549             break;
00550 
00551         case XL_XF:
00552             HandleXF(r);
00553             break;
00554 
00555         case XL_BOUNDSHEET:
00556             HandleBoundSheet(r);
00557             break;
00558 
00559         case XL_EXTSST:
00560             break;
00561         case XL_CONTINUE:
00562             break;
00563 
00564         case XL_EOF:
00565             BOFs--;
00566             break;
00567 
00568         default:
00569             break;
00570         };
00571     };
00572 };
00573 
00574 void ExcelBook::GetSheets(void)
00575 {
00576     ExcelSheet* sheet;
00577     Sheets.resize(0);
00578     sheet=GetSheet();
00579     while (sheet->Cells.count()!= 0 )
00580     {
00581         Sheets.resize(Sheets.count()+1);
00582         Sheets[Sheets.count()-1]=sheet;
00583         sheet->name=*Names[Sheets.count()-1];
00584         sheet=GetSheet();
00585     };
00586 };
00587 
00588 bool ExcelBook::ParseBook(char *file)
00589 {
00590     dateformat=QString("");
00591     DetectEndian();
00592     if ( !OpenFile( file ) )
00593             return false;
00594     SeekBOF();
00595     ParseSheets();
00596     GetSheets();
00597     return true;
00598 };
00599 
00600 QString ExcelBook::GetASCII(char* inbytes, int pos, int chars)
00601 {
00602     int i;
00603     QString outstr="";
00604     for (i = 0; i < chars; i++)
00605     {
00606         outstr.append(inbytes[i+pos]);
00607     };
00608     return outstr;
00609 };
00610 
00611 QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars)
00612 {
00613     QString outstr="";
00614     int i;
00615     int rc;
00616     for (i=0; i<chars*2; i++)
00617     {
00618         rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]);
00619         outstr.append(QChar(rc));
00620         i++;
00621     };
00622     return outstr;
00623 };
00624 
00625 
00626 void ExcelBook::HandleBoundSheet(ExcelBREC* rec)
00627 {
00628     char* data;
00629     int type;
00630     int visibility;
00631     int length;
00632     int pos;
00633     QString name;
00634     pos = 8;
00635     data   = GetDataOfBREC(rec);
00636     type = data[4];
00637     visibility = data[5];
00638     length = data[6];
00639     if(data[7]==0)
00640     {
00641         //ascii
00642         name=GetASCII(data,pos,length);
00643     }
00644     else
00645     {
00646         name=GetUnicode(data,pos,length);
00647     };
00648     Names.resize(Names.count()+1);
00649     Names[Names.count()-1]=new QString(name);
00650 };
00651 
00652 void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec)
00653 {
00654     char* data;
00655     QString name;
00656     int length;
00657     int pos;
00658     pos = 15;
00659     data   = GetDataOfBREC(rec);
00660     length = data[3];
00661     name = GetASCII(data,pos,length);
00662 
00663 
00664 };
00665 
00666 ExcelFormat* ExcelBook::GetFormatting(int xf)
00667 {
00668     int i;
00669     ExcelFormat* rec;
00670     rec=new ExcelFormat();
00671     for (i = 0; formatter[i].code != 0; i++)
00672     {
00673         if (xf == formatter[i].code) break;
00674     };
00675     if (formatter[i].format ==NULL) return NULL;
00676     rec->code   = xf;
00677     rec->type   = formatter[i].type;
00678     rec->format = formatter[i].format;
00679     return rec;
00680 };
00681 
00682 void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes)
00683 {
00684     QString str=QString("");
00685     char* data;
00686     int chars, pos, options, i;
00687     int richstring, fareaststring, runlength=0;
00688     int richruns=0,fareastsize=0;
00689     int totalstrings;
00690     int uniquestrings;
00691     data = GetDataOfBREC(rec);
00692     totalstrings  = Integer4Byte(data[0], data[1], data[2], data[3]);
00693     uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]);
00694     pos = 8;
00695     for (i = 0; i < uniquestrings; i++)
00696     {
00697         richruns=0; fareastsize=0;
00698         chars = Integer2Byte(data[pos], data[pos+1]);
00699         pos += 2;
00700         options = data[pos];
00701         pos++;
00702         fareaststring = ((options & 0x04) != 0);
00703         richstring     = ((options & 0x08) != 0);
00704         if(richstring)
00705         {
00706             richruns= Integer2Byte(data[pos],data[pos+1]);
00707             pos+=2;
00708         };
00709         if(fareaststring)
00710         {
00711             fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]);
00712             pos+=4;
00713         };
00714 
00715         if ((options & 0x01) == 0) //8 bit chars
00716         {
00717             /* ascii */
00718             str = GetASCII(bytes,pos,chars);
00719             pos=pos+chars;
00720             if(str[0]=='=') str[0]=' ';
00721         }else //16 bit chars
00722         {
00723             /* unicode */
00724             str = GetUnicode(bytes,pos,chars);
00725             pos=pos+chars*2;
00726         };
00727         // HERE TO PUT richformat handling
00728         if (richstring)
00729         {
00730             pos += 4 * richruns;
00731         };
00732         if (fareaststring)
00733         {
00734             pos += fareastsize;
00735         };
00736         //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode());
00737         SharedStrings.resize(SharedStrings.count()+1);
00738         SharedStrings[SharedStrings.count()-1]=new QString(str);
00739     }
00740 };
00741 
00742 
00743 char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont)
00744 {
00745     int i, pos;
00746     int length;
00747 
00748     char* data;
00749     char* bytes;
00750     length = rec->length;
00751     for (i = 0; i < (int) cont->rec.count(); i++)
00752     {
00753         length += cont->rec[i]->length;
00754     }
00755     bytes = GetDataOfBREC(rec);
00756     pos = rec->length;
00757     for (i = 0; i < (int) cont->rec.count(); i++)
00758     {
00759         data = GetDataOfBREC(cont->rec[i]);
00760         *bytes += pos;
00761         bytes = data;
00762         pos += cont->rec[i]->length;
00763     }
00764     return bytes;
00765 };
00766 
00767 
00768 void ExcelBook::HandleSST(ExcelBREC* rec)
00769 {
00770     char* bytes;
00771     SSTList* cont;
00772     cont= new SSTList;
00773     ExcelBREC* nr;
00774     nr = PeekBREC();
00775     while (nr->code == XL_CONTINUE)
00776     {
00777         cont->rec.resize(cont->rec.count()+1);
00778         cont->rec[cont->rec.count()-1]=GetBREC();
00779         nr = PeekBREC();
00780     }
00781     bytes = MergeBytesFromSSTs(rec,cont);
00782     HandleSetOfSST(rec, bytes);
00783     for(int w1=0;w1<(int)cont->rec.count();w1++)
00784     {
00785         if(cont->rec[w1]!=NULL) {delete cont->rec[w1];cont->rec[w1]=NULL;};
00786     };
00787     cont->rec.resize(0);
00788 };
00789 
00790 void ExcelBook::HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec)
00791 {
00792     int index, row, col;
00793     char* data;
00794     data = GetDataOfBREC(rec);
00795     index = Integer4Byte(data[6], data[7], data[8], data[9]);
00796     row = Integer2Byte(data[0], data[1]);
00797     col = Integer2Byte(data[2], data[3]);
00798     sheet->Set(row,col, CellLabel(row, col, *GetString(index)));
00799 };
00800 
00801 ExcelCell* ExcelBook::CellLabel(int row, int col, QString str)
00802 {
00803     ExcelCell* c;
00804     c= new ExcelCell;
00805     c->row = row;
00806     c->col = col;
00807     c->type = CELL_LABEL;
00808     c->valuec = str;
00809     return c;
00810 };
00811 
00812 ExcelCell* ExcelBook::CellNumber(int row, int col, int index, double d)
00813 {
00814     ExcelCell* c;
00815     c=new ExcelCell;
00816     c->row = row;
00817     c->col = col;
00818     c->xfindex = index;
00819     c->type = CELL_NUMBER;
00820     c->valued = d;
00821     return c;
00822 };
00823 
00824 QString* ExcelBook::CellDataString(ExcelSheet* sh, int row, int col)
00825 {
00826     time_t date;
00827     struct tm *tmptr;
00828     ExcelCell* c;
00829     char str[128];
00830     QString format;
00831     int precision;
00832     int utcOffsetDays = 25569;
00833     int sInADay = 24 * 60 * 60;
00834     c = sh->Get(row,col);
00835     if (c == NULL) return new QString("");
00836     switch (c->type)
00837     {
00838     case CELL_LABEL:
00839         return new QString(c->valuec);
00840     case CELL_NUMBER:
00841         if (XFRecords[c->xfindex]->type == DATEFORMAT)
00842         {
00843 
00844             format = XFRecords[c->xfindex]->format;
00845             date = (time_t) ((c->valued - utcOffsetDays) * sInADay);
00846             tmptr = gmtime(&date);
00847             if (dateformat)
00848             {
00849                 strftime(str,1024,dateformat.ascii(),tmptr);
00850             }
00851             else
00852             {
00853                 strftime(str,1024,format.ascii(),tmptr);
00854             };
00855         }
00856         else
00857             if (XFRecords[c->xfindex]->type == NUMBERFORMAT)
00858             {
00859                 format = XFRecords[c->xfindex]->format;
00860                 //sprintf(str,format.ascii(),c->valued);
00861                 // the real format is ignored...
00862                 // because there is more work to be done in the field
00863                 precision = CellGetPrecision(c->valued);
00864                 sprintf(str,"%.*f",precision,c->valued);
00865             }
00866             else
00867             {
00868                 precision = CellGetPrecision(c->valued);
00869                 sprintf(str,"%.*f",precision,c->valued);
00870             };
00871         break;
00872     case CELL_DATE:
00873         break;
00874     case CELL_BOOLEAN:
00875         break;
00876     case CELL_ERROR:
00877         break;
00878     }
00879     return new QString(str);
00880 };
00881 
00882 int ExcelBook::CellGetPrecision(double d)
00883 {
00884     double t;
00885     int i,x;
00886     int count;
00887     if (d < 0) d *= -1;
00888     i = (int)d;
00889     t = d - (double)i;
00890     if (t <= 0)
00891     {
00892         return 0;
00893     };
00894     count = 0;
00895     for (x = 6; x > 1; x--)
00896     {
00897         i = (int)d;
00898         t = d - (double)i;
00899         t *= pow(10,x - 2);
00900         i = (int)t;
00901         t = t - (double)i;
00902         t *= 10;
00903         i = (int)t;
00904         if (i > 0) break;
00905         count++;
00906     };
00907     return (5 - count);
00908 };
00909 
00910 
00911 void ExcelBook::CellSetDateFormat(char *d)
00912 {
00913     dateformat = QString(d);
00914 };
00915 
00916 void ExcelBook::HandleMulrk(ExcelSheet* sheet, ExcelBREC* record)
00917 {
00918     struct mulrk mulrk;
00919     char* data;
00920     ExcelCell* cell;
00921     int len;
00922     int i;
00923     len = record->length;
00924     data = GetDataOfBREC(record);
00925     mulrk.row   = Integer2Byte(data[0],data[1]);
00926     mulrk.first = Integer2Byte(data[2],data[3]);
00927     mulrk.last  = Integer2Byte(data[len - 2],data[len - 1]);
00928     mulrk.numrks = mulrk.last - mulrk.first + 1;
00929     MulrkRead(&mulrk, data);
00930     for (i = 0; i < mulrk.numrks; i++)
00931     {
00932         cell = CellNumber(mulrk.row, mulrk.first + i, mulrk.xfindices[i], mulrk.rkdbls[i]);
00933         sheet->Set(mulrk.row,mulrk.first+ i, cell);
00934         //printf("handleMULRK:row=%d,col=%d,val=%f\r\n",mulrk.row,mulrk.first+i,mulrk.rkdbls[i]);
00935     }
00936     //delete(mulrk.xfindices);
00937     //delete(mulrk.rkdbls);
00938 };
00939 
00940 void ExcelBook::MulrkRead(struct mulrk *mulrk, char* data)
00941 {
00942     double d;
00943     int i;
00944     int pos;
00945     pos = 4;
00946     mulrk->xfindices.resize(mulrk->numrks);
00947     mulrk->rkdbls.resize(mulrk->numrks);
00948     for (i = 0; i < mulrk->numrks; i++)
00949     {
00950         mulrk->xfindices[i] = Integer2Byte(data[pos], data[pos+1]);
00951         d=Double4Byte(data[pos+2], data[pos+3], data[pos+4], data[pos+5]);
00952         //printf("double:%f\r\n",d);
00953         mulrk->rkdbls[i] = d;
00954         pos += 6;
00955     }
00956 };
00957 
00958 
00959 void ExcelBook::HandleNumber(ExcelSheet* sheet, ExcelBREC* record)
00960 {
00961     int xfindex, row, col;
00962     char* data;
00963     double d;
00964     data = GetDataOfBREC(record);
00965     row = Integer2Byte(data[0], data[1]);
00966     col = Integer2Byte(data[2], data[3]);
00967     xfindex = Integer2Byte(data[4], data[5]);
00968 #if defined(__arm__) && !defined(__vfp__)
00969     d=Double8Byte(data[10], data[11], data[12], data[13],data[6], data[7], data[8], data[9]);
00970 #else
00971     d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]);
00972 #endif
00973     //even if ARM is little endian... doubles are been placed as bigendian words.
00974     //thanks pb_ for that. :)
00975     sheet->Set(row,col, CellNumber(row,col,xfindex,d));
00976     //printf("handleNumber:row=%d,col=%d,val=%f\r\n",row,col,d);
00977 };
00978 
00979 ExcelFormat::ExcelFormat()
00980 {
00981     code=0;type=0;format="";
00982 };
00983 
00984 ExcelFormat::ExcelFormat(int c,int t, QString s)
00985 {
00986     code=c;type=t;format=s;
00987 };
00988 
00989 
00990 void ExcelBook::HandleFormat(ExcelBREC* rec)
00991 {
00992     ExcelFormat* xfrec;
00993     char* data;
00994     int format;
00995     data   = GetDataOfBREC(rec);
00996     format = Integer2Byte(data[2],data[3]);
00997     xfrec  = GetFormatting(format);
00998     /*int idx;
00999     idx=XFRecords.count()-1;
01000     XFRecords[idx]->code=xfrec->code;
01001     XFRecords[idx]->type=xfrec->type;
01002     XFRecords[idx]->format="manos";
01003     //XFRecords[XFRecords.count()-1]=xfrec;
01004     printf("6\r\n");*/
01005 };
01006 
01007 void ExcelBook::HandleXF(ExcelBREC* rec)
01008 {
01009     ExcelFormat* xfrec;
01010     char* data;
01011     int format;
01012     data   = GetDataOfBREC(rec);
01013     format = Integer2Byte(data[2],data[3]);
01014     xfrec  = GetFormatting(format);
01015     XFRecords.resize(XFRecords.count()+1);
01016     XFRecords[XFRecords.count()-1]=xfrec;
01017 };
01018 
01019 
01020 
01021 void ExcelBook::HandleRK(ExcelSheet* sheet, ExcelBREC* record)
01022 {
01023     int xfindex, row, col;
01024     char* data;
01025     double d;
01026     data = GetDataOfBREC(record);
01027     row = Integer2Byte(data[0], data[1]);
01028     col = Integer2Byte(data[2], data[3]);
01029     xfindex = Integer2Byte(data[4], data[5]);
01030     d=Double4Byte(data[6], data[7], data[8], data[9]);
01031     sheet->Set(row,col,CellNumber(row,col,xfindex,d));
01032     //printf("handleRK:row=%d,col=%d,val=%f\r\n",row,col,d);
01033 };
01034 
01035 
01036 void ExcelBook::HandleFormula(ExcelSheet* sheet, ExcelBREC* record)
01037 {
01038     int xfindex, row, col;
01039     char* data;
01040     double d;
01041     data = GetDataOfBREC(record);
01042     row = Integer2Byte(data[0], data[1]);
01043     col = Integer2Byte(data[2], data[3]);
01044     if (data[6] == 0 && data[12] == -1 && data[13] == -1)
01045     {
01046         // string
01047     }
01048     else
01049         if (data[6] == 1  && data[12] == -1 && data[13] == -1)
01050         {
01051             // boolean
01052         }
01053         else
01054             if ( data[6] == 2 && data[12] == -1 && data[13] == -1)
01055             {
01056                 // error
01057             }
01058             else
01059             {
01060                 // number
01061                 xfindex = Integer2Byte(data[4], data[5]);
01062                 d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]);
01063                 QString s1;
01064                 int sz;
01065                 sz=Integer2Byte(data[20],data[21]);// size of the formula
01066                 char* formuladata;
01067                 formuladata=new char[sz];
01068                 for(int w1=0;w1<sz;w1++)
01069                 {
01070                     formuladata[w1]=data[22+w1];
01071                 };
01072                 //22 is the first 0 idx of formula data
01073                 s1="="+GetFormula(row,col,sheet,formuladata,sz);
01074                 //printf("GetFormula:Formula=%s\r\n",s1.ascii());
01075                 sheet->Set(row,col,CellLabel(row,col,s1));
01076             }
01077 };
01078 
01079 
01080 QString ExcelBook::GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz)
01081 {
01082     int length=sz;
01083     printf("{FormulaParser}\r\n");
01084     printf("row=%d, col=%d, length=%d\r\n",row,col,length);
01085     int idx=0;
01086     int w1,w2,w3,w4;
01087     double d1;
01088     int token;
01089     QString s1;
01090     QList <QString> operands;
01091     operands.setAutoDelete(TRUE);
01092     QString formula;
01093     operands.clear();
01094     while( idx<length )
01095     {
01096         token= data[idx]; idx++;
01097         switch(token)
01098         {
01099         case 0x1E: //prtInt
01100             w1=Integer2Byte(data[idx],data[idx+1]);
01101             idx=idx+2;
01102             operands.prepend(new QString(QString::number(w1)));
01103             printf(" token:ptgInt,num=%d\r\n",w1);
01104             break;
01105         case 0x1F: //ptgNumber
01106 #if defined(__arm__) && !defined(__vfp__)
01107             d1=Double8Byte(data[idx+4],data[idx+5],data[idx+6],data[idx+7]
01108                            ,data[idx],data[idx+1],data[idx+2],data[idx+3]);
01109 #else
01110             d1=Double8Byte(data[idx],data[idx+1],data[idx+2],data[idx+3]
01111                            ,data[idx+4],data[idx+5],data[idx+6],data[idx+7]);
01112 #endif
01113             idx=idx+8;
01114             operands.prepend(new QString(QString::number(d1)));
01115             printf(" token:ptgNumber,num=%f\r\n",d1);
01116             break;
01117         case 0x17: //ptgStr
01118             if(Version==8)
01119             {
01120                 //unicode string
01121                 //w1=Integer2Byte(data[idx],data[idx+1]);idx+=2;
01122                 w1=data[idx];idx++;
01123                 printf("len=%d\r\n",w1);
01124                 int richruns=0; int fareastsize=0;
01125                 int richstring,fareaststring;
01126                 int options = data[idx];idx++;
01127                 fareaststring = ((options & 0x04) != 0);
01128                 richstring     = ((options & 0x08) != 0);
01129                 if(richstring)
01130                 {
01131                     //containts rich string formatting.
01132                     printf("STRING:richstring\r\n");
01133                     richruns= Integer2Byte(data[idx],data[idx+1]);
01134                     printf("richruns:%d\r\n",richruns);
01135                     idx+=2;
01136                 };
01137                 if(fareaststring)
01138                 {
01139                     //contains far east formatting
01140                     printf("STRING:fareast!\r\n");
01141                     fareastsize=Integer4Byte(data[idx], data[idx+1],
01142                                              data[idx+2], data[idx+3]);
01143                     printf("fareastsize=%d",fareastsize);
01144                     idx+=4;
01145                 };
01146                 if ((options & 0x01) == 0) //8 bit chars
01147                 {
01148                     /* ascii */
01149                     s1 = GetASCII(data,idx,w1);
01150                     idx=idx+w1;
01151                     printf("STRING:ASCII=%s\r\n",s1.ascii());
01152                 }else //16 bit chars
01153                 {
01154                     /* unicode */
01155                     s1 = GetUnicode(data,idx,w1);
01156                     idx=idx+w1*2;
01157                     printf("STRING:unicode=%s\r\n",s1.ascii());
01158                 };
01159                 // HERE TO PUT richformat handling
01160                 if (richstring)
01161                 {
01162                     idx += 4 * richruns;
01163                 };
01164                 if (fareaststring)
01165                 {
01166                     idx += fareastsize;
01167                 };
01168                 s1=QString("""")+s1+QString("""");
01169                 operands.prepend(new QString(s1));
01170             }
01171             else
01172             {
01173                 w1=data[idx];idx++;
01174                 s1=GetASCII(data,idx,w1);
01175                 s1=QString("""")+s1+QString("""");
01176                 idx=idx+w1;
01177                 operands.prepend(new QString(s1));
01178             };
01179             printf(" token:ptgStr,num=%d\r\n",w1);
01180             break;
01181         case 0x25:
01182         case 0x45:
01183         case 0x65: // ptgArea
01184             if(Version==8)
01185             {
01186                 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row1
01187                 w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row2
01188                 w3=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col1
01189                 w4=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col2
01190             }
01191             else
01192             {
01193                 w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row1
01194                 w2=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row2
01195                 w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col1
01196                 w4=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col2
01197             };
01198             //ignores relative or absolute refs
01199             s1=FindCellName(w1,w3)+":"+FindCellName(w2,w4);
01200             printf(" token:ptgArea,ref=%s\r\n",s1.ascii());
01201             operands.prepend(new QString(s1));
01202             break;
01203         case 0x24:
01204         case 0x44:
01205         case 0x64://ptgRef
01206             if(Version==8)
01207             {
01208                 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row
01209                 w2=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col
01210             }
01211             else
01212             {
01213                 w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row
01214                 w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col
01215             };
01216             s1=FindCellName(w1,w2);
01217             printf("token:ptgRef,ref=%s\r\n",s1.ascii());
01218             operands.prepend(new QString(s1));
01219             break;
01220         case 0x1D: // ptgBool
01221             w1=data[idx];idx++;
01222             printf("token:ptgBool,val=%d\r\n",w1);
01223             operands.prepend(new QString(QString::number(w1)));
01224             break;
01225         case 0x16://ptg MissArg
01226             printf("token:ptgMissArg, val=' '\r\n");
01227             operands.prepend(new QString("0"));
01228             break;
01229         case 0x12://ptgUplus==
01230             printf("token:ptgUplus\r\n");
01231             s1=QString("+")+operands.first()->ascii();
01232             operands.removeFirst();
01233             operands.prepend(new QString(s1));
01234             break;
01235         case 0x13://ptgUminus
01236             printf("token:ptgUminus\r\n");
01237             s1=QString("-")+operands.first()->ascii();
01238             operands.removeFirst();
01239             operands.prepend(new QString(s1));
01240             break;
01241         case 0x03://ptgAdd
01242             printf("token:ptgAdd\r\n");
01243             operands.first();
01244             s1=operands.next()->ascii()
01245                +QString("+")+operands.first()->ascii();
01246             operands.removeFirst();operands.removeFirst();
01247             operands.prepend(new QString(s1));
01248             break;
01249         case 0x04://ptgSub
01250             printf("token:ptgSub\r\n");
01251             operands.first();
01252             s1=operands.next()->ascii()
01253                +QString("-")+operands.first()->ascii();
01254             operands.removeFirst();operands.removeFirst();
01255             operands.prepend(new QString(s1));
01256             break;
01257         case 0x05://ptgMul
01258             printf("token:ptgMul\r\n");
01259             operands.first();
01260             s1=operands.next()->ascii()
01261                +QString("*")+operands.first()->ascii();
01262             operands.removeFirst();operands.removeFirst();
01263             operands.prepend(new QString(s1));
01264             break;
01265         case 0x06://ptgDiv
01266             printf("token:ptgDiv\r\n");
01267             operands.first();
01268             s1=operands.next()->ascii()
01269                +QString("/")+operands.first()->ascii();
01270             operands.removeFirst();operands.removeFirst();
01271             operands.prepend(new QString(s1));
01272             break;
01273         case 0x07://ptgPOWER
01274             printf("token:ptgPow\r\n");
01275             operands.first();
01276             s1=QString("POWER(")+operands.next()->ascii()
01277                +QString(",")+operands.first()->ascii()+QString(")");
01278             operands.removeFirst();operands.removeFirst();
01279             operands.prepend(new QString(s1));
01280             break;
01281         case 0x08://ptgConcat
01282             printf("token:ptgConcat\r\n");
01283             operands.first();
01284             s1=QString("CONCATENATE(")+operands.next()->ascii()
01285                +QString(",")+operands.first()->ascii()+QString(")");
01286             operands.removeFirst();operands.removeFirst();
01287             operands.prepend(new QString(s1));
01288             break;
01289         case 0x15://ptgParenthesis
01290             printf("token:ptgParenthesis\r\n");
01291             s1=QString("(")+operands.first()->ascii()+QString(")");
01292             operands.removeFirst();
01293             operands.prepend(new QString(s1));
01294             break;
01295         case 0x14://ptgPercent
01296             printf("token:ptgPercent\r\n");
01297             s1=operands.first()->ascii()+QString("*0.01");
01298             operands.removeFirst();
01299             operands.prepend(new QString(s1));
01300             break;
01301         case 0x9://ptgLessThan
01302             printf("token:ptgLESS\r\n");
01303             operands.first();
01304             s1=operands.next()->ascii()
01305                +QString("<")+operands.first()->ascii();
01306             operands.removeFirst();operands.removeFirst();
01307             operands.prepend(new QString(s1));
01308             break;
01309         case 0xa://ptgLessEqual
01310             printf("token:ptgLESS_EQUAL\r\n");
01311             operands.first();
01312             s1=operands.next()->ascii()
01313                +QString("<=")+operands.first()->ascii();
01314             operands.removeFirst();operands.removeFirst();
01315             operands.prepend(new QString(s1));
01316             break;
01317         case 0xb://ptgEQUAL
01318             printf("token:ptgEQUAL\r\n");
01319             operands.first();
01320             s1=operands.next()->ascii()
01321                +QString("==")+operands.first()->ascii();
01322             operands.removeFirst();operands.removeFirst();
01323             operands.prepend(new QString(s1));
01324             break;
01325         case 0xc://ptgGREATER_EQUAL
01326             printf("token:ptgGREAT_EQUAL\r\n");
01327             operands.first();
01328             s1=operands.next()->ascii()
01329                +QString(">=")+operands.first()->ascii();
01330             operands.removeFirst();operands.removeFirst();
01331             operands.prepend(new QString(s1));
01332             break;
01333         case 0xd://ptgGREAT_THAN
01334             printf("token:ptgGREAT_THAN\r\n");
01335             operands.first();
01336             s1=operands.next()->ascii()
01337                +QString(">")+operands.first()->ascii();
01338             operands.removeFirst();operands.removeFirst();
01339             operands.prepend(new QString(s1));
01340             break;
01341         case 0xe://ptgNOT_EQUAL
01342             printf("token:ptgNOTequal\r\n");
01343             operands.first();
01344             s1=operands.next()->ascii()
01345                +QString("!=")+operands.first()->ascii();
01346             operands.removeFirst();operands.removeFirst();
01347             operands.prepend(new QString(s1));
01348             break;
01349         case 0x19://attribute can be Sum,If,Choose
01350             w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
01351             idx++;
01352             printf("token:ATTRIBUTE:0x%x\r\n",w3);
01353             for(w4=idx;w4<length;w4++)
01354                 printf("0x%x, ",data[w4]);
01355             if(w3&0x01)//choose
01356             {
01357                 printf("token:CHOOSE\r\n");
01358             }
01359             else if(w3&0x02)//if
01360             {
01361                 printf("token:IF\r\n");
01362             }
01363             else if(w3&0x10)//sum
01364             {
01365                 printf("token:SUM\r\n");
01366             };
01367 
01368             break;
01369 
01370 
01371         case 0x21:
01372         case 0x22:
01373         case 0x42:
01374         case 0x62:
01375         case 0x41:
01376         case 0x61://ptgFunction
01377             printf("token:ptgFunction\r\n");
01378             if(token==0x22||token==0x42||token==0x62)
01379             {
01380                 w2=(int)data[idx];idx++;
01381                 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
01382             }
01383             else
01384             {
01385                 w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
01386             };
01387             switch(w1)
01388             {
01389             case 0xf://SIN
01390                 s1=QString("SIN(")+operands.first()->ascii()+QString(")");
01391                 operands.removeFirst();
01392                 operands.prepend(new QString(s1));
01393                 break;
01394             case 0x10://COS
01395                 s1=QString("COS(")+operands.first()->ascii()+QString(")");
01396                 operands.removeFirst();
01397                 operands.prepend(new QString(s1));
01398                 break;
01399             case 0x11://tan
01400                 s1=QString("TAN(")+operands.first()->ascii()+QString(")");
01401                 operands.removeFirst();
01402                 operands.prepend(new QString(s1));
01403                 break;
01404             case 0x62://asin
01405                 s1=QString("ASIN(")+operands.first()->ascii()+QString(")");
01406                 operands.removeFirst();
01407                 operands.prepend(new QString(s1));
01408                 break;
01409             case 0x63://ACOS
01410                 s1=QString("ACOS(")+operands.first()->ascii()+QString(")");
01411                 operands.removeFirst();
01412                 operands.prepend(new QString(s1));
01413                 break;
01414             case 0x12://ATAN
01415                 s1=QString("ATAN(")+operands.first()->ascii()+QString(")");
01416                 operands.removeFirst();
01417                 operands.prepend(new QString(s1));
01418                 break;
01419             case 0xe5://SINH
01420                 s1=QString("SINH(")+operands.first()->ascii()+QString(")");
01421                 operands.removeFirst();
01422                 operands.prepend(new QString(s1));
01423                 break;
01424             case 0xe6://COSH
01425                 s1=QString("COSH(")+operands.first()->ascii()+QString(")");
01426                 operands.removeFirst();
01427                 operands.prepend(new QString(s1));
01428                 break;
01429             case 0xe7://TANH
01430                 s1=QString("TANH(")+operands.first()->ascii()+QString(")");
01431                 operands.removeFirst();
01432                 operands.prepend(new QString(s1));
01433                 break;
01434             case 0xe8://ASINH
01435                 s1=QString("ASINH(")+operands.first()->ascii()+QString(")");
01436                 operands.removeFirst();
01437                 operands.prepend(new QString(s1));
01438                 break;
01439             case 0xe9://ACOSH
01440                 s1=QString("ACOSH(")+operands.first()->ascii()+QString(")");
01441                 operands.removeFirst();
01442                 operands.prepend(new QString(s1));
01443                 break;
01444             case 0xea://ATANH
01445                 s1=QString("ATANH(")+operands.first()->ascii()+QString(")");
01446                 operands.removeFirst();
01447                 operands.prepend(new QString(s1));
01448                 break;
01449             case 0x13://pi
01450                 s1="PI()";
01451                 operands.prepend(new QString(s1));
01452                 break;
01453             case 0x14://sqrt
01454                 s1=QString("SQRT(")+operands.first()->ascii()+QString(")");
01455                 operands.removeFirst();
01456                 operands.prepend(new QString(s1));
01457                 break;
01458             case 0x15://exp
01459                 s1=QString("EXP(")+operands.first()->ascii()+QString(")");
01460                 operands.removeFirst();
01461                 operands.prepend(new QString(s1));
01462                 break;
01463             case 0x16://LN
01464                 s1=QString("LN(")+operands.first()->ascii()+QString(")");
01465                 operands.removeFirst();
01466                 operands.prepend(new QString(s1));
01467                 break;
01468             case 0x17://LOG10
01469                 s1=QString("LOG10(")+operands.first()->ascii()+QString(")");
01470                 operands.removeFirst();
01471                 operands.prepend(new QString(s1));
01472                 break;
01473             case 0x18://ABS
01474                 s1=QString("ABS(")+operands.first()->ascii()+QString(")");
01475                 operands.removeFirst();
01476                 operands.prepend(new QString(s1));
01477                 break;
01478             case 0x19://int
01479                 s1=QString("INT(")+operands.first()->ascii()+QString(")");
01480                 operands.removeFirst();
01481                 operands.prepend(new QString(s1));
01482                 break;
01483             case 0x1a://sign
01484                 s1=QString("SIGN(")+operands.first()->ascii()+QString(")");
01485                 operands.removeFirst();
01486                 operands.prepend(new QString(s1));
01487                 break;
01488             case 0x1b://round
01489                 operands.first();
01490                 s1=QString("ROUND(")+operands.next()->ascii()
01491                    +QString(",")+operands.first()->ascii()
01492                    +QString(")");
01493                 operands.removeFirst();operands.removeFirst();
01494                 operands.prepend(new QString(s1));
01495                 break;
01496             case 0x1d://index
01497                 operands.first();
01498                 s1=QString("INDEX(")+operands.next()->ascii()
01499                    +QString(",")
01500                    +operands.first()->ascii()+QString(")");
01501                 operands.removeFirst();
01502                 operands.removeFirst();
01503                 operands.prepend(new QString(s1));
01504                 break;
01505             case 0x1: // if ATTRIBUTE
01506                 operands.first();operands.next();
01507                 s1=QString("IF(")+operands.next()->ascii()+QString(",");
01508                 operands.first();
01509                 s1=s1+operands.next()->ascii()+QString(",");
01510                 s1=s1+operands.first()->ascii()+QString(")");
01511                 operands.removeFirst();
01512                 operands.removeFirst();
01513                 operands.removeFirst();
01514                 operands.prepend(new QString(s1));
01515                 break;
01516             case 0x81://isblank
01517                 s1=QString("ISBLANK(")+operands.first()->ascii()
01518                    +QString(")");
01519                 operands.removeFirst();
01520                 operands.prepend(new QString(s1));
01521                 break;
01522             case 0x80://isnumber
01523                 s1=QString("ISNUMBER(")+operands.first()->ascii()
01524                    +QString(")");
01525                 operands.removeFirst();
01526                 operands.prepend(new QString(s1));
01527                 break;
01528             case 0x120://ceiling
01529                 operands.first();
01530                 s1=QString("CEILING(")+operands.next()->ascii()
01531                    +QString(",")+operands.first()->ascii()
01532                    +QString(")");
01533                 operands.removeFirst();operands.removeFirst();
01534                 operands.prepend(new QString(s1));
01535                 break;
01536             case 0x11d://floor
01537                 operands.first();
01538                 s1=QString("FLOOR(")+operands.next()->ascii()
01539                    +QString(",")+operands.first()->ascii()
01540                    +QString(")");
01541                 operands.removeFirst();operands.removeFirst();
01542                 operands.prepend(new QString(s1));
01543                 break;
01544             case 0x157://degrees
01545                 s1=QString("DEGREES(")+operands.first()->ascii()
01546                    +QString(")");
01547                 operands.removeFirst();
01548                 operands.prepend(new QString(s1));
01549                 break;
01550             case 0x156://radians
01551                 s1=QString("RADIANS(")+operands.first()->ascii()
01552                    +QString(")");
01553                 operands.removeFirst();
01554                 operands.prepend(new QString(s1));
01555                 break;
01556             case 0xb8://fact
01557                 s1=QString("FACT(")+operands.first()->ascii()
01558                    +QString(")");
01559                 operands.removeFirst();
01560                 operands.prepend(new QString(s1));
01561                 break;
01562             case 0x27://MOD
01563                 operands.first();
01564                 s1=QString("MOD(")+operands.next()->ascii()
01565                    +QString(",")+operands.first()->ascii()
01566                    +QString(")");
01567                 operands.removeFirst();operands.removeFirst();
01568                 operands.prepend(new QString(s1));
01569                 break;
01570             case 0x151://power
01571                 operands.first();
01572                 s1=QString("POWER(")+operands.next()->ascii()
01573                    +QString(",")+operands.first()->ascii()
01574                    +QString(")");
01575                 operands.removeFirst();operands.removeFirst();
01576                 operands.prepend(new QString(s1));
01577                 break;
01578             case 0x3f://rand()
01579                 s1="RAND()";
01580                 operands.prepend(new QString(s1));
01581                 break;
01582             case 0x4://sum
01583                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01584                 s1=QString("SUM(")+operands.first()->ascii()
01585                    +QString(")");
01586                 operands.removeFirst();
01587                 operands.prepend(new QString(s1));
01588                 break;
01589             case 0x6://min
01590                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01591                 s1=QString("MIN(")+operands.first()->ascii()
01592                    +QString(")");
01593                 operands.removeFirst();
01594                 operands.prepend(new QString(s1));
01595                 break;
01596             case 0x7://max
01597                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01598                 s1=QString("MAX(")+operands.first()->ascii()
01599                    +QString(")");
01600                 operands.removeFirst();
01601                 operands.prepend(new QString(s1));
01602                 break;
01603             case 0x5://average
01604                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01605                 s1=QString("AVERAGE(")+operands.first()->ascii()
01606                    +QString(")");
01607                 operands.removeFirst();
01608                 operands.prepend(new QString(s1));
01609                 break;
01610             case 0x2e://var
01611                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01612                 s1=QString("VAR(")+operands.first()->ascii()
01613                    +QString(")");
01614                 operands.removeFirst();
01615                 operands.prepend(new QString(s1));
01616                 break;
01617             case 0xc2://varp
01618                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01619                 s1=QString("VARP(")+operands.first()->ascii()
01620                    +QString(")");
01621                 operands.removeFirst();
01622                 operands.prepend(new QString(s1));
01623                 break;
01624             case 0xc://stdev
01625                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01626                 s1=QString("STDEV(")+operands.first()->ascii()
01627                    +QString(")");
01628                 operands.removeFirst();
01629                 operands.prepend(new QString(s1));
01630                 break;
01631             case 0xc1://stdevp
01632                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01633                 s1=QString("STDEVP(")+operands.first()->ascii()
01634                    +QString(")");
01635                 operands.removeFirst();
01636                 operands.prepend(new QString(s1));
01637                 break;
01638             case 0x143://skew
01639                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01640                 s1=QString("SKEW(")+operands.first()->ascii()
01641                    +QString(")");
01642                 operands.removeFirst();
01643                 operands.prepend(new QString(s1));
01644                 break;
01645             case 0x142://kurt
01646                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01647                 s1=QString("KURT(")+operands.first()->ascii()
01648                    +QString(")");
01649                 operands.removeFirst();
01650                 operands.prepend(new QString(s1));
01651                 break;
01652             case 0x0://count
01653                 for(w4=1;w4<w2;w4++) operands.removeFirst();
01654                 s1=QString("COUNT(")+operands.first()->ascii()
01655                    +QString(")");
01656                 operands.removeFirst();
01657                 operands.prepend(new QString(s1));
01658                 break;
01659 
01660             default:
01661                 printf("token:FUNCTION_UNKNOWN=0x%x\r\n",w1);
01662                 return QString("FUNC_UNKNOWN");
01663                 break;
01664 
01665             };
01666 
01667             break;
01668 
01669         default:
01670             printf("tokenUNKNOWN=0x%x\r\n",token);
01671             return QString("TOKEN_UKNOWN");
01672             //it is dangerous to go to idx++ and not return
01673             // because the result is unexpected.
01674             // but there is a possibility the the parser will give the correct
01675             // answer, because there are some tokens in excel formulas that can be                  //ignored.
01676             idx++;
01677             break;
01678         };
01679 
01680     };
01681 
01682 
01683 
01684     printf("{////FormulaParser}\r\n");
01685     printf("GetFormula:::::::r=%d,c=%d,,,%s\r\n",row,col,s1.ascii());
01686     printf("\r\n");
01687     s1=operands.first()->ascii();
01688     operands.clear();
01689     return QString(s1);
01690 };
01691 
01692 QString ExcelBook::FindCellName(int row, int col)
01693 {
01694     row++;col++;
01695     QString s1="";
01696     int i1=col % 26;
01697     int i2=col / 26;
01698     if (i2!=0) s1=(char)(i2+65); //65 =A
01699     s1=s1+(char)(i1+65-1);
01700     return (s1+QString::number(row));
01701 };
01702 
01703 
01704 
01705 
01706 
01707 
01708 
01709 

Generated on Sat Nov 5 16:17:00 2005 for OPIE by  doxygen 1.4.2