?? spreadwi.cpp
字號:
//spreadwin.cpp, (c)2000, 2001, 2002, 2003, 2004, 2005 by R. Lackner//// This file is part of RLPlot.//// RLPlot 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.//// RLPlot 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 General Public License for more details.//// You should have received a copy of the GNU General Public License// along with RLPlot; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//#include "rlplot.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <fcntl.h> //file open flags#include <sys/stat.h> //I/O flags#ifdef _WINDOWS #include <io.h> //for read/write#else #define O_BINARY 0x0 #include <unistd.h>#endifextern const LineDEF GrayLine;extern EditText *CurrText;extern char *LoadFile;extern char TmpTxt[];extern Default defs;extern UndoObj Undo;
static ReadCache *Cache = 0L;static TextDEF ssText;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Get item from *.csv filebool GetItemCSV(char *Text, int cbText){ char c; int i; for (i = 0, *Text = 0; i < cbText; ) { c = Cache->Getc(); switch(c) { case ',': //column separator Text[i] = 0; return true; case 0x0a: //end of line: mark by false return but text o.k. Text[i] = 0; return false; default: if(c > 0x20) Text[i++] = c; //printable character else if(i >0 && c == 0x20) Text[i++] = c; else if(!c && Cache->IsEOF()) { Text[i] = 0; return false; } else Text[i] = 0; //ignore non printing characters } } return false;}//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// process a memory block (i.e. clipboard data) as if file inputint ProcMemData(GraphObj *g, unsigned char *ptr, bool dispatch){ int i, RetVal = FF_UNKNOWN, nt, nl, nc, ns; if(ptr) { for(i = nt = nl = nc = ns = 0; ptr[i] && nl<100; i++) { switch(ptr[i]) { case 0x09: //tab nt++; break; case 0x0a: //LF nl++; break; case ',': nc++; break;
case ' ': ns++;
break;
} } if(dispatch && i && !nt && !nl) { if(CurrText){
g->Command(CMD_SETFOCUS, 0L, 0L);
for(i = 0; ptr[i]; i++) CurrText->AddChar(ptr[i], i? 0L : Undo.cdisp, 0L); g->Command(CMD_REDRAW, 0L, 0L);
}
} else if(nt) RetVal = FF_TSV; else if(nl && ptr[0] == '<') RetVal = FF_XML; else if(nc == nl && defs.DecPoint[0] == ',') RetVal = FF_TSV; else if(nl && nc && 0 == (nc % nl)) RetVal = FF_CSV; else if(nl && ns && 0 == (ns % nl)) RetVal = FF_SSV;
else if(nl) RetVal = FF_TSV; if(dispatch) switch(RetVal) { case FF_CSV: g->Command(CMD_PASTE_CSV, ptr, 0L); break; case FF_TSV: g->Command(CMD_PASTE_TSV, ptr, 0L); break; case FF_SSV: g->Command(CMD_PASTE_SSV, ptr, 0L); break;
case FF_XML: g->Command(CMD_PASTE_XML, ptr, 0L); break; } } return RetVal;}//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// This graphic object displays a spreadsheet//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~class SpreadWin:public GraphObj{public: anyOutput *w; POINT ssOrg; RECT currRC; SpreadWin(GraphObj *par, DataObj *Data); ~SpreadWin(); void DoPlot(anyOutput *target); bool Command(int cmd, void *tmpl, anyOutput *o); bool ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cpos); bool PrintData(anyOutput *o);
void WriteGraphXML(unsigned char **ptr, long *cbd);private: int ch, cw, fw; //cell height and width, row button width
bool is_modified; char *filename; ssButton **cButtons, **rButtons;
ssButton *aButton;
POINT cpos; DataObj *d; int NumGraphs; Graph **g;};SpreadWin::SpreadWin(GraphObj *par, DataObj *Data):GraphObj(par, Data){ d = Data; g = 0L; ssOrg.x = ssOrg.y = 0; NumGraphs = 0; ch = 19; cw = 76; fw = 32; filename=0L; aButton = 0L;
w = 0L; if(w = NewDispClass(this)){ w->hasHistMenu = true; ssText.RotBL = ssText.RotCHAR = 0.0; ssText.fSize = 0.0f;#ifdef _WINDOWS ssText.iSize = w->un2iy(defs.GetSize(SIZE_CELLTEXT));#else ssText.iSize = w->un2iy(defs.GetSize(SIZE_CELLTEXT)*.7);#endif ssText.Align = TXA_VCENTER | TXA_HLEFT; ssText.Mode = TXM_TRANSPARENT; ssText.Style = TXS_NORMAL; ssText.ColBg = 0x00e8e8e8L; ssText.ColTxt = 0x00000000L; ssText.text = 0L; ssText.Font = FONT_HELVETICA; w->SetTextSpec(&ssText); w->SetMenu(MENU_SPREAD); w->FileHistory(); w->Erase(0x00e8e8e8L); w->Caption("RLPlot data"); cw = w->un2ix(defs.GetSize(SIZE_CELLWIDTH)); ch = w->un2iy(defs.GetSize(SIZE_CELLTEXT)/defs.ss_txt) + 2; fw = 32; } cButtons = rButtons = 0L; Id = GO_SPREADDATA;
is_modified = false;}SpreadWin::~SpreadWin(){ int i;
if(parent) { if(cButtons) { for(i = 0; cButtons[i]; i++) if(cButtons[i]) delete(cButtons[i]); free(cButtons); } if(rButtons) { for(i = 0; rButtons[i]; i++) if(rButtons[i]) delete(rButtons[i]); free(rButtons); }
if (aButton) delete(aButton); if (w) delete w; if (g && NumGraphs) { for(i = 0; i < NumGraphs; i++) if(g[i]) { g[i]->Command(CMD_CAN_DELETE, 0L, 0L); delete(g[i]); }
free (g);
}
if(filename) free(filename); filename=0L;
}
}
void
SpreadWin::DoPlot(anyOutput *o){ o->ActualSize(&currRC); o->StartPage(); d->Command(CMD_DOPLOT, (void*)this, o); o->EndPage();}boolSpreadWin::Command(int cmd, void *tmpl, anyOutput *o){ char *Name; Graph **g1, *g2; int i, j, k; MouseEvent *mev;
POINT p1; if(d) { switch(cmd) {
case CMD_CURRPOS:
if(tmpl && cButtons && rButtons) {
int ac = 1, na = 0;
RECT urc;
if(((POINT*)tmpl)->x != cpos.x) {
for(cpos.x = ((POINT*)tmpl)->x, i = 0; cButtons[i]; i++) {
cButtons[i]->Command(CMD_SELECT, (cpos.x == (i+ssOrg.x)) ? &ac : &na, w);
}
urc.left = cButtons[0]->rDims.left; urc.bottom = cButtons[0]->rDims.bottom;
urc.top = cButtons[0]->rDims.top; urc.right = urc.left + cw * (i-1);
w->UpdateRect(&urc, false);
}
if(((POINT*)tmpl)->y != cpos.y) {
for(cpos.y = ((POINT*)tmpl)->y, i = 0; rButtons[i]; i++) {
rButtons[i]->Command(CMD_SELECT, (cpos.y == (i+ssOrg.y)) ? &ac : &na, w);
}
urc.left = rButtons[0]->rDims.left; urc.right = rButtons[0]->rDims.right;
urc.top = rButtons[0]->rDims.top; urc.bottom = urc.top + ch * (i-1);
w->UpdateRect(&urc, false);
}
}
return true; case CMD_CAN_CLOSE:
HideTextCursor();
for(i = 0; i < NumGraphs; i++) {
if((g[i]) && !g[i]->Command(cmd, tmpl, o)) return false;
}
if(is_modified) {
is_modified=false;
i = YesNoCancelBox("The spreadsheet has been modified!\n\nDo you want to save it now?");
if(i == 2) return false;
else if(i == 1) return Command(CMD_SAVEDATAAS, tmpl, o);
}
//fall through
case CMD_CAN_DELETE:
HideTextCursor();
if(is_modified && YesNoBox("The spreadsheet has been modified!\n\nDo you want to save it now?")){
is_modified=false;
return Command(CMD_SAVEDATAAS, tmpl, o);
}
Undo.KillDisp(w);
is_modified=false;
return true;
case CMD_MRK_DIRTY:
return is_modified = true;
case CMD_WRITE_GRAPHS:
if (g && NumGraphs) WriteGraphXML((unsigned char**)tmpl, (long*)o);
return true;
case CMD_DROP_GRAPH: if(o) o->FileHistory(); if(!g) g = (Graph **)calloc(2, sizeof(Graph*)); else { g1 = (Graph **)calloc(NumGraphs+2, sizeof(Graph*)); if(!g1) return false; for(i = 0; i < NumGraphs; i++) g1[i] = g[i]; free(g); g = g1; } if(!g) return false; g[NumGraphs] = (Graph *)tmpl; if(g[NumGraphs]){ g[NumGraphs]->parent = this; NumGraphs++; g[NumGraphs-1]->Command(CMD_SET_DATAOBJ, (void *)d, 0L); g[NumGraphs-1]->DoPlot(NULL); } return true; case CMD_NEWGRAPH: if((g2 = new Graph(this, d, 0L)) && g2->PropertyDlg() && Command(CMD_DROP_GRAPH, g2, o))return Command(CMD_REDRAW, 0L, o); else if(g2) DeleteGO(g2);
Undo.SetDisp(w); return false; case CMD_NEWPAGE: if((g2 = new Page(this, d)) && Command(CMD_DROP_GRAPH, g2, o))return Command(CMD_REDRAW, 0L, o); else if(g2) DeleteGO(g2); Undo.SetDisp(w);
return false; case CMD_DELGRAPH: if (g && NumGraphs) { for(i = 0; i < NumGraphs; i++) if(g[i]){ g[i]->Command(CMD_CAN_DELETE, 0L, 0L); DeleteGO(g[i]); } free (g); } g = 0L; NumGraphs = 0; Undo.Flush(); return true; case CMD_DELOBJ: if (g) { for(i = 0; i <= NumGraphs; i++) { if(g[i] == (Graph *)tmpl) { delete (g[i]); g[i] = 0L; return true; } } } return false; case CMD_SAVEDATAAS:
is_modified=false; if((Name = SaveDataAsName(filename)) && Name[0]){ if(o) o->FileHistory(); if(Name && d->WriteData(Name)) { if(filename) free(filename); filename = strdup(Name); }
else return false; }
else return false; return true; case CMD_DROPFILE:
if(!Command(CMD_CAN_CLOSE, 0L, o)) return false;
if(IsRlpFile((char*)tmpl)) return OpenGraph(this, (char*)tmpl, 0L); else if(d->ReadData((char*)tmpl, 0L, FF_UNKNOWN)){ if(filename) free(filename); filename = strdup((char*)tmpl);
return Command(CMD_SETSCROLL, 0L, w); } return false; case CMD_OPEN: if(!Command(CMD_CAN_CLOSE, 0L, o)) return false;
if((Name = OpenDataName(filename)) && Name[0]){ if(o) o->FileHistory(); if(IsRlpFile(Name)) return OpenGraph(this, Name, 0L); else if(d->ReadData(Name, 0L, FF_UNKNOWN)){ if(filename) free(filename); filename = strdup(Name); return Command(CMD_SETSCROLL, 0L, w); } } return false; case CMD_ADDROWCOL: if(DoSpShSize(d)) DoPlot(o);
return true; case CMD_MOUSE_EVENT: if(o && (mev = (MouseEvent*)tmpl) && mev->y > o->MenuHeight) {
if(mev->x < fw && mev->y < (o->MenuHeight + ch) && aButton) {
aButton->Command(cmd, tmpl, o);
} else if(mev->x < fw && rButtons) { i = (mev->y - o->MenuHeight - ch)/ch; if(rButtons[i]) rButtons[i]->Command(cmd, tmpl, o); } else if(mev->y < (o->MenuHeight + ch) && cButtons) { i = (mev->x - fw)/cw; if(cButtons[i]) cButtons[i]->Command(cmd, tmpl, o); } else if(o->MrkMode == MRK_SSB_DRAW) o->HideMark(); }
return d->Command(cmd, tmpl, o);
case CMD_PASTE_TSV: case CMD_PASTE_CSV: case CMD_PASTE_SSV:
Undo.DataObject(this, w, d, 0L, 0L);
case CMD_COPY_SYLK: case CMD_ADDCHAR: case CMD_SHIFTUP: case CMD_COPY_TSV: case CMD_COPY_XML: case CMD_QUERY_COPY: case CMD_TAB: case CMD_SHTAB: case CMD_SHIFTDOWN: case CMD_CURRLEFT: case CMD_CURRIGHT: case CMD_CURRUP: case CMD_CURRDOWN: case CMD_SHIFTRIGHT: case CMD_POS_FIRST: case CMD_POS_LAST: case CMD_SHIFTLEFT: case CMD_DELETE: case CMD_TOOLMODE: case CMD_FILLRANGE: case CMD_CUT:
case CMD_PASTE_XML: case CMD_DELROW: case CMD_INSROW:
case CMD_INSCOL: case CMD_DELCOL: case CMD_UNDO: case CMD_SHPGUP: case CMD_SHPGDOWN:
return d->Command(cmd, tmpl, o);
case CMD_REDRAW:
Undo.SetDisp(w);
d->Command(cmd, tmpl, o);
return true; case CMD_SETSCROLL: HideTextCursor(); o->ActualSize(&currRC); k = (currRC.bottom-currRC.top)/ch; d->GetSize(&i, &j); o->SetScroll(true, 0, j, k, ssOrg.y); k = (currRC.right-currRC.left)/cw; o->SetScroll(false, 0, i, k, ssOrg.x); DoPlot(o); return true; case CMD_PAGEUP: case CMD_PAGEDOWN: k = (currRC.bottom-currRC.top)/ch; k = k > 3 ? k-2 : 1;
p1.x = fw + 2; p1.y = ch + 2;
if(CurrText){
p1.x = CurrText->GetX()+2; p1.y = CurrText->GetY()+12;
}
d->GetSize(&i, &j);
if(cmd == CMD_PAGEUP) ssOrg.y = ssOrg.y > k ? ssOrg.y-k : 0;
else ssOrg.y = ssOrg.y < j-k*2 ? ssOrg.y+k : j > k ? j-k : 0;
Command(CMD_SETSCROLL, tmpl, o);
CurrText = 0L; d->Select(&p1);
return true;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -