summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-sheet/Excel.cpp1664
-rw-r--r--noncore/apps/opie-sheet/Excel.h205
-rw-r--r--noncore/apps/opie-sheet/cell-select.xpm44
-rw-r--r--noncore/apps/opie-sheet/excel16.xpm187
-rw-r--r--noncore/apps/opie-sheet/func-comma.xpm41
-rw-r--r--noncore/apps/opie-sheet/func-cross.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-divide.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-equal.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-func.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-minus.xpm40
-rw-r--r--noncore/apps/opie-sheet/func-paran-close.xpm41
-rw-r--r--noncore/apps/opie-sheet/func-paran-open.xpm41
-rw-r--r--noncore/apps/opie-sheet/func-plus.xpm40
-rw-r--r--noncore/apps/opie-sheet/mainwindow.cpp238
-rw-r--r--noncore/apps/opie-sheet/mainwindow.h14
-rw-r--r--noncore/apps/opie-sheet/opie-sheet.pro4
-rw-r--r--noncore/apps/opie-sheet/sheet.cpp2015
-rw-r--r--noncore/apps/opie-sheet/sheet.h93
18 files changed, 4434 insertions, 393 deletions
diff --git a/noncore/apps/opie-sheet/Excel.cpp b/noncore/apps/opie-sheet/Excel.cpp
new file mode 100644
index 0000000..225c3e1
--- a/dev/null
+++ b/noncore/apps/opie-sheet/Excel.cpp
@@ -0,0 +1,1664 @@
+
+
+#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",
-". ",
-". ... ",
-" ... .+++. ",
-" ..+@+++. ",
-" .+++@++@. ",
-" .+@+++@@++. ",
-" .@++@++@+++. ",
-" .@@++@@+++++. ",
-" .++@+@+++++++. ",
-" .++@++++++++. ",
-" .++@+++++++. ",
-" .++@+++++@. ",
-" .++@+++@+. ",
-" .++@@@+. ",
-" .++++. ",
-" .... "};
+"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",
-" ",
-" ",
-" ",
-" ... ",
-" ..... ",
-" ...... ",
-" ...... ",
-" ..... ",
-" .. ",
-" . ",
-" .. ",
-" .. ",
-" . ",
-" ",
-" ",
-" "};
+"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",
-" ",
-" ",
-" ",
-" .. ",
-" .. ",
-" .. ",
-" ... .. ... ",
-" .......... ",
-" ...... ",
-" .... ",
-" ...... ",
-" ... ... ",
-" . . ",
-" ",
-" ",
-" "};
+"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",
-" ",
-" ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" "};
+"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",
-" ",
-" ",
-" ",
-" ",
-" ",
-" .......... ",
-" .......... ",
-" ",
-" ",
-" .......... ",
-" .......... ",
-" ",
-" ",
-" ",
-" ",
-" "};
+"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",
-" ",
-" .. ",
-" .. ",
-" . ",
-" . ",
-" . ",
-" ..... ",
-" . ",
-" . . . ",
-" . . . ",
-" . . ",
-" . . . ",
-" . . . ",
-" . ",
-" . ",
-" "};
+"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",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ....... ",
-" ....... ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" ",
-" "};
+"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",
-" ",
-" . ",
-" .. ",
-" . ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" . ",
-" .. ",
-" . ",
-" ",
-" "};
+"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",
-" ",
-" . ",
-" .. ",
-" . ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" . ",
-" .. ",
-" . ",
-" ",
-" "};
+"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",
-" ",
-" ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" ............ ",
-" ............ ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" ",
-" "};
+"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
@@ -1,835 +1,1021 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
* Opie Sheet (formerly Sheet/Qt)
* by Serdar Ozler <sozler@sitebest.com>
*/
#include "mainwindow.h"
#include <qpe/filemanager.h>
#include <qpe/qcopenvelope_qws.h>
#include <qpe/resource.h>
#include <qmessagebox.h>
#include <qfile.h>
#include <qtranslator.h>
#include <qradiobutton.h>
#include "cellformat.h"
#include "numberdlg.h"
#include "textdlg.h"
#include "sortdlg.h"
#include "finddlg.h"
#include "func-plus.xpm"
#include "func-minus.xpm"
#include "func-cross.xpm"
#include "func-divide.xpm"
#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();
initFunctionsToolbar();
initStandardToolbar();
initSheet();
// set window title
setCaption(tr("Opie Sheet"));
// create sheets
selectorFileNew(DocLnk());
}
MainWindow::~MainWindow()
{
if (currentDoc) delete currentDoc;
}
void MainWindow::documentSave(DocLnk *lnkDoc)
{
FileManager fm;
QByteArray streamBuffer;
QDataStream stream(streamBuffer, IO_WriteOnly);
typeSheet *currentSheet=findSheet(sheet->getName());
if (!currentSheet)
{
QMessageBox::critical(this, tr("Error"), tr("Inconsistency error!"));
return;
}
sheet->copySheetData(&currentSheet->data);
stream.writeRawBytes("SQT100", 6);
stream << (Q_UINT32)listSheets.count();
for (typeSheet *tempSheet=listSheets.first(); tempSheet; tempSheet=listSheets.next())
{
stream << tempSheet->name << (Q_UINT32)tempSheet->data.count();
for (typeCellData *tempCell=tempSheet->data.first(); tempCell; tempCell=tempSheet->data.next())
stream << (Q_UINT32)tempCell->col << (Q_UINT32)tempCell->row << tempCell->borders.right << tempCell->borders.bottom << tempCell->background << (Q_UINT32)tempCell->alignment << tempCell->fontColor << tempCell->font << tempCell->data;
}
lnkDoc->setType("application/sheet-qt");
if (!fm.saveFile(*lnkDoc, streamBuffer))
{
QMessageBox::critical(this, tr("Error"), tr("File cannot be saved!"));
return;
}
documentModified=FALSE;
}
void MainWindow::documentOpen(const DocLnk &lnkDoc)
{
FileManager fm;
QByteArray streamBuffer;
if (!lnkDoc.isValid() || !fm.loadFile(lnkDoc, streamBuffer))
{
QMessageBox::critical(this, tr("Error"), tr("File cannot be opened!"));
documentModified=FALSE;
selectorFileNew(DocLnk());
return;
}
QDataStream stream(streamBuffer, IO_ReadOnly);
Q_UINT32 countSheet, countCell, i, j, row, col, alignment;
typeSheet *newSheet;
typeCellData *newCell;
char fileFormat[7];
stream.readRawBytes(fileFormat, 6);
fileFormat[6]=0;
if ((QString)fileFormat!="SQT100")
{
QMessageBox::critical(this, tr("Error"), tr("Invalid file format!"));
documentModified=FALSE;
selectorFileNew(DocLnk());
return;
}
stream >> countSheet;
for (i=0; i<countSheet; ++i)
{
newSheet=new typeSheet;
newSheet->data.setAutoDelete(TRUE);
stream >> newSheet->name >> countCell;
comboSheets->insertItem(newSheet->name);
for (j=0; j<countCell; ++j)
{
newCell=new typeCellData;
stream >> col >> row >> newCell->borders.right >> newCell->borders.bottom >> newCell->background >> alignment >> newCell->fontColor >> newCell->font >> newCell->data;
newCell->col=col;
newCell->row=row;
newCell->alignment=(Qt::AlignmentFlags)alignment;
newSheet->data.append(newCell);
}
listSheets.append(newSheet);
if (i==0)
{
sheet->setName(newSheet->name);
sheet->setSheetData(&newSheet->data);
}
}
}
int MainWindow::saveCurrentFile(bool ask)
{
if (ask)
{
int result=QMessageBox::information(this, tr("Save File"), tr("Do you want to save the current file?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel);
if (result!=QMessageBox::Yes) return result;
}
if (!currentDoc->isValid())
{
TextDialog dialogText(this);
if (dialogText.exec(tr("Save File"), tr("&File Name:"), tr("UnnamedFile"))!=QDialog::Accepted || dialogText.getValue().isEmpty()) return QMessageBox::Cancel;
currentDoc->setName(dialogText.getValue());
currentDoc->setFile(QString::null);
currentDoc->setLinkFile(QString::null);
}
documentSave(currentDoc);
return QMessageBox::Yes;
}
void MainWindow::selectorFileNew(const DocLnk &lnkDoc)
{
selectorHide();
if (documentModified && saveCurrentFile()==QMessageBox::Cancel) return;
if (currentDoc) delete currentDoc;
currentDoc = new DocLnk(lnkDoc);
editData->clear();
listSheets.clear();
comboSheets->clear();
typeSheet *newSheet=createNewSheet();
newSheet->data.setAutoDelete(TRUE);
sheet->setName(newSheet->name);
sheet->setSheetData(&newSheet->data);
for (int i=1; i<DEFAULT_NUM_SHEETS; ++i)
createNewSheet();
documentModified=FALSE;
}
void MainWindow::closeEvent(QCloseEvent *e)
{
if (documentModified && saveCurrentFile()==QMessageBox::Cancel) e->ignore();
else e->accept();
}
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;
}
void MainWindow::selectorShow()
{
sheet->hide();
setCentralWidget(fileSelector);
fileSelector->show();
fileSelector->reread();
}
void MainWindow::selectorHide()
{
fileSelector->hide();
setCentralWidget(sheet);
sheet->show();
}
void MainWindow::slotFileNew()
{
selectorFileNew(DocLnk());
}
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)
{
selectorFileOpen(DocLnk(applnk_filename));
}
void MainWindow::initActions()
{
fileNew=new QAction(tr("New File"), Resource::loadPixmap( "new" ), tr("&New"), 0, this);
connect(fileNew, SIGNAL(activated()), this, SLOT(slotFileNew()));
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()));
editAccept=new QAction(tr("Accept"),Resource::loadPixmap( "enter" ) , tr("&Accept"), 0, this);
connect(editAccept, SIGNAL(activated()), this, SLOT(slotEditAccept()));
editCancel=new QAction(tr("Cancel"), Resource::loadPixmap( "close" ), tr("&Cancel"), 0, this);
connect(editCancel, SIGNAL(activated()), this, SLOT(slotEditCancel()));
editCellSelect=new QAction(tr("Cell Selector"), QPixmap(cell_select_xpm), tr("Cell &Selector"), 0, this);
editCellSelect->setToggleAction(TRUE);
connect(editCellSelect, SIGNAL(toggled(bool)), this, SLOT(slotCellSelect(bool)));
editCut=new QAction(tr("Cut Cells"), tr("Cu&t"), 0, this);
editCopy=new QAction(tr("Copy Cells"), tr("&Copy"), 0, this);
editPaste=new QAction(tr("Paste Cells"), tr("&Paste"), 0, this);
connect(editPaste, SIGNAL(activated()), this, SLOT(slotEditPaste()));
editPasteContents=new QAction(tr("Paste Contents"), tr("Paste Cont&ents"), 0, this);
connect(editPasteContents, SIGNAL(activated()), this, SLOT(slotEditPasteContents()));
editClear=new QAction(tr("Clear Cells"), tr("C&lear"), 0, this);
insertCells=new QAction(tr("Insert Cells"), tr("C&ells"), 0, this);
connect(insertCells, SIGNAL(activated()), this, SLOT(slotInsertCells()));
insertRows=new QAction(tr("Insert Rows"), tr("&Rows"), 0, this);
connect(insertRows, SIGNAL(activated()), this, SLOT(slotInsertRows()));
insertCols=new QAction(tr("Insert Columns"), tr("&Columns"), 0, this);
connect(insertCols, SIGNAL(activated()), this, SLOT(slotInsertCols()));
insertSheets=new QAction(tr("Add Sheets"), tr("&Sheets"), 0, this);
connect(insertSheets, SIGNAL(activated()), this, SLOT(slotInsertSheets()));
formatCells=new QAction(tr("Cells"), tr("&Cells"), 0, this);
connect(formatCells, SIGNAL(activated()), this, SLOT(slotFormatCells()));
rowHeight=new QAction(tr("Row Height"), tr("H&eight"), 0, this);
connect(rowHeight, SIGNAL(activated()), this, SLOT(slotRowHeight()));
rowAdjust=new QAction(tr("Adjust Row"), tr("&Adjust"), 0, this);
connect(rowAdjust, SIGNAL(activated()), this, SLOT(slotRowAdjust()));
rowShow=new QAction(tr("Show Row"), tr("&Show"), 0, this);
connect(rowShow, SIGNAL(activated()), this, SLOT(slotRowShow()));
rowHide=new QAction(tr("Hide Row"), tr("&Hide"), 0, this);
connect(rowHide, SIGNAL(activated()), this, SLOT(slotRowHide()));
colWidth=new QAction(tr("Column Width"), tr("&Width"), 0, this);
connect(colWidth, SIGNAL(activated()), this, SLOT(slotColumnWidth()));
colAdjust=new QAction(tr("Adjust Column"), tr("&Adjust"), 0, this);
connect(colAdjust, SIGNAL(activated()), this, SLOT(slotColumnAdjust()));
colShow=new QAction(tr("Show Column"), tr("&Show"), 0, this);
connect(colShow, SIGNAL(activated()), this, SLOT(slotColumnShow()));
colHide=new QAction(tr("Hide Column"), tr("&Hide"), 0, this);
connect(colHide, SIGNAL(activated()), this, SLOT(slotColumnHide()));
sheetRename=new QAction(tr("Rename Sheet"), tr("&Rename"), 0, this);
connect(sheetRename, SIGNAL(activated()), this, SLOT(slotSheetRename()));
sheetRemove=new QAction(tr("Remove Sheet"), tr("R&emove"), 0, this);
connect(sheetRemove, SIGNAL(activated()), this, SLOT(slotSheetRemove()));
dataSort=new QAction(tr("Sort Data"), tr("&Sort"), 0, this);
connect(dataSort, SIGNAL(activated()), this, SLOT(slotDataSort()));
dataFindReplace=new QAction(tr("Find && Replace"), tr("&Find && Replace"), 0, this);
connect(dataFindReplace, SIGNAL(activated()), this, SLOT(slotDataFindReplace()));
funcEqual=new QAction(tr("Equal To"), QPixmap(func_equal_xpm), tr("&Equal To"), 0, this);
funcEqual->setToolTip("=");
connect(funcEqual, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
funcPlus=new QAction(tr("Addition"), QPixmap(func_plus_xpm), tr("&Addition"), 0, this);
funcPlus->setToolTip("+");
connect(funcPlus, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
funcMinus=new QAction(tr("Subtraction"), QPixmap(func_minus_xpm), tr("&Subtraction"), 0, this);
funcMinus->setToolTip("-");
connect(funcMinus, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
funcCross=new QAction(tr("Multiplication"), QPixmap(func_cross_xpm), tr("&Multiplication"), 0, this);
funcCross->setToolTip("*");
connect(funcCross, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
funcDivide=new QAction(tr("Division"), QPixmap(func_divide_xpm), tr("&Division"), 0, this);
funcDivide->setToolTip("/");
connect(funcDivide, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
funcParanOpen=new QAction(tr("Open ParanthesistempCellData->row+row1, tempCellData->col+col1"), QPixmap(func_paran_open_xpm), tr("&Open Paranthesis"), 0, this);
funcParanOpen->setToolTip("(");
connect(funcParanOpen, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
funcParanClose=new QAction(tr("Close Paranthesis"), QPixmap(func_paran_close_xpm), tr("&Close Paranthesis"), 0, this);
funcParanClose->setToolTip(")");
connect(funcParanClose, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
funcComma=new QAction(tr("Comma"), QPixmap(func_comma_xpm), tr("&Comma"), 0, this);
funcComma->setToolTip(",");
connect(funcComma, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
}
void MainWindow::initMenu()
{
menu=new QMenuBar(this);
menuFile=new QPopupMenu;
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);
menuEdit->insertSeparator();
editCut->addTo(menuEdit);
editCopy->addTo(menuEdit);
editPaste->addTo(menuEdit);
editPasteContents->addTo(menuEdit);
editClear->addTo(menuEdit);
menu->insertItem(tr("&Edit"), menuEdit);
menuInsert=new QPopupMenu;
menu->insertItem(tr("&Insert"), menuInsert);
menuFormat=new QPopupMenu;
formatCells->addTo(menuFormat);
menu->insertItem(tr("&Format"), menuFormat);
menuData=new QPopupMenu;
dataSort->addTo(menuData);
dataFindReplace->addTo(menuData);
menu->insertItem(tr("&Data"), menuData);
// menuHelp=new QPopupMenu;
// helpGeneral->addTo(menuHelp);
// helpAbout->addTo(menuHelp);
// menu->insertItem(tr("&Help"), menuHelp);
submenuRow=new QPopupMenu;
rowHeight->addTo(submenuRow);
rowAdjust->addTo(submenuRow);
rowShow->addTo(submenuRow);
rowHide->addTo(submenuRow);
menuFormat->insertItem(tr("&Row"), submenuRow);
submenuCol=new QPopupMenu;
colWidth->addTo(submenuCol);
colAdjust->addTo(submenuCol);
colShow->addTo(submenuCol);
colHide->addTo(submenuCol);
menuFormat->insertItem(tr("Colum&n"), submenuCol);
submenuSheet=new QPopupMenu;
sheetRename->addTo(submenuSheet);
sheetRemove->addTo(submenuSheet);
menuFormat->insertItem(tr("&Sheet"), submenuSheet);
submenuFunc=new QPopupMenu;
menuInsert->insertItem(tr("&Function"), submenuFunc);
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);
}
void MainWindow::initStandardToolbar()
{
toolbarStandard=new QToolBar(this);
toolbarStandard->setHorizontalStretchable(TRUE);
moveToolBar(toolbarStandard, Top);
fileNew->addTo(toolbarStandard);
fileOpen->addTo(toolbarStandard);
fileSave->addTo(toolbarStandard);
comboSheets=new QComboBox(toolbarStandard);
toolbarStandard->setStretchableWidget(comboSheets);
connect(comboSheets, SIGNAL(activated(const QString &)), this, SLOT(slotSheetChanged(const QString &)));
}
void MainWindow::initFunctionsToolbar()
{
toolbarFunctions=new QToolBar(this);
toolbarFunctions->setHorizontalStretchable(TRUE);
moveToolBar(toolbarFunctions, Bottom);
funcEqual->addTo(toolbarFunctions);
funcPlus->addTo(toolbarFunctions);
funcMinus->addTo(toolbarFunctions);
funcCross->addTo(toolbarFunctions);
funcDivide->addTo(toolbarFunctions);
funcParanOpen->addTo(toolbarFunctions);
funcParanClose->addTo(toolbarFunctions);
funcComma->addTo(toolbarFunctions);
toolFunction=new QToolButton(toolbarFunctions);
toolFunction->setPixmap(func_func_xpm);
toolFunction->setTextLabel(tr("Functions"));
toolFunction->setPopup(submenuFunc);
toolFunction->setPopupDelay(0);
}
void MainWindow::initEditToolbar()
{
toolbarEdit=new QToolBar(this);
toolbarEdit->setHorizontalStretchable(TRUE);
moveToolBar(toolbarEdit, Bottom);
editAccept->addTo(toolbarEdit);
editCancel->addTo(toolbarEdit);
editData=new QLineEdit(toolbarEdit);
toolbarEdit->setStretchableWidget(editData);
connect(editData, SIGNAL(returnPressed()), this, SLOT(slotEditAccept()));
editCellSelect->addTo(toolbarEdit);
}
void MainWindow::slotHelpAbout()
{
QDialog dialogAbout(this, 0, TRUE);
dialogAbout.resize(width()-40, height()-80);
dialogAbout.setCaption(tr("About Opie Sheet"));
QLabel label(tr("Opie Sheet\nSpreadsheet Software for Opie\nQWDC Beta Winner (as Sheet/Qt)\n\nDeveloped by: Serdar Ozler\nRelease 1.0.2\nRelease Date: October 08, 2002\n\nThis product is licensed under GPL. It is freely distributable. If you want to get the latest version and also the source code, please visit the web site.\n\nhttp://qtopia.sitebest.com"), &dialogAbout);
label.setGeometry(dialogAbout.rect());
label.setAlignment(Qt::AlignCenter | Qt::WordBreak);
dialogAbout.exec();
}
void MainWindow::initSheet()
{
sheet=new Sheet(DEFAULT_NUM_ROWS, DEFAULT_NUM_COLS, this);
setCentralWidget(sheet);
connect(sheet, SIGNAL(currentDataChanged(const QString &)), editData, SLOT(setText(const QString &)));
connect(sheet, SIGNAL(cellClicked(const QString &)), this, SLOT(slotCellClicked(const QString &)));
connect(sheet, SIGNAL(sheetModified()), this, SLOT(slotDocModified()));
connect(editCut, SIGNAL(activated()), sheet, SLOT(editCut()));
connect(editCopy, SIGNAL(activated()), sheet, SLOT(editCopy()));
connect(editClear, SIGNAL(activated()), sheet, SLOT(editClear()));
}
void MainWindow::slotEditAccept()
{
sheet->setData(editData->text());
}
void MainWindow::slotEditCancel()
{
editData->setText(sheet->getData());
}
void MainWindow::slotCellSelect(bool lock)
{
sheet->lockClicks(lock);
}
void MainWindow::addToData(const QString &data)
{
editData->setText(editData->text().insert(editData->cursorPosition(), data));
}
void MainWindow::slotFuncOutput()
{
if (sender()->isA("QAction"))
addToData(((QAction *)sender())->toolTip());
}
void MainWindow::slotInsertRows()
{
NumberDialog dialogNumber(this);
if (dialogNumber.exec(tr("Insert Rows"), tr("&Number of rows:"))==QDialog::Accepted)
sheet->insertRows(dialogNumber.getValue());
}
void MainWindow::slotInsertCols()
{
NumberDialog dialogNumber(this);
if (dialogNumber.exec(tr("Insert Columns"), tr("&Number of columns:"))==QDialog::Accepted)
sheet->insertColumns(dialogNumber.getValue());
}
void MainWindow::slotInsertSheets()
{
NumberDialog dialogNumber(this);
if (dialogNumber.exec(tr("Add Sheets"), tr("&Number of sheets:"))==QDialog::Accepted)
for (int i=dialogNumber.getValue(); i>0; --i) createNewSheet();
}
void MainWindow::slotCellClicked(const QString &cell)
{
editCellSelect->setOn(FALSE);
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;
newSheet->name=tr("Sheet")+QString::number(currentNo);
newSheet->data.setAutoDelete(TRUE);
comboSheets->insertItem(newSheet->name);
listSheets.append(newSheet);
return newSheet;
}
typeSheet *MainWindow::findSheet(const QString &name)
{
for (typeSheet *tempSheet=listSheets.first(); tempSheet; tempSheet=listSheets.next())
if (tempSheet->name==name)
return tempSheet;
return NULL;
}
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);
connect(action, SIGNAL(activated()), this, SLOT(slotFuncOutput()));
action->addTo(w);
}
void MainWindow::slotFormatCells()
{
CellFormat dialogCellFormat(this);
dialogCellFormat.showMaximized();
dialogCellFormat.exec(sheet);
}
void MainWindow::slotEditPaste()
{
sheet->editPaste();
}
void MainWindow::slotEditPasteContents()
{
sheet->editPaste(TRUE);
}
void MainWindow::slotRowHeight()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
NumberDialog dialogNumber(this);
if (dialogNumber.exec(tr("Row Height"), tr("&Height of each row:"), sheet->rowHeight(row1))==QDialog::Accepted)
{
int newHeight=dialogNumber.getValue(), row;
for (row=row1; row<=row2; ++row)
sheet->setRowHeight(row, newHeight);
}
}
void MainWindow::slotRowAdjust()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
for (int row=row1; row<=row2; ++row)
sheet->adjustRow(row);
}
void MainWindow::slotRowShow()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
for (int row=row1; row<=row2; ++row)
sheet->showRow(row);
}
void MainWindow::slotRowHide()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
for (int row=row1; row<=row2; ++row)
sheet->hideRow(row);
}
void MainWindow::slotColumnWidth()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
NumberDialog dialogNumber(this);
if (dialogNumber.exec(tr("Column Width"), tr("&Width of each column:"), sheet->columnWidth(col1))==QDialog::Accepted)
{
int newWidth=dialogNumber.getValue(), col;
for (col=col1; col<=col2; ++col)
sheet->setColumnWidth(col, newWidth);
}
}
void MainWindow::slotColumnAdjust()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
for (int col=col1; col<=col2; ++col)
sheet->adjustColumn(col);
}
void MainWindow::slotColumnShow()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
for (int col=col1; col<=col2; ++col)
sheet->showColumn(col);
}
void MainWindow::slotColumnHide()
{
int row1, row2, col1, col2;
sheet->getSelection(&row1, &col1, &row2, &col2);
for (int col=col1; col<=col2; ++col)
sheet->hideColumn(col);
}
void MainWindow::slotFileSaveAs()
{
TextDialog dialogText(this);
if (dialogText.exec(tr("Save File As"), tr("&File Name:"), currentDoc->name())!=QDialog::Accepted || dialogText.getValue().isEmpty()) return;
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();
typeSheet *tempSheet=findSheet(newName);
if (tempSheet)
{
QMessageBox::critical(this, tr("Error"), tr("There is already a sheet named '"+newName+'\''));
return;
}
tempSheet=findSheet(sheet->getName());
for (int i=0; i<comboSheets->count(); ++i)
if (comboSheets->text(i)==tempSheet->name)
{
comboSheets->changeItem(newName, i);
break;
}
tempSheet->name=newName;
sheet->setName(newName);
}
void MainWindow::slotSheetRemove()
{
if (comboSheets->count()<2)
{
QMessageBox::warning(this, tr("Error"), tr("There is only one sheet!"));
return;
}
if (QMessageBox::information(this, tr("Remove Sheet"), tr("Are you sure?"), QMessageBox::Yes, QMessageBox::No)==QMessageBox::Yes)
{
typeSheet *tempSheet=findSheet(sheet->getName());
for (int i=0; i<comboSheets->count(); ++i)
if (comboSheets->text(i)==tempSheet->name)
{
comboSheets->removeItem(i);
break;
}
comboSheets->setCurrentItem(0);
slotSheetChanged(comboSheets->currentText());
listSheets.remove(tempSheet);
}
}
void MainWindow::slotDataSort()
{
SortDialog dialogSort(this);
dialogSort.showMaximized();
dialogSort.exec(sheet);
}
void MainWindow::slotDocModified()
{
documentModified=TRUE;
}
void MainWindow::slotInsertCells()
{
QDialog dialogInsert(this, 0, TRUE);
dialogInsert.resize(180, 130);
dialogInsert.setCaption(tr("Insert Cells"));
QVButtonGroup *group=new QVButtonGroup(tr("&Type"), &dialogInsert);
group->setGeometry(10, 10, 160, 110);
QRadioButton *radio=new QRadioButton(tr("Shift cells &down"), group);
radio=new QRadioButton(tr("Shift cells &right"), group);
radio=new QRadioButton(tr("Entire ro&w"), group);
radio=new QRadioButton(tr("Entire &column"), group);
group->setButton(0);
if (dialogInsert.exec()==QDialog::Accepted)
switch (group->id(group->selected()))
{
case 0: sheet->insertRows(1, FALSE); break;
case 1: sheet->insertColumns(1, FALSE); break;
case 2: sheet->insertRows(1, TRUE); break;
case 3: sheet->insertColumns(1, TRUE); break;
}
}
void MainWindow::slotDataFindReplace()
{
FindDialog dialogFind(this);
dialogFind.showMaximized();
dialogFind.exec(sheet);
}
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
@@ -1,133 +1,141 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
* Opie Sheet (formerly Sheet/Qt)
* by Serdar Ozler <sozler@sitebest.com>
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <qpe/applnk.h>
#include <qpe/fileselector.h>
#include <qmenubar.h>
#include <qtoolbar.h>
#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;
};
class MainWindow: public QMainWindow
{
Q_OBJECT
// 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;
QComboBox *comboSheets;
QToolButton *toolFunction;
QList<typeSheet> listSheets;
QString helpFile;
// Other objects
Sheet *sheet;
// Variables
bool documentModified;
// Private functions
void initMenu();
void initActions();
void initFunctionsToolbar();
void initEditToolbar();
void initStandardToolbar();
void initSheet();
void addToData(const QString &data);
int saveCurrentFile(bool ask=TRUE);
void documentOpen(const DocLnk &lnkDoc);
void documentSave(DocLnk *lnkDoc);
void closeEvent(QCloseEvent *e);
void addFlyAction(const QString &text, const QString &menuText, const QString &tip, QWidget *w);
typeSheet *createNewSheet();
typeSheet *findSheet(const QString &name);
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();
void slotInsertCells();
void slotInsertRows();
void slotInsertCols();
void slotInsertSheets();
void slotDataSort();
void slotDataFindReplace();
void slotRowHeight();
void slotRowAdjust();
void slotRowShow();
void slotRowHide();
void slotColumnWidth();
void slotColumnAdjust();
void slotColumnShow();
void slotColumnHide();
void slotSheetRename();
void slotSheetRemove();
void slotFuncOutput();
void slotCellSelect(bool lock);
void slotCellClicked(const QString &cell);
void slotSheetChanged(const QString &name);
void slotDocModified();
void selectorShow();
void selectorHide();
void selectorFileNew(const DocLnk &lnkDoc);
void selectorFileOpen(const DocLnk &lnkDoc);
public:
static QString appName() { return QString::fromLatin1("sheetqt"); }
MainWindow(QWidget *p, const char*, WFlags);
~MainWindow();
void setHelpFile(const QString &help_filename) { helpFile=help_filename; }
public slots:
void setDocument(const QString &applnk_filename);
};
#endif
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
@@ -1,872 +1,2565 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
* Opie Sheet (formerly Sheet/Qt)
* by Serdar Ozler <sozler@sitebest.com>
*/
#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)
{
defaultBorders.right=defaultBorders.bottom=QPen(Qt::gray, 1, Qt::SolidLine);
defaultCellData.data="";
defaultCellData.background=QBrush(Qt::white, Qt::SolidPattern);
defaultCellData.alignment=(Qt::AlignmentFlags)(Qt::AlignLeft | Qt::AlignTop);
defaultCellData.fontColor=Qt::black;
defaultCellData.font=font();
defaultCellData.borders=defaultBorders;
clicksLocked=FALSE;
selectionNo=-1;
setSelectionMode(QTable::Single);
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;
typeCellData *cellData=new typeCellData;
cellData->row=row;
cellData->col=col;
cellData->data=defaultCellData.data;
cellData->borders=defaultCellData.borders;
cellData->alignment=defaultCellData.alignment;
cellData->font=defaultCellData.font;
cellData->fontColor=defaultCellData.fontColor;
cellData->background=defaultCellData.background;
sheetData.append(cellData);
return cellData;
}
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)
{
QString tempData(cellData1->data);
cellData1->data=cellData2->data;
cellData2->data=tempData;
setText(cellData1->row, cellData1->col, dataParser(findCellName(cellData1->row, cellData1->col), cellData1->data));
setText(cellData2->row, cellData2->col, dataParser(findCellName(cellData2->row, cellData2->col), cellData2->data));
emit sheetModified();
}
}
QString Sheet::getParameter(const QString &parameters, int paramNo, bool giveError, const QString funcName)
{
QString params(parameters);
int position;
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;
}
if (*col1>*col2)
{
col=*col1;
*col1=*col2;
*col2=col;
}
return TRUE;
}
bool Sheet::findRowColumn(const QString &variable, int *row, int *col, bool giveError)
{
int position=variable.find(QRegExp("\\d"));
if (position<1)
{
if (giveError) QMessageBox::critical(this, tr("Error"), tr("Invalid variable: '"+variable+'\''));
return FALSE;
}
*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::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 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)
+ {
+ tempResult=text(row, col).toDouble(&ok);
+ if (ok)
+ {
+ 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;
+};
-double Sheet::functionMin(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 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)
+ {
+ tempResult=text(row, col).toDouble(&ok);
+ if (ok)
+ {
+ 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;
+}
+
+
+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;
- if (!findRange(param1, param2, &row1, &col1, &row2, &col2)) return 0;
-
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 && (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));
+ {
+ 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")
- 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)));
+ {
+ val1=fabs(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
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)
+ val1=acos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ACOSH")
{
- case '+':
- case '-':
- return 1;
-
- case '*':
- case '/':
- return 2;
- }
- return 0;
-}
-
-void Sheet::pushCharStack(QStack<QChar> *stackChars, const QChar &character)
+ 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")
{
- QChar *temp=new QChar(character);
- stackChars->push(temp);
-}
-
-void Sheet::pushStringStack(QStack<QString> *stackStrings, const QString &string)
+ val1=asin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ASINH")
{
- QString *temp=new QString(string);
- stackStrings->push(temp);
-}
-
-QChar Sheet::popCharStack(QStack<QChar> *stackChars)
+ val1=asinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ATAN")
{
- if (stackChars->isEmpty())
+ val1=atan(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="ATAN2")
{
- QMessageBox::critical(this, tr("Error"), tr("Syntax error!"));
- return '0';
- }
-
- QChar *temp=stackChars->pop();
- QChar temp2(*temp);
- delete temp;
- return temp2;
-}
-
-QString Sheet::popStringStack(QStack<QString> *stackStrings)
+ 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")
{
- if (stackStrings->isEmpty())
+ val1=cos(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="COSH")
{
- 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)
+ val1=cosh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="DEGREES")
{
- QStack<QString> stackElements;
- QStack<QChar> stackOperators;
- QString tempElement(""), temp2Element, firstElement, secondElement;
- int paranCount;
-
- for (unsigned int i=0; i<data.length(); ++i)
+ val1=calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok)*180.0/M_PI;
+ return QString::number(val1);
+ };
+ if (function=="EXP")
{
- if (data[i]=='+' || data[i]=='-' || data[i]=='*' || data[i]=='/')
+ 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")
{
- pushStringStack(&stackElements, tempElement);
- tempElement="";
- if (!stackOperators.isEmpty() && getOperatorPriority(*stackOperators.top())>getOperatorPriority(data[i]))
+ // 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")
{
- secondElement=popStringStack(&stackElements);
- firstElement=popStringStack(&stackElements);
- pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement)));
- }
- pushCharStack(&stackOperators, data[i]);
- }
- else
- if (data[i]==',')
+ val1=sin(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="SINH")
{
- if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement);
- while (!stackOperators.isEmpty())
+ val1=sinh(calculateVariable(getParameter(parameters, 0, TRUE, function)).toDouble(&ok));
+ return QString::number(val1);
+ };
+ if (function=="TAN")
{
- secondElement=popStringStack(&stackElements);
- firstElement=popStringStack(&stackElements);
- pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement)));
- }
- tempElement="";
- }
- else
- if (data[i]=='(')
+ 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")
{
- paranCount=1;
- temp2Element="";
- for (++i; paranCount>0; ++i)
+ //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")
{
- 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;
- }
+ //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
- tempElement+=data[i];
- }
- if (!tempElement.isEmpty()) pushStringStack(&stackElements, tempElement);
- while (!stackOperators.isEmpty())
+ 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]]
+ */
+
+
+
+ return 0;
+};
+
+
+
+
+QString Sheet::dataParserHelper(const QString &data)
{
- secondElement=popStringStack(&stackElements);
- firstElement=popStringStack(&stackElements);
- pushStringStack(&stackElements, QString::number(calculateFunction(popCharStack(&stackOperators), firstElement+","+secondElement)));
- }
+ 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);
+};
+
- 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();
}
QString Sheet::getData()
{
typeCellData *cellData=findCellData(currentRow(), currentColumn());
if (cellData)
return cellData->data;
return "";
}
void Sheet::lockClicks(bool lock)
{
clicksLocked=lock;
}
void Sheet::paintCell(QPainter *p, int row, int col, const QRect & cr, bool selected)
{
if (selected && row==currentRow() && col==currentColumn()) selected=FALSE;
int sheetDataCurrent=sheetData.at();
typeCellData *cellData=findCellData(row, col);
if (sheetDataCurrent>=0) sheetData.at(sheetDataCurrent);
if (!cellData) cellData=&defaultCellData;
if (selected)
p->fillRect(0, 0, cr.width(), cr.height(), colorGroup().highlight());
else
{
p->fillRect(0, 0, cr.width(), cr.height(), colorGroup().base());
p->fillRect(0, 0, cr.width(), cr.height(), cellData->background);
}
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);
p->drawLine(rx, 0, rx, ry);
p->setPen(cellData->borders.bottom);
p->drawLine(0, ry, rx, ry);
p->setPen(pen);
}
void Sheet::viewportMousePressEvent(QMouseEvent *e)
{
QMouseEvent ce(e->type(), viewportToContents(e->pos()), e->globalPos(), e->button(), e->state());
if (clicksLocked)
{
if (selectionNo<0)
{
clearSelection();
QTableSelection newSelection;
newSelection.init(rowAt(ce.pos().y()), columnAt(ce.pos().x()));
newSelection.expandTo(newSelection.anchorRow(), newSelection.anchorCol());
selectionNo=addSelection(newSelection);
}
}
else
QTable::contentsMousePressEvent(&ce);
}
void Sheet::viewportMouseMoveEvent(QMouseEvent *e)
{
QMouseEvent ce(e->type(), viewportToContents(e->pos()), e->globalPos(), e->button(), e->state());
if (clicksLocked)
{
if (selectionNo>=0)
{
QTableSelection oldSelection(selection(selectionNo));
oldSelection.expandTo(rowAt(ce.pos().y()), columnAt(ce.pos().x()));
if (!(oldSelection==selection(selectionNo)))
{
removeSelection(selectionNo);
selectionNo=addSelection(oldSelection);
}
}
}
else
QTable::contentsMouseMoveEvent(&ce);
}
void Sheet::viewportMouseReleaseEvent(QMouseEvent *e)
{
QMouseEvent ce(e->type(), viewportToContents(e->pos()), e->globalPos(), e->button(), e->state());
if (clicksLocked && selectionNo>=0)
{
QTableSelection oldSelection(selection(selectionNo));
oldSelection.expandTo(rowAt(ce.pos().y()), columnAt(ce.pos().x()));
removeSelection(selectionNo);
selectionNo=-1;
if (oldSelection.topRow()==oldSelection.bottomRow() && oldSelection.leftCol()==oldSelection.rightCol())
emit cellClicked(findCellName(oldSelection.topRow(), oldSelection.leftCol()));
else
emit cellClicked(findCellName(oldSelection.topRow(), oldSelection.leftCol())+','+findCellName(oldSelection.bottomRow(), oldSelection.rightCol()));
}
else
QTable::contentsMouseReleaseEvent(&ce);
}
QString Sheet::findCellName(int row, int col)
{
return (getHeaderString(col+1)+QString::number(row+1));
}
void Sheet::copySheetData(QList<typeCellData> *destSheetData)
{
typeCellData *tempCellData, *newCellData;
destSheetData->clear();
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
{
newCellData=new typeCellData;
*newCellData=*tempCellData;
destSheetData->append(newCellData);
}
}
void Sheet::setSheetData(QList<typeCellData> *srcSheetData)
{
typeCellData *tempCellData, *newCellData;
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
{
clearCell(tempCellData->row, tempCellData->col);
updateCell(tempCellData->row, tempCellData->col);
}
sheetData.clear();
for (tempCellData=srcSheetData->first(); tempCellData; tempCellData=srcSheetData->next())
{
newCellData=new typeCellData;
*newCellData=*tempCellData;
sheetData.append(newCellData);
setText(newCellData->row, newCellData->col, dataParser(findCellName(newCellData->row, newCellData->col), newCellData->data));
}
emit sheetModified();
}
void Sheet::setName(const QString &name)
{
sheetName=name;
emit sheetModified();
}
QString Sheet::getName()
{
return sheetName;
}
void Sheet::setBrush(int row, int col, const QBrush &brush)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=createCellData(row, col);
if (cellData)
{
cellData->background=brush;
emit sheetModified();
}
}
QBrush Sheet::getBrush(int row, int col)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=&defaultCellData;
return cellData->background;
}
void Sheet::setTextAlign(int row, int col, Qt::AlignmentFlags flags)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=createCellData(row, col);
if (cellData)
{
cellData->alignment=flags;
emit sheetModified();
}
}
Qt::AlignmentFlags Sheet::getAlignment(int row, int col)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=&defaultCellData;
return cellData->alignment;
}
void Sheet::setTextFont(int row, int col, const QFont &font, const QColor &color)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=createCellData(row, col);
if (cellData)
{
cellData->font=font;
cellData->fontColor=color;
emit sheetModified();
}
}
QFont Sheet::getFont(int row, int col)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=&defaultCellData;
return cellData->font;
}
QColor Sheet::getFontColor(int row, int col)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=&defaultCellData;
return cellData->fontColor;
}
void Sheet::setPen(int row, int col, int vertical, const QPen &pen)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=createCellData(row, col);
if (cellData)
{
if (vertical)
cellData->borders.right=pen;
else
cellData->borders.bottom=pen;
emit sheetModified();
}
}
QPen Sheet::getPen(int row, int col, int vertical)
{
typeCellData *cellData=findCellData(row, col);
if (!cellData) cellData=&defaultCellData;
return (vertical ? cellData->borders.right : cellData->borders.bottom);
}
void Sheet::getSelection(int *row1, int *col1, int *row2, int *col2)
{
int selectionNo=currentSelection();
if (selectionNo>=0)
{
QTableSelection selection(selection(selectionNo));
*row1=selection.topRow();
*row2=selection.bottomRow();
*col1=selection.leftCol();
*col2=selection.rightCol();
}
else
{
*row1=*row2=currentRow();
*col1=*col2=currentColumn();
}
}
void Sheet::editClear()
{
int row1, row2, col1, col2;
getSelection(&row1, &col1, &row2, &col2);
int row, col;
for (row=row1; row<=row2; ++row)
for (col=col1; col<=col2; ++col)
{
setText(row, col, "");
slotCellChanged(row, col);
}
}
void Sheet::editCopy()
{
clipboardData.clear();
int row1, row2, col1, col2;
getSelection(&row1, &col1, &row2, &col2);
typeCellData *cellData, *newCellData;
int row, col;
for (row=row1; row<=row2; ++row)
for (col=col1; col<=col2; ++col)
{
cellData=findCellData(row, col);
if (cellData)
{
newCellData=new typeCellData;
*newCellData=*cellData;
newCellData->row-=row1;
newCellData->col-=col1;
clipboardData.append(newCellData);
}
}
}
void Sheet::editCut()
{
editCopy();
editClear();
}
void Sheet::editPaste(bool onlyContents)
{
int row1=currentRow(), col1=currentColumn();
typeCellData *cellData, *tempCellData;
for (tempCellData=clipboardData.first(); tempCellData; tempCellData=clipboardData.next())
{
cellData=findCellData(tempCellData->row+row1, tempCellData->col+col1);
if (!cellData) cellData=createCellData(tempCellData->row+row1, tempCellData->col+col1);
if (cellData)
{
if (onlyContents)
cellData->data=tempCellData->data;
else
{
*cellData=*tempCellData;
cellData->row+=row1;
cellData->col+=col1;
}
setText(cellData->row, cellData->col, dataParser(findCellName(cellData->row, cellData->col), cellData->data));
emit sheetModified();
}
}
}
void Sheet::insertRows(int no, bool allColumns)
{
setNumRows(numRows()+no);
typeCellData *tempCellData;
int row=currentRow(), col=currentColumn();
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
if (tempCellData->row>=row && (allColumns || tempCellData->col==col))
{
clearCell(tempCellData->row, tempCellData->col);
tempCellData->row+=no;
}
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
if (tempCellData->row>=row && (allColumns || tempCellData->col==col))
{
updateCell(tempCellData->row-no, tempCellData->col);
setText(tempCellData->row, tempCellData->col, dataParser(findCellName(tempCellData->row, tempCellData->col), tempCellData->data));
}
emit sheetModified();
}
void Sheet::insertColumns(int no, bool allRows)
{
int noCols=numCols();
int newCols=noCols+no;
setNumCols(newCols);
for (int i=noCols; i<newCols; ++i)
horizontalHeader()->setLabel(i, getHeaderString(i+1), DEFAULT_COL_WIDTH);
typeCellData *tempCellData;
int col=currentColumn(), row=currentRow();
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
if (tempCellData->col>=col && (allRows || tempCellData->row==row))
{
clearCell(tempCellData->row, tempCellData->col);
tempCellData->col+=no;
}
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
if (tempCellData->col>=col && (allRows || tempCellData->row==row))
{
updateCell(tempCellData->row, tempCellData->col-no);
setText(tempCellData->row, tempCellData->col, dataParser(findCellName(tempCellData->row, tempCellData->col), tempCellData->data));
}
emit sheetModified();
}
void Sheet::dataFindReplace(const QString &findStr, const QString &replaceStr, bool matchCase, bool allCells, bool entireCell, bool replace, bool replaceAll)
{
typeCellData *tempCellData;
int row1, col1, row2, col2;
getSelection(&row1, &col1, &row2, &col2);
bool found=FALSE;
for (tempCellData=sheetData.first(); tempCellData; tempCellData=sheetData.next())
if (allCells || (tempCellData->row>=row1 && tempCellData->row<=row2 && tempCellData->col>=col1 && tempCellData->col<=col2))
{
QTableItem *cellItem=item(tempCellData->row, tempCellData->col);
if (cellItem && (entireCell ? (matchCase ? cellItem->text()==findStr : cellItem->text().upper()==findStr.upper()) : cellItem->text().find(findStr, 0, matchCase)>=0))
{
if (!found)
{
found=TRUE;
clearSelection();
}
setCurrentCell(tempCellData->row, tempCellData->col);
if (replace)
{
tempCellData->data=cellItem->text().replace(QRegExp(findStr, matchCase), replaceStr);
setText(tempCellData->row, tempCellData->col, dataParser(findCellName(tempCellData->row, tempCellData->col), tempCellData->data));
}
if (!replace || !replaceAll) break;
}
}
if (found)
{
if (replace)
slotCellChanged(currentRow(), currentColumn());
}
else
QMessageBox::warning(this, tr("Error"), tr("Search key not found!"));
}
//
// Static functions
//
QString Sheet::getHeaderString(int section)
{
if (section<1) return "";
return getHeaderString((section-1)/26)+QChar('A'+(section-1)%26);
}
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
@@ -1,136 +1,211 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
* Opie Sheet (formerly Sheet/Qt)
* by Serdar Ozler <sozler@sitebest.com>
*/
#ifndef SHEET_H
#define SHEET_H
#include <qtable.h>
#include <qstack.h>
typedef struct typeCellBorders
{
QPen right, bottom;
};
typedef struct typeCellData
{
int col, row;
typeCellBorders borders;
QBrush background;
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;
int selectionNo;
typeCellBorders defaultBorders;
typeCellData defaultCellData;
// 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);
double functionCount(const QString &param1, const QString &param2);
// 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();
void setPen(int row, int col, int vertical, const QPen &pen);
QPen getPen(int row, int col, int vertical);
void setBrush(int row, int col, const QBrush &brush);
QBrush getBrush(int row, int col);
void setTextAlign(int row, int col, Qt::AlignmentFlags flags);
Qt::AlignmentFlags getAlignment(int row, int col);
void setTextFont(int row, int col, const QFont &font, const QColor &color);
QFont getFont(int row, int col);
QColor getFontColor(int row, int col);
void lockClicks(bool lock=TRUE);
void copySheetData(QList<typeCellData> *destSheetData);
void setSheetData(QList<typeCellData> *srcSheetData);
void getSelection(int *row1, int *col1, int *row2, int *col2);
void insertRows(int no=1, bool allColumns=TRUE);
void insertColumns(int no=1, bool allRows=TRUE);
void dataFindReplace(const QString &find, const QString &replace, bool matchCase=TRUE, bool allCells=TRUE, bool entireCell=FALSE, bool replace=FALSE, bool replaceAll=FALSE);
// Static functions
static int getHeaderColumn(const QString &section);
static QString getHeaderString(int section);
public slots:
void editCut();
void editCopy();
void editPaste(bool onlyContents=FALSE);
void editClear();
void swapCells(int row1, int col1, int row2, int col2);
signals:
void currentDataChanged(const QString &data);
void cellClicked(const QString &cell);
void sheetModified();
};
#endif