summaryrefslogtreecommitdiff
authorhayzel <hayzel>2004-01-07 08:08:29 (UTC)
committer hayzel <hayzel>2004-01-07 08:08:29 (UTC)
commit08bc72c34cae85e5cc6541c9daaeba121597c961 (patch) (side-by-side diff)
treedf5b263a84099ffdf8e0b86fda9a9fe61b90d30e
parent656e80e7b35c4aefd49ffe7756d895f4e7370de1 (diff)
downloadopie-08bc72c34cae85e5cc6541c9daaeba121597c961.zip
opie-08bc72c34cae85e5cc6541c9daaeba121597c961.tar.gz
opie-08bc72c34cae85e5cc6541c9daaeba121597c961.tar.bz2
January 7, 2004
* Release by hayzel (koppermind@panafonet.gr) This version has many valuable changes, though It may have some annoying bugs. Please if you are interested in opie-sheet try it hard, so I can fix some of them. Also If you want some other functions that must be here and are missing feel free to ask them. (no financial functions please. :) I really hate them ) -Fixed a bug with non closed parenthesis editing&recalculation infinite loop. -Added support for functions that can parse parameters not ONLY as numbers but also as strings. -Added many functions that cover many computational topics rendering opie-sheet a computational tool-spreadsheet at last. (total 90 functions!) -Maintained compatibility with the opie-fileformat. -New icons. -Found that the DataParser was not a real RPN compiler of the expressions. In fact it was returning faulty results in calculations, in both binary or unary operations. A1-A2-A3 was parsed as A1-(A2-A3). A1 was parsed as A1. -Added new class "Expression" a general Parser for spreadsheet-expression. Imported from an old C# project of mine. -Now can also parse <>=!%&^|"" in expressions. -Added experimental Excel File format import!. The opie-sheet can import any excel file in BIFF7/BIFF8 format. These formats are used in Excel XP,2000,95. The Excel Importer class is in a good coding level.. BUT it is not complete. Only strings,numbers,formulas are imported. Not formatting rules. Not all the functions are converted in the functions of opie-sheet. Infact FEW functions are converted. -Fixed a bug with Sheet Recalculation. Added ReCalc() function. Opie-sheet was calculating wrong the values of expression in opening/importing. if a value needed was not loaded yet in the time of calculation. Solved with ReCalc() each time the active sheet is changing. *known issues: -if someone enters directly text as parameter to a string function the text renders as uppercase due to the calculation engine that uppercases all the parsing sentence. -randbetween return only integer part random... if both limit numbers are integers. -skew and kurt function give different results compared to kspread-oofice equivalents. -unstable parser Excel Class -string vars and string functions are not correctly handled by excel importer. -unicode strings are converted FINE in QString unicode format, but cannot be rendered fine if a suitable unicode font is not setuped as the default string. So the string is junked in the opie-sheet and may crash the parser. *TODOs: -surelly a much full-stable excel importer. -Cell Manipulation of many Data is really slow.... must change the QList data type. To a structure more efficient. -maybe some more functions. -maybe some kind of charts drawing? -maybe kspread or ooffice files import/export.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-sheet/Excel.cpp1664
-rw-r--r--noncore/apps/opie-sheet/Excel.h205
-rw-r--r--noncore/apps/opie-sheet/cell-select.xpm46
-rw-r--r--noncore/apps/opie-sheet/excel16.xpm187
-rw-r--r--noncore/apps/opie-sheet/func-comma.xpm43
-rw-r--r--noncore/apps/opie-sheet/func-cross.xpm42
-rw-r--r--noncore/apps/opie-sheet/func-divide.xpm42
-rw-r--r--noncore/apps/opie-sheet/func-equal.xpm42
-rw-r--r--noncore/apps/opie-sheet/func-func.xpm42
-rw-r--r--noncore/apps/opie-sheet/func-minus.xpm42
-rw-r--r--noncore/apps/opie-sheet/func-paran-close.xpm43
-rw-r--r--noncore/apps/opie-sheet/func-paran-open.xpm43
-rw-r--r--noncore/apps/opie-sheet/func-plus.xpm42
-rw-r--r--noncore/apps/opie-sheet/mainwindow.cpp238
-rw-r--r--noncore/apps/opie-sheet/mainwindow.h14
-rw-r--r--noncore/apps/opie-sheet/opie-sheet.pro4
-rw-r--r--noncore/apps/opie-sheet/sheet.cpp2069
-rw-r--r--noncore/apps/opie-sheet/sheet.h93
18 files changed, 4471 insertions, 430 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 @@
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include <sys/types.h>
+#include <strings.h>
+#include <qstring.h>
+#include <qlist.h>
+#include <qarray.h>
+#include "Excel.h"
+
+static xfrecord formatter[] = {
+{ 0xe , DATEFORMAT, "%m/%d/%y"},
+{ 0xf , DATEFORMAT, "%d-%b-%y"},
+{ 0x10, DATEFORMAT, "%d-%b"},
+{ 0x11, DATEFORMAT, "%b-%y"},
+{ 0x12, DATEFORMAT, "%I:%M %p"},
+{ 0x13, DATEFORMAT, "%I:%M:%S %p"},
+{ 0x14, DATEFORMAT, "%H:%M"},
+{ 0x15, DATEFORMAT, "%H:%M:%S"},
+{ 0x16, DATEFORMAT, "%m/%d/%y %H:%M"},
+{ 0x2d, DATEFORMAT, "%M:%S"},
+{ 0x2e, DATEFORMAT, "%H:%M:%S"},
+{ 0x2f, DATEFORMAT, "%M:%S"},
+{ 0xa5, DATEFORMAT, "%m/%d/%y %I:%M %p"},
+{ 0x1 , NUMBERFORMAT, "%.0f"},
+{ 0x2 , NUMBERFORMAT, "%.2f"},
+{ 0x3 , NUMBERFORMAT, "#,##%.0f"},
+{ 0x4 , NUMBERFORMAT, "#,##%.2f"},
+{ 0x5 , NUMBERFORMAT, "$#,##%.0f"},
+{ 0x6 , NUMBERFORMAT, "$#,##%.0f"},
+{ 0x7 , NUMBERFORMAT, "$#,##%.2f"},
+{ 0x8 , NUMBERFORMAT, "$#,##%.2f"},
+{ 0x9 , NUMBERFORMAT, "%.0f%%"},
+{ 0xa , NUMBERFORMAT, "%.2f%%"},
+{ 0xb , NUMBERFORMAT, "%e"},
+{ 0x25, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
+{ 0x26, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
+{ 0x27, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
+{ 0x28, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
+{ 0x29, NUMBERFORMAT, "#,##%.0f;(#,##0)"},
+{ 0x2a, NUMBERFORMAT, "$#,##%.0f;($#,##0)"},
+{ 0x2b, NUMBERFORMAT, "#,##%.2f;(#,##0.00)"},
+{ 0x2c, NUMBERFORMAT, "$#,##%.2f;($#,##0.00)"},
+{ 0x30, NUMBERFORMAT, "##0.0E0"},
+{ 0, 0, ""}
+};
+
+
+
+int ExcelBook::Integer2Byte(int b1, int b2)
+{
+ int i1 = b1 & 0xff;
+ int i2 = b2 & 0xff;
+ int val = i2 << 8 | i1;
+ return val;
+};
+
+int ExcelBook::Integer4Byte(int b1,int b2,int b3,int b4)
+{
+ int i1 = Integer2Byte(b1, b2);
+ int i2 = Integer2Byte(b3, b4);
+ int val = i2 << 16 | i1;
+ return val;
+};
+
+int ExcelBook::Integer2ByteFile(FILE *f) {
+ int i1, i2;
+ i1 = fgetc(f);
+ i2 = fgetc(f);
+ return Integer2Byte(i1,i2);
+};
+
+float ExcelBook::Float4Byte(int b1, int b2, int b3, int b4)
+{
+ int i;
+ float f;
+ unsigned char *ieee;
+ ieee = (unsigned char *) &f;
+ for (i = 0; i < 4; i++) ieee[i] = 0;
+ ieee[0] = ((int)b4) & 0xff;
+ ieee[1] = ((int)b3) & 0xff;
+ ieee[2] = ((int)b2) & 0xff;
+ ieee[3] = ((int)b1) & 0xff;
+ return f;
+};
+
+double ExcelBook::Double4Byte(int b1, int b2, int b3, int b4)
+{
+ long int rk;
+ double value;
+
+ rk=Integer4Byte(b1,b2,b3,b4);
+ //printf("Double4Bytes:%d,%d,%d,%d\r\n",b1,b2,b3,b4);
+ if ( (rk & 0x02) != 0)
+ {
+ long int intval = rk >> 2; //drops the 2 bits
+ printf("Double4Byte:intval=%d, rk=%d, rk>>2=%d\r\n",intval,rk,rk>>2);
+ value = (double) intval;
+ printf("Double4Byte: VALUEINT=%f\r\n",value);
+ if ( (rk & 0x01) != 0)
+ {
+ value /= 100.0;
+ };
+ return value;
+ }else
+ {
+
+ union { double d; unsigned long int b[2]; } dbl_byte;
+ unsigned long int valbits = (rk & 0xfffffffc);
+ #if defined(__arm__) && !defined(__vfp__)
+ dbl_byte.b[0]=valbits;
+ dbl_byte.b[1]=0;
+ #else
+ dbl_byte.b[0]=0;
+ dbl_byte.b[1]=valbits;
+ #endif
+ printf("dbl_byte.b[0]=%d,dbl_byte.b[1]=%d\r\n",dbl_byte.b[0],dbl_byte.b[1]);
+ value=dbl_byte.d;
+ printf("Double4Byte: VALUE=%f\r\n",value);
+
+ if ( (rk & 0x01) != 0)
+ {
+ value /= 100.0;
+ };
+ return value;
+ };
+};
+
+void ExcelBook::DetectEndian(void)
+{
+ int end;
+ long i = 0x44332211;
+ unsigned char* a = (unsigned char*) &i;
+ end = (*a != 0x11);
+ if (end == 1) {
+ endian = BIG_ENDIAN;
+ printf("BIGENDIAN!\r\n");
+ } else {
+ endian = LITTLE_ENDIAN;
+ printf("LITTLEENDIAN!\r\n");
+ }
+};
+
+double ExcelBook::Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8)
+{
+ int i;
+ double d;
+ unsigned char *ieee;
+ ieee = (unsigned char *)&d;
+ for (i = 0; i < 8; i++) ieee[i] = 0;
+ if (endian == BIG_ENDIAN) {
+ ieee[0] = ((int)b8) & 0xff;ieee[1] = ((int)b7) & 0xff;
+ ieee[2] = ((int)b6) & 0xff;ieee[3] = ((int)b5) & 0xff;
+ ieee[4] = ((int)b4) & 0xff;ieee[5] = ((int)b3) & 0xff;
+ ieee[6] = ((int)b2) & 0xff;ieee[7] = ((int)b1) & 0xff;
+ } else {
+ ieee[0] = ((int)b1) & 0xff;ieee[1] = ((int)b2) & 0xff;
+ ieee[2] = ((int)b3) & 0xff;ieee[3] = ((int)b4) & 0xff;
+ ieee[4] = ((int)b5) & 0xff;ieee[5] = ((int)b6) & 0xff;
+ ieee[6] = ((int)b7) & 0xff;ieee[7] = ((int)b8) & 0xff;
+ }
+ return d;
+};
+
+bool ExcelBook::OpenFile(char *Filename)
+{
+ printf("Opening excel file!\r\n");
+ File= fopen(Filename, "r");
+ Position=0; // first byte index in file
+ XFRecords.resize(0);
+ SharedStrings.resize(0);
+ Names.resize(0);
+ Sheets.resize(0);
+ if(File==NULL) return false;
+ printf("Opened excel file!\r\n");
+ return true;
+};
+
+bool ExcelBook::CloseFile(void)
+{
+ int w1;
+ for(w1=0;w1<(int)XFRecords.count();w1++)
+ {
+ if(XFRecords[w1]!=NULL) {delete XFRecords[w1];XFRecords[w1]=NULL;};
+ };
+ for(w1=0;w1<(int)SharedStrings.count();w1++)
+ {
+ if(SharedStrings[w1]!=NULL) {delete SharedStrings[w1];SharedStrings[w1]=NULL;};
+ };
+ for(w1=0;w1<(int)Names.count();w1++)
+ {
+ if(Names[w1]!=NULL) {delete Names[w1];Names[w1]=NULL;};
+ };
+ for(w1=0;w1<(int)Sheets.count();w1++)
+ {
+ if(Sheets[w1]!=NULL) {delete Sheets[w1];Sheets[w1]=NULL;};
+ };
+ XFRecords.resize(0);
+ SharedStrings.resize(0);
+ Names.resize(0);
+ Sheets.resize(0);
+ fclose(File);
+ printf("closed excel file!\r\n");
+ if(File==NULL) return true;
+ return false;
+};
+
+void ExcelBook::SeekPosition(int pos)
+{
+ if(!feof(File))
+ {
+ Position=pos;
+ //printf("SeekPosition:Pos:%d\r\n",Position);
+ fseek(File,pos,SEEK_SET);
+ };
+};
+
+void ExcelBook::SeekSkip(int pos)
+{
+ if(!feof(File))
+ {
+ Position=Position+pos;
+ //printf("SeekSkip:Pos:%d\r\n",Position);
+ fseek(File, Position, SEEK_SET);
+ };
+};
+
+int ExcelBook::FileEOF(void)
+{
+ if(File!=NULL) return(feof(File)); else return 0;
+ //EOF is defined in stdlib as -1
+};
+
+int ExcelBook::Get2Bytes(void)
+{
+ int i1,i2;
+ i1=0; i2=0;
+ if (!feof(File))
+ {
+ i1=fgetc(File);
+ Position++;
+ };
+ if (!feof(File))
+ {
+ i2=fgetc(File);
+ Position++;
+ };
+ return Integer2Byte(i1,i2);
+};
+
+char* ExcelBook::Read(int pos, int length)
+{
+ int i;
+ char *data;
+ data= new char[length];
+ SeekPosition(pos);
+ for(i=0; i<length; i++)
+ {
+ if(!feof(File)) data[i]=fgetc(File);
+ };
+ Position= Position+length;
+ return data;
+};
+
+QString ExcelBook::ReadUnicodeChar(int pos, int length)
+{
+ int i;
+ QString data;
+ int i1=' ',i2=' ',ii;
+ SeekPosition(pos);
+ for(i=0; i<length; i++)
+ {
+ if(!feof(File)) i1=fgetc(File);
+ if(!feof(File)) i2=fgetc(File);
+ ii=Integer2Byte(i1,i2);
+ data.append(ii);
+ Position+=2;
+ };
+ return data;
+};
+
+QString* ExcelBook::GetString(int num)
+{
+ if(num>=0 && num<(int)SharedStrings.count())
+ {
+ return SharedStrings[num];
+ };
+ return new QString("");
+};
+
+int ExcelBook::SeekBOF(void)
+{
+ int opcode,version,streamtype,length,ret=0;
+ char *data;
+ while(!feof(File))
+ {
+ opcode=Get2Bytes();
+ if(opcode==XL_BOF)
+ {
+ length=Get2Bytes();
+ data=Read(Position,length);
+ version=Integer2Byte(data[0], data[1]);
+ streamtype=Integer2Byte(data[2], data[3]);
+ printf("SEEKBOF:opcode=XLBOF, %d ,version %d\r\n",Position,version);
+ delete data; data=NULL;
+ if (version==BIFF8) ret=8;
+ else if(version==BIFF7) ret=7;
+ printf("SEEKBOF:versionBIFF%d\r\n",ret);
+ if(streamtype==WBKGLOBAL) return ret *2;
+ else if(streamtype==WRKSHEET) return ret *1;
+ return 1;
+ };
+ };
+ return 0;
+};
+
+ExcelBREC* ExcelBook::GetBREC(void)
+{
+ ExcelBREC* rec;
+ rec= new ExcelBREC;
+ if(FileEOF()) return NULL;
+ rec->data=NULL;
+ rec->code=Get2Bytes();
+ rec->length=Get2Bytes();
+ rec->position=Position;
+ SeekSkip(rec->length);
+ return rec;
+};
+
+ExcelBREC* ExcelBook::PeekBREC(void)
+{
+ int oldpos;
+ ExcelBREC* NextRec;
+ oldpos=Position;
+ NextRec=GetBREC();
+ SeekPosition(oldpos);
+ return NextRec;
+};
+
+char* ExcelBook::GetDataOfBREC(ExcelBREC* record)
+{
+ if(record->data==NULL)
+ {
+ ConvertCharToArray(record,Read(record->position,record->length),record->length);
+ };
+ return record->data;//new?
+};
+
+void ExcelBook::ConvertCharToArray(ExcelBREC* record, char* chars, int length)
+{
+ record->data=new char[length];
+ for(int w1=0;w1<=length-1;w1++)
+ record->data[w1]=chars[w1];
+};
+
+
+bool ExcelSheet::InitCells()
+{
+ int r;
+ Cells.resize(rows * cols + cols+1);
+ if(Cells.count()==0) return false;
+ for(r=0;r < Cells.count();r++)
+ {
+ Cells[r]=NULL;
+ };
+ return true;
+};
+
+void ExcelSheet::Set(int row, int col, ExcelCell* cell)
+{
+ if(cell!=NULL&&(row*cols+col)<Cells.count())
+ {
+ Cells[row*cols+col]=cell;
+ };
+};
+
+ExcelCell* ExcelSheet::Get(int row, int col)
+{
+ ExcelCell* cell;
+ cell=Cells[row*cols+col];
+ if(cell==NULL) return NULL;
+ return cell;
+};
+
+int ExcelBook::SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record)
+{
+ char* data=NULL;
+ switch (record->code)
+ {
+ case XL_DIMENSION:
+ data = GetDataOfBREC(record);
+ if (record->length == 10)
+ {
+ sheet->rows = Integer2Byte(data[2], data[3]);
+ sheet->cols = Integer2Byte(data[6], data[7]);
+ } else
+ {
+ sheet->rows = Integer4Byte(data[4], data[5], data[6], data[7]);
+ sheet->cols = Integer2Byte(data[10], data[11]);
+ }
+ sheet->InitCells();
+ break;
+
+ case XL_LABELSST:
+ HandleLabelSST(sheet, record);
+ break;
+
+ case XL_RK:
+ case XL_RK2:
+ HandleRK(sheet, record);
+ break;
+
+ case XL_MULRK:
+ HandleMulrk(sheet, record);
+ break;
+
+ case XL_ROW:
+ break;
+
+ case XL_NUMBER:
+ HandleNumber(sheet, record);
+ break;
+
+ case XL_BOOLERR:
+ break;
+
+ case XL_CONTINUE:
+ break;
+
+ case XL_FORMULA:
+ case XL_FORMULA2:
+ HandleFormula(sheet, record);
+ break;
+
+ case XL_LABEL:
+ break;
+
+ case XL_NAME:
+ HandleName(sheet, record);
+ break;
+
+ case XL_BOF:
+ break;
+ case XL_EOF:
+ return 0;
+ default:
+ break;
+ };
+ return 1;
+};
+
+int ExcelBook::ReadSheet(ExcelSheet* sheet)
+{
+ ExcelBREC* record;
+ int oldpos;
+ oldpos = Position;
+ SeekPosition(sheet->position);
+ record = GetBREC();
+ while (record!=NULL)
+ {
+ if (!SheetHandleRecord(sheet, record)) break;
+ record=GetBREC();
+ };
+ SeekPosition(oldpos);
+ return 1;
+};
+
+ExcelSheet* ExcelBook::GetSheet(void)
+{
+ ExcelSheet* sh=NULL;
+ int type;
+ type=SeekBOF();
+ Version=type;
+ sh=new ExcelSheet;
+ if(type)
+ {
+ sh->type=type;
+ sh->position=Position;
+ sh->name=QString("");
+ };
+ if(type==8||type==7)
+ {
+ ReadSheet(sh);
+ };
+ return sh;
+};
+
+void ExcelBook::ParseSheets(void)
+{
+ int BOFs;
+ ExcelBREC* r;
+ BOFs=1;
+ r=GetBREC();
+ while(BOFs)
+ {
+ r=GetBREC();
+ switch(r->code)
+ {
+ case XL_SST:
+ HandleSST(r);
+ break;
+
+ case XL_TXO:
+ break;
+ case XL_NAME:
+ break;
+ case XL_ROW:
+ break;
+
+ case XL_FORMAT:
+ HandleFormat(r);
+ break;
+
+ case XL_XF:
+ HandleXF(r);
+ break;
+
+ case XL_BOUNDSHEET:
+ HandleBoundSheet(r);
+ break;
+
+ case XL_EXTSST:
+ break;
+ case XL_CONTINUE:
+ break;
+
+ case XL_EOF:
+ BOFs--;
+ break;
+
+ default:
+ break;
+ };
+ };
+};
+
+void ExcelBook::GetSheets(void)
+{
+ ExcelSheet* sheet;
+ Sheets.resize(0);
+ sheet=GetSheet();
+ while (sheet->Cells.count()!= 0 )
+ {
+ Sheets.resize(Sheets.count()+1);
+ Sheets[Sheets.count()-1]=sheet;
+ sheet->name=*Names[Sheets.count()-1];
+ sheet=GetSheet();
+ };
+};
+
+bool ExcelBook::ParseBook(char *file)
+{
+ dateformat=QString("");
+ DetectEndian();
+ OpenFile(file);
+ SeekBOF();
+ ParseSheets();
+ GetSheets();
+ return true;
+};
+
+QString ExcelBook::GetASCII(char* inbytes, int pos, int chars)
+{
+ int i;
+ QString outstr="";
+ for (i = 0; i < chars; i++)
+ {
+ outstr.append(inbytes[i+pos]);
+ };
+ return outstr;
+};
+
+QString ExcelBook::GetUnicode(char * inbytes, int pos, int chars)
+{
+ QString outstr="";
+ int i;
+ int rc;
+ for (i=0; i<chars*2; i++)
+ {
+ rc=Integer2Byte(inbytes[i+pos],inbytes[i+pos+1]);
+ outstr.append(QChar(rc));
+ i++;
+ };
+ return outstr;
+};
+
+
+void ExcelBook::HandleBoundSheet(ExcelBREC* rec)
+{
+ char* data;
+ int type;
+ int visibility;
+ int length;
+ int pos;
+ QString name;
+ pos = 8;
+ data = GetDataOfBREC(rec);
+ type = data[4];
+ visibility = data[5];
+ length = data[6];
+ if(data[7]==0)
+ {
+ //ascii
+ name=GetASCII(data,pos,length);
+ }else
+ {
+ name=GetUnicode(data,pos,length);
+ };
+ Names.resize(Names.count()+1);
+ Names[Names.count()-1]=new QString(name);
+};
+
+void ExcelBook::HandleName(ExcelSheet* sheet, ExcelBREC* rec)
+{
+ char* data;
+ QString name;
+ int length;
+ int pos;
+ pos = 15;
+ data = GetDataOfBREC(rec);
+ length = data[3];
+ name = GetASCII(data,pos,length);
+
+
+};
+
+ExcelFormat* ExcelBook::GetFormatting(int xf)
+{
+ int i;
+ ExcelFormat* rec;
+ rec=new ExcelFormat();
+ for (i = 0; formatter[i].code != 0; i++)
+ {
+ if (xf == formatter[i].code) break;
+ };
+ if (formatter[i].format ==NULL) return NULL;
+ rec->code = xf;
+ rec->type = formatter[i].type;
+ rec->format = formatter[i].format;
+ return rec;
+};
+
+void ExcelBook::HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes)
+{
+ QString str=QString("");
+ char* data;
+ int chars, pos, options, i;
+ int richstring, fareaststring, runlength=0;
+ int richruns=0,fareastsize=0;
+ int totalstrings;
+ int uniquestrings;
+ data = GetDataOfBREC(rec);
+ totalstrings = Integer4Byte(data[0], data[1], data[2], data[3]);
+ uniquestrings = Integer4Byte(data[4], data[5], data[6], data[7]);
+ pos = 8;
+ for (i = 0; i < uniquestrings; i++)
+ {
+ richruns=0; fareastsize=0;
+ chars = Integer2Byte(data[pos], data[pos+1]);
+ pos += 2;
+ options = data[pos];
+ pos++;
+ fareaststring = ((options & 0x04) != 0);
+ richstring = ((options & 0x08) != 0);
+ if(richstring)
+ {
+ richruns= Integer2Byte(data[pos],data[pos+1]);
+ pos+=2;
+ };
+ if(fareaststring)
+ {
+ fareastsize=Integer4Byte(data[pos], data[pos+1], data[pos+2], data[pos+3]);
+ pos+=4;
+ };
+
+ if ((options & 0x01) == 0) //8 bit chars
+ {
+ /* ascii */
+ str = GetASCII(bytes,pos,chars);
+ pos=pos+chars;
+ if(str[0]=='=') str[0]=' ';
+ }else //16 bit chars
+ {
+ /* unicode */
+ str = GetUnicode(bytes,pos,chars);
+ pos=pos+chars*2;
+ };
+ // HERE TO PUT richformat handling
+ if (richstring)
+ {
+ pos += 4 * richruns;
+ };
+ if (fareaststring)
+ {
+ pos += fareastsize;
+ };
+ //printf("String=%s, length=%d first=0x%x\r\n",str.ascii(),str.length(),str[0].unicode());
+ SharedStrings.resize(SharedStrings.count()+1);
+ SharedStrings[SharedStrings.count()-1]=new QString(str);
+ }
+};
+
+
+char* ExcelBook::MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont)
+{
+ int i, pos;
+ int length;
+
+ char* data;
+ char* bytes;
+ length = rec->length;
+ for (i = 0; i < (int) cont->rec.count(); i++)
+ {
+ length += cont->rec[i]->length;
+ }
+ bytes = GetDataOfBREC(rec);
+ pos = rec->length;
+ for (i = 0; i < (int) cont->rec.count(); i++)
+ {
+ data = GetDataOfBREC(cont->rec[i]);
+ *bytes += pos;
+ bytes = data;
+ pos += cont->rec[i]->length;
+ }
+ return bytes;
+};
+
+
+void ExcelBook::HandleSST(ExcelBREC* rec)
+{
+ char* bytes;
+ SSTList* cont;
+ cont= new SSTList;
+ ExcelBREC* nr;
+ nr = PeekBREC();
+ while (nr->code == XL_CONTINUE)
+ {
+ cont->rec.resize(cont->rec.count()+1);
+ cont->rec[cont->rec.count()-1]=GetBREC();
+ nr = PeekBREC();
+ }
+ bytes = MergeBytesFromSSTs(rec,cont);
+ HandleSetOfSST(rec, bytes);
+ for(int w1=0;w1<(int)cont->rec.count();w1++)
+ {
+ if(cont->rec[w1]!=NULL) {delete cont->rec[w1];cont->rec[w1]=NULL;};
+ };
+ cont->rec.resize(0);
+};
+
+void ExcelBook::HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec)
+{
+ int index, row, col;
+ char* data;
+ data = GetDataOfBREC(rec);
+ index = Integer4Byte(data[6], data[7], data[8], data[9]);
+ row = Integer2Byte(data[0], data[1]);
+ col = Integer2Byte(data[2], data[3]);
+ sheet->Set(row,col, CellLabel(row, col, *GetString(index)));
+};
+
+ExcelCell* ExcelBook::CellLabel(int row, int col, QString str)
+{
+ ExcelCell* c;
+ c= new ExcelCell;
+ c->row = row;
+ c->col = col;
+ c->type = CELL_LABEL;
+ c->valuec = str;
+ return c;
+};
+
+ExcelCell* ExcelBook::CellNumber(int row, int col, int index, double d)
+{
+ ExcelCell* c;
+ c=new ExcelCell;
+ c->row = row;
+ c->col = col;
+ c->xfindex = index;
+ c->type = CELL_NUMBER;
+ c->valued = d;
+ return c;
+};
+
+QString* ExcelBook::CellDataString(ExcelSheet* sh, int row, int col)
+{
+ time_t date;
+ struct tm *tmptr;
+ ExcelCell* c;
+ char str[128];
+ QString format;
+ int precision;
+ int utcOffsetDays = 25569;
+ int sInADay = 24 * 60 * 60;
+ c = sh->Get(row,col);
+ if (c == NULL) return new QString("");
+ switch (c->type)
+ {
+ case CELL_LABEL:
+ return new QString(c->valuec);
+ case CELL_NUMBER:
+ if (XFRecords[c->xfindex]->type == DATEFORMAT)
+ {
+
+ format = XFRecords[c->xfindex]->format;
+ date = (time_t) ((c->valued - utcOffsetDays) * sInADay);
+ tmptr = gmtime(&date);
+ if (dateformat)
+ {
+ strftime(str,1024,dateformat.ascii(),tmptr);
+ } else
+ {
+ strftime(str,1024,format.ascii(),tmptr);
+ };
+ } else
+ if (XFRecords[c->xfindex]->type == NUMBERFORMAT)
+ {
+ format = XFRecords[c->xfindex]->format;
+ //sprintf(str,format.ascii(),c->valued);
+ // the real format is ignored...
+ // because there is more work to be done in the field
+ precision = CellGetPrecision(c->valued);
+ sprintf(str,"%.*f",precision,c->valued);
+ }else
+ {
+ precision = CellGetPrecision(c->valued);
+ sprintf(str,"%.*f",precision,c->valued);
+ };
+ break;
+ case CELL_DATE:
+ break;
+ case CELL_BOOLEAN:
+ break;
+ case CELL_ERROR:
+ break;
+ }
+ return new QString(str);
+};
+
+int ExcelBook::CellGetPrecision(double d)
+{
+ double t;
+ int i,x;
+ int count;
+ if (d < 0) d *= -1;
+ i = (int)d;
+ t = d - (double)i;
+ if (t <= 0)
+ {
+ return 0;
+ };
+ count = 0;
+ for (x = 6; x > 1; x--)
+ {
+ i = (int)d;
+ t = d - (double)i;
+ t *= pow(10,x - 2);
+ i = (int)t;
+ t = t - (double)i;
+ t *= 10;
+ i = (int)t;
+ if (i > 0) break;
+ count++;
+ };
+ return (5 - count);
+};
+
+
+void ExcelBook::CellSetDateFormat(char *d)
+{
+ dateformat = QString(d);
+};
+
+void ExcelBook::HandleMulrk(ExcelSheet* sheet, ExcelBREC* record)
+{
+ struct mulrk mulrk;
+ char* data;
+ ExcelCell* cell;
+ int len;
+ int i;
+ len = record->length;
+ data = GetDataOfBREC(record);
+ mulrk.row = Integer2Byte(data[0],data[1]);
+ mulrk.first = Integer2Byte(data[2],data[3]);
+ mulrk.last = Integer2Byte(data[len - 2],data[len - 1]);
+ mulrk.numrks = mulrk.last - mulrk.first + 1;
+ MulrkRead(&mulrk, data);
+ for (i = 0; i < mulrk.numrks; i++)
+ {
+ cell = CellNumber(mulrk.row, mulrk.first + i, mulrk.xfindices[i], mulrk.rkdbls[i]);
+ sheet->Set(mulrk.row,mulrk.first+ i, cell);
+ //printf("handleMULRK:row=%d,col=%d,val=%f\r\n",mulrk.row,mulrk.first+i,mulrk.rkdbls[i]);
+ }
+ //delete(mulrk.xfindices);
+ //delete(mulrk.rkdbls);
+};
+
+void ExcelBook::MulrkRead(struct mulrk *mulrk, char* data)
+{
+ double d;
+ int i;
+ int pos;
+ pos = 4;
+ mulrk->xfindices.resize(mulrk->numrks);
+ mulrk->rkdbls.resize(mulrk->numrks);
+ for (i = 0; i < mulrk->numrks; i++)
+ {
+ mulrk->xfindices[i] = Integer2Byte(data[pos], data[pos+1]);
+ d=Double4Byte(data[pos+2], data[pos+3], data[pos+4], data[pos+5]);
+ //printf("double:%f\r\n",d);
+ mulrk->rkdbls[i] = d;
+ pos += 6;
+ }
+};
+
+
+void ExcelBook::HandleNumber(ExcelSheet* sheet, ExcelBREC* record)
+{
+ int xfindex, row, col;
+ char* data;
+ double d;
+ data = GetDataOfBREC(record);
+ row = Integer2Byte(data[0], data[1]);
+ col = Integer2Byte(data[2], data[3]);
+ xfindex = Integer2Byte(data[4], data[5]);
+ #if defined(__arm__) && !defined(__vfp__)
+ d=Double8Byte(data[10], data[11], data[12], data[13],data[6], data[7], data[8], data[9]);
+ #else
+ d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]);
+ #endif
+ //even if ARM is little endian... doubles are been placed as bigendian words.
+ //thanks pb_ for that. :)
+ sheet->Set(row,col, CellNumber(row,col,xfindex,d));
+ //printf("handleNumber:row=%d,col=%d,val=%f\r\n",row,col,d);
+};
+
+ExcelFormat::ExcelFormat()
+{
+code=0;type=0;format="";
+};
+
+ExcelFormat::ExcelFormat(int c,int t, QString s)
+{
+ code=c;type=t;format=s;
+};
+
+
+void ExcelBook::HandleFormat(ExcelBREC* rec)
+{
+ ExcelFormat* xfrec;
+ char* data;
+ int format;
+ data = GetDataOfBREC(rec);
+ format = Integer2Byte(data[2],data[3]);
+ xfrec = GetFormatting(format);
+ /*int idx;
+ idx=XFRecords.count()-1;
+ XFRecords[idx]->code=xfrec->code;
+ XFRecords[idx]->type=xfrec->type;
+ XFRecords[idx]->format="manos";
+ //XFRecords[XFRecords.count()-1]=xfrec;
+ printf("6\r\n");*/
+};
+
+void ExcelBook::HandleXF(ExcelBREC* rec)
+{
+ ExcelFormat* xfrec;
+ char* data;
+ int format;
+ data = GetDataOfBREC(rec);
+ format = Integer2Byte(data[2],data[3]);
+ xfrec = GetFormatting(format);
+ XFRecords.resize(XFRecords.count()+1);
+ XFRecords[XFRecords.count()-1]=xfrec;
+};
+
+
+
+void ExcelBook::HandleRK(ExcelSheet* sheet, ExcelBREC* record)
+{
+ int xfindex, row, col;
+ char* data;
+ double d;
+ data = GetDataOfBREC(record);
+ row = Integer2Byte(data[0], data[1]);
+ col = Integer2Byte(data[2], data[3]);
+ xfindex = Integer2Byte(data[4], data[5]);
+ d=Double4Byte(data[6], data[7], data[8], data[9]);
+ sheet->Set(row,col,CellNumber(row,col,xfindex,d));
+ //printf("handleRK:row=%d,col=%d,val=%f\r\n",row,col,d);
+};
+
+
+void ExcelBook::HandleFormula(ExcelSheet* sheet, ExcelBREC* record)
+{
+ int xfindex, row, col;
+ char* data;
+ double d;
+ data = GetDataOfBREC(record);
+ row = Integer2Byte(data[0], data[1]);
+ col = Integer2Byte(data[2], data[3]);
+ if (data[6] == 0 && data[12] == -1 && data[13] == -1)
+ {
+ // string
+ } else
+ if (data[6] == 1 && data[12] == -1 && data[13] == -1)
+ {
+ // boolean
+ } else
+ if ( data[6] == 2 && data[12] == -1 && data[13] == -1)
+ {
+ // error
+ }
+ else
+ {
+ // number
+ xfindex = Integer2Byte(data[4], data[5]);
+ d=Double8Byte(data[6], data[7], data[8], data[9],data[10], data[11], data[12], data[13]);
+ QString s1;
+ int sz;
+ sz=Integer2Byte(data[20],data[21]);// size of the formula
+ char* formuladata;
+ formuladata=new char[sz];
+ for(int w1=0;w1<sz;w1++)
+ {
+ formuladata[w1]=data[22+w1];
+ };
+ //22 is the first 0 idx of formula data
+ s1="="+GetFormula(row,col,sheet,formuladata,sz);
+ //printf("GetFormula:Formula=%s\r\n",s1.ascii());
+ sheet->Set(row,col,CellLabel(row,col,s1));
+ }
+};
+
+
+QString ExcelBook::GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz)
+{
+ int length=sz;
+ printf("{FormulaParser}\r\n");
+ printf("row=%d, col=%d, length=%d\r\n",row,col,length);
+ int idx=0;
+ int w1,w2,w3,w4;
+ double d1;
+ int token;
+ QString s1;
+ QList <QString> operands;
+ operands.setAutoDelete(TRUE);
+ QString formula;
+ operands.clear();
+ while( idx<length )
+ {
+ token= data[idx]; idx++;
+ switch(token)
+ {
+ case 0x1E: //prtInt
+ w1=Integer2Byte(data[idx],data[idx+1]);
+ idx=idx+2;
+ operands.prepend(new QString(QString::number(w1)));
+ printf(" token:ptgInt,num=%d\r\n",w1);
+ break;
+ case 0x1F: //ptgNumber
+ #if defined(__arm__) && !defined(__vfp__)
+ d1=Double8Byte(data[idx+4],data[idx+5],data[idx+6],data[idx+7]
+ ,data[idx],data[idx+1],data[idx+2],data[idx+3]);
+ #else
+ d1=Double8Byte(data[idx],data[idx+1],data[idx+2],data[idx+3]
+ ,data[idx+4],data[idx+5],data[idx+6],data[idx+7]);
+ #endif
+ idx=idx+8;
+ operands.prepend(new QString(QString::number(d1)));
+ printf(" token:ptgNumber,num=%f\r\n",d1);
+ break;
+ case 0x17: //ptgStr
+ if(Version==8)
+ {
+ //unicode string
+ //w1=Integer2Byte(data[idx],data[idx+1]);idx+=2;
+ w1=data[idx];idx++;
+ printf("len=%d\r\n",w1);
+ int richruns=0; int fareastsize=0;
+ int richstring,fareaststring;
+ int options = data[idx];idx++;
+ fareaststring = ((options & 0x04) != 0);
+ richstring = ((options & 0x08) != 0);
+ if(richstring)
+ {
+ //containts rich string formatting.
+ printf("STRING:richstring\r\n");
+ richruns= Integer2Byte(data[idx],data[idx+1]);
+ printf("richruns:%d\r\n",richruns);
+ idx+=2;
+ };
+ if(fareaststring)
+ {
+ //contains far east formatting
+ printf("STRING:fareast!\r\n");
+ fareastsize=Integer4Byte(data[idx], data[idx+1],
+ data[idx+2], data[idx+3]);
+ printf("fareastsize=%d",fareastsize);
+ idx+=4;
+ };
+ if ((options & 0x01) == 0) //8 bit chars
+ {
+ /* ascii */
+ s1 = GetASCII(data,idx,w1);
+ idx=idx+w1;
+ printf("STRING:ASCII=%s\r\n",s1.ascii());
+ }else //16 bit chars
+ {
+ /* unicode */
+ s1 = GetUnicode(data,idx,w1);
+ idx=idx+w1*2;
+ printf("STRING:unicode=%s\r\n",s1.ascii());
+ };
+ // HERE TO PUT richformat handling
+ if (richstring)
+ {
+ idx += 4 * richruns;
+ };
+ if (fareaststring)
+ {
+ idx += fareastsize;
+ };
+ s1=QString("""")+s1+QString("""");
+ operands.prepend(new QString(s1));
+ }else
+ {
+ w1=data[idx];idx++;
+ s1=GetASCII(data,idx,w1);
+ s1=QString("""")+s1+QString("""");
+ idx=idx+w1;
+ operands.prepend(new QString(s1));
+ };
+ printf(" token:ptgStr,num=%d\r\n",w1);
+ break;
+ case 0x25:
+ case 0x45:
+ case 0x65: // ptgArea
+ if(Version==8)
+ {
+ w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row1
+ w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row2
+ w3=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col1
+ w4=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col2
+ }else
+ {
+ w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row1
+ w2=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row2
+ w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col1
+ w4=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col2
+ };
+ //ignores relative or absolute refs
+ s1=FindCellName(w1,w3)+":"+FindCellName(w2,w4);
+ printf(" token:ptgArea,ref=%s\r\n",s1.ascii());
+ operands.prepend(new QString(s1));
+ break;
+ case 0x24:
+ case 0x44:
+ case 0x64://ptgRef
+ if(Version==8)
+ {
+ w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//row
+ w2=Integer2Byte(data[idx],data[idx+1]) & 0x00FF;idx=idx+2;//col
+ }else
+ {
+ w1=Integer2Byte(data[idx],data[idx+1]) & 0x3FFF;idx=idx+2;//row
+ w2=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;//col
+ };
+ s1=FindCellName(w1,w2);
+ printf("token:ptgRef,ref=%s\r\n",s1.ascii());
+ operands.prepend(new QString(s1));
+ break;
+ case 0x1D: // ptgBool
+ w1=data[idx];idx++;
+ printf("token:ptgBool,val=%d\r\n",w1);
+ operands.prepend(new QString(QString::number(w1)));
+ break;
+ case 0x16://ptg MissArg
+ printf("token:ptgMissArg, val=' '\r\n");
+ operands.prepend(new QString("0"));
+ break;
+ case 0x12://ptgUplus==
+ printf("token:ptgUplus\r\n");
+ s1=QString("+")+operands.first()->ascii();
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x13://ptgUminus
+ printf("token:ptgUminus\r\n");
+ s1=QString("-")+operands.first()->ascii();
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x03://ptgAdd
+ printf("token:ptgAdd\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("+")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x04://ptgSub
+ printf("token:ptgSub\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("-")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x05://ptgMul
+ printf("token:ptgMul\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("*")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x06://ptgDiv
+ printf("token:ptgDiv\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("/")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x07://ptgPOWER
+ printf("token:ptgPow\r\n");
+ operands.first();
+ s1=QString("POWER(")+operands.next()->ascii()
+ +QString(",")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x08://ptgConcat
+ printf("token:ptgConcat\r\n");
+ operands.first();
+ s1=QString("CONCATENATE(")+operands.next()->ascii()
+ +QString(",")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x15://ptgParenthesis
+ printf("token:ptgParenthesis\r\n");
+ s1=QString("(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x14://ptgPercent
+ printf("token:ptgPercent\r\n");
+ s1=operands.first()->ascii()+QString("*0.01");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x9://ptgLessThan
+ printf("token:ptgLESS\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("<")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xa://ptgLessEqual
+ printf("token:ptgLESS_EQUAL\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("<=")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xb://ptgEQUAL
+ printf("token:ptgEQUAL\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("==")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xc://ptgGREATER_EQUAL
+ printf("token:ptgGREAT_EQUAL\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString(">=")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xd://ptgGREAT_THAN
+ printf("token:ptgGREAT_THAN\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString(">")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xe://ptgNOT_EQUAL
+ printf("token:ptgNOTequal\r\n");
+ operands.first();
+ s1=operands.next()->ascii()
+ +QString("!=")+operands.first()->ascii();
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x19://attribute can be Sum,If,Choose
+ w3=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
+ idx++;
+ printf("token:ATTRIBUTE:0x%x\r\n",w3);
+ for(w4=idx;w4<length;w4++)
+ printf("0x%x, ",data[w4]);
+ if(w3&0x01)//choose
+ {
+ printf("token:CHOOSE\r\n");
+ }
+ else if(w3&0x02)//if
+ {
+ printf("token:IF\r\n");
+ }
+ else if(w3&0x10)//sum
+ {
+ printf("token:SUM\r\n");
+ };
+
+ break;
+
+
+ case 0x21:
+ case 0x22:
+ case 0x42:
+ case 0x62:
+ case 0x41:
+ case 0x61://ptgFunction
+ printf("token:ptgFunction\r\n");
+ if(token==0x22||token==0x42||token==0x62)
+ {
+ w2=(int)data[idx];idx++;
+ w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
+ }else
+ {
+ w1=Integer2Byte(data[idx],data[idx+1]);idx=idx+2;
+ };
+ switch(w1)
+ {
+ case 0xf://SIN
+ s1=QString("SIN(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x10://COS
+ s1=QString("COS(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x11://tan
+ s1=QString("TAN(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x62://asin
+ s1=QString("ASIN(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x63://ACOS
+ s1=QString("ACOS(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x12://ATAN
+ s1=QString("ATAN(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xe5://SINH
+ s1=QString("SINH(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xe6://COSH
+ s1=QString("COSH(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xe7://TANH
+ s1=QString("TANH(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xe8://ASINH
+ s1=QString("ASINH(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xe9://ACOSH
+ s1=QString("ACOSH(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xea://ATANH
+ s1=QString("ATANH(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x13://pi
+ s1="PI()";
+ operands.prepend(new QString(s1));
+ break;
+ case 0x14://sqrt
+ s1=QString("SQRT(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x15://exp
+ s1=QString("EXP(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x16://LN
+ s1=QString("LN(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x17://LOG10
+ s1=QString("LOG10(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x18://ABS
+ s1=QString("ABS(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x19://int
+ s1=QString("INT(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x1a://sign
+ s1=QString("SIGN(")+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x1b://round
+ operands.first();
+ s1=QString("ROUND(")+operands.next()->ascii()
+ +QString(",")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x1d://index
+ operands.first();
+ s1=QString("INDEX(")+operands.next()->ascii()
+ +QString(",")
+ +operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x1: // if ATTRIBUTE
+ operands.first();operands.next();
+ s1=QString("IF(")+operands.next()->ascii()+QString(",");
+ operands.first();
+ s1=s1+operands.next()->ascii()+QString(",");
+ s1=s1+operands.first()->ascii()+QString(")");
+ operands.removeFirst();
+ operands.removeFirst();
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x81://isblank
+ s1=QString("ISBLANK(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x80://isnumber
+ s1=QString("ISNUMBER(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x120://ceiling
+ operands.first();
+ s1=QString("CEILING(")+operands.next()->ascii()
+ +QString(",")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x11d://floor
+ operands.first();
+ s1=QString("FLOOR(")+operands.next()->ascii()
+ +QString(",")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x157://degrees
+ s1=QString("DEGREES(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x156://radians
+ s1=QString("RADIANS(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xb8://fact
+ s1=QString("FACT(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x27://MOD
+ operands.first();
+ s1=QString("MOD(")+operands.next()->ascii()
+ +QString(",")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x151://power
+ operands.first();
+ s1=QString("POWER(")+operands.next()->ascii()
+ +QString(",")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x3f://rand()
+ s1="RAND()";
+ operands.prepend(new QString(s1));
+ break;
+ case 0x4://sum
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("SUM(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x6://min
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("MIN(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x7://max
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("MAX(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x5://average
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("AVERAGE(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x2e://var
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("VAR(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xc2://varp
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("VARP(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xc://stdev
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("STDEV(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0xc1://stdevp
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("STDEVP(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x143://skew
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("SKEW(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x142://kurt
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("KURT(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+ case 0x0://count
+ for(w4=1;w4<w2;w4++) operands.removeFirst();
+ s1=QString("COUNT(")+operands.first()->ascii()
+ +QString(")");
+ operands.removeFirst();
+ operands.prepend(new QString(s1));
+ break;
+
+ default:
+ printf("token:FUNCTION_UNKNOWN=0x%x\r\n",w1);
+ return QString("FUNC_UNKNOWN");
+ break;
+
+ };
+
+ break;
+
+ default:
+ printf("tokenUNKNOWN=0x%x\r\n",token);
+ return QString("TOKEN_UKNOWN");
+ //it is dangerous to go to idx++ and not return
+ // because the result is unexpected.
+ // but there is a possibility the the parser will give the correct
+ // answer, because there are some tokens in excel formulas that can be //ignored.
+ idx++;
+ break;
+ };
+
+ };
+
+
+
+ printf("{////FormulaParser}\r\n");
+ printf("GetFormula:::::::r=%d,c=%d,,,%s\r\n",row,col,s1.ascii());
+ printf("\r\n");
+ s1=operands.first()->ascii();
+ operands.clear();
+return QString(s1);
+};
+
+QString ExcelBook::FindCellName(int row, int col)
+{
+ row++;col++;
+ QString s1="";
+ int i1=col % 26;
+ int i2=col / 26;
+ if (i2!=0) s1=(char)(i2+65); //65 =A
+ s1=s1+(char)(i1+65-1);
+ return (s1+QString::number(row));
+};
+
+
+
+
+
+
+
+
diff --git a/noncore/apps/opie-sheet/Excel.h b/noncore/apps/opie-sheet/Excel.h
new file mode 100644
index 0000000..0a581cf
--- a/dev/null
+++ b/noncore/apps/opie-sheet/Excel.h
@@ -0,0 +1,205 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+#include <sys/types.h>
+#include <strings.h>
+#include <qstring.h>
+#include <qarray.h>
+#include <qlist.h>
+
+#define DATEFORMAT 0x1
+#define NUMBERFORMAT 0x2
+
+#define BIFF8 0x600
+#define BIFF7 0x500
+#define WBKGLOBAL 0x5
+#define WRKSHEET 0x10
+
+#define XL_ARRAY 0x221
+#define XL_BOUNDSHEET 0x85
+#define XL_BOF 0x809
+#define XL_BOOLERR 0x205
+#define XL_CONTINUE 0x3c
+#define XL_DIMENSION 0x200
+#define XL_EOF 0x0a
+#define XL_EXTSST 0xff
+#define XL_FORMULA 0x406
+#define XL_FORMULA2 0x6
+#define XL_FORMAT 0x41e
+#define XL_INDEX 0x20b
+#define XL_LABEL 0x204
+#define XL_LABELSST 0xfd
+#define XL_MULRK 0xbd
+#define XL_NAME 0x18
+#define XL_NOTE 0x1c
+#define XL_NUMBER 0x203
+#define XL_RK 0x7e
+#define XL_RK2 0x27e
+#define XL_ROW 0x208
+#define XL_SST 0xfc
+#define XL_STRING 0x207
+#define XL_TXO 0x1b6
+#define XL_XF 0xe0
+#define XL_UNKNOWN 0xffff
+
+#define CELL_LABEL 0x2
+#define CELL_NUMBER 0x3
+#define CELL_DATE 0x4
+#define CELL_BOOLEAN 0x5
+#define CELL_ERROR 0x6
+
+
+
+class ExcelFormat
+{
+public:
+int code;
+int type;
+QString format;
+ExcelFormat();
+ExcelFormat(int c,int t, QString s);
+};
+
+struct xfrecord
+{
+int code;
+int type;
+QString format;
+};
+
+class ExcelCell
+{
+public:
+int type;
+int row,col;
+int xfindex; //xf format index of cell
+int valuei;
+double valued;
+QString valuec;
+
+};
+
+class ExcelBREC
+{
+public:
+ int code;
+ int length;
+ int position;
+ char* data;
+};
+
+class SSTList
+{
+public:
+ QArray <ExcelBREC*> rec;
+};
+
+class ExcelSheet
+{
+public:
+ QString name;
+ ExcelBREC BOFRecord;
+ int position;
+ int type;
+ int rows;
+ int cols;
+
+ int cellsize,rowalloc,cellalloc;
+ QArray <ExcelCell*> Cells;
+ bool InitCells(void); // true if ok
+ ExcelCell* Get(int row, int col);
+ void Set(int row, int col, ExcelCell* cell);
+
+};
+
+struct mulrk {
+ int row;
+ int first;
+ int last;
+ int numrks;
+ QArray<int> rknumbers;
+ QArray<double> rkdbls;
+ QArray<int> xfindices;
+};
+
+
+
+
+class ExcelBook
+{
+public:
+FILE *File;
+int Position;
+//int stringcount;
+QArray <QString*> SharedStrings;
+//int xfcount;
+QArray <ExcelFormat*> XFRecords;
+//int Sheetcount;
+QArray <ExcelSheet*> Sheets;
+//int name count;
+QArray <QString*> Names;
+
+QString dateformat;
+int Version;
+int endian;
+int Integer2Byte(int b1, int b2 );
+int Integer4Byte(int b1, int b2, int b3, int b4 );
+int Integer2ByteFile(FILE *f);
+float Float4Byte(int b1, int b2, int b3, int b4);
+double Double4Byte(int b1, int b2, int b3, int b4);
+double Double8Byte(int b1, int b2, int b3, int b4, int b5, int b6, int b7, int b8);
+void DetectEndian(void);
+
+bool OpenFile(char *Filename); // true if ok
+bool CloseFile(void); // true if ok
+void SeekPosition(int pos); // go to Pos
+void SeekSkip(int pos); // skips pos bytes.
+int FileEOF(void); //returns -1 if EOF else 0
+int Get2Bytes(void); //gets an int from the file
+char* Read(int pos, int length);
+QString ReadUnicodeChar(int pos, int length);
+QString* GetString(int num); //gets the num string from SharedStrings;
+int SeekBOF(void);
+ExcelBREC* GetBREC(void);
+ExcelBREC* PeekBREC(void);
+char* GetDataOfBREC(ExcelBREC* record);
+void ConvertCharToArray(ExcelBREC* record, char* chars, int length);
+int SheetHandleRecord(ExcelSheet* sheet, ExcelBREC* record);
+int ReadSheet(ExcelSheet* sheet); //read the sheet sheet*
+ExcelSheet* GetSheet(void);
+void ParseSheets(void);
+void GetSheets(void);
+
+bool ParseBook(char *file); // THIS IS THE MAIN PARSE FUNCTION of file
+QString GetASCII(char* inbytes, int pos, int chars);
+QString GetUnicode(char * inbytes, int pos, int chars);
+void HandleBoundSheet( ExcelBREC* rec);
+void HandleName(ExcelSheet* sheet, ExcelBREC* rec);
+ExcelFormat* GetFormatting(int xf);
+void HandleSetOfSST(ExcelBREC* rec/*, SSTList* cont*/, char* bytes);
+char* MergeBytesFromSSTs(ExcelBREC* rec,SSTList* cont);
+void HandleSST(ExcelBREC* rec);
+void HandleLabelSST(ExcelSheet* sheet, ExcelBREC* rec);
+ExcelCell* CellLabel(int row, int col, QString str);
+ExcelCell* CellNumber(int row, int col, int index, double d);
+QString* CellDataString(ExcelSheet* sh, int row, int col);
+int CellGetPrecision(double d);
+void CellSetDateFormat(char *d);
+void HandleMulrk(ExcelSheet* sheet, ExcelBREC* record);
+void MulrkRead(struct mulrk *mulrk, char* data);
+void HandleNumber(ExcelSheet* sheet, ExcelBREC* record);
+void HandleFormat(ExcelBREC* rec);
+void HandleXF(ExcelBREC* rec);
+void HandleRK(ExcelSheet* sheet, ExcelBREC* record);
+void HandleFormula(ExcelSheet* sheet, ExcelBREC* record);
+QString GetFormula(int row, int col, ExcelSheet* sheet, char* data, int sz);
+QString FindCellName(int row, int col);
+
+
+
+
+
+};
+
diff --git a/noncore/apps/opie-sheet/cell-select.xpm b/noncore/apps/opie-sheet/cell-select.xpm
index 2b0ab7e..4836c02 100644
--- a/noncore/apps/opie-sheet/cell-select.xpm
+++ b/noncore/apps/opie-sheet/cell-select.xpm
@@ -1,23 +1,25 @@
/* XPM */
-static const char * cell_select_xpm[] = {
-"16 16 4 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #BEBEBE",
-". ",
-". ... ",
-" ... .+++. ",
-" ..+@+++. ",
-" .+++@++@. ",
-" .+@+++@@++. ",
-" .@++@++@+++. ",
-" .@@++@@+++++. ",
-" .++@+@+++++++. ",
-" .++@++++++++. ",
-" .++@+++++++. ",
-" .++@+++++@. ",
-" .++@+++@+. ",
-" .++@@@+. ",
-" .++++. ",
-" .... "};
+static const char *cell_select_xpm[]={
+"16 16 6 1",
+"# c None",
+"c c #0058c0",
+". c #585858",
+"b c #58a8ff",
+"a c #a8dcff",
+"d c #c0ffff",
+".###############",
+".#####...#######",
+"#...#.aab.######",
+"###..acaaa.#####",
+"###.aaacabc.####",
+"##.acaaaccab.###",
+"#.caacabbaaa.###",
+"#.ccaacbaaaaa.##",
+"#.bacbcaaaadaa.#",
+"##.bacbaaaddda.#",
+"###.bacaaaadaa.#",
+"####.bacaaaaac.#",
+"#####.bacaaacb.#",
+"######.bacccb.##",
+"#######.babb.###",
+"########....####"};
diff --git a/noncore/apps/opie-sheet/excel16.xpm b/noncore/apps/opie-sheet/excel16.xpm
new file mode 100644
index 0000000..45dd96d
--- a/dev/null
+++ b/noncore/apps/opie-sheet/excel16.xpm
@@ -0,0 +1,187 @@
+/* XPM */
+static const char *excel16_xpm[]={
+"16 16 168 2",
+"aL c None",
+"Qt c None",
+"aK c #24440a",
+"#y c #247d21",
+"#B c #276d1e",
+"aw c #284a0d",
+"au c #2b4e10",
+"#P c #2c6e1a",
+"ag c #2d5114",
+"ad c #2e541a",
+"af c #304326",
+"#2 c #317a1c",
+"ae c #334f25",
+"#5 c #335919",
+"#F c #375d1f",
+"#O c #3a872f",
+"#t c #3d6324",
+"ac c #3d7939",
+"#Y c #3e7132",
+"#p c #407f39",
+"#Z c #42903e",
+"#i c #436d28",
+".9 c #446e2a",
+"aJ c #466628",
+"av c #476430",
+"aI c #476829",
+".W c #47732d",
+"#K c #479643",
+"#1 c #48872e",
+"aH c #496b2d",
+".6 c #4a8a49",
+"aG c #4b6e31",
+".z c #4b7832",
+"#L c #4d9647",
+"aF c #4e7336",
+"aE c #52783b",
+".m c #527a3e",
+"#x c #529c4f",
+"#N c #549c4b",
+"aD c #567a3f",
+"#V c #579342",
+"#X c #588649",
+"aC c #598041",
+".T c #598955",
+"#A c #59a354",
+"#W c #5a8f48",
+"aB c #5d8745",
+"ax c #5d914d",
+"#o c #5ea657",
+"#C c #5f8755",
+"aA c #5f8947",
+".5 c #5f9f5a",
+"#e c #60965b",
+"#f c #609c5b",
+"az c #618b4a",
+".l c #629450",
+"ay c #679350",
+".k c #689854",
+"#U c #69a15f",
+"ah c #6c9c59",
+"#d c #6cae66",
+".R c #6da767",
+".S c #6ea564",
+"#n c #6eaf67",
+".3 c #6fad69",
+"#0 c #6fb067",
+".j c #719f5f",
+"ab c #729a6b",
+"#6 c #72a161",
+".2 c #74a270",
+"#J c #75b56d",
+".i c #76a366",
+"#l c #77ae74",
+"#M c #78b570",
+"#I c #79b176",
+".4 c #79b870",
+"#S c #7ba66b",
+".N c #7bb374",
+".h c #7da970",
+".1 c #7fbd76",
+"#G c #81ab74",
+"#c c #81bb78",
+".M c #83bb7b",
+"aa c #869782",
+".g c #86b079",
+"a# c #879783",
+"a. c #889885",
+"#u c #88b279",
+"#9 c #899886",
+".U c #89b188",
+".L c #89c081",
+".O c #8ab485",
+".0 c #8ac381",
+".f c #8eb580",
+"#j c #8eb680",
+".y c #91a483",
+"#m c #91c28a",
+"#. c #92b885",
+"#8 c #93ae91",
+".e c #93ba87",
+"#3 c #93be91",
+"at c #94a089",
+"#4 c #96a18b",
+"#z c #96c78d",
+".# c #97bc8a",
+"#D c #99b598",
+"#Q c #9abb99",
+"#R c #9ba890",
+".d c #9bbf90",
+"#E c #9ca991",
+"#s c #9ca992",
+"#b c #9dc895",
+"#h c #9fac95",
+".c c #9fc294",
+"#a c #a0c99b",
+".8 c #a2b198",
+".V c #a3b199",
+".b c #a4c699",
+".K c #a5b29b",
+".Z c #a6cf9f",
+".Y c #a7cda1",
+".a c #a9c99e",
+".n c #acc4a3",
+".x c #b2c3aa",
+"ai c #b4c4ab",
+".w c #b6c7ad",
+"#7 c #b7c7ae",
+".v c #b9cab1",
+"#T c #bbcab3",
+".u c #bbcbb3",
+".Q c #bbd0ba",
+"#H c #bccbb4",
+".t c #beceb7",
+".s c #c0d1ba",
+"#k c #c1d1bb",
+".r c #c2d1bc",
+"## c #c2d2bc",
+".X c #c4d5be",
+".q c #c6d9c1",
+".p c #c8d9c2",
+".o c #c9dac3",
+"#q c #cdddcd",
+"as c #d3e3d3",
+"ar c #d4e4d4",
+"aq c #d7e6d7",
+"ap c #d8e7d9",
+"ao c #dae9db",
+".7 c #dce8db",
+"#r c #dce9dc",
+"an c #ddebdd",
+"#g c #dfecdf",
+"am c #e1ede0",
+"al c #e3ede3",
+"#w c #e5efe5",
+"ak c #e6efe6",
+".J c #e7f0e7",
+"aj c #e8f0e8",
+".I c #eaf2ea",
+".P c #ebf3eb",
+".H c #ecf4ec",
+".G c #f0f5f0",
+".F c #f2f7f2",
+"#v c #f3f7f3",
+".E c #f4f8f4",
+".D c #f7f9f6",
+".C c #f9fbf8",
+".B c #fafcfa",
+".A c #fcfdfc",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
+"Qt.#.a.b.c.d.e.f.g.h.i.j.k.l.mQt",
+"Qt.a.n.o.p.q.r.s.t.u.v.w.x.y.zQt",
+"Qt.b.o.A.B.C.D.E.F.G.H.I.J.K.zQt",
+"Qt.c.p.L.M.N.O.P.Q.R.S.T.U.V.WQt",
+"Qt.d.X.Y.Z.0.1.2.3.4.5.6.7.8.9Qt",
+"Qt#.##.D#a#b#c#d#e#f.6.7#g#h#iQt",
+"Qt#j#k.E.F#l#m#n#o#p#q#g#r#s#tQt",
+"Qt#u.s#v#w#x#y#z#A#A#B#C#D#E#FQt",
+"Qt#G#H.P#I#J#K#L#M#N#O#P#Q#R#FQt",
+"Qt#S#T#U#V#W#X#Y#Z#0#1#2#3#4#5Qt",
+"Qt#6#7#8#9a.a#aaabacadaeaf#4agQt",
+"QtahaiajakalamanaoapaqarasatauQt",
+"Qt.kavavavavavavavavavavavavawQt",
+"QtaxayazaAaBaCaDaEaFaGaHaIaJaKQt",
+"aLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaL"};
diff --git a/noncore/apps/opie-sheet/func-comma.xpm b/noncore/apps/opie-sheet/func-comma.xpm
index 3b2bbf9..2e680d2 100644
--- a/noncore/apps/opie-sheet/func-comma.xpm
+++ b/noncore/apps/opie-sheet/func-comma.xpm
@@ -1,21 +1,24 @@
/* XPM */
-static const char * func_comma_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" ",
-" ... ",
-" ..... ",
-" ...... ",
-" ...... ",
-" ..... ",
-" .. ",
-" . ",
-" .. ",
-" .. ",
-" . ",
-" ",
-" ",
-" "};
+static const char *func_comma_xpm[]={
+"16 16 5 1",
+". c None",
+"# c #000000",
+"a c #0000ff",
+"b c #0058c0",
+"c c #0080ff",
+"................",
+"................",
+"................",
+"......###.......",
+".....#aaa#......",
+".....#bcca#.....",
+".....#bbaa#.....",
+"......##ba#.....",
+"........#b#.....",
+"........#b#.....",
+".......#b#......",
+"......#b#.......",
+"......##........",
+"................",
+"................",
+"................"};
diff --git a/noncore/apps/opie-sheet/func-cross.xpm b/noncore/apps/opie-sheet/func-cross.xpm
index 6f77502..3b3f3d5 100644
--- a/noncore/apps/opie-sheet/func-cross.xpm
+++ b/noncore/apps/opie-sheet/func-cross.xpm
@@ -1,21 +1,23 @@
/* XPM */
-static const char * func_cross_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" ",
-" .. ",
-" .. ",
-" .. ",
-" ... .. ... ",
-" .......... ",
-" ...... ",
-" .... ",
-" ...... ",
-" ... ... ",
-" . . ",
-" ",
-" ",
-" "};
+static const char *func_cross_xpm[]={
+"16 16 4 1",
+". c None",
+"b c #0000ff",
+"a c #0058c0",
+"# c #585858",
+"................",
+"................",
+"....#......##...",
+"...#a#....#ab#..",
+"..#bba#..#abb#..",
+"...#bba##abb#...",
+"....#bbaabb#....",
+".....#bbbb#.....",
+".....#bbbb#.....",
+"....#bbaabb#....",
+"...#bba##abb#...",
+"..#bba#..#abb#..",
+"..#ba#....#a#...",
+"...##......#....",
+"................",
+"................"};
diff --git a/noncore/apps/opie-sheet/func-divide.xpm b/noncore/apps/opie-sheet/func-divide.xpm
index 1ac6a07..beb3473 100644
--- a/noncore/apps/opie-sheet/func-divide.xpm
+++ b/noncore/apps/opie-sheet/func-divide.xpm
@@ -1,21 +1,23 @@
/* XPM */
-static const char * func_divide_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" "};
+static const char *func_divide_xpm[]={
+"16 16 4 1",
+". c None",
+"# c #000000",
+"b c #0000ff",
+"a c #0058c0",
+"................",
+"................",
+"...........##...",
+"..........#ab#..",
+".........#aba#..",
+"........#bba#...",
+".......#bba#....",
+"......#bba#.....",
+".....#abb#......",
+"....#abb#.......",
+"...#abb#........",
+"..#aba#.........",
+"..#ba#..........",
+"...##...........",
+"................",
+"................"};
diff --git a/noncore/apps/opie-sheet/func-equal.xpm b/noncore/apps/opie-sheet/func-equal.xpm
index 60f8710..8f34895 100644
--- a/noncore/apps/opie-sheet/func-equal.xpm
+++ b/noncore/apps/opie-sheet/func-equal.xpm
@@ -1,21 +1,23 @@
/* XPM */
-static const char * func_equal_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" ",
-" ",
-" ",
-" .......... ",
-" .......... ",
-" ",
-" ",
-" .......... ",
-" .......... ",
-" ",
-" ",
-" ",
-" ",
-" "};
+static const char *func_equal_xpm[]={
+"16 16 4 1",
+". c None",
+"b c #0000ff",
+"a c #0058c0",
+"# c #585858",
+"................",
+"................",
+"................",
+"...##########...",
+"..#aaabbbbaaa#..",
+"..#bbbbbbbbbb#..",
+"..############..",
+"................",
+"................",
+"..############..",
+"..#bbbbbbbbbb#..",
+"..#aaabbbbaaa#..",
+"...##########...",
+"................",
+"................",
+"................"};
diff --git a/noncore/apps/opie-sheet/func-func.xpm b/noncore/apps/opie-sheet/func-func.xpm
index c1f7852..b9ec747 100644
--- a/noncore/apps/opie-sheet/func-func.xpm
+++ b/noncore/apps/opie-sheet/func-func.xpm
@@ -1,21 +1,23 @@
/* XPM */
-static const char * func_func_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" .. ",
-" .. ",
-" . ",
-" . ",
-" . ",
-" ..... ",
-" . ",
-" . . . ",
-" . . . ",
-" . . ",
-" . . . ",
-" . . . ",
-" . ",
-" . ",
-" "};
+static const char *func_func_xpm[]={
+"16 16 4 1",
+". c None",
+"a c #0000ff",
+"b c #0058c0",
+"# c #585858",
+"................",
+".........#ab....",
+".......#aa##....",
+".......ab#......",
+".......ab#......",
+"......#a#.......",
+"....#aaaa#......",
+"....bbabbb......",
+"....##ab#a#.ba..",
+".....aa##baba#..",
+".....ab#.#ba#...",
+".....ab#.baba...",
+"....#a#.ba##ba..",
+"....ab#..#..#b..",
+"...#a#..........",
+"................"};
diff --git a/noncore/apps/opie-sheet/func-minus.xpm b/noncore/apps/opie-sheet/func-minus.xpm
index fa2cb4f..b747bd7 100644
--- a/noncore/apps/opie-sheet/func-minus.xpm
+++ b/noncore/apps/opie-sheet/func-minus.xpm
@@ -1,21 +1,23 @@
/* XPM */
-static const char * func_minus_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ....... ",
-" ....... ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
+static const char *func_minus_xpm[]={
+"16 16 4 1",
+". c None",
+"a c #0000ff",
+"b c #0058c0",
+"# c #585858",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"...##########...",
+"...#aaaaaabb#...",
+"...#bbaaaaaa#...",
+"...##########...",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................"};
diff --git a/noncore/apps/opie-sheet/func-paran-close.xpm b/noncore/apps/opie-sheet/func-paran-close.xpm
index 85191d5..1e9994c 100644
--- a/noncore/apps/opie-sheet/func-paran-close.xpm
+++ b/noncore/apps/opie-sheet/func-paran-close.xpm
@@ -1,21 +1,24 @@
/* XPM */
-static const char * func_paran_close_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" . ",
-" .. ",
-" . ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" . ",
-" .. ",
-" . ",
-" ",
-" "};
+static const char *func_paran_close_xpm[]={
+"16 16 5 1",
+"c c None",
+". c None",
+"b c #0000ff",
+"# c #0058c0",
+"a c #585858",
+"......#a........",
+"......#baa......",
+".......#bba.....",
+"........#b#.....",
+"........c##a....",
+"........c#ba....",
+"........c#ba....",
+"........c#ba....",
+"........c#ba....",
+"........c#ba....",
+"........#b#a....",
+".......abb#.....",
+".......#bba.....",
+"......#baa......",
+"......#a........",
+"................"};
diff --git a/noncore/apps/opie-sheet/func-paran-open.xpm b/noncore/apps/opie-sheet/func-paran-open.xpm
index 3c7870b..ace24b0 100644
--- a/noncore/apps/opie-sheet/func-paran-open.xpm
+++ b/noncore/apps/opie-sheet/func-paran-open.xpm
@@ -1,21 +1,24 @@
/* XPM */
-static const char * func_paran_open_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" . ",
-" .. ",
-" . ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" . ",
-" .. ",
-" . ",
-" ",
-" "};
+static const char *func_paran_open_xpm[]={
+"16 16 5 1",
+"c c None",
+". c None",
+"b c #0000ff",
+"a c #0058c0",
+"# c #585858",
+"........#a......",
+"......##ba......",
+".....#bba.......",
+".....aba........",
+"....#aacc.......",
+"....#bacc.......",
+"....#bacc.......",
+"....#bacc.......",
+"....#bac........",
+"....#bac........",
+"....#aac........",
+".....abbc.......",
+".....#bba.......",
+"......##bac.....",
+"........#ac.....",
+"..........c....."};
diff --git a/noncore/apps/opie-sheet/func-plus.xpm b/noncore/apps/opie-sheet/func-plus.xpm
index a917c64..c779f23 100644
--- a/noncore/apps/opie-sheet/func-plus.xpm
+++ b/noncore/apps/opie-sheet/func-plus.xpm
@@ -1,21 +1,23 @@
/* XPM */
-static const char * func_plus_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #000000",
-" ",
-" ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" ............ ",
-" ............ ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" ",
-" "};
+static const char *func_plus_xpm[]={
+"16 16 4 1",
+". c None",
+"a c #0000ff",
+"b c #0058c0",
+"# c #585858",
+"................",
+"................",
+"......####......",
+"......#ab#......",
+"......#ab#......",
+"......#ab#......",
+"..####babb####..",
+"..#aaaaaabbbb#..",
+"..#bbbbaaaaaa#..",
+"..####bbab####..",
+"......#ba#......",
+"......#ba#......",
+"......#ba#......",
+"......####......",
+"................",
+"................"};
diff --git a/noncore/apps/opie-sheet/mainwindow.cpp b/noncore/apps/opie-sheet/mainwindow.cpp
index 78b3073..a725e31 100644
--- a/noncore/apps/opie-sheet/mainwindow.cpp
+++ b/noncore/apps/opie-sheet/mainwindow.cpp
@@ -35,29 +35,34 @@
#include "func-paran-open.xpm"
#include "func-paran-close.xpm"
#include "func-comma.xpm"
#include "func-func.xpm"
#include "func-equal.xpm"
#include "cell-select.xpm"
+#include "excel16.xpm"
-#define DEFAULT_NUM_ROWS 199
+#define DEFAULT_NUM_ROWS 300
#define DEFAULT_NUM_COLS (26*3)
#define DEFAULT_NUM_SHEETS 3
MainWindow::MainWindow(QWidget *parent, const char* n, WFlags fl)
:QMainWindow(parent, n, fl)
{
// initialize variables
documentModified=FALSE;
// construct objects
currentDoc=0;
fileSelector=new FileSelector("application/sheet-qt", this, QString::null);
+ ExcelSelector=new FileSelector("application/excel",this,QString::null,FALSE);
connect(fileSelector, SIGNAL(closeMe()), this, SLOT(selectorHide()));
connect(fileSelector, SIGNAL(newSelected(const DocLnk &)), this, SLOT(selectorFileNew(const DocLnk &)));
connect(fileSelector, SIGNAL(fileSelected(const DocLnk &)), this, SLOT(selectorFileOpen(const DocLnk &)));
+ connect(ExcelSelector,SIGNAL(fileSelected(const DocLnk &)),this,SLOT(slotImportExcel(const DocLnk &)));
+ connect(ExcelSelector,SIGNAL(closeMe()), this, SLOT(ExcelSelectorHide()));
+
listSheets.setAutoDelete(TRUE);
initActions();
initMenu();
initEditToolbar();
@@ -214,13 +219,13 @@ void MainWindow::closeEvent(QCloseEvent *e)
void MainWindow::selectorFileOpen(const DocLnk &lnkDoc)
{
selectorHide();
if (documentModified && saveCurrentFile()==QMessageBox::Cancel) return;
if (currentDoc) delete currentDoc;
- currentDoc = new DocLnk(lnkDoc);
+ currentDoc = new DocLnk();
listSheets.clear();
comboSheets->clear();
documentOpen(lnkDoc);
documentModified=FALSE;
}
@@ -247,12 +252,27 @@ void MainWindow::slotFileNew()
void MainWindow::slotFileOpen()
{
selectorShow();
}
+void MainWindow::slotImportExcelOpen()
+{
+ sheet->hide();
+ setCentralWidget(ExcelSelector);
+ ExcelSelector->show();
+ ExcelSelector->reread();
+}
+
+void MainWindow::ExcelSelectorHide()
+{
+ ExcelSelector->hide();
+ setCentralWidget(sheet);
+ sheet->show();
+}
+
void MainWindow::slotFileSave()
{
saveCurrentFile(FALSE);
}
void MainWindow::setDocument(const QString &applnk_filename)
@@ -267,14 +287,17 @@ void MainWindow::initActions()
fileOpen=new QAction(tr("Open File"), Resource::loadPixmap( "fileopen" ), tr("&Open"), 0, this);
connect(fileOpen, SIGNAL(activated()), this, SLOT(slotFileOpen()));
fileSave=new QAction(tr("Save File"),Resource::loadPixmap( "save" ), tr("&Save"), 0, this);
connect(fileSave, SIGNAL(activated()), this, SLOT(slotFileSave()));
fileSaveAs=new QAction(tr("Save File As"), Resource::loadPixmap( "save" ), tr("Save &As"), 0, this);
connect(fileSaveAs, SIGNAL(activated()), this, SLOT(slotFileSaveAs()));
+
//fileQuit=new QAction(tr("Quit"), tr("&Quit"), 0, this);
//connect(fileQuit, SIGNAL(activated()), this, SLOT(close()));
+ fileExcelImport=new QAction(tr("Import Excel file"),QPixmap(excel16_xpm),tr("Import E&xcel file"),0,this);
+ connect(fileExcelImport, SIGNAL(activated()), this, SLOT(slotImportExcelOpen()));
// helpGeneral=new QAction(tr("General Help"), QPixmap(help_general_xpm), tr("&General"), 0, this);
//connect(helpGeneral, SIGNAL(activated()), this, SLOT(slotHelpGeneral()));
//helpAbout=new QAction(tr("About Opie Sheet"), tr("&About"), 0, this);
//connect(helpAbout, SIGNAL(activated()), this, SLOT(slotHelpAbout()));
@@ -367,12 +390,14 @@ void MainWindow::initMenu()
fileNew->addTo(menuFile);
fileOpen->addTo(menuFile);
fileSave->addTo(menuFile);
fileSaveAs->addTo(menuFile);
// menuFile->insertSeparator();
// fileQuit->addTo(menuFile);
+ menuFile->insertSeparator();
+ fileExcelImport->addTo(menuFile);
menu->insertItem(tr("&File"), menuFile);
menuEdit=new QPopupMenu;
editAccept->addTo(menuEdit);
editCancel->addTo(menuEdit);
editCellSelect->addTo(menuEdit);
@@ -425,37 +450,133 @@ void MainWindow::initMenu()
submenuFuncStd=new QPopupMenu;
funcPlus->addTo(submenuFuncStd);
funcMinus->addTo(submenuFuncStd);
funcCross->addTo(submenuFuncStd);
funcDivide->addTo(submenuFuncStd);
- submenuFunc->insertItem(tr("&Standard"), submenuFuncStd);
-
- submenuFuncMath=new QPopupMenu;
- addFlyAction(tr("Summation"), tr("&Summation"), "SUM(", submenuFuncMath);
- addFlyAction(tr("Absolute Value"), tr("&Absolute"), "ABS(", submenuFuncMath);
- submenuFuncMath->insertSeparator();
- addFlyAction(tr("Sine"), tr("Si&ne"), "SIN(", submenuFuncMath);
- addFlyAction(tr("Arc Sine"), tr("A&rc Sine"), "ASIN(", submenuFuncMath);
- addFlyAction(tr("Cosine"), tr("&Cosine"), "COS(", submenuFuncMath);
- addFlyAction(tr("ArcCosine"), tr("Arc Cos&ine"), "COS(", submenuFuncMath);
- addFlyAction(tr("Tangent"), tr("&Tangent"), "TAN(", submenuFuncMath);
- addFlyAction(tr("Arc Tangent"), tr("Arc Tan&gent"), "ATAN(", submenuFuncMath);
- addFlyAction(tr("Arc Tangent of Coordinates"), tr("C&oor. Arc Tangent"), "ATAN2(", submenuFuncMath);
- submenuFuncMath->insertSeparator();
- addFlyAction(tr("Exponential"), tr("&Exponential"), "EXP(", submenuFuncMath);
- addFlyAction(tr("Logarithm"), tr("&Logarithm"), "LOG(", submenuFuncMath);
- addFlyAction(tr("Power"), tr("&Power"), "POW(", submenuFuncMath);
- submenuFunc->insertItem(tr("&Mathematical"), submenuFuncMath);
+ submenuFunc->insertItem(tr("&Simple"), submenuFuncStd);
+
+
+
+ submenuFuncStandard=new QPopupMenu;
+ addFlyAction(tr("ABS(x)"), tr("ABS(x)"), "ABS(", submenuFuncStandard);
+ addFlyAction(tr("CEILING(x,acc)"), tr("CEILING(x,acc)"), "CEILING(", submenuFuncStandard);
+ addFlyAction(tr("FACT(x)"), tr("FACT(x)"), "FACT(", submenuFuncStandard);
+ addFlyAction(tr("FLOOR(x,acc)"), tr("FLOOR(x,acc)"), "FLOOR(", submenuFuncStandard);
+ addFlyAction(tr("INT(x)"), tr("INT(x)"), "INT(", submenuFuncStandard);
+ addFlyAction(tr("MOD(x,y)"), tr("MOD(x,y)"), "MOD(", submenuFuncStandard);
+ addFlyAction(tr("ROUND(x,digits)"), tr("ROUND(x,digits)"), "ROUND(", submenuFuncStandard);
+ addFlyAction(tr("SIGN(x)"), tr("SIGN(x)"), "SIGN(", submenuFuncStandard);
+ submenuFuncStandard->insertSeparator();
+ addFlyAction(tr("EXP(x)"), tr("EXP(x)"), "EXP(", submenuFuncStandard);
+ addFlyAction(tr("LN(x)"), tr("LN(x)"), "LN(", submenuFuncStandard);
+ addFlyAction(tr("LOG(x,b)"), tr("LOG(x,b)"), "LOG(", submenuFuncStandard);
+ addFlyAction(tr("LOG10(x)"), tr("LOG10(x)"), "LOG10(", submenuFuncStandard);
+ addFlyAction(tr("POWER(x,y)"), tr("POWER(x,y)"), "POWER(", submenuFuncStandard);
+ addFlyAction(tr("SQRT(x)"), tr("SQRT(x)"), "SQRT(", submenuFuncStandard);
+ submenuFuncStandard->insertSeparator();
+ addFlyAction(tr("DEGREES(x)"), tr("DEGREES(x)"), "DEGREES(", submenuFuncStandard);
+ addFlyAction(tr("RADIANS(x)"), tr("RADIANS(x)"), "RADIANS(", submenuFuncStandard);
+ addFlyAction(tr("PI()"), tr("PI()"), "PI()", submenuFuncStandard);
+ addFlyAction(tr("RAND()"), tr("RAND()"), "RAND(", submenuFuncStandard);
+ addFlyAction(tr("RANDBETWEEN(a,b)"), tr("RANDBETWEEN(a,b)"), "RANDBETWEEN(", submenuFuncStandard);
+ submenuFunc->insertItem(tr("S&tandard"), submenuFuncStandard);
+
+ submenuFuncLogic=new QPopupMenu;
+ addFlyAction(tr("AND(x1,x2)"), tr("AND(x1,x2)"), "AND(", submenuFuncLogic);
+ addFlyAction(tr("NOT(x)"), tr("NOT(x)"), "NOT(", submenuFuncLogic);
+ addFlyAction(tr("OR(x1,x2)"), tr("OR(x1,x2)"), "OR(", submenuFuncLogic);
+ submenuFuncLogic->insertSeparator();
+ addFlyAction(tr("IF(compare,val1,val2)"), tr("IF(compare,val1,val2)"), "IF(", submenuFuncLogic);
+ addFlyAction(tr("INDEX(range,index)"),tr("INDEX(range,index)"), "INDEX(", submenuFuncLogic);
+ addFlyAction(tr("ISBLANK(x)"), tr("ISBLANK(x)"), "ISBLANK(", submenuFuncLogic);
+ addFlyAction(tr("ISNUMBER(x)"), tr("ISNUMBER(x)"), "ISNUMBER(", submenuFuncLogic);
+ addFlyAction(tr("EVEN(x)"), tr("EVEN(x)"), "EVEN(", submenuFuncLogic);
+ addFlyAction(tr("ISEVEN(x)"), tr("ISEVEN(x)"), "ISEVEN(", submenuFuncLogic);
+ addFlyAction(tr("ODD(x)"), tr("ODD(x)"), "ODD(", submenuFuncLogic);
+ addFlyAction(tr("ISODD(x)"), tr("ISODD(x)"), "ISODD(", submenuFuncLogic);
+ submenuFunc->insertItem(tr("Logical-&Information"), submenuFuncLogic);
+
+ submenuFuncTrig=new QPopupMenu;
+ addFlyAction(tr("SIN(x)"), tr("SIN(x)"), "SIN(", submenuFuncTrig);
+ addFlyAction(tr("COS(x)"), tr("COS(x)"), "COS(", submenuFuncTrig);
+ addFlyAction(tr("TAN(x)"), tr("TAN(x)"), "TAN(", submenuFuncTrig);
+ addFlyAction(tr("ASIN(x)"), tr("ASIN(x)"), "ASIN(", submenuFuncTrig);
+ addFlyAction(tr("ACOS(x)"), tr("ACOS(x)"), "ACOS(", submenuFuncTrig);
+ addFlyAction(tr("ATAN(x)"), tr("ATAN(x)"), "ATAN(", submenuFuncTrig);
+ addFlyAction(tr("ATAN2(x,y)"), tr("ATAN2(x,y)"), "ATAN2(", submenuFuncTrig);
+ submenuFuncTrig->insertSeparator();
+ addFlyAction(tr("SINH(x)"), tr("SINH(x)"), "SINH(", submenuFuncTrig);
+ addFlyAction(tr("COSH(x)"), tr("COSH(x)"), "COSH(", submenuFuncTrig);
+ addFlyAction(tr("TANH(x)"), tr("TANH(x)"), "TANH(", submenuFuncTrig);
+ addFlyAction(tr("ACOSH(x)"), tr("ACOSH(x)"), "ACOSH(", submenuFuncTrig);
+ addFlyAction(tr("ASINH(x)"), tr("ASINH(x)"), "ASINH(", submenuFuncTrig);
+ addFlyAction(tr("ATANH(x)"), tr("ATANH(x)"), "ATANH(", submenuFuncTrig);
+ submenuFunc->insertItem(tr("&Trigonometric"), submenuFuncTrig);
+
+ submenuFuncString=new QPopupMenu;
+ addFlyAction(tr("LEN(s)"), tr("LEN(s)"), "LEN(",submenuFuncString);
+ addFlyAction(tr("LEFT(s,num)"), tr("LEFT(s,num)"), "LEFT(",submenuFuncString);
+ addFlyAction(tr("RIGHT(s,num)"), tr("RIGHT(s,num)"), "RIGHT(",submenuFuncString);
+ addFlyAction(tr("MID(s,pos,len)"), tr("MID(s,pos,len)"), "MID(",submenuFuncString);
+ submenuFuncString->insertSeparator();
+ addFlyAction(tr("CONCATENATE(s1,s2..)"), tr("CONCATENATE(s1,s2..)"), "CONCATENATE(",submenuFuncString);
+ addFlyAction(tr("EXACT(s1,s2)"), tr("EXACT(s1,s2)"), "EXACT(",submenuFuncString);
+ addFlyAction(tr("FIND(what,where,pos)"),
+ tr("FIND(what,where,pos)"), "FIND(",submenuFuncString);
+ addFlyAction(tr("REPLACE(s,pos,len,ns)"), tr("REPLACE(s,pos,len,ns)"), "REPLACE(",submenuFuncString);
+ addFlyAction(tr("REPT(s,n)"), tr("REPT(s,n)"), "REPT(",submenuFuncString);
+ submenuFuncString->insertSeparator();
+ addFlyAction(tr("UPPER(s)"), tr("UPPER(s)"), "UPPER(",submenuFuncString);
+ addFlyAction(tr("LOWER(s)"), tr("LOWER(s)"), "LOWER(",submenuFuncString);
+ submenuFunc->insertItem(tr("&Strings"), submenuFuncString);
submenuFuncStat=new QPopupMenu;
- addFlyAction(tr("Average"), tr("&Average"), "AVG(", submenuFuncStat);
- addFlyAction(tr("Maximum"), tr("Ma&ximum"), "MAX(", submenuFuncStat);
- addFlyAction(tr("Minimum"), tr("&Minimum"), "MIN(", submenuFuncStat);
- addFlyAction(tr("Count"), tr("&Count"), "COUNT(", submenuFuncStat);
- submenuFunc->insertItem(tr("&Statistical"), submenuFuncStat);
+ addFlyAction(tr("AVERAGE(range)"), tr("AVERAGE(range)"), "AVERAGE(",submenuFuncStat);
+ addFlyAction(tr("COUNT(range)"), tr("COUNT(range)"), "COUNT(",submenuFuncStat);
+ addFlyAction(tr("COUNTIF(range,eqls)"), tr("COUNTIF(range,eqls)"), "COUNTIF(",submenuFuncStat);
+ addFlyAction(tr("MAX(range)"), tr("MAX(range)"), "MAX(",submenuFuncStat);
+ addFlyAction(tr("MIN(range)"), tr("MIN(range)"), "MIN(",submenuFuncStat);
+ addFlyAction(tr("SUM(range)"), tr("SUM(range)"), "SUM(",submenuFuncStat);
+ addFlyAction(tr("SUMSQ(range)"), tr("SUMSQ(range)"), "SUMSQ(",submenuFuncStat);
+ submenuFuncStat->insertSeparator();
+ addFlyAction(tr("AVERAGE(range)"), tr("AVERAGE(range)"), "AVERAGE(",submenuFuncStat);
+ addFlyAction(tr("VAR(range)"), tr("VAR(range)"), "VAR(",submenuFuncStat);
+ addFlyAction(tr("VARP(range)"), tr("VARP(range)"), "VARP(",submenuFuncStat);
+ addFlyAction(tr("STDEV(range)"), tr("STDEV(range)"), "STDEV(",submenuFuncStat);
+ addFlyAction(tr("STDEVP(range)"), tr("STDEVP(range)"), "STDEVP(",submenuFuncStat);
+ addFlyAction(tr("SKEW(range)"), tr("SKEW(range)"), "SKEW(",submenuFuncStat);
+ addFlyAction(tr("KURT(range)"), tr("KURT(range)"), "KURT(",submenuFuncStat);
+ submenuFunc->insertItem(tr("Sta&tistical"), submenuFuncStat);
+
+ submenuFuncScientific=new QPopupMenu;
+ addFlyAction(tr("BESSELI(x,n)"), tr("BESSELI(x,n)"), "BESSELI(",submenuFuncScientific);
+ addFlyAction(tr("BESSELJ(x,n)"), tr("BESSELJ(x,n)"), "BESSELJ(",submenuFuncScientific);
+ addFlyAction(tr("BESSELK(x,n)"), tr("BESSELK(x,n)"), "BESSELK(",submenuFuncScientific);
+ addFlyAction(tr("BESSELY(x,n)"), tr("BESSELY(x,n)"), "BESSELY(",submenuFuncScientific);
+ submenuFuncScientific->insertSeparator();
+ addFlyAction(tr("BETAI(x,a,b)"), tr("BETAI(x,a,b)"), "BETAI(",submenuFuncScientific);
+ addFlyAction(tr("ERF(a,b)"), tr("ERF(a,b)"), "ERF(",submenuFuncScientific);
+ addFlyAction(tr("ERFC(a,b)"), tr("ERFC(a,b)"), "ERFC(",submenuFuncScientific);
+ addFlyAction(tr("GAMMALN(x)"), tr("GAMMALN(x)"), "GAMMALN(",submenuFuncScientific);
+ addFlyAction(tr("GAMMAP(x,a)"), tr("GAMMAP(x,a)"), "GAMMAP(",submenuFuncScientific);
+ addFlyAction(tr("GAMMAQ(x,a)"), tr("GAMMAQ(x,a)"), "GAMMAQ(",submenuFuncScientific);
+ submenuFunc->insertItem(tr("Scienti&fic"), submenuFuncScientific);
+
+ submenuFuncDistr=new QPopupMenu;
+ addFlyAction(tr("BETADIST(z,a,b,Q?)"), tr("BETADIST(z,a,b,Q?)"), "BETADIST(",submenuFuncDistr);
+ addFlyAction(tr("CHI2DIST(x,n,Q?)"), tr("CHI2DIST(x,n,Q?)"), "CHI2DIST(",submenuFuncDistr);
+ addFlyAction(tr("CHIDIST(x,n,Q?)"), tr("CHIDIST(x,n,Q?)"), "CHIDIST(",submenuFuncDistr);
+ addFlyAction(tr("FDIST(z,deg1,deg2,Q?)"), tr("FDIST(z,deg1,deg2,Q?)"), "FDIST(",submenuFuncDistr);
+ addFlyAction(tr("GAMMADIST(x,a,b,Q?)"), tr("GAMMADIST(x,a,b,Q?)"), "GAMMADIST(",submenuFuncDistr);
+ addFlyAction(tr("NORMALDIST(x,m,s,Q?)"), tr("NORMALDIST(x,m,s,Q?)"), "NORMALDIST(",submenuFuncDistr);
+ addFlyAction(tr("PHI(x,Q?)"), tr("PHI(x,Q?)"), "PHI(",submenuFuncDistr);
+ addFlyAction(tr("POISSON(x,n,Q?)"), tr("POISSON(x,n,Q?)"), "POISSON(",submenuFuncDistr);
+ submenuFunc->insertItem(tr("&Distributions"), submenuFuncDistr);
+
+
menuInsert->insertSeparator();
insertCells->addTo(menuInsert);
insertRows->addTo(menuInsert);
insertCols->addTo(menuInsert);
insertSheets->addTo(menuInsert);
@@ -594,13 +715,13 @@ void MainWindow::slotCellClicked(const QString &cell)
addToData(cell);
}
typeSheet *MainWindow::createNewSheet()
{
typeSheet *newSheet=new typeSheet;
- int currentNo=1, tempNo;
+ int currentNo=1, tempNo=0;
bool ok;
for (typeSheet *tempSheet=listSheets.first(); tempSheet; tempSheet=listSheets.next())
if (tempSheet->name.startsWith(tr("Sheet")) && (tempNo=tempSheet->name.mid(tr("Sheet").length()).toInt(&ok))>=currentNo && ok)
currentNo=tempNo+1;
@@ -622,12 +743,13 @@ typeSheet *MainWindow::findSheet(const QString &name)
void MainWindow::slotSheetChanged(const QString &name)
{
sheet->copySheetData(&findSheet(sheet->getName())->data);
sheet->setName(name);
sheet->setSheetData(&findSheet(name)->data);
+ sheet->ReCalc();
}
void MainWindow::addFlyAction(const QString &text, const QString &menuText, const QString &tip, QWidget *w)
{
QAction *action=new QAction(text, menuText, 0, this);
action->setToolTip(tip);
@@ -742,12 +864,76 @@ void MainWindow::slotFileSaveAs()
currentDoc->setName(dialogText.getValue());
currentDoc->setFile(QString::null);
currentDoc->setLinkFile(QString::null);
documentSave(currentDoc);
}
+void MainWindow::slotImportExcel(const DocLnk &lnkDoc)
+{
+ ExcelBook file1;
+ file1.ParseBook((char *)lnkDoc.file().ascii());
+ int NumOfSheets=file1.Sheets.count();
+ printf("OpieSheet::NumberOfSheets:%d\r\n",NumOfSheets);
+ if (documentModified && saveCurrentFile()==QMessageBox::Cancel) return;
+ if (currentDoc) delete currentDoc;
+ currentDoc = new DocLnk();
+ listSheets.clear();
+ comboSheets->clear();
+ int w1,r,c;
+ ExcelSheet* sh1;
+ typeSheet* newSheet;
+ QString* str;
+ typeCellData* newCell;
+ for(w1=1;w1<=NumOfSheets;w1++)
+ {
+ sh1=file1.Sheets[w1-1];
+ printf("OpieSheet:newSheet:%x,r=%d,c=%d\r\n",sh1,sh1->rows,sh1->cols);
+ newSheet=new typeSheet;
+ newSheet->data.setAutoDelete(TRUE);
+ newSheet->name=sh1->name;
+ printf("OpieSheet:Sheetname:%s\r\n",sh1->name.ascii());
+ comboSheets->insertItem(newSheet->name);
+ for(r=1; r <= sh1->rows; r++)
+ {
+ for(c=1;c <= sh1->cols; c++)
+ {
+ str=file1.CellDataString(sh1,r-1,c-1);
+ if(str!=NULL && r<DEFAULT_NUM_ROWS && c<DEFAULT_NUM_COLS)
+ {
+ newCell=new typeCellData;
+ newCell->row=r-1;
+ newCell->col=c-1;
+ if(str!=NULL) newCell->data=QString(*str); else newCell->data=QString("");
+ newCell->background=QBrush(Qt::white, Qt::SolidPattern);
+ newCell->alignment=(Qt::AlignmentFlags)(Qt::AlignLeft | Qt::AlignTop);
+ newCell->fontColor=Qt::black;
+ newCell->font=font();
+ newCell->borders.right=QPen(Qt::gray, 1, Qt::SolidLine);
+ newCell->borders.bottom=QPen(Qt::gray, 1, Qt::SolidLine);
+ newSheet->data.append(newCell);
+ //there is no format parsing at the moment or style parsing
+ //printf("OpieSheetNumber:row=%d,col=%d,val=%s\r\n",r,c,str->latin1());
+ };
+ };
+ };
+ listSheets.append(newSheet);
+ if (w1==1)//if i==0 link sheet1 with sheetview
+ {
+ sheet->setName(newSheet->name);
+ sheet->setSheetData(&newSheet->data);
+ sheet->ReCalc();
+ };
+
+ };
+ file1.CloseFile();
+ printf("Excel FILE read OK\r\n");
+ documentModified=TRUE;
+
+
+}
+
void MainWindow::slotSheetRename()
{
TextDialog dialogText(this);
if (dialogText.exec(tr("Rename Sheet"), tr("&Sheet Name:"), sheet->getName())!=QDialog::Accepted || dialogText.getValue().isEmpty()) return;
QString newName=dialogText.getValue();
diff --git a/noncore/apps/opie-sheet/mainwindow.h b/noncore/apps/opie-sheet/mainwindow.h
index bd99c36..eacbe36 100644
--- a/noncore/apps/opie-sheet/mainwindow.h
+++ b/noncore/apps/opie-sheet/mainwindow.h
@@ -22,13 +22,13 @@
#include <qmainwindow.h>
#include <qaction.h>
#include <qlineedit.h>
#include <qbutton.h>
#include <qcombobox.h>
#include <qtoolbutton.h>
-
+#include "Excel.h"
#include "sheet.h"
typedef struct typeSheet
{
QString name;
QList<typeCellData> data;
@@ -40,18 +40,21 @@ class MainWindow: public QMainWindow
// QPE objects
DocLnk* currentDoc;
QMenuBar *menu;
QToolBar *toolbarFunctions, *toolbarEdit, *toolbarStandard;
FileSelector *fileSelector;
+ FileSelector *ExcelSelector;
// QT objects
QPopupMenu *menuFile, *menuEdit, *menuInsert, *menuFormat, *menuData, *menuHelp,
- *submenuFunc, *submenuFuncStd, *submenuFuncMath, *submenuFuncStat,
+ *submenuFunc, *submenuFuncStd, *submenuFuncStandard, *submenuFuncLogic,
+ *submenuFuncTrig, *submenuFuncString, *submenuFuncScientific, *submenuFuncDistr,
+ *submenuFuncStat,
*submenuRow, *submenuCol, *submenuSheet;
- QAction *fileNew, *fileOpen, *fileSave, *fileSaveAs, *fileQuit, *helpAbout, *editAccept, *editCancel, *formatCells,
+ QAction *fileNew, *fileOpen, *fileSave, *fileSaveAs, *fileExcelImport, *fileQuit, *helpAbout, *editAccept, *editCancel, *formatCells,
*funcPlus, *funcMinus, *funcCross, *funcDivide, *funcParanOpen, *funcParanClose, *funcComma, *funcEqual,
*editCut, *editCopy, *editPaste, *editPasteContents, *editClear, *insertCols, *insertRows, *insertSheets, *insertCells,
*rowHeight, *rowShow, *rowHide, *rowAdjust, *colWidth, *colShow, *colHide, *colAdjust, *sheetRename, *sheetRemove,
*dataSort, *dataFindReplace, *editCellSelect, *helpGeneral;
QLineEdit *editData;
QButton *buttonUp, *buttonDown, *buttonLeft, *buttonRight;
@@ -84,12 +87,17 @@ class MainWindow: public QMainWindow
private slots:
void slotFileNew();
void slotFileOpen();
void slotFileSave();
void slotFileSaveAs();
+
+ void slotImportExcel(const DocLnk &lnkDoc);
+ void slotImportExcelOpen();
+ void ExcelSelectorHide();
+
void slotHelpAbout();
void slotEditAccept();
void slotEditCancel();
void slotEditPaste();
void slotEditPasteContents();
void slotFormatCells();
diff --git a/noncore/apps/opie-sheet/opie-sheet.pro b/noncore/apps/opie-sheet/opie-sheet.pro
index 81a3366..334a221 100644
--- a/noncore/apps/opie-sheet/opie-sheet.pro
+++ b/noncore/apps/opie-sheet/opie-sheet.pro
@@ -1,9 +1,9 @@
CONFIG = qt warn_on release quick-app
-HEADERS = mainwindow.h sheet.h cellformat.h finddlg.h numberdlg.h sortdlg.h textdlg.h
-SOURCES = main.cpp mainwindow.cpp sheet.cpp cellformat.cpp finddlg.cpp numberdlg.cpp sortdlg.cpp textdlg.cpp
+HEADERS = mainwindow.h sheet.h cellformat.h finddlg.h numberdlg.h sortdlg.h textdlg.h Excel.h
+SOURCES = main.cpp mainwindow.cpp sheet.cpp cellformat.cpp finddlg.cpp numberdlg.cpp sortdlg.cpp textdlg.cpp Excel.cpp
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include
LIBS += -lqpe
TARGET = sheetqt
include ( $(OPIEDIR)/include.pro )
diff --git a/noncore/apps/opie-sheet/sheet.cpp b/noncore/apps/opie-sheet/sheet.cpp
index c2563c2..103b83b 100644
--- a/noncore/apps/opie-sheet/sheet.cpp
+++ b/noncore/apps/opie-sheet/sheet.cpp
@@ -14,12 +14,15 @@
#include "sheet.h"
#include <qmainwindow.h>
#include <qmessagebox.h>
#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
#define DEFAULT_COL_WIDTH 50
Sheet::Sheet(int numRows, int numCols, QWidget *parent)
:QTable(numRows, numCols, parent)
{
@@ -37,35 +40,38 @@ Sheet::Sheet(int numRows, int numCols, QWidget *parent)
sheetData.setAutoDelete(TRUE);
clipboardData.setAutoDelete(TRUE);
for (int i=0; i<numCols; ++i)
horizontalHeader()->setLabel(i, getHeaderString(i+1), DEFAULT_COL_WIDTH);
+
connect(this, SIGNAL(currentChanged(int, int)), this, SLOT(slotCellSelected(int, int)));
connect(this, SIGNAL(valueChanged(int, int)), this, SLOT(slotCellChanged(int, int)));
}
Sheet::~Sheet()
{
}
typeCellData *Sheet::findCellData(int row, int col)
{
typeCellData *tempCellData;
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
- if (tempCellData->row==row && tempCellData->col==col)
- return tempCellData;
+ {
+ if (tempCellData->row==row && tempCellData->col==col) return tempCellData;
+ }
return NULL;
}
void Sheet::slotCellSelected(int row, int col)
{
typeCellData *cellData=findCellData(row, col);
if (cellData)
+ {
emit currentDataChanged(cellData->data);
- else
+ }else
emit currentDataChanged("");
}
typeCellData *Sheet::createCellData(int row, int col)
{
if (row<0 || col<0) return NULL;
@@ -85,16 +91,44 @@ typeCellData *Sheet::createCellData(int row, int col)
void Sheet::slotCellChanged(int row, int col)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=createCellData(row, col);
if (cellData) cellData->data=text(row, col);
for (cellData=sheetData.first(); cellData; cellData=sheetData.next())
- setText(cellData->row, cellData->col, dataParser(findCellName(cellData->row, cellData->col), cellData->data));
+ {
+ // modified by Toussis Manolis koppermind@panafonet.gr
+ // the parser was crashing if there were no closed parenthesis.
+ int w1,ii=0;
+ for(w1=0;w1<=(int)text(row, col).length();w1++)
+ {
+ if(text(row,col)[w1]=='(') ii++;
+ if(text(row,col)[w1]==')') ii--;
+ };
+ if(ii==0) setText(cellData->row, cellData->col, dataParser(findCellName(cellData->row, cellData->col), cellData->data));
+ //end of modification
+ // old was plain:
+ //setText(cellData->row, cellData->col, dataParser(findCellName(cellData->row, cellData->col), cellData->data));
+ };
emit sheetModified();
}
+
+void Sheet::ReCalc(void)
+{
+ typeCellData* cellData;
+ for (cellData=sheetData.first(); cellData; cellData=sheetData.next())
+ {
+ //printf("cellchanged:%d, %d\r\n",cellData->row,cellData->col);
+
+ slotCellChanged(cellData->row,cellData->col);
+ };
+};
+
+
+
+
void Sheet::swapCells(int row1, int col1, int row2, int col2)
{
typeCellData *cellData1=findCellData(row1, col1), *cellData2=findCellData(row2, col2);
if (!cellData1) cellData1=createCellData(row1, col1);
if (!cellData2) cellData2=createCellData(row2, col2);
if (cellData1 && cellData2)
@@ -115,25 +149,26 @@ QString Sheet::getParameter(const QString &parameters, int paramNo, bool giveErr
for (int i=0; i<paramNo; ++i)
{
position=params.find(',');
if (position<0)
{
if (giveError) QMessageBox::critical(this, tr("Error"), tr("Too few arguments to function '"+funcName+'\''));
- return QString();
+ //printf("params:%s\r\n",parameters.ascii());
+ return QString(NULL);
}
params=params.mid(position+1);
}
position=params.find(',');
if (position<0) return params;
return params.left(position);
}
bool Sheet::findRange(const QString &variable1, const QString &variable2, int *row1, int *col1, int *row2, int *col2)
{
int row, col;
- if (!findRowColumn(variable1, row1, col1, TRUE) || !findRowColumn(variable2, row2, col2, TRUE)) return FALSE;
+ if (!findRowColumn(variable1, row1, col1, FALSE) || !findRowColumn(variable2, row2, col2, FALSE)) return FALSE;
if (*row1>*row2)
{
row=*row1;
*row1=*row2;
*row2=row;
}
@@ -156,294 +191,1658 @@ bool Sheet::findRowColumn(const QString &variable, int *row, int *col, bool give
}
*row=variable.mid(position).toInt()-1;
*col=getHeaderColumn(variable.left(position))-1;
return TRUE;
}
-double Sheet::calculateVariable(const QString &variable)
+QString Sheet::calculateVariable(const QString &variable)
{
bool ok;
+ printf("calculateVariable=%s,len=%d\r\n",variable.ascii(),variable.length());
+ if(variable.left(1)=="\"") return QString(variable.mid(1,variable.length()-2));
double tempResult=variable.toDouble(&ok);
- if (ok) return tempResult;
+ if (ok)
+ {
+ if(tempResult!=0.0)
+ {
+ return QString::number(tempResult);
+ }
+ else
+ {
+ if(variable!="0" || variable!="0.0") return QString(variable); // hereis a string variable
+ return QString::number(tempResult);
+ };
+ };
int row, col;
- return (findRowColumn(variable, &row, &col, TRUE) ? dataParser(variable, text(row, col)).toDouble() : 0);
+ if(findRowColumn(variable, &row, &col, FALSE)) return dataParser(variable, text(row,col));
+ //return (findRowColumn(variable, &row, &col, TRUE) ? dataParser(variable, text(row, col)) : 0);
+ return QString(variable);
}
+double Sheet::BesselI0(double x)
+{
+ //Returns the modi ed Bessel function I0(x) for any real x.
+ double ax,ans;
+ double y;
+ if ((ax=fabs(x)) < 3.75)
+ {
+ y=x/3.75;
+ y*=y;
+ ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492 +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
+ }else
+ {
+ y=3.75/ax;
+ ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1 +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2 +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1 +y*0.392377e-2))))))));
+ }
+ return ans;
+};
+
+double Sheet::BesselI1(double x)
+{
+ double ax,ans;
+ double y;
+ if ((ax=fabs(x)) < 3.75)
+ {
+ y=x/3.75;
+ y*=y;
+ ans=ax*(0.5+y*(0.87890594+y*(0.51498869+y*(0.15084934 +y*(0.2658733e-1+y*(0.301532e-2+y*0.32411e-3))))));
+ } else
+ {
+ y=3.75/ax;
+ ans=0.2282967e-1+y*(-0.2895312e-1+y*(0.1787654e-1 -y*0.420059e-2)); ans=0.39894228+y*(-0.3988024e-1+y*(-0.362018e-2 +y*(0.163801e-2+y*(-0.1031555e-1+y*ans))));
+ ans *= (exp(ax)/sqrt(ax));
+ }
+ return x < 0.0 ? -ans : ans;
+};
+
+double Sheet::BesselI(int n, double x)
+{
+ double ACC=40.0;
+ double BIGNO=1.0e10;
+ double BIGNI=1.0e-10;
+ int j;
+ double bi,bim,bip,tox,ans;
+ if (n < 2) return 0.0;
+ if (x == 0.0) return 0.0; else
+ {
+ tox=2.0/fabs(x);
+ bip=ans=0.0;
+ bi=1.0;
+ for (j=2*(n+(int) sqrt(ACC*n));j>0;j--)
+ {
+ bim=bip+j*tox*bi;
+ bip=bi;
+ bi=bim;
+ if (fabs(bi) > BIGNO)
+ {
+ ans *= BIGNI;
+ bi *= BIGNI;
+ bip *= BIGNI;
+ }
+ if (j == n) ans=bip;
+ }
+ ans *= BesselI0(x)/bi;
+ return x < 0.0 && (n & 1) ? -ans : ans;
+ }
+};
+
+double Sheet::BesselK0(double x)
+{
+ double y,ans;
+ if (x <= 2.0)
+ {
+ y=x*x/4.0;
+ ans=(-log(x/2.0)*BesselI0(x))+(-0.57721566+y*(0.42278420 +y*(0.23069756+y*(0.3488590e-1+y*(0.262698e-2 +y*(0.10750e-3+y*0.74e-5))))));
+ } else
+ {
+ y=2.0/x;
+ ans=(exp(-x)/sqrt(x))*(1.25331414+y*(-0.7832358e-1 +y*(0.2189568e-1+y*(-0.1062446e-1+y*(0.587872e-2 +y*(-0.251540e-2+y*0.53208e-3))))));
+ }
+return ans;
+};
+
+double Sheet::BesselK1(double x)
+{
+ double y,ans;
+ if (x <= 2.0)
+ {
+ y=x*x/4.0;
+ ans=(log(x/2.0)*BesselI1(x))+(1.0/x)*(1.0+y*(0.15443144 +y*(-0.67278579+y*(-0.18156897+y*(-0.1919402e-1 +y*(-0.110404e-2+y*(-0.4686e-4)))))));
+ } else
+ {
+ y=2.0/x;
+ ans=(exp(-x)/sqrt(x))*(1.25331414+y*(0.23498619 +y*(-0.3655620e-1+y*(0.1504268e-1+y*(-0.780353e-2 +y*(0.325614e-2+y*(-0.68245e-3)))))));
+ }
+ return ans;
+};
+
+double Sheet::BesselK(int n, double x)
+{
+ int j;
+ double bk,bkm,bkp,tox;
+ if (n < 2) return 0.0;
+ tox=2.0/x;
+ bkm=BesselK0(x);
+ bk=BesselK1(x);
+ for (j=1;j<n;j++)
+ {
+ bkp=bkm+j*tox*bk;
+ bkm=bk;
+ bk=bkp;
+ }
+ return bk;
+};
+
+double Sheet::BesselJ0(double x)
+{
+ double ax,z;
+ double xx,y,ans,ans1,ans2;
+ if ((ax=fabs(x)) < 8.0)
+ {
+ y=x*x;
+ ans1=57568490574.0+y*(-13362590354.0+y*(651619640.7 +y*(-11214424.18+y*(77392.33017+y*(-184.9052456)))));
+ ans2=57568490411.0+y*(1029532985.0+y*(9494680.718 +y*(59272.64853+y*(267.8532712+y*1.0))));
+ ans=ans1/ans2;
+ } else
+ {
+ z=8.0/ax;
+ y=z*z;
+ xx=ax-0.785398164;
+ ans1=1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 +y*(-0.2073370639e-5+y*0.2093887211e-6)));
+ ans2 = -0.1562499995e-1+y*(0.1430488765e-3 +y*(-0.6911147651e-5+y*(0.7621095161e-6 -y*0.934935152e-7)));
+ ans=sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2);
+ }
+ return ans;
+};
+
+double Sheet::BesselY0(double x)
+{
+ double z;
+ double xx,y,ans,ans1,ans2;
+ if (x < 8.0)
+ {
+ y=x*x;
+ ans1 = -2957821389.0+y*(7062834065.0+y*(-512359803.6 +y*(10879881.29+y*(-86327.92757+y*228.4622733))));
+ ans2=40076544269.0+y*(745249964.8+y*(7189466.438 +y*(47447.26470+y*(226.1030244+y*1.0))));
+ ans=(ans1/ans2)+0.636619772*BesselJ0(x)*log(x);
+ } else
+ {
+ z=8.0/x;
+ y=z*z;
+ xx=x-0.785398164;
+ ans1=1.0+y*(-0.1098628627e-2+y*(0.2734510407e-4 +y*(-0.2073370639e-5+y*0.2093887211e-6)));
+ ans2 = -0.1562499995e-1+y*(0.1430488765e-3 +y*(-0.6911147651e-5+y*(0.7621095161e-6 +y*(-0.934945152e-7))));
+ ans=sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2);
+ }
+ return ans;
+};
+
+double Sheet::BesselJ1(double x)
+{
+ double ax,z;
+ double xx,y,ans,ans1,ans2;
+ if ((ax=fabs(x)) < 8.0)
+ {
+ y=x*x;
+ ans1=x*(72362614232.0+y*(-7895059235.0+y*(242396853.1 +y*(-2972611.439+y*(15704.48260+y*(-30.16036606))))));
+ ans2=144725228442.0+y*(2300535178.0+y*(18583304.74 +y*(99447.43394+y*(376.9991397+y*1.0))));
+ ans=ans1/ans2;
+ } else
+ {
+ z=8.0/ax; y=z*z; xx=ax-2.356194491;
+ ans1=1.0+y*(0.183105e-2+y*(-0.3516396496e-4 +y*(0.2457520174e-5+y*(-0.240337019e-6))));
+ ans2=0.04687499995+y*(-0.2002690873e-3 +y*(0.8449199096e-5+y*(-0.88228987e-6 +y*0.105787412e-6)));
+ ans=sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2);
+ if (x < 0.0) ans = -ans;
+ }
+ return ans;
+};
+
+double Sheet::BesselY1(double x)
+{
+ double z;
+ double xx,y,ans,ans1,ans2;
+ if (x < 8.0)
+ {
+ y=x*x;
+ ans1=x*(-0.4900604943e13+y*(0.1275274390e13 +y*(-0.5153438139e11+y*(0.7349264551e9 +y*(-0.4237922726e7+y*0.8511937935e4)))));
+ ans2=0.2499580570e14+y*(0.4244419664e12 +y*(0.3733650367e10+y*(0.2245904002e8 +y*(0.1020426050e6+y*(0.3549632885e3+y)))));
+ ans=(ans1/ans2)+0.636619772*(BesselJ1(x)*log(x)-1.0/x);
+ } else
+ {
+ z=8.0/x;
+ y=z*z;
+ xx=x-2.356194491;
+ ans1=1.0+y*(0.183105e-2+y*(-0.3516396496e-4 +y*(0.2457520174e-5+y*(-0.240337019e-6))));
+ ans2=0.04687499995+y*(-0.2002690873e-3 +y*(0.8449199096e-5+y*(-0.88228987e-6 +y*0.105787412e-6)));
+ ans=sqrt(0.636619772/x)*(sin(xx)*ans1+z*cos(xx)*ans2);
+ }
+ return ans;
+};
+
+double Sheet::BesselY(int n, double x)
+{
+ int j;
+ double by,bym,byp,tox;
+ if (n < 2) return 0.0;
+ tox=2.0/x;
+ by=BesselY1(x);
+ bym=BesselY0(x);
+ for (j=1;j<n;j++)
+ {
+ byp=j*tox*by-bym;
+ bym=by;
+ by=byp;
+ }
+ return by;
+};
+
+double Sheet::BesselJ(int n, double x)
+{
+ double ACC=40.0;
+ double BIGNO=1.0e10;
+ double BIGNI=1.0e-10;
+ int j,jsum,m;
+ double ax,bj,bjm,bjp,sum,tox,ans;
+ if (n < 2) return 0.0;
+ ax=fabs(x);
+ if (ax == 0.0) return 0.0;
+ else if (ax > (double) n)
+ {
+ tox=2.0/ax;
+ bjm=BesselJ0(ax);
+ bj=BesselJ1(ax);
+ for (j=1;j<n;j++)
+ {
+ bjp=j*tox*bj-bjm;
+ bjm=bj;
+ bj=bjp;
+ }
+ ans=bj;
+ } else
+ {
+ tox=2.0/ax;
+ m=2*((n+(int) sqrt(ACC*n))/2);
+ jsum=0;
+ bjp=ans=sum=0.0;
+ bj=1.0;
+ for (j=m;j>0;j--)
+ {
+ bjm=j*tox*bj-bjp;
+ bjp=bj;
+ bj=bjm;
+ if (fabs(bj) > BIGNO)
+ {
+ bj *= BIGNI;
+ bjp *= BIGNI;
+ ans *= BIGNI;
+ sum *= BIGNI;
+ }
+ if (jsum) sum += bj;
+ jsum=!jsum;
+ if (j == n) ans=bjp;
+ }
+ sum=2.0*sum-bj;
+ ans /= sum;
+ }
+ return x < 0.0 && (n & 1) ? -ans : ans;
+};
+
+double Sheet::GammaLn(double xx)
+{
+ double x,y,tmp,ser;
+ static double cof[6]={76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5};
+ int j;
+ y=x=xx;
+ tmp=x+5.5;
+ tmp -= (x+0.5)*log(tmp);
+ ser=1.000000000190015;
+ for (j=0;j<=5;j++) ser += cof[j]/++y;
+ return -tmp+log(2.5066282746310005*ser/x);
+};
+
+double Sheet::Factorial(double n)
+{
+ if (n < 0) return 0.0;
+ if (n > 100) return 0.0;
+ return exp(GammaLn(n+1.0));
+};
+
+double Sheet::GammaP(double a, double x)
+{
+// returns GammaP(a,x)
+//void gcf(float *gammcf, float a, float x, float *gln);
+//void gser(float *gamser, float a, float x, float *gln);
+ double gamser,gammcf,gln;
+ if (x < 0.0 || a <= 0.0) return 0.0;//error
+ if (x < (a+1.0))
+ {
+ GammaSeries(&gamser,a,x,&gln);
+ return gamser;
+ }else
+ {
+ GammaContinuedFraction(&gammcf,a,x,&gln);
+ return 1.0-gammcf;
+ }
+};
+
+double Sheet::GammaQ(double a,double x)
+{
+ //returns GammaQ(a,x)=1.0 - GammaP(a,x);
+ return (1.0-GammaP(a,x));
+};
+
+
+void Sheet::GammaSeries(double *gamser, double a, double x, double *gln)
+{
+ double EPS=3.0e-7;
+ int ITMAX=100;
+ int n;
+ double sum,del,ap;
+ *gln=GammaLn(a);
+ if (x <= 0.0)
+ {
+ if (x < 0.0) return;//error
+ *gamser=0.0;
+ return;
+ } else
+ {
+ ap=a;
+ del=sum=1.0/a;
+ for (n=1;n<=ITMAX;n++)
+ {
+ ++ap;
+ del *= x/ap;
+ sum += del;
+ if (fabs(del) < fabs(sum)*EPS)
+ {
+ *gamser=sum*exp(-x+a*log(x)-(*gln));
+ return;
+ }
+ } return;
+ return;
+ }
+};
+
+
+void Sheet::GammaContinuedFraction(double *gammcf, double a, double x, double *gln)
+{
+ double EPS=3.0e-7;
+ double FPMIN=1.0e-30;
+ int ITMAX=100;
+ int i;
+ double an,b,c,d,del,h;
+ *gln=GammaLn(a);
+ b=x+1.0-a;
+ c=1.0/FPMIN;
+ d=1.0/b; h=d;
+ for (i=1;i<=ITMAX;i++)
+ {
+ an = -i*(i-a);
+ b += 2.0; d=an*d+b;
+ if (fabs(d) < FPMIN) d=FPMIN;
+ c=b+an/c;
+ if (fabs(c) < FPMIN) c=FPMIN;
+ d=1.0/d; del=d*c; h *= del;
+ if (fabs(del-1.0) < EPS) break;
+ }
+ if (i > ITMAX) return;
+ *gammcf=exp(-x+a*log(x)-(*gln))*h;
+};
+
+double Sheet::ErrorFunction(double x)
+{
+ return x < 0.0 ? -GammaP(0.5,x*x) : GammaP(0.5,x*x);
+};
+
+double Sheet::ErrorFunctionComplementary(double x)
+{
+ return x < 0.0 ? 1.0+GammaP(0.5,x*x) : GammaQ(0.5,x*x);
+};
+
+double Sheet::Beta(double z, double w)
+{
+ return exp(GammaLn(z)+GammaLn(w)-GammaLn(z+w));
+};
+
+
+double Sheet::BetaContinuedFraction(double a, double b, double x)
+{
+ int MAXIT=100;
+ double EPS=3.0e-7;
+ double FPMIN=1.0e-30;
+ int m,m2;
+ double aa,c,d,del,h,qab,qam,qap;
+ qab=a+b;
+ qap=a+1.0; qam=a-1.0; c=1.0;
+ d=1.0-qab*x/qap;
+ if (fabs(d) < FPMIN) d=FPMIN;
+ d=1.0/d; h=d;
+ for (m=1;m<=MAXIT;m++)
+ {
+ m2=2*m; aa=m*(b-m)*x/((qam+m2)*(a+m2));
+ d=1.0+aa*d;
+ if (fabs(d) < FPMIN) d=FPMIN;
+ c=1.0+aa/c;
+ if (fabs(c) < FPMIN) c=FPMIN;
+ d=1.0/d; h *= d*c;
+ aa = -(a+m)*(qab+m)*x/((a+m2)*(qap+m2)); d=1.0+aa*d;
+ if (fabs(d) < FPMIN) d=FPMIN;
+ c=1.0+aa/c;
+ if (fabs(c) < FPMIN) c=FPMIN; d=1.0/d;
+ del=d*c; h *= del;
+ if (fabs(del-1.0) < EPS) break;
+ }
+ if (m > MAXIT) return 0.0;
+ return h;
+};
+
+double Sheet::BetaIncomplete(double a, double b, double x)
+{
+ double bt;
+ if (x < 0.0 || x > 1.0) return 0.0;
+ if (x == 0.0 || x == 1.0) bt=0.0; else
+ bt=exp(GammaLn(a+b)-GammaLn(a)-GammaLn(b)+a*log(x)+b*log(1.0-x));
+ if (x < (a+1.0)/(a+b+2.0)) return bt*BetaContinuedFraction(a,b,x)/a; else
+ return 1.0-bt*BetaContinuedFraction(b,a,1.0-x)/b;
+};
+
+
+
double Sheet::functionSum(const QString &param1, const QString &param2)
{
int row1, col1, row2, col2, row, col;
+ double result=0, tempResult;
+ bool ok;
+ if (findRange(param1, param2, &row1, &col1, &row2, &col2))
+ {
+ for (row=row1; row<=row2; ++row)
+ for (col=col1; col<=col2; ++col)
+ {
+ tempResult=text(row, col).toDouble(&ok);
+ if (ok) result+=tempResult;
+ }
+ return result;
+ }else
+ {
+ double d1=0,d2=0;
+ d1=calculateVariable(param1).toDouble(&ok);
+ d2=calculateVariable(param2).toDouble(&ok);
+ return(d1+d2);
+ };
+ return 0;
+}
+
+QString Sheet::functionIndex(const QString &param1, const QString &param2, int indx)
+{
+ int row1, col1, row2, col2, row, col;
if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
+ int ii=1;
+ for (col=col1; col<=col2; ++col)
+ for (row=row1; row<=row2; ++row)
+ {
+ if(ii==indx) return text(row,col);
+ ii++;
+ }
+ return QString("");
+}
+
+
+double Sheet::functionVariancePopulation(const QString &param1, const QString &param2)
+{
+ int row1, col1, row2, col2, row, col;
+ if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
+ double avg1=functionAvg(param1,param2);
double result=0, tempResult;
+ int count1=0;
bool ok;
for (row=row1; row<=row2; ++row)
for (col=col1; col<=col2; ++col)
{
tempResult=text(row, col).toDouble(&ok);
- if (ok) result+=tempResult;
+ if (ok) { result=result + (tempResult - avg1)*(tempResult - avg1); count1++;};
}
-
+ if(count1>0) result=result/double(count1); else result=0.0;
return result;
-}
+};
-double Sheet::functionMin(const QString &param1, const QString &param2)
+double Sheet::functionVariance(const QString &param1, const QString &param2)
{
int row1, col1, row2, col2, row, col;
if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
+ double avg1=functionAvg(param1,param2);
+ double result=0, tempResult;
+ int count1=0;
+ bool ok;
+ for (row=row1; row<=row2; ++row)
+ for (col=col1; col<=col2; ++col)
+ {
+ tempResult=text(row, col).toDouble(&ok);
+ if (ok) { result=result + (tempResult - avg1)*(tempResult - avg1); count1++;};
+ }
+ if(count1>1) result=result/double(count1-1); else result=0.0;
+ return result;
+};
- double min=0, tempMin;
- bool ok, init=FALSE;
+double Sheet::functionSkew(const QString &param1, const QString &param2)
+{
+ int row1, col1, row2, col2, row, col;
+ if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
+ double avg1=functionAvg(param1,param2);
+ double var1=sqrt(functionVariancePopulation(param1,param2));
+ if(var1==0.0) return 0.0;
+ double result=0, tempResult;
+ int count1=0;
+ bool ok;
for (row=row1; row<=row2; ++row)
for (col=col1; col<=col2; ++col)
{
- tempMin=text(row, col).toDouble(&ok);
- if (ok && (!init || tempMin<min))
+ tempResult=text(row, col).toDouble(&ok);
+ if (ok)
{
- min=tempMin;
- init=TRUE;
- }
+ result=result + (tempResult - avg1)*(tempResult - avg1)*(tempResult - avg1)/(var1*var1*var1);
+ count1++;
+ };
}
+ if(count1>0) result=result/double(count1); else result=0.0;
+ return result;
+};
- return min;
-}
-
-double Sheet::functionMax(const QString &param1, const QString &param2)
+double Sheet::functionKurt(const QString &param1, const QString &param2)
{
int row1, col1, row2, col2, row, col;
if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
-
- double max=0, tempMax;
- bool ok, init=FALSE;
+ double avg1=functionAvg(param1,param2);
+ double var1=sqrt(functionVariancePopulation(param1,param2));
+ if(var1==0.0) return 0.0;
+ double result=0, tempResult;
+ int count1=0;
+ bool ok;
for (row=row1; row<=row2; ++row)
for (col=col1; col<=col2; ++col)
{
- tempMax=text(row, col).toDouble(&ok);
- if (ok && (!init || tempMax>max))
+ tempResult=text(row, col).toDouble(&ok);
+ if (ok)
{
- max=tempMax;
- init=TRUE;
- }
+ result=result + (tempResult - avg1)*(tempResult - avg1)*
+ (tempResult - avg1)*(tempResult - avg1)/(var1*var1*var1*var1);
+ count1++;
+ };
}
+ if(count1>0) result=result/double(count1)-3.0; else result=0.0;
+ return result;
+};
+
+
+
+double Sheet::functionSumSQ(const QString &param1, const QString &param2)
+{
+ int row1, col1, row2, col2, row, col;
+ double result=0, tempResult;
+ bool ok;
+ if (findRange(param1, param2, &row1, &col1, &row2, &col2))
+ {
+ for (row=row1; row<=row2; ++row)
+ for (col=col1; col<=col2; ++col)
+ {
+ tempResult=text(row, col).toDouble(&ok);
+ if (ok) result+=tempResult*tempResult;
+ }
+ return result;
+ }else
+ {
+ double d1=0,d2=0;
+ d1=calculateVariable(param1).toDouble(&ok);
+ d2=calculateVariable(param2).toDouble(&ok);
+ return(d1*d1+d2*d2);
+ };
+ return 0;
+}
+
- return max;
+
+double Sheet::functionMin(const QString &param1, const QString &param2)
+{
+ int row1, col1, row2, col2, row, col;
+ double min=0, tempMin;
+ bool ok, init=FALSE;
+ if (findRange(param1, param2, &row1, &col1, &row2, &col2))
+ {
+ for (row=row1; row<=row2; ++row)
+ for (col=col1; col<=col2; ++col)
+ {
+ tempMin=text(row, col).toDouble(&ok);
+ if (ok && (!init || tempMin<min))
+ {
+ min=tempMin;
+ init=TRUE;
+ }
+ }
+ return min;
+ }else
+ {
+ double d1=0,d2=0;
+ d1=calculateVariable(param1).toDouble(&ok);
+ d2=calculateVariable(param2).toDouble(&ok);
+ if(d1<d2) return(d1); else return(d2);
+ };
+ return 0;
+}
+
+double Sheet::functionMax(const QString &param1, const QString &param2)
+{
+ int row1, col1, row2, col2, row, col;
+ double max=0, tempMax;
+ bool ok, init=FALSE;
+ if (findRange(param1, param2, &row1, &col1, &row2, &col2))
+ {
+ for (row=row1; row<=row2; ++row)
+ for (col=col1; col<=col2; ++col)
+ {
+ tempMax=text(row, col).toDouble(&ok);
+ if (ok && (!init || tempMax>max))
+ {
+ max=tempMax;
+ init=TRUE;
+ }
+ };
+ return max;
+ }else
+ {
+ double d1=0,d2=0;
+ d1=calculateVariable(param1).toDouble(&ok);
+ d2=calculateVariable(param2).toDouble(&ok);
+ if(d1>d2) return(d1); else return(d2);
+ };
+ return 0;
}
double Sheet::functionAvg(const QString &param1, const QString &param2)
{
double resultSum=functionSum(param1, param2), resultCount=functionCount(param1, param2);
return (resultCount>0 ? resultSum/resultCount : 0);
}
double Sheet::functionCount(const QString &param1, const QString &param2)
{
int row1, col1, row2, col2, row, col;
- if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
+ int divider=0;
+ bool ok;
+ if (findRange(param1, param2, &row1, &col1, &row2, &col2))
+ {
+ for (row=row1; row<=row2; ++row)
+ for (col=col1; col<=col2; ++col)
+ {
+ text(row, col).toDouble(&ok);
+ if (ok) ++divider;
+ };
+ return divider;
+ }else
+ {
+ double d1=0,d2=0;int ii=0;
+ d1=calculateVariable(param1).toDouble(&ok);
+ if (ok) ii++;
+ d2=calculateVariable(param2).toDouble(&ok);
+ if (ok) ii++;
+ return(ii);
+ };
+ return 0;
+}
+double Sheet::functionCountIf(const QString &param1, const QString &param2, const QString &param3)
+{
+ int row1, col1, row2, col2, row, col;
+ if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
+ //same as count except check if each field is equal to param3
int divider=0;
+ QString s2;
bool ok;
+ s2=calculateVariable(param3);
for (row=row1; row<=row2; ++row)
for (col=col1; col<=col2; ++col)
{
text(row, col).toDouble(&ok);
- if (ok) ++divider;
+ if (ok && (s2==text(row,col)) ) ++divider;
}
-
return divider;
}
-double Sheet::calculateFunction(const QString &function, const QString &parameters)
+
+QString Sheet::calculateFunction(const QString &function, const QString &parameters, int NumOfParams)
{
+ bool ok;
+ double val1=0.0,val2=0.0,val3=0.0;
+ long int vali=0;
+ int w1,w2;
+ int row,col;
+ QString s1,s2;
+//basic functions
if (function=="+")
- return calculateVariable(getParameter(parameters, 0))+calculateVariable(getParameter(parameters, 1));
+ {
+ s1=calculateVariable(getParameter(parameters, 0));
+ s2=calculateVariable(getParameter(parameters, 1));
+ val1=s1.toDouble(&ok)+s2.toDouble(&ok);
+ return QString::number(val1);
+
+ };
if (function=="-")
- return calculateVariable(getParameter(parameters, 0))-calculateVariable(getParameter(parameters, 1));
+ {
+ s1=calculateVariable(getParameter(parameters, 0));
+ s2=calculateVariable(getParameter(parameters, 1));
+ val1=s1.toDouble(&ok)-s2.toDouble(&ok);
+ return QString::number(val1);
+ };
if (function=="*")
- return calculateVariable(getParameter(parameters, 0))*calculateVariable(getParameter(parameters, 1));
+ {
+ val1=calculateVariable(
+ getParameter(parameters, 0)).toDouble(&ok)
+ *calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ return QString::number(val1);
+ };
if (function=="/")
- return calculateVariable(getParameter(parameters, 0))/calculateVariable(getParameter(parameters, 1));
- if (function=="SUM")
- return functionSum(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
- if (function=="COUNT")
- return functionCount(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
- if (function=="MIN")
- return functionMin(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
- if (function=="MAX")
- return functionMax(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
- if (function=="AVG")
- return functionAvg(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
- if (function=="ABS")
- return fabs(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="SIN")
- return sin(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="COS")
- return cos(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="TAN")
- return tan(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="ATAN")
- return atan(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="ATAN2")
- return atan2(calculateVariable(getParameter(parameters, 0, TRUE, function)), calculateVariable(getParameter(parameters, 1, TRUE, function)));
- if (function=="ASIN")
- return asin(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="ACOS")
- return acos(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="EXP")
- return exp(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="LOG")
- return log(calculateVariable(getParameter(parameters, 0, TRUE, function)));
- if (function=="POW")
- return pow(calculateVariable(getParameter(parameters, 0, TRUE, function)), calculateVariable(getParameter(parameters, 1, TRUE, function)));
- return 0;
-}
-
-int Sheet::getOperatorPriority(char oper)
-{
- switch (oper)
{
- case '+':
- case '-':
- return 1;
-
- case '*':
- case '/':
- return 2;
- }
- return 0;
-}
+ val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ if(val2==0.0) return QString("Err101");
+ val1=val1/val2;
+ return QString::number(val1);
+ };
+ if (function==">")
+ {
+ val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ if(val1>val2) return QString::number(1); else return QString::number(0);
+ };
+ if (function=="<")
+ {
+ val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ if(val1<val2) return QString::number(1); else return QString::number(0);
+ };
+ if (function==">=")
+ {
+ val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ if(val1>=val2) return QString::number(1); else return QString::number(0);
+ };
+ if (function=="<=")
+ {
+ val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ if(val1<=val2) return QString::number(1); else return QString::number(0);
+ };
+ if (function=="!=")
+ {
+ val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ if(val1!=val2) return QString::number(1); else return QString::number(0);
+ };
+ if (function=="=="||function=="=")
+ {
+ val1=calculateVariable(getParameter(parameters, 0)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1)).toDouble(&ok);
+ if(val1==val2) return QString::number(1); else return QString::number(0);
+ };
+
+ //LOGICAL / INFO
+ if (function=="ISBLANK")
+ {
+ if(findRowColumn(getParameter(parameters, 0), &row, &col, FALSE))
+ {
+ if(text(row,col).length()==0) val1=1; else val1=0;
+ }else
+ {
+ if(findRowColumn(calculateVariable(getParameter(parameters, 0)), &row,&col, FALSE))
+ {
+ if(text(row,col).length()==0) val1=1; else val1=0;
+ }else
+ {
+ val1=0;
+ };
+ };
+ return QString::number(val1);
+ };
+
+
+ if (function=="ISNUMBER")
+ {
+ if(findRowColumn(getParameter(parameters, 0, TRUE, function), &row, &col, FALSE))
+ {
+ val1=text(row,col).toDouble(&ok);
+ if(ok) val1=1; else val1=0;
+ }else
+ {
+ if(findRowColumn(calculateVariable(getParameter(parameters, 0, TRUE, function)), &row,&col, FALSE))
+ {
+ val1=text(row,col).toDouble(&ok);
+ if(ok) val1=1; else val1=0;
+ }else
+ {
+ val1=0;
+ };
+ };
+ return QString::number(val1);
+ };
+ if (function=="AND")
+ {
+ vali=calculateVariable(getParameter(parameters, 0, TRUE, function)).toInt(&ok)
+ & calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ return QString::number(vali);
+ };
+ if (function=="OR")
+ {
+ vali=calculateVariable(getParameter(parameters, 0, TRUE, function)).toInt(&ok)
+ | calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ return QString::number(vali);
+ };
+ if (function=="NOT")
+ {
+ vali=!calculateVariable(getParameter(parameters, 0, TRUE, function)).toInt(&ok);
+ return QString::number(vali);
+ };
+
+ // MATHEMATICAL FUNCTIONS
+ if (function=="ABS")
+ {
+ val1=fabs(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ACOS")
+ {
+ val1=acos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ACOSH")
+ {
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ if(val1<1.0) return QString::number(0);
+ val1=acosh(val1);
+ return QString::number(val1);
+ };
+ if (function=="ASIN")
+ {
+ val1=asin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ASINH")
+ {
+ val1=asinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ATAN")
+ {
+ val1=atan(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ATAN2")
+ {
+ val1=atan2(calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok),
+ calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ATANH")
+ {
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ if(val1<=-1.0 || val1>=1.0) return QString("Err101");
+ val1=atanh(val1);
+ return QString::number(val1);
+ };
+ if (function=="CEILING")
+ {
+ // rounds up param1 to specified accuracy param2
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ if(val2==0.0) return QString::number(val1);
+ val1=ceil(val1/val2)*val2;
+ return QString::number(val1);
+ };
+ if (function=="COS")
+ {
+ val1=cos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="COSH")
+ {
+ val1=cosh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="DEGREES")
+ {
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)*180.0/M_PI;
+ return QString::number(val1);
+ };
+ if (function=="EXP")
+ {
+ val1=exp(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="FACT")
+ {
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=Factorial(val1);
+ return QString::number(val2);
+ };
+ if (function=="FLOOR")
+ {
+ // rounds down param1 to specified accuracy param2
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ if(val2==0.0) return QString::number(val1);
+ val1=floor(val1/val2)*val2;
+ return QString::number(val1);
+ };
+ if (function=="INT")
+ {
+ // rounds down param1
+ val1=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="EVEN")
+ {
+ //converts param1 to even
+ vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ if(vali % 2 !=0) val1=vali+1; else val1=vali;
+ return QString::number(val1);
+ };
+ if (function=="ODD")
+ {
+ //converts param1 to odd
+ vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ if(vali % 2 !=0) val1=vali; else val1=vali+1;
+ return QString::number(val1);
+ };
+ if (function=="ISEVEN")
+ {
+ //Is Even param1?
+ vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ if(vali % 2 == 0) val1=1; else val1=0;
+ return QString::number(val1);
+ };
+ if (function=="ISODD")
+ {
+ //Is odd param1?
+ vali=int(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ if(vali % 2 == 0) val1=0; else val1=1;
+ return QString::number(val1);
+ };
+ if (function=="LN")
+ {
+ // returns the natural logarithm of param1
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ if(val1<=0.0) return QString("Err101");
+ val1=log(val1);
+ return QString::number(val1);
+ };
+ if (function=="LOG10")
+ {
+ // returns the base-10 logarithm of param1
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ if(val1<=0.0) return QString("Err101");
+ val1=log10(val1);
+ return QString::number(val1);
+ };
+ if (function=="LOG")
+ {
+ // return the base-param2 logarithm of param1
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ if(val1<=0.0 || val2<=0.0 ) return QString("Err101");
+ val1=log(val1)/log(val2);
+ return QString::number(val1);
+ };
+ if (function=="MOD")
+ {
+ // return the modulus of param1/param2
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ if(val2==0.0) return QString("Err101");
+ val1=(int(val1) % int(val2));
+ return QString::number(val1);
+ };
+ if (function=="POWER")
+ {
+ // return the param1^param2
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ if(val1<0.0 && (floor(val2)!=val2)) return QString("Err101");
+ val1=pow(val1,val2);
+ return QString::number(val1);
+ };
+ if (function=="PI")
+ {
+ return QString::number(M_PI);
+ };
+ if (function=="RADIANS")
+ {
+ // param1 deg->rad
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)*M_PI/180.0;
+ return QString::number(val1);
+ };
+ if (function=="RAND")
+ {
+ // retuns random number 0>x>1
+ srand((unsigned int)time((time_t *)NULL));
+ val1=double(rand())/double(RAND_MAX);
+ return QString::number(val1);
+ };
+ if (function=="RANDBETWEEN")
+ {
+ // returns random number between param1>x>param2
+ //TOFIX: this is not ok because I think results is always int related.
+ srand((unsigned int)time((time_t *)NULL));
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ val1=fmod(double(rand()),(val2-val1))+val1;
+ return QString::number(val1);
+ };
+ if (function=="ROUND")
+ {
+ // rounds down param1 to specified digits param2 (positive decimal digits)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ val2=pow(10.0,-val2);
+ val1=floor(val1/val2)*val2;
+ return QString::number(val1);
+ };
+ if (function=="SIGN")
+ {
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ if(val1>=0.0) return QString::number(1.0); else return QString::number(-1.0);
+ };
+ if (function=="CHGSGN")//changes sign (for unary operator)
+ {
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ return QString::number((-1.0)*val1);
+ };
+ if (function=="SIN")
+ {
+ val1=sin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="SINH")
+ {
+ val1=sinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="TAN")
+ {
+ val1=tan(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="TANH")
+ {
+ val1=tanh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="SQRT")
+ {
+ val1=sqrt(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+
+
+// STRING FUNCTIONS
+ if (function=="CONCATENATE")
+ {
+ // concatenates strings together
+ w1=0;
+ s1="";
+ while(getParameter(parameters, w1, FALSE, function)!="") //parse all params;
+ {
+ s1=s1+calculateVariable(getParameter(parameters, w1));
+ w1++;
+ };
+ return QString(s1);
+ };
+ if (function=="EXACT")
+ {
+ // compare two string if they are exactly the same
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ s2=calculateVariable(getParameter(parameters, 1, TRUE, function));
+ if(s1==s2) return QString::number(1); else return QString::number(0);
+ };
+ if (function=="FIND")
+ {
+ // finds param1 in param2 from pos param3 and after
+ // returns -1 if not found
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ s2=calculateVariable(getParameter(parameters, 1, TRUE, function));
+ vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok);
+ val1=s2.find(s1,vali);
+ return QString::number(val1);
+ };
+ if (function=="LEFT")
+ {
+ // returns the param2 left chars from param1 string
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ s2=s1.left(vali);
+ return QString(s2);
+ };
+ if (function=="LEN")
+ {
+ // return the length of a string(param1)
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ return QString::number(s1.length());
+ };
+ if (function=="MID")
+ {
+ // returns the mid word of string param1 with start param2 and len param3
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ w1=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ w2=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok);
+ s2=s1.mid(w1,w2);
+ return QString(s2);
+ };
+ if (function=="REPLACE")
+ {
+ //replace in param1 text in pos param2 and length param3 to newtext param4
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ w1=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ w2=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok);
+ s2=calculateVariable(getParameter(parameters, 3, TRUE, function));
+ if(w1<0 || w2<0) return QString(s1);
+ s1=s1.left(w2-1)+s2+s1.right(s1.length()-w1-w2);
+ return QString(s1);
+ };
+ if (function=="REPT")
+ {
+ //repeats param1 string param2 times
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ w1=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ for(w2=1;w2<=w1;w2++)
+ {
+ s2=s2.append(s1);
+ };
+ return QString(s2);
+ };
+ if (function=="RIGHT")
+ {
+ // returns the param2 right chars from param1 string
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ s2=s1.right(vali);
+ return QString(s2);
+ };
+ if (function=="UPPER")
+ {
+ // returns the upper param1 string
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ s1=s1.upper();
+ return QString(s1);
+ };
+ if (function=="LOWER")
+ {
+ // returns the lower param1 string
+ s1=calculateVariable(getParameter(parameters, 0, TRUE, function));
+ s1=s1.lower();
+ return QString(s1);
+ };
+ if (function=="IF")
+ {
+ //usage: IF(param1,param2,param3)
+ //returns param4 if true(param1)/ param5 if false(param1)
+ val1=getParameter(parameters, 0, TRUE, function).toDouble(&ok);
+ if(val1==1.0)
+ {
+ s1=calculateVariable(getParameter(parameters, 1, TRUE, function));
+ return QString(s1);
+ }else
+ {
+ s1=calculateVariable(getParameter(parameters, 2, TRUE, function));
+ return QString(s1);
+ };
+ };
+ if (function=="SUM")
+ {
+ //NumOfParams
+ val2=0.0;
+ for(w1=1;w1<=(NumOfParams/2);w1++)
+ {
+ val1=functionSum(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function));
+ val2=val2+val1;
+ };
+ if(NumOfParams%2==1)
+ {
+ val2=val2+calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok);
+ };
+ return QString::number(val2);
+ };
+ if (function=="INDEX")
+ {
+ s1=functionIndex(getParameter(parameters,0,TRUE,function), getParameter(parameters, 1, TRUE, function), getParameter(parameters,2,TRUE,function).toInt(&ok));
+ return QString(s1);
+ };
+ if (function=="SUMSQ")
+ {
+ //NumOfParams
+ val2=0.0;
+ for(w1=1;w1<=(NumOfParams/2);w1++)
+ {
+ val1=functionSumSQ(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function));
+ val2=val2+val1;
+ };
+ if(NumOfParams%2==1)
+ {
+ val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok);
+ val2=val2+val1*val1;
+ };
+ return QString::number(val2);
+ };
+ if (function=="COUNT")
+ {
+ //NumOfParams
+ val2=0.0;
+ for(w1=1;w1<=(NumOfParams/2);w1++)
+ {
+ val1=functionCount(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function));
+ val2=val2+val1;
+ };
+ if(NumOfParams%2==1)
+ {
+ val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok);
+ if(ok) val2=val2+1;
+ };
+ return QString::number(val2);
+ };
+ if (function=="COUNTIF")
+ {
+ //NumOfParams
+ val1=functionCountIf(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function), getParameter(parameters, 2, TRUE, function));
+ return QString::number(val1);
+ };
+ if (function=="MIN")
+ {
+ //NumOfParams
+ val2=0.0;
+ for(w1=1;w1<=(NumOfParams/2);w1++)
+ {
+ val1=functionMin(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function));
+ val2=val1;
+ };
+ if(NumOfParams%2==1)
+ {
+ val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok);
+ if(val1<val2) val2=val1;
+ };
+ return QString::number(val2);
+ };
+ if (function=="MAX")
+ {
+ //NumOfParams
+ val2=0.0;
+ for(w1=1;w1<=(NumOfParams/2);w1++)
+ {
+ val1=functionMax(getParameter(parameters, (w1-1)*2, FALSE, function), getParameter(parameters, (w1-1)*2+1, TRUE, function));
+ val2=val1;
+ };
+ if(NumOfParams%2==1)
+ {
+ val1=calculateVariable(getParameter(parameters,NumOfParams-1,FALSE, function)).toDouble(&ok);
+ if(val1>val2) val2=val1;
+ };
+ return QString::number(val2);
+ };
+ if (function=="AVERAGE")
+ {
+ val1=functionAvg(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
+ return QString::number(val1);
+ };
+
+ if(function=="BESSELI")
+ {
+ // BesselI (x,n)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ val2=BesselI(vali,val1);
+ return QString::number(val2);
+ };
+ if(function=="BESSELJ")
+ {
+ // BesselJ (x,n)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ val2=BesselJ(vali,val1);
+ return QString::number(val2);
+ };
+ if(function=="BESSELK")
+ {
+ // BesselK (x,n)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ val2=BesselK(vali,val1);
+ return QString::number(val2);
+ };
+ if(function=="BESSELY")
+ {
+ // BesselY (x,n)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ val2=BesselY(vali,val1);
+ return QString::number(val2);
+ };
+ if(function=="GAMMALN")
+ {
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=GammaLn(val1);
+ return QString::number(val2);
+ };
+ if(function=="ERF")
+ {
+ // ERF (a,b)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ return QString::number(ErrorFunction(val2)-ErrorFunction(val1));
+ };
+ if(function=="ERFC")
+ {
+ // ERFC (a,b)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ return QString::number(ErrorFunctionComplementary(val2)-ErrorFunctionComplementary(val1));
+ };
+ if(function=="POISSON")
+ {
+ // POISSON DISTR(x,n,distr/desnt)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok);
+ if(vali==1)
+ {
+ return QString::number(GammaQ(floor(val1)+1, val2));
+ }else
+ {
+ return QString::number(exp(-val2)*pow(val2,val1)/exp(GammaLn(val1+1.0)));
+ };
+ };
+ if(function=="CHIDIST")
+ {
+ // POISSON CHIDIST(x,n,distr/density)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok);
+ if(vali==1)
+ {
+ return QString::number(GammaP(val2/2.0,val1*val1/2.0));
+ } else
+ {
+ return QString::number(
+ pow(val1,val2-1.0)*exp(-val1*val1/2)/ ( pow(2,val2/2.0-1.0)*exp(GammaLn(val2/2.0)))
+ );
+ };
+ };
+ if(function=="CHI2DIST")
+ {
+ // POISSON CHISQUAREDIST(x,n,distr/density)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 2, TRUE, function)).toInt(&ok);
+ if(vali==1)
+ {
+ return QString::number(GammaP(val2/2.0,val1/2.0));
+ } else
+ {
+ return QString::number(
+ pow(val1,val2/2.0-1.0)/(exp(val1/2.0)*pow(sqrt(2.0),val2)*exp(GammaLn(val2/2.0)))
+ );
+ };
+ };
+ if(function=="BETAI")
+ {
+ // BETA INCOMPLETE BETA(x,a,b)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok);
+ return QString::number(BetaIncomplete(val2,val3,val1));
+ };
+ if(function=="GAMMAP")
+ {
+ // GammaP (x,a)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ return QString::number(GammaP(val2,val1));
+ };
+ if(function=="GAMMAQ")
+ {
+ // GammaQ (x,a)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ return QString::number(GammaQ(val2,val1));
+ };
+ if (function=="VAR")
+ {
+ val1=functionVariance(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
+ return QString::number(val1);
+ };
+ if (function=="VARP")
+ {
+ val1=functionVariancePopulation(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
+ return QString::number(val1);
+ };
+ if (function=="STDEV")
+ {
+ val1=functionVariance(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
+ if(val1<=0.0) return QString::number(0.0);
+ return QString::number(sqrt(val1));
+ };
+ if (function=="STDEVP")
+ {
+ val1=functionVariancePopulation(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
+ if(val1<=0.0) return QString::number(0.0);
+ return QString::number(sqrt(val1));
+ };
+ if (function=="SKEW")
+ {
+ val1=functionSkew(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
+ return QString::number(val1);
+ };
+ if (function=="KURT")
+ {
+ val1=functionKurt(getParameter(parameters, 0, TRUE, function), getParameter(parameters, 1, TRUE, function));
+ return QString::number(val1);
+ };
+ if(function=="GAMMADIST")
+ {
+ // GAMMADIST (x,alpha,beta,distribution?density1:0)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok);
+ if(vali==1)//distribution
+ {
+ if(val3==0.0) return QString::number(0.0);
+ else
+ return QString::number(GammaP(val2,val1/val3));
+ }else //density
+ {
+ return QString::number(
+ pow(val1,val2-1.0)*exp(-val1/val3) / (pow(val3,val2)*exp(GammaLn(val2)))
+ );
+ };
+ };
+ if(function=="BETADIST")
+ {
+ // BETADIST (z,alpha,beta,distribution?density1:0)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok);
+ if(vali==1)//distribution
+ {
+ return QString::number(BetaIncomplete(val2,val3,val1));
+ }else //density
+ {
+ return QString::number(
+ pow(val1,val2-1.0)*pow(1.0-val1,val3-1.0) / Beta(val2,val3)
+ );
+ };
+ };
+ if(function=="FDIST")
+ {
+ // FDIST (z,d1,d2,distribution?density1:0)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok);
+ if(vali==1)//distribution
+ {
+ return QString::number(
+ -BetaIncomplete(val3/2,val2/2,val3/(val3+val2*val1))
+ +BetaIncomplete(val3/2,val2/2,1)
+ );
+ }else //density
+ {
+ return QString::number(
+ pow(val2,val2/2)*pow(val3,val3/2)*pow(val1,val2/2-1)/
+ (pow(val3+val2*val1,(val2+val3)/2)*Beta(val2/2,val3/2))
+ );
+ };
+ };
+ if(function=="NORMALDIST")
+ {
+ // NORMALDIST (x,m,s,distribution?density1:0)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ val2=calculateVariable(getParameter(parameters, 1, TRUE, function)).toDouble(&ok);
+ val3=calculateVariable(getParameter(parameters, 2, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 3, TRUE, function)).toInt(&ok);
+ if(vali==1)//distribution
+ {
+ return QString::number(
+ (ErrorFunction((val1-val2)/(sqrt(2)*val3))+1)/2.0
+ );
+ }else //density
+ {
+ return QString::number(
+ exp(-pow(((val1-val2)/val3),2)/2)/(val3*sqrt(2*M_PI))
+ );
+ };
+ };
+ if(function=="PHI")
+ {
+ // NORMALDIST (x,distribution?density1:0) with mean=0 s=1.0
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok);
+ vali=calculateVariable(getParameter(parameters, 1, TRUE, function)).toInt(&ok);
+ if(vali==1)//distribution
+ {
+ return QString::number(
+ (ErrorFunction(val1/(sqrt(2)))+1)/2.0
+ );
+ }else //density
+ {
+ return QString::number(
+ exp(-pow(val1,2)/2)/(sqrt(2*M_PI))
+ );
+ };
+ };
+ /*
+ StudentTDistribution/: PDF[StudentTDistribution[n_], x_] :=
+ 1/(Sqrt[n] Beta[n/2, 1/2]) Sqrt[n/(n+x^2)]^(n+1) /;
+ ParameterQ[StudentTDistribution[n]]
+
+ StudentTDistribution/: CDF[StudentTDistribution[n_], x_] :=
+ (1 + Sign[x] BetaRegularized[n/(n+x^2), 1, n/2, 1/2])/2 /;
+ ParameterQ[StudentTDistribution[n]]
+ */
-void Sheet::pushCharStack(QStack<QChar> *stackChars, const QChar &character)
-{
- QChar *temp=new QChar(character);
- stackChars->push(temp);
-}
-void Sheet::pushStringStack(QStack<QString> *stackStrings, const QString &string)
-{
- QString *temp=new QString(string);
- stackStrings->push(temp);
-}
-QChar Sheet::popCharStack(QStack<QChar> *stackChars)
-{
- if (stackChars->isEmpty())
- {
- QMessageBox::critical(this, tr("Error"), tr("Syntax error!"));
- return '0';
- }
+ return 0;
+};
- QChar *temp=stackChars->pop();
- QChar temp2(*temp);
- delete temp;
- return temp2;
-}
-QString Sheet::popStringStack(QStack<QString> *stackStrings)
-{
- if (stackStrings->isEmpty())
- {
- QMessageBox::critical(this, tr("Error"), tr("Syntax error!"));
- return "0";
- }
- QString *temp=stackStrings->pop();
- QString temp2(*temp);
- delete temp;
- return temp2;
-}
QString Sheet::dataParserHelper(const QString &data)
{
- QStack<QString> stackElements;
- QStack<QChar> stackOperators;
- QString tempElement(""), temp2Element, firstElement, secondElement;
- int paranCount;
+ if(data.left(1)=="""" && data.right(1)=="""") return QString(data);
+ Expression exp1(data);
+ exp1.Parse();
+ QStack<QString> stack1;
+ stack1.setAutoDelete(TRUE);
+ int i=0;
+ QString* s1;
+ QString* s2=NULL;
+ int* i1;
+ int args,tokentype;
+ QString tempval;
+ s1=exp1.CompiledBody.first();i1=exp1.CompiledBodyType.first();
+ while(i<=(int)exp1.CompiledBody.count()-1)
+ {
+ args= ((*i1) & 0xFF00)>>8; tokentype=(*i1) & 0x00FF;
+ if(tokentype==NUMBER_TOKEN)
+ {
+ stack1.push(new QString(*s1));
+ //printf("Parse:Number=%s\r\n",s1->latin1());
+ }
+ else if(tokentype==VARIABLE_TOKEN)
+ {
+ stack1.push(new QString(*s1));
+ //printf("Parse:Var=%s\r\n",s1->latin1());
+ //here to put implementation of other types of variables except cell.
+ //for example names
+ }
+ else if(tokentype==STRING_TOKEN)
+ {
+ stack1.push(new QString(*s1));
+ //printf("Parse:String=%s\r\n",s1->ascii());
+ }
+ else if(tokentype==FUNCTION_TOKEN)
+ {
+ QString params="";
+ for(int w1=1;w1<=args;w1++)
+ {
+ if((int)stack1.count()!=0) s2=stack1.pop();
+ params=*s2+params;//args in reverse order
+ params=","+params;
+ };
+ params=params.mid(1);
+ if(params==NULL) params="0";
+ //printf("Parse:Func=%s, params=%s, stackcount=%d,args=%d\r\n"
+ // ,s1->latin1(),params.latin1(),stack1.count(),args);
+ tempval=calculateFunction(*s1,params,args);
+ tempval=tempval.upper();
+ stack1.push(new QString(tempval));
+ };
+
+ //loops to next token
+ if(exp1.CompiledBody.next()!=NULL) s1=exp1.CompiledBody.current(); else break;
+ if(exp1.CompiledBodyType.next()!=NULL) i1=exp1.CompiledBodyType.current(); else break;
+ i++;
+ };
+ if((int)stack1.count()!=0)s2=stack1.pop(); else s2=new QString("!ERROR");
+ tempval=*s2;
+ return(tempval);
+};
- for (unsigned int i=0; i<data.length(); ++i)
- {
- if (data[i]=='+' || data[i]=='-' || data[i]=='*' || data[i]=='/')
- {
- pushStringStack(&stackElements, tempElement);
- tempElement="";
- if (!stackOperators.isEmpty() && getOperatorPriority(*stackOperators.top())>getOperatorPriority(data[i]))
- {
- secondElement=popStringStack(&stackElements);
- firstElement=popStringStack(&stackElements);
- pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement)));
- }
- pushCharStack(&stackOperators, data[i]);
- }
- else
- if (data[i]==',')
- {
- if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement);
- while (!stackOperators.isEmpty())
- {
- secondElement=popStringStack(&stackElements);
- firstElement=popStringStack(&stackElements);
- pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement)));
- }
- tempElement="";
- }
- else
- if (data[i]=='(')
- {
- paranCount=1;
- temp2Element="";
- for (++i; paranCount>0; ++i)
- {
- temp2Element+=data[i];
- if (data[i]=='(') ++paranCount;
- if (data[i]==')') --paranCount;
- }
- temp2Element=dataParserHelper(temp2Element.left(temp2Element.length()-1));
- if (tempElement.isEmpty())
- tempElement=temp2Element;
- else
- tempElement.setNum(calculateFunction(tempElement, temp2Element));
- --i;
- }
- else
- tempElement+=data[i];
- }
- if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement);
- while (!stackOperators.isEmpty())
- {
- secondElement=popStringStack(&stackElements);
- firstElement=popStringStack(&stackElements);
- pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement)));
- }
- if (!stackElements.isEmpty())
- tempElement=popStringStack(&stackElements);
- while (!stackElements.isEmpty())
- tempElement.prepend(popStringStack(&stackElements)+",");
- return tempElement;
-}
QString Sheet::dataParser(const QString &cell, const QString &data)
{
QString strippedData(data);
strippedData.replace(QRegExp("\\s"), "");
if (strippedData.isEmpty() || strippedData[0]!='=') return data;
if (listDataParser.find(cell)!=listDataParser.end()) return "0";
listDataParser.append(cell);
+ // printf("DATAPARSER: data=%s, cell=%s\r\n",data.ascii(),cell.ascii());
strippedData=dataParserHelper(strippedData.remove(0, 1).upper().replace(QRegExp(":"), ","));
int i=0;
QString tempParameter(getParameter(strippedData, i)), result="";
do
{
- result+=","+QString::number(calculateVariable(tempParameter));
+ result+=","+calculateVariable(tempParameter);
tempParameter=getParameter(strippedData, ++i);
}
while (!tempParameter.isNull());
listDataParser.remove(cell);
return result.mid(1);
}
+
void Sheet::setData(const QString &data)
{
setText(currentRow(), currentColumn(), data);
slotCellChanged(currentRow(), currentColumn());
activateNextCell();
}
@@ -479,12 +1878,13 @@ void Sheet::paintCell(QPainter *p, int row, int col, const QRect & cr, bool sele
QTableItem *cellItem=item(row, col);
if (cellItem)
{
p->setPen(selected ? colorGroup().highlightedText() : cellData->fontColor);
p->setFont(cellData->font);
+ QString str=cellItem->text();
p->drawText(2, 2, cr.width()-4, cr.height()-4, cellData->alignment, cellItem->text());
}
int rx=cr.width()-1, ry=cr.height()-1;
QPen pen(p->pen());
p->setPen(cellData->borders.right);
@@ -867,6 +2267,299 @@ QString Sheet::getHeaderString(int section)
int Sheet::getHeaderColumn(const QString &section)
{
if (section.isEmpty()) return 0;
return (section[section.length()-1]-'A'+1)+getHeaderColumn(section.left(section.length()-1))*26;
}
+
+
+//Expression Parser Class Definition
+
+
+QChar Expression::chunk0(void)
+{
+ if(chunk.length()>0) return(chunk[0]); else return('\0');
+};
+
+Expression::Expression(QString expr1)// constructor
+{
+ Body=expr1;
+ SYMBOL="+-*/%^=()<>&|!,";
+ MATHSYMBOL="+-*/%^=<>&|!,";
+ // lnlim=1.0e-36; // Smallest number allowed
+ // loglim=1.0e-10 ; // Smallest number allowed in call to log10() *
+ ErrorFound=TRUE;
+ n=0;chunk="";SymbGroup=NONE_TOKEN;InExpr=Body;
+ ArgsOfFunc=0;
+ CompiledBody.setAutoDelete(TRUE);
+ CompiledBodyType.setAutoDelete(TRUE);
+ //CompiledBody=QStringList(0);
+};
+
+bool Expression::isSymbol(QChar ch)
+{
+ int j = 0;
+ while (j<=((int)SYMBOL.length()-1) && ch!=SYMBOL[j]) j++;
+ if(j<((int)SYMBOL.length())) return true; else return false;
+};
+
+bool Expression::isMathSymbol(QChar ch)
+{
+ int j = 0;
+ while (j<=((int)MATHSYMBOL.length()-1) && ch!=MATHSYMBOL[j]) j++;
+ if(j<((int)MATHSYMBOL.length())) return true; else return false;
+};
+
+void Expression::GetNext()
+{
+ chunk="";
+ if(n>=(int)InExpr.length()) return;
+ while (InExpr[n]==' ') n++;
+ if(InExpr[n]=='\"')
+ {
+ while ( (n<(int)InExpr.length()) && (InExpr[n+1]!='\"') )
+ {
+ printf("chunk=%s\r\n",chunk.latin1());
+ chunk+=InExpr[n];
+ n++;
+ };
+ chunk+=InExpr[n];
+ printf("2\r\n");
+ SymbGroup=STRING_TOKEN;
+ }
+ else if (isSymbol(InExpr[n]))
+ {
+ SymbGroup=SYMBOL_TOKEN;
+ chunk+=InExpr[n];
+ n++;
+ if( (n<(int)InExpr.length()) &&
+ isMathSymbol(InExpr[n-1]) &&
+ isMathSymbol(InExpr[n]) )
+ {
+ SymbGroup=SYMBOL_TOKEN;
+ chunk+=InExpr[n];
+ n++;
+ };
+ }
+ else if ((InExpr[n].isLetter())||(InExpr[n]=='#'))
+ {
+ while ( (n<(int)InExpr.length()) && !isSymbol(InExpr[n]) )
+ {
+ if (!(InExpr[n]==' ')) chunk+=InExpr[n];
+ n++;
+ };
+ if (InExpr[n]=='(') SymbGroup=FUNCTION_TOKEN; // function TOKEN
+ else SymbGroup=VARIABLE_TOKEN;
+ }
+ else if((n<(int)InExpr.length()) &&
+ ((InExpr[n].isDigit()) || (InExpr[n]=='.')))
+ {
+ while( n<(int)InExpr.length() )
+ {
+ if((InExpr[n].isDigit()) || InExpr[n]=='.')
+ {
+ chunk+=InExpr[n];
+ SymbGroup=NUMBER_TOKEN;
+ n++;
+ }
+ else if(InExpr[n]=='e')
+ {
+ if((n+1)<(int)InExpr.length())
+ {
+ if(InExpr[n+1]=='-' || InExpr[n+1]=='+' || InExpr[n+1].isDigit())
+ {
+ chunk+=InExpr[n];
+ chunk+=InExpr[n+1];
+ SymbGroup=NUMBER_TOKEN;
+ n+=2;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }//while
+ }//else if
+};//end function
+
+
+void Expression::First()
+{
+ GetNext();
+ if (!(chunk=="") && !ErrorFound) Third();
+ else ErrorFound = true;
+};
+
+void Expression::Third()
+{
+ QChar sign, secS='\0';
+ Fourth();
+ sign = chunk0();
+ if((int)chunk.length()>1) secS=chunk[1];
+ while( sign == '+' || sign == '-'||
+ sign == '<' || sign == '>'|| sign == '%'||
+ sign == '&' || sign == '|' || sign == '!' || sign == '='
+ )
+ {
+ GetNext();
+ Fourth();
+ QString name;
+ if( sign == '+' ) name= "+" ;
+ else if(sign=='-') name= "-" ;
+ else if(sign=='>' && secS=='\0') name= ">" ;
+ else if(sign=='<' && secS=='\0') name= "<" ;
+ else if(sign=='=' && secS=='=') name= "==" ;
+ else if(sign=='!' && secS=='=') name= "!=" ;
+ else if(sign=='>' && secS=='=') name= ">=" ;
+ else if(sign=='<' && secS=='=') name= "<=" ;
+ else if(sign=='&' && secS=='&') name= "AND" ;
+ else if(sign=='|' && secS=='|') name= "OR" ;
+ else if(sign=='%') name= "MOD" ;
+ CompiledBody.append(new QString(name)); // not sure if pushed in the back.
+ CompiledBodyType.append(new int(FUNCTION_TOKEN | 2<<8)); //2 argument functions
+ sign = chunk0();
+ }
+};
+
+void Expression::Fourth()
+{
+ QChar sign;
+ Fifth();
+ sign = chunk0();
+ while( sign == '*' || sign == '/' )
+ {
+ GetNext();
+ Fifth();
+ QString name;
+ if( sign == '*' ) name= "*" ;
+ else name= "/" ;
+ CompiledBody.append(new QString(name));
+ CompiledBodyType.append(new int(FUNCTION_TOKEN | 2<<8)); //2 arguments functions
+ sign = chunk0();
+ }
+};
+
+void Expression::Fifth()
+{
+ Sixth();
+ //if(chunk.Length==0) return;
+ if( chunk0() == '^' )
+ {
+ GetNext();
+ Fifth();
+ CompiledBody.append(new QString("POWER"));
+ CompiledBodyType.append(new int(FUNCTION_TOKEN | 2<<8)); // 2 argument functions
+ }
+};
+
+void Expression::Sixth()
+{
+ char sign;
+ sign = ' ';
+ if(SymbGroup== SYMBOL_TOKEN &&
+ chunk0() == '+' || chunk0() == '-' | chunk0() == '!')
+ {
+ sign = chunk0();
+ GetNext();
+ }
+ Seventh();
+ if( sign == '-' )
+ {
+ CompiledBody.append(new QString("CHGSGN")); // unary minus
+ CompiledBodyType.append(new int(FUNCTION_TOKEN | 1<<8)); //1 argument
+ }
+ if( sign == '!' )
+ {
+ CompiledBody.append(new QString("NOT")); // unary minus
+ CompiledBodyType.append(new int(FUNCTION_TOKEN | 1<<8)); //1 argument
+ }
+};
+
+
+void Expression::Seventh()
+{
+ if( chunk0() == '(' && SymbGroup==SYMBOL_TOKEN)
+ {
+ GetNext();
+ Third(); //parse the insides until we get a ')'
+ if (chunk0() != ')') ErrorFound = true;
+ GetNext();
+ }
+ else Eighth();
+};
+
+void Expression::Eighth()
+{
+ if ( SymbGroup== NUMBER_TOKEN )
+ {
+ CompiledBody.append(new QString(chunk));
+ CompiledBodyType.append(new int(NUMBER_TOKEN));
+ GetNext();
+ }
+ else if ( SymbGroup== VARIABLE_TOKEN )
+ {
+ CompiledBody.append(new QString(chunk));
+ CompiledBodyType.append(new int(VARIABLE_TOKEN));
+ GetNext();
+ }
+ else if (SymbGroup== STRING_TOKEN )
+ {
+ CompiledBody.append(new QString(chunk+QString("\"")));
+ CompiledBodyType.append(new int(STRING_TOKEN));
+ GetNext();
+ }
+ else Ninth();
+};
+
+void Expression::Ninth()
+{
+ if ( SymbGroup== FUNCTION_TOKEN )
+ {
+ QString TempFunk = chunk ;
+ GetNext();
+ if(chunk0() == '(' )
+ {
+ FuncDepth++;
+ ArgsOfFunc.resize(FuncDepth+1);
+ ArgsOfFunc[FuncDepth]=1;
+ //ArgsOfFunc=1;
+ GetNext();
+ Third();
+ while(chunk0()==',') //function arguments separator
+ {
+ //ArgsOfFunc++;
+ ArgsOfFunc[FuncDepth]++;
+ GetNext();
+ Third();
+ };
+ if (chunk0() != ')') ErrorFound = true;
+
+ CompiledBody.append(new QString(TempFunk));
+ if (TempFunk=="PI") ArgsOfFunc[FuncDepth]=0;
+ // couldn't find a better way to parse function PI() with 0 args. :)
+ CompiledBodyType.append(new int(FUNCTION_TOKEN | (ArgsOfFunc[FuncDepth]<<8) ));
+ //the mask &FF00 gives the arguments of the functions passed.
+ FuncDepth--;
+ ArgsOfFunc.resize(FuncDepth+1);
+ GetNext();
+ }
+ }
+ else
+ ErrorFound = true;
+};
+
+bool Expression::Parse()
+{
+ CompiledBody.clear();
+ ErrorFound = false;
+ n = 0;ArgsOfFunc.resize(0);FuncDepth=0;
+ InExpr=Body;
+ First();
+ return(!ErrorFound);
+};
+
+
diff --git a/noncore/apps/opie-sheet/sheet.h b/noncore/apps/opie-sheet/sheet.h
index f4e9d38..41f1b86 100644
--- a/noncore/apps/opie-sheet/sheet.h
+++ b/noncore/apps/opie-sheet/sheet.h
@@ -31,12 +31,58 @@ typedef struct typeCellData
Qt::AlignmentFlags alignment;
QColor fontColor;
QFont font;
QString data;
};
+
+#define NONE_TOKEN 0
+#define NUMBER_TOKEN 1
+#define VARIABLE_TOKEN 2
+#define FUNCTION_TOKEN 3
+#define SYMBOL_TOKEN 4
+#define STRING_TOKEN 5
+
+class Expression
+{
+public:
+ QString Body;
+ QList<QString> CompiledBody;
+ QList<int> CompiledBodyType;
+ QString SYMBOL;
+ QString MATHSYMBOL;
+ QArray<int> ArgsOfFunc;
+ int FuncDepth;
+ bool ErrorFound;
+ int n; // holds the current parser position
+ QString chunk; // the piece in the parser we are on
+ int SymbGroup; // the current type
+
+ QString InExpr;
+
+ QChar chunk0(void); // retunrs the first char of expression;
+ Expression(QString expr1);// constructor
+
+ bool isSymbol(QChar ch);
+ bool isMathSymbol(QChar ch);
+ void GetNext();
+ void First();
+ void Third();
+ void Fourth();
+ void Fifth();
+ void Sixth();
+ void Seventh();
+ void Eighth();
+ void Ninth();
+
+ bool Expression::Parse(); //parses the expression in RPN format;
+
+};
+
+
+
class Sheet: public QTable
{
Q_OBJECT
// Variables
bool clicksLocked;
@@ -47,27 +93,56 @@ class Sheet: public QTable
// QT objects
QList<typeCellData> sheetData, clipboardData;
QString pressedCell, releasedCell, sheetName;
QStringList listDataParser;
// Private functions
- int getOperatorPriority(char oper);
bool findRowColumn(const QString &variable, int *row, int *col, bool giveError=FALSE);
QString findCellName(int row, int col);
bool findRange(const QString &variable1, const QString &variable2, int *row1, int *col1, int *row2, int *col2);
- double calculateVariable(const QString &variable);
- double calculateFunction(const QString &function, const QString &parameters);
- QChar popCharStack(QStack<QChar> *stackChars);
- QString popStringStack(QStack<QString> *stackStrings);
+ QString calculateVariable(const QString &variable);
+ QString calculateFunction(const QString &function, const QString &parameters, int NumOfParams);
QString getParameter(const QString &parameters, int paramNo, bool giveError=FALSE, const QString funcName="");
QString dataParser(const QString &cell, const QString &data);
QString dataParserHelper(const QString &data);
typeCellData *createCellData(int row, int col);
typeCellData *findCellData(int row, int col);
- void pushCharStack(QStack<QChar> *stackChars, const QChar &character);
- void pushStringStack(QStack<QString> *stackStrings, const QString &string);
+
+
+//LOGICAL / INFO
+ double functionCountIf(const QString &param1, const QString &param2, const QString &param3);
+ double functionSumSQ(const QString &param1, const QString &param2); //sum of squares
+ QString functionIndex(const QString &param1, const QString &param2, int indx);
+//math functions computations
+ double BesselI0(double x);
+ double BesselI(int n, double x);
+ double BesselK0(double x);
+ double BesselI1(double x);
+ double BesselK1(double x);
+ double BesselK(int n, double x);
+ double BesselJ0(double x);
+ double BesselY0(double x);
+ double BesselJ1(double x);
+ double BesselY1(double x);
+ double BesselY(int n, double x);
+ double BesselJ(int n, double x);
+ double GammaLn(double xx);
+ double Factorial(double n);
+ double GammaP(double a, double x);
+ double GammaQ(double a,double x);
+ void GammaSeries(double *gamser, double a, double x, double *gln);
+ void GammaContinuedFraction(double *gammcf, double a, double x, double *gln);
+ double ErrorFunction(double x);
+ double ErrorFunctionComplementary(double x);
+ double Beta(double z, double w);
+ double BetaContinuedFraction(double a, double b, double x);
+ double BetaIncomplete(double a, double b, double x);
+ double functionVariance(const QString &param1, const QString &param2);
+ double functionVariancePopulation(const QString &param1, const QString &param2);
+ double functionSkew(const QString &param1, const QString &param2);
+ double functionKurt(const QString &param1, const QString &param2);
// Sheet/Qt parser functions
double functionSum(const QString &param1, const QString &param2);
double functionAvg(const QString &param1, const QString &param2);
double functionMax(const QString &param1, const QString &param2);
double functionMin(const QString &param1, const QString &param2);
@@ -76,20 +151,20 @@ class Sheet: public QTable
// Reimplemented QTable functions
void paintCell(QPainter *p, int row, int col, const QRect & cr, bool selected);
void viewportMousePressEvent(QMouseEvent *e);
void viewportMouseMoveEvent(QMouseEvent *e);
void viewportMouseReleaseEvent(QMouseEvent *e);
- private slots:
+ public slots:
void slotCellSelected(int row, int col);
void slotCellChanged(int row, int col);
public:
Sheet(int numRows, int numCols, QWidget *parent);
~Sheet();
-
+ void ReCalc(void);
void setData(const QString &data);
QString getData();
void setName(const QString &data);
QString getName();