author | eilers <eilers> | 2004-11-06 19:41:22 (UTC) |
---|---|---|
committer | eilers <eilers> | 2004-11-06 19:41:22 (UTC) |
commit | 82023570a9b5880629a5f7ce477479ffcb7af930 (patch) (side-by-side diff) | |
tree | df2e790812950d2a2cc32af3e39cc8d293133259 | |
parent | 90d458c63d274a66ca427710b88e2f090a0ab11b (diff) | |
download | opie-82023570a9b5880629a5f7ce477479ffcb7af930.zip opie-82023570a9b5880629a5f7ce477479ffcb7af930.tar.gz opie-82023570a9b5880629a5f7ce477479ffcb7af930.tar.bz2 |
Avoid crash if app was unable to open the file
-rw-r--r-- | noncore/apps/opie-sheet/Excel.cpp | 3 | ||||
-rw-r--r-- | noncore/apps/opie-sheet/mainwindow.cpp | 7 |
2 files changed, 7 insertions, 3 deletions
diff --git a/noncore/apps/opie-sheet/Excel.cpp b/noncore/apps/opie-sheet/Excel.cpp index 57aef20..338bc30 100644 --- a/noncore/apps/opie-sheet/Excel.cpp +++ b/noncore/apps/opie-sheet/Excel.cpp @@ -1,1708 +1,1709 @@ /* =. This file is part of the Opie Project .=l. Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org> .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Excel.h" /* STD */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <sys/types.h> #include <strings.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); + if ( !OpenFile( file ) ) + return false; 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/mainwindow.cpp b/noncore/apps/opie-sheet/mainwindow.cpp index 7394623..3095142 100644 --- a/noncore/apps/opie-sheet/mainwindow.cpp +++ b/noncore/apps/opie-sheet/mainwindow.cpp @@ -1,1028 +1,1031 @@ /* =. This file is part of the Opie Project .=l. Copyright (C) 2004 Opie Developer Team <opie-devel@handhelds.org> .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * Opie Sheet (formerly Sheet/Qt) * by Serdar Ozler <sozler@sitebest.com> */ #include "mainwindow.h" /* OPIE */ #include <qpe/resource.h> #include <qpe/qpeapplication.h> /* QT */ #include <qmessagebox.h> #include <qradiobutton.h> /* STD */ #include "cellformat.h" #include "numberdlg.h" #include "textdlg.h" #include "sortdlg.h" #include "finddlg.h" #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/opie-sheet", 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(¤tSheet->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/opie-sheet"); 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 ); 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"),Resource::loadPixmap( "opie-sheet/excel16" ),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"), Resource::loadPixmap( "opie-sheet/cell-select" ), 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"), Resource::loadPixmap( "opie-sheet/func-equal" ), tr("&Equal To"), 0, this); funcEqual->setToolTip("="); connect(funcEqual, SIGNAL(activated()), this, SLOT(slotFuncOutput())); funcPlus=new QAction(tr("Addition"), Resource::loadPixmap( "opie-sheet/func-plus" ), tr("&Addition"), 0, this); funcPlus->setToolTip("+"); connect(funcPlus, SIGNAL(activated()), this, SLOT(slotFuncOutput())); funcMinus=new QAction(tr("Subtraction"), Resource::loadPixmap( "opie-sheet/func-minus" ), tr("&Subtraction"), 0, this); funcMinus->setToolTip("-"); connect(funcMinus, SIGNAL(activated()), this, SLOT(slotFuncOutput())); funcCross=new QAction(tr("Multiplication"), Resource::loadPixmap ("opie-sheet/func-cross" ), tr("&Multiplication"), 0, this); funcCross->setToolTip("*"); connect(funcCross, SIGNAL(activated()), this, SLOT(slotFuncOutput())); funcDivide=new QAction(tr("Division"), Resource::loadPixmap( "opie-sheet/func-divide" ), tr("&Division"), 0, this); funcDivide->setToolTip("/"); connect(funcDivide, SIGNAL(activated()), this, SLOT(slotFuncOutput())); funcParanOpen=new QAction(tr("Open ParanthesistempCellData->row+row1, tempCellData->col+col1"), Resource::loadPixmap( "opie-sheet/func-paran-open" ), tr("&Open Paranthesis"), 0, this); funcParanOpen->setToolTip("("); connect(funcParanOpen, SIGNAL(activated()), this, SLOT(slotFuncOutput())); funcParanClose=new QAction(tr("Close Paranthesis"), Resource::loadPixmap( "opie-sheet/func-paran-close" ), tr("&Close Paranthesis"), 0, this); funcParanClose->setToolTip(")"); connect(funcParanClose, SIGNAL(activated()), this, SLOT(slotFuncOutput())); funcComma=new QAction(tr("Comma"), Resource::loadPixmap( "opie-sheet/func-comma" ), 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("&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(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(Resource::loadPixmap( "opie-sheet/func-func" )); 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=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); QPEApplication::showDialog( &dialogCellFormat ); 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()); + if ( !file1.ParseBook((char *)lnkDoc.file().ascii()) ){ + QMessageBox::critical(this, tr("Error"), tr("<td>Unable to open or parse file!</td>")); + return; + } 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); + // 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); QPEApplication::showDialog( &dialogSort ); 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); QPEApplication::showDialog( &dialogFind ); dialogFind.exec(sheet); } |