[rlplot] 05/23: Imported Upstream version 1.1
Andreas Tille
tille at debian.org
Wed Jun 29 09:50:55 UTC 2016
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository rlplot.
commit 4dc4177dfb02f5c866b363b20f0cc632a7ea917a
Author: Andreas Tille <tille at debian.org>
Date: Wed Jun 29 11:43:54 2016 +0200
Imported Upstream version 1.1
---
Export.cpp | 121 ++--
Fileio.cpp | 184 ++++--
ODbuttons.cpp | 26 +-
Output.cpp | 84 ++-
PlotObs.cpp | 178 ++++--
PropertyDlg.cpp | 1419 +++++++++++++++++++++++++++++---------------
QT_Spec.cpp | 688 ++++++++++++---------
QT_Spec.h | 79 ++-
RLPLOT.RC | 74 +--
TheDialog.cpp | 224 ++++++-
TheDialog.h | 12 +-
UtilObj.cpp | 285 +++++----
Utils.cpp | 140 ++++-
Version.h | 4 +-
WinSpec.cpp | 73 ++-
exprlp.cpp | 17 +-
mfcalc.cpp | 1773 ++++++++++++++++++++++++++++++++++++++-----------------
mfcalc.y | 1037 +++++++++++++++++++++++---------
resource.h | 86 ---
rlp_math.cpp | 729 +++++++++++++++++++++--
rlplot.cpp | 1617 ++++++++++++++++++++++++++++++++++----------------
rlplot.h | 144 ++++-
rlplot.spec | 13 +-
spreadwi.cpp | 501 +++++++++-------
24 files changed, 6663 insertions(+), 2845 deletions(-)
diff --git a/Export.cpp b/Export.cpp
index 7b4b7f5..86107e6 100755
--- a/Export.cpp
+++ b/Export.cpp
@@ -1,4 +1,4 @@
-//Export.cpp, Copyright (c) 2002, 2003, 2004 R.Lackner
+//Export.cpp, Copyright (c) 2002-2006 R.Lackner
//export graph files
//
// This file is part of RLPlot.
@@ -33,6 +33,7 @@
#include <unistd.h>
#endif
+extern char TmpTxt[];
extern Default defs;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -240,7 +241,6 @@ ExportWMF::EndPage()
unsigned short end_token[3] = {3, 0, 0};
write(oFile, &end_token, 6);
-// file_size = tell(oFile);
file_size = lseek(oFile, 0L, SEEK_CUR);
lseek(oFile, 0L, SEEK_SET);
header.mtSize0 = (file_size>>1)&0xffff;
@@ -636,7 +636,11 @@ ExportSVG::SetFill(FillDEF *fill)
bool
ExportSVG::SetTextSpec(TextDEF *set)
{
- if(!set->iSize && set->fSize > 0.0f) set->iSize = un2iy(set->fSize);
+ if(set->fSize > 0.0) {
+ if((set->Style & TXS_SUPER) || (set->Style & TXS_SUB))
+ set->iSize = un2iy(set->fSize * 0.71);
+ else set->iSize = un2iy(set->fSize);
+ }
if(!set->iSize) return false;
return anyOutput::SetTextSpec(set);
}
@@ -799,7 +803,7 @@ ExportSVG::oSolidLine(POINT *p)
bool
ExportSVG::oTextOut(int x, int y, char *txt, int cb)
{
- int i, h, ix, iy;
+ int i, j, h, ix, iy, dy;
char tmptxt[140], *nt;
if(!txt || !txt[0]) return false;
@@ -807,19 +811,18 @@ ExportSVG::oTextOut(int x, int y, char *txt, int cb)
if(TxtSet.Align & TXA_VCENTER) iy = y + h/3;
else if(TxtSet.Align & TXA_VBOTTOM) iy = y;
else iy = y + iround(h * 0.8);
- ix = x;
- if((TxtSet.Style & TXS_SUB) || (TxtSet.Style & TXS_SUPER)) h = iround((double)TxtSet.iSize * 0.8);
+ ix = x; dy = 0;
if(TxtSet.Style & TXS_SUB) {
- if((TxtSet.Align & TXA_VCENTER) == TXA_VCENTER) iy +=un2iy(TxtSet.fSize*0.4);
- else if((TxtSet.Align & TXA_VBOTTOM) == TXA_VBOTTOM) iy += un2iy(TxtSet.fSize*0.2);
- else if((TxtSet.Align & TXA_VTOP) == TXA_VTOP) iy += un2iy(TxtSet.fSize*.6);
+ if((TxtSet.Align & TXA_VCENTER) == TXA_VCENTER) dy = un2iy(TxtSet.fSize*0.4);
+ else if((TxtSet.Align & TXA_VBOTTOM) == TXA_VBOTTOM) dy = un2iy(TxtSet.fSize*0.2);
+ else if((TxtSet.Align & TXA_VTOP) == TXA_VTOP) dy = un2iy(TxtSet.fSize*.6);
}
else if(TxtSet.Style & TXS_SUPER) {
- if((TxtSet.Align & TXA_VCENTER) == TXA_VCENTER) iy -= un2iy(TxtSet.fSize*0.4);
- else if((TxtSet.Align & TXA_VBOTTOM) == TXA_VBOTTOM) iy -= un2iy(TxtSet.fSize*0.6);
- else if((TxtSet.Align & TXA_VTOP) == TXA_VTOP) iy -= un2iy(TxtSet.fSize*0.2);
+ if((TxtSet.Align & TXA_VCENTER) == TXA_VCENTER) dy = -un2iy(TxtSet.fSize*0.4);
+ else if((TxtSet.Align & TXA_VBOTTOM) == TXA_VBOTTOM) dy = -un2iy(TxtSet.fSize*0.6);
+ else if((TxtSet.Align & TXA_VTOP) == TXA_VTOP) dy = -un2iy(TxtSet.fSize*0.2);
}
- sprintf(output, "<text x=\"%d\" y=\"%d\" ", ix, iy);
+ sprintf(output, "<text x=\"%d\" y=\"%d\" dy=\"%d\" ", ix, iy, dy);
if(fabs(TxtSet.RotBL) >.01 || fabs(TxtSet.RotCHAR) >.01) {
sprintf(tmptxt,"transform=\"rotate(%.0f,%d,%d)\" ", -TxtSet.RotBL, ix, iy);
strcat(output, tmptxt);
@@ -840,14 +843,31 @@ ExportSVG::oTextOut(int x, int y, char *txt, int cb)
sprintf(tmptxt, "font-size:%d; text-anchor:%s \">", h,
(TxtSet.Align & TXA_HRIGHT) ? "end" : (TxtSet.Align & TXA_HCENTER) ? "middle":"start");
AddToOutput(tmptxt);
- nt = str2xml(txt);
- if((TxtSet.Style & TXS_SUB) || (TxtSet.Style & TXS_SUPER)) {
- for(i = strlen(nt)+6, nt[i+1]=0; i > 5; i--) {
- nt[i] = nt[i-6];
+ if(TxtSet.Font == FONT_GREEK) {
+ for(i = j = 0; txt[i] && j < 4090; i++) {
+ switch(txt[i]) {
+ case '"':
+ j += sprintf(TmpTxt+j, """);
+ break;
+ case '&':
+ j += sprintf(TmpTxt+j, "&");
+ break;
+ case '<':
+ j += sprintf(TmpTxt+j, "<");
+ break;
+ case '>':
+ j += sprintf(TmpTxt+j, ">");
+ break;
+ default:
+ if(txt[i] >= 'A' && txt[i] <= 'Z') j += sprintf(TmpTxt+j, "&#%d;", txt[i] - 'A' + 0x391);
+ else if(txt[i] >= 'a' && txt[i] <= 'z') j += sprintf(TmpTxt+j, "&#%d;", txt[i] - 'a' + 0x3B1);
+ else if(txt[i] > 31) TmpTxt[j++] = txt[i];
+ break;
+ }
}
- nt[0] = '&'; nt[1] = 'n'; nt[2] = 'b';
- nt[3] = 's'; nt[4] = 'p'; nt[5] = ';';
+ nt = TmpTxt;
}
+ else nt = str2xml(txt);
if((strlen(indent)+strlen(nt)+strlen(output)) <110) strcat(output, nt);
else {
fprintf(oFile, "%s%s\n", indent, output);
@@ -997,9 +1017,10 @@ private:
fRECT SolLines[2000];
int nSolLines;
GraphObj *go;
- char *name;
+ char *name, FontName[30];
FILE *oFile;
DWORD CurrCol;
+ bool bFontChange;
float ix2eps(int x);
float iy2eps(int y);
@@ -1010,16 +1031,11 @@ private:
ExportEPS::ExportEPS(GraphObj *g, char *FileName, DWORD flags)
{
- hgo =0L;
- nSolLines = 0;
- DeskRect.left = DeskRect.top = 0;
+ hgo =0L; nSolLines = 0; DeskRect.left = DeskRect.top = 0;
DeskRect.right = DeskRect.bottom = 0x4fffffff;
- dFillCol = 0xffffffffL;
- hres = vres = 720.0f;
- go = g;
- if(FileName)name = strdup(FileName);
- else name = 0L;
- oFile = 0L;
+ dFillCol = 0xffffffffL; hres = vres = 720.0f;
+ go = g; bFontChange = false; oFile = 0L;
+ if(FileName)name = strdup(FileName); else name = 0L;
}
ExportEPS::~ExportEPS()
@@ -1064,15 +1080,12 @@ ExportEPS::SetFill(FillDEF *fill)
bool
ExportEPS::SetTextSpec(TextDEF *set)
{
- char FontName[30];
-
- if(!set->iSize && set->fSize > 0.0f) set->iSize = un2iy(set->fSize);
- if(!set->iSize) return false;
- if(set->iSize == TxtSet.iSize && set->Style == TxtSet.Style &&
- set->Font == TxtSet.Font){
- anyOutput::SetTextSpec(set);
- return true;
+ if(set->fSize > 0.0) {
+ if((set->Style & TXS_SUPER) || (set->Style & TXS_SUB))
+ set->iSize = un2iy(set->fSize * 0.71);
+ else set->iSize = un2iy(set->fSize);
}
+ if(!set->iSize) return false;
anyOutput::SetTextSpec(set);
switch(TxtSet.Font) {
case FONT_TIMES: sprintf(FontName, "(Times"); break;
@@ -1081,8 +1094,7 @@ ExportEPS::SetTextSpec(TextDEF *set)
}
if(TxtSet.Style & TXS_BOLD) strcat(FontName, "-Bold");
if(TxtSet.Style & TXS_ITALIC) strcat(FontName, "-Italic");
- strcat(FontName, ")");
- fprintf(oFile, "\n%s findfont %d scalefont setfont ", FontName, TxtSet.iSize/10);
+ strcat(FontName, ")"); bFontChange = true;
return true;
}
@@ -1224,27 +1236,46 @@ bool
ExportEPS::oTextOut(int x, int y, char *txt, int cb)
{
int h, ix, iy, w;
- float fx, fy;
+ float fx, fy, lw;
- FlushSolLines();
+ FlushSolLines(); if(!txt || !txt[0]) return true;
oGetTextExtent(txt, cb, &w, &h);
+ if(bFontChange) {
+ fprintf(oFile, "\n%s findfont %d scalefont setfont ", FontName, TxtSet.iSize/10);
+ bFontChange = false;
+ }
if(TxtSet.Align & TXA_VCENTER) iy = y + h/3;
else if(TxtSet.Align & TXA_VBOTTOM) iy = y;
else iy = y + iround(h*.8);
if(TxtSet.Align & TXA_HRIGHT) ix = x-w;
else if(TxtSet.Align & TXA_HCENTER) ix = x-w/2;
- else ix = x;
+ else ix = x; lw = (float)(iy-y)/150.0f;
fprintf(oFile,"\n");
if(fabs(TxtSet.RotBL) >.01 || fabs(TxtSet.RotCHAR) >.01) {
+ if(TxtSet.Style & TXS_SUB) iy += un2iy(TxtSet.fSize*0.6);
+ else if(TxtSet.Style & TXS_SUPER) iy -= un2iy(TxtSet.fSize*.2);
fprintf(oFile, "gsave %.1f %.1f translate %f rotate %.1f %.1f moveto\n",
ix2eps(x), iy2eps(y), TxtSet.RotBL, (float)(ix-x)/10.0f, (float)(iy-y)/-10.0f);
- if(CurrCol != TxtSet.ColTxt) fprintf(oFile, "%s ", col2eps(CurrCol = TxtSet.ColTxt));
- fprintf(oFile, "(%s) show grestore ", txt);
+ fprintf(oFile, "%s ", col2eps(CurrCol = TxtSet.ColTxt));
+ fprintf(oFile, "(%s) show ", txt);
+ if(TxtSet.Style & TXS_UNDERLINE) {
+ fprintf(oFile, "\ncurrentpoint %.1f exch pop moveto", (float)(iy-y)/-10.0f - lw*1.2);
+ fprintf(oFile, " 0 %.1f lineto %s %.1f setlinewidth stroke ", (float)(iy-y)/-10.0f -lw*1.2,
+ col2eps(TxtSet.ColTxt), lw);
+ }
+ fprintf(oFile, "grestore\n");
}
else {
+ if(TxtSet.Style & TXS_SUB) iy += un2iy(TxtSet.fSize*0.6);
+ else if(TxtSet.Style & TXS_SUPER) iy -= un2iy(TxtSet.fSize*.2);
fx = ix2eps(ix); fy = iy2eps(iy);
- if(CurrCol != TxtSet.ColTxt) fprintf(oFile, "%s ", col2eps(CurrCol = TxtSet.ColTxt));
+ fprintf(oFile, "%s ", col2eps(CurrCol = TxtSet.ColTxt));
fprintf(oFile,"%.1f %.1f moveto (%s) show ", fx, fy, txt);
+ if(TxtSet.Style & TXS_UNDERLINE) {
+ fprintf(oFile, "\ncurrentpoint %.1f exch pop moveto", fy - lw*1.2);
+ fprintf(oFile, " %.1f %.1f lineto %s %.1f setlinewidth stroke\n", fx, fy - lw*1.2,
+ col2eps(TxtSet.ColTxt), lw);
+ }
}
return true;
}
diff --git a/Fileio.cpp b/Fileio.cpp
index e022eb8..edfb6f6 100755
--- a/Fileio.cpp
+++ b/Fileio.cpp
@@ -1,4 +1,4 @@
-//FileIO.cpp, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
+//FileIO.cpp, Copyright (c) 2001-2006 R.Lackner
//read/write graphic objects
//
// This file is part of RLPlot.
@@ -211,7 +211,7 @@ int WriteEscString(char *txt, char *buff, int cb)
if(!txt || !txt[0]) return 0;
l = strlen(txt);
- if((l+10) > esc_str_size) esc_str = (char*)realloc(esc_str, esc_str_size = (l+10));
+ if((l+10) > esc_str_size) esc_str = (char*)realloc(esc_str, esc_str_size = (l+100));
j = 0; esc_str[j++] = '"';
for(i = 0; txt[i]; i++) {
switch(txt[i]) {
@@ -219,8 +219,8 @@ int WriteEscString(char *txt, char *buff, int cb)
case '\n': j += sprintf(esc_str+j, "\\n"); break;
default: esc_str[j++] = txt[i];
}
- if(j > esc_str_size -2) esc_str = (char*)realloc(esc_str, (esc_str_size += 20));
- if(j > lim) {
+ if(j > (esc_str_size -10)) esc_str = (char*)realloc(esc_str, (esc_str_size += 100));
+ if(j > lim && (l-i) > 5) {
j += sprintf(esc_str+j, "\"\n \"");
lim += 60;
}
@@ -806,7 +806,7 @@ void UpdGOfromMem(GraphObj *go, unsigned char *buff)
delete Cache; Cache = 0L;
}
-bool OpenGraph(GraphObj *root, char *name, unsigned char *mem)
+bool OpenGraph(GraphObj *root, char *name, unsigned char *mem, bool bPaste)
{
unsigned char c, tmp[80];
char debug[80];
@@ -857,10 +857,10 @@ bool OpenGraph(GraphObj *root, char *name, unsigned char *mem)
hv = HashValue(tmp);
switch(hv) {
case 3895: go = new Axis(FILE_READ); break;
- case 7496002: go = new Bar(FILE_READ); break;
+ case 886: go = new Bar(FILE_READ); break;
case 81384: go = new Symbol(FILE_READ); break;
case 62229: go = new Bubble(FILE_READ); break;
- case 7892802: go = new Box(FILE_READ); break;
+ case 948: go = new Box(FILE_READ); break;
case 15411: go = new Arrow(FILE_READ); break;
case 1052406: go = new ErrorBar(FILE_READ); break;
case 324566: go = new Whisker(FILE_READ); break;
@@ -872,7 +872,8 @@ bool OpenGraph(GraphObj *root, char *name, unsigned char *mem)
case 61662266: go = new DataPolygon(FILE_READ); break;
case 435228: go = new segment(FILE_READ); break;
case 1741325: go = new polyline(FILE_READ); break;
- case 435258: go = new polygon(FILE_READ); break;
+ case 435258: go = new polygon(FILE_READ); break;
+ case 92534: go = new Bezier(FILE_READ); break;
case 6888037: go = new rectangle(FILE_READ); break;
case 1780087: go = new roundrec(FILE_READ); break;
case 78813: go = new Sphere(FILE_READ); break;
@@ -930,12 +931,9 @@ bool OpenGraph(GraphObj *root, char *name, unsigned char *mem)
if((go = Notary->PopGO(lid))) {
go->Command(CMD_SET_DATAOBJ, 0L, 0L);
delete Notary; Notary = 0L;
- if(root->Id == GO_PAGE) {
- if(go->Id == GO_PAGE){
- if(!(root->parent->Command(CMD_DROP_GRAPH,(void *)go, 0L))) DeleteGO(go);
- }
- else if(!(root->Command(CMD_DROP_GRAPH, (void *)go, 0L))) DeleteGO(go);
- }
+ if(bPaste && root->Command(CMD_PASTE_OBJ, (void *)go, 0L)) {
+ // object accepted
+ }
else if(!(root->Command(CMD_DROP_GRAPH, (void *)go, 0L))){
DeleteGO(go); go = 0L;
}
@@ -1522,7 +1520,8 @@ ErrorBar::FileIO(int rw)
{"Pos", typLFPOINT, &fPos, 0L},
{"Err", typLFLOAT, &ferr, 0L},
{"Size", typLFLOAT, &SizeBar, 0L},
- {"Line", typLAST | typLINEDEF, &ErrLine, 0L}};
+ {"Line", typLINEDEF, &ErrLine, 0L},
+ {"Desc", typLAST | typTEXT, &name, 0L}};
switch(rw) {
case SAVE_VARS:
@@ -1532,6 +1531,8 @@ ErrorBar::FileIO(int rw)
SizeBar = defs.GetSize(SIZE_ERRBAR);
ErrLine.width = defs.GetSize(SIZE_ERRBAR_LINE);
ErrLine.color = defs.Color(COL_SYM_LINE);
+ mo = 0L;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
return true;
case FILE_READ:
return ExecInput(Desc);
@@ -1619,7 +1620,8 @@ Whisker::FileIO(int rw)
{"High", typLFPOINT, &pos1, 0L},
{"Low", typLFPOINT, &pos2, 0L},
{"Size", typLFLOAT, &size, 0L},
- {"Line", typLAST | typLINEDEF, &LineDef, 0L}};
+ {"Line", typLINEDEF, &LineDef, 0L},
+ {"Desc", typLAST | typTEXT, &name, 0L}};
switch(rw) {
case SAVE_VARS:
@@ -1629,6 +1631,8 @@ Whisker::FileIO(int rw)
size = defs.GetSize(SIZE_WHISKER);
LineDef.width = defs.GetSize(SIZE_WHISKER_LINE);
LineDef.color = defs.Color(COL_WHISKER);
+ mo = 0L;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
return true;
case FILE_READ:
return ExecInput(Desc);
@@ -1999,7 +2003,32 @@ polyline::FileIO(int rw)
type == 1 ? (char*)"polygon" : (char*)"polyline", Desc);
}
return false;
-}
+}
+
+bool
+Bezier::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"moveable", typNZINT, &moveable, 0L},
+ {"Data", typFPLST, &Values, &nPoints},
+ {"Line", typLINEDEF, &pgLine, 0L},
+ {"FillLine", typLINEDEF, &pgFillLine, 0L},
+ {"Fill", typLAST | typFILLDEF, &pgFill, 0L}};
+
+ switch(rw) {
+ case INIT_VARS:
+ //assume that all initialization is done by polyline::FileIO(int rw)
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ pgFill.hatch = &pgFillLine;
+ return true;
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "bezier", Desc);
+ }
+ return false;
+}
bool
rectangle::FileIO(int rw)
@@ -2120,7 +2149,7 @@ Legend::FileIO(int rw)
D_Rect.Xmax = d*1.3; D_Rect.Ymax = d*0.4;
F_Rect.Ymin = 0.0; F_Rect.Xmin = d*0.2;
F_Rect.Xmax = d*1.3; F_Rect.Ymax = d*0.4;
- to = 0L;
+ to = 0L; hasLine = false;
trc.left = trc.right = trc.top = trc.bottom = 0;
if(!name) name=strdup("Legend");
return true;
@@ -2528,6 +2557,7 @@ DensDisp::FileIO(int rw)
{
descIO Desc[] = {
{"Type", typNZINT, &type, 0L},
+ {"hide", typNZINT, &hidden, 0L},
{"Bounds", typFRECT, &Bounds, 0L},
{"xRange", typTEXT, &xRange, 0L},
{"yRange", typTEXT, &yRange, 0L},
@@ -2570,6 +2600,7 @@ StackBar::FileIO(int rw)
{
descIO Desc[] = {
{"Bounds", typFRECT, &Bounds, 0L},
+ {"hide", typNZINT, &hidden, 0L},
{"x_axis", typNZINT, &use_xaxis, 0L},
{"y_axis", typNZINT, &use_yaxis, 0L},
{"cumData", typNZINT, &cum_data_mode, 0L},
@@ -2622,6 +2653,7 @@ PieChart::FileIO(int rw)
descIO Desc[] = {
{"ssRefA", typTEXT, &ssRefA, 0L},
{"ssRefR", typTEXT, &ssRefR, 0L},
+ {"hide", typNZINT, &hidden, 0L},
{"CtDef", typLFPOINT, &CtDef, 0L},
{"FacRad", typLFLOAT, &FacRad, 0L},
{"Segs", typLAST | typOBJLST, &Segments, (long*)&nPts}};
@@ -2664,6 +2696,7 @@ GoGroup::FileIO(int rw)
{
descIO Desc[] = {
{"Pos", typNZLFPOINT, &fPos, 0L},
+ {"hide", typNZINT, &hidden, 0L},
{"Items", typLAST | typOBJLST, &Objects, (long*)&nObs}};
int i;
@@ -2704,6 +2737,7 @@ Scatt3D::FileIO(int rw)
{"ssRefX", typTEXT, &ssRefX, 0L},
{"ssRefY", typTEXT, &ssRefY, 0L},
{"ssRefZ", typTEXT, &ssRefZ, 0L},
+ {"hide", typNZINT, &hidden, 0L},
{"Line", typGOBJ, &Line, 0L},
{"Balls", typOBJLST, &Balls, &nBalls},
{"Columns", typOBJLST, &Columns, &nColumns},
@@ -2763,6 +2797,7 @@ Ribbon::FileIO(int rw)
{
descIO Desc[] = {
{"Type", typNZINT, &type, 0L},
+ {"hide", typNZINT, &hidden, 0L},
{"z-pos", typNZLFLOAT, &z_value},
{"z-width", typNZLFLOAT, &z_width},
{"relwidth", typNZLFLOAT, &relwidth},
@@ -2884,6 +2919,7 @@ bool
Function::FileIO(int rw)
{
descIO Desc[] = {
+ {"hide", typNZINT, &hidden, 0L},
{"x1", typNZLFLOAT, &x1, 0L},
{"x2", typNZLFLOAT, &x2, 0L},
{"xstep", typNZLFLOAT, &xstep, 0L},
@@ -2930,6 +2966,7 @@ bool
FitFunc::FileIO(int rw)
{
descIO Desc[] = {
+ {"hide", typNZINT, &hidden, 0L},
{"ssXref", typTEXT, &ssXref, 0L},
{"ssYref", typTEXT, &ssYref, 0L},
{"x1", typNZLFLOAT, &x1, 0L},
@@ -2940,7 +2977,7 @@ FitFunc::FileIO(int rw)
{"maxiter", typNZINT, &maxiter, 0L},
{"Line", typLINEDEF, &Line, 0L},
{"f_xy", typTEXT, &cmdxy, 0L},
- {"p_xy", typTEXT, &parxy, 0L},
+ {"p_xy", typTEXT, &parxy, 0L},
{"Symbols", typLAST | typOBJLST, &Symbols, &nPoints}};
int i;
@@ -3199,7 +3236,6 @@ bool
Plot3D::FileIO(int rw)
{
fPOINT3D rot_vec, rot_ang;
- //DEBUG: must initialize rot_vec, rot_ang in case they are not present in file
descIO Desc[] = {
{"xBounds", typLFPOINT, &xBounds, 0L},
{"yBounds", typLFPOINT, &yBounds, 0L},
@@ -3238,7 +3274,9 @@ Plot3D::FileIO(int rw)
free(name); name=strdup(TmpTxt);
}
return true;
- case FILE_READ:
+ case FILE_READ:
+ rot_vec.fx = 0.919384; rot_vec.fy = 0.389104; rot_vec.fz = -0.057709;
+ rot_ang.fx = 0.327146; rot_ang.fy = 0.944974; rot_ang.fz = 0.055026;
ExecInput(Desc);
RotDef[0] = rot_vec.fx; RotDef[1] = rot_vec.fy; RotDef[2] = rot_vec.fz;
RotDef[3] = rot_ang.fx; RotDef[4] = rot_ang.fy; RotDef[5] = rot_ang.fz;
@@ -3264,7 +3302,6 @@ bool
Func3D::FileIO(int rw)
{
fPOINT3D rot_vec, rot_ang;
- //DEBUG: must initialize rot_vec, rot_ang in case they are not present in file
descIO Desc[] = {
{"Type", typNZINT, &type, 0L},
{"xBounds", typLFPOINT, &xBounds, 0L},
@@ -3283,7 +3320,6 @@ Func3D::FileIO(int rw)
{"z1", typNZLFLOAT, &x1, 0L},
{"z2", typNZLFLOAT, &x2, 0L},
{"zstep", typNZLFLOAT, &xstep, 0L},
- {"g_idx", typNZINT, &g_idx, 0L},
{"Line", typLINEDEF, &Line, 0L},
{"Fill", typFILLDEF, &Fill, 0L},
{"f_xz", typTEXT, &cmdxy, 0L},
@@ -3297,7 +3333,7 @@ Func3D::FileIO(int rw)
x1 = -20.0; x2 = 20.0; xstep = 2.0;
z1 = -20.0; z2 = 20.0; zstep = 2.0;
gda = 0L; gob = 0L;
- g_idx = 0; param = cmdxy = 0L;
+ param = cmdxy = 0L;
Line.width = defs.GetSize(SIZE_HAIRLINE);
Line.patlength = defs.GetSize(SIZE_PATLENGTH);
Line.color = Line.pattern = 0x0L;
@@ -3311,6 +3347,8 @@ Func3D::FileIO(int rw)
}
return true;
case FILE_READ:
+ rot_vec.fx = 0.919384; rot_vec.fy = 0.389104; rot_vec.fz = -0.057709;
+ rot_ang.fx = 0.327146; rot_ang.fy = 0.944974; rot_ang.fz = 0.055026;
ExecInput(Desc);
RotDef[0] = rot_vec.fx; RotDef[1] = rot_vec.fy; RotDef[2] = rot_vec.fz;
RotDef[3] = rot_ang.fx; RotDef[4] = rot_ang.fy; RotDef[5] = rot_ang.fz;
@@ -3326,6 +3364,83 @@ Func3D::FileIO(int rw)
}
return false;
}
+
+void
+FitFunc3D::RegGO(void *n)
+{
+}
+
+bool
+FitFunc3D::FileIO(int rw)
+{
+ fPOINT3D rot_vec, rot_ang;
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssXref", typTEXT, &ssXref, 0L},
+ {"ssYref", typTEXT, &ssYref, 0L},
+ {"ssZref", typTEXT, &ssZref, 0L},
+ {"xBounds", typLFPOINT, &xBounds, 0L},
+ {"yBounds", typLFPOINT, &yBounds, 0L},
+ {"zBounds", typLFPOINT, &zBounds, 0L},
+ {"Corner1", typPOINT3D, &cub1, 0L},
+ {"Corner2", typPOINT3D, &cub2, 0L},
+ {"Center", typPOINT3D, &rotC, 0L},
+ {"rot_vec", typPOINT3D, &rot_vec, 0L},
+ {"rot_ang", typPOINT3D, &rot_ang, 0L},
+ {"Axes", typOBJLST, &Axes, (long*)&nAxes},
+ {"Plots", typOBJLST, &plots, (long*)&nPlots},
+ {"x1", typNZLFLOAT, &x1, 0L},
+ {"x2", typNZLFLOAT, &x2, 0L},
+ {"xstep", typNZLFLOAT, &xstep, 0L},
+ {"z1", typNZLFLOAT, &x1, 0L},
+ {"z2", typNZLFLOAT, &x2, 0L},
+ {"zstep", typNZLFLOAT, &xstep, 0L},
+ {"maxiter", typNZINT, &maxiter, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"f_xz", typTEXT, &cmdxy, 0L},
+ {"param", typLAST | typTEXT, ¶m, 0L}};
+ int i;
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ x1 = -20.0; x2 = 20.0; xstep = 2.0;
+ z1 = -20.0; z2 = 20.0; zstep = 2.0;
+ gda = 0L; gob = 0L;
+ conv = 1.0e-15; maxiter = 100;
+ param = cmdxy = ssXref = ssYref = ssZref = 0L;
+ Line.width = defs.GetSize(SIZE_HAIRLINE);
+ Line.patlength = defs.GetSize(SIZE_PATLENGTH);
+ Line.color = Line.pattern = 0x0L;
+ Fill.color = 0x00c0c0c0;
+ Fill.color2 = 0x00ffffff;
+ Fill.hatch = 0L;
+ Fill.type = FILL_LIGHT3D;
+ if(name) {
+ sprintf(TmpTxt, "FitFunc3D (Plot %d)", cPlots);
+ free(name); name=strdup(TmpTxt);
+ }
+ return true;
+ case FILE_READ:
+ rot_vec.fx = 0.919384; rot_vec.fy = 0.389104; rot_vec.fz = -0.057709;
+ rot_ang.fx = 0.327146; rot_ang.fy = 0.944974; rot_ang.fz = 0.055026;
+ ExecInput(Desc);
+ RotDef[0] = rot_vec.fx; RotDef[1] = rot_vec.fy; RotDef[2] = rot_vec.fz;
+ RotDef[3] = rot_ang.fx; RotDef[4] = rot_ang.fy; RotDef[5] = rot_ang.fz;
+ return true;
+ case FILE_WRITE:
+ rot_vec.fx = RotDef[0]; rot_vec.fy = RotDef[1]; rot_vec.fz = RotDef[2];
+ rot_ang.fx = RotDef[3]; rot_ang.fy = RotDef[4]; rot_ang.fz = RotDef[5];
+ //do all plots
+ for(i = 0; plots && i< nPlots; i++) if(plots[i]) plots[i]->FileIO(rw);
+ //do all axes
+ if(Axes) for(i = 0; i< nAxes; i++) if(Axes[i]) Axes[i]->FileIO(rw);
+ ExecOutput(Notary->RegisterGO(this), "FitFunc3D", Desc);
+ }
+ return false;
+}
void
Graph::RegGO(void *n)
@@ -3365,10 +3480,8 @@ Graph::FileIO(int rw)
ixax = iyax = -1;
switch(rw) {
case INIT_VARS:
- InitVarsGO(Desc);
- units = defs.cUnits = defs.dUnits;
- OwnDisp = false;
- dirty = true;
+ InitVarsGO(Desc); units = defs.cUnits = defs.dUnits;
+ OwnDisp = false; dirty = true;
GRect.Ymin = defs.GetSize(SIZE_GRECT_TOP); GRect.Ymax = defs.GetSize(SIZE_GRECT_BOTTOM);
GRect.Xmin = defs.GetSize(SIZE_GRECT_LEFT); GRect.Xmax = defs.GetSize(SIZE_GRECT_RIGHT);
DRect.Ymin = defs.GetSize(SIZE_DRECT_TOP); DRect.Ymax = defs.GetSize(SIZE_DRECT_BOTTOM);
@@ -3376,16 +3489,14 @@ Graph::FileIO(int rw)
ColGR = defs.Color(COL_GRECT); ColGRL = defs.Color(COL_GRECTLINE);
ColDR = defs.Color(COL_DRECT); ColBG = defs.Color(COL_BG);
ColAX = defs.Color(COL_AXIS);
- x_axis.max = y_axis.max = 1.0;
- x_axis.owner = y_axis.owner = (void *)this;
+ x_axis.max = y_axis.max = 1.0; x_axis.owner = y_axis.owner = (void *)this;
rcDim.left = rcDim.right = rcDim.top = rcDim.bottom = 0;
rcUpd.left = rcUpd.right = rcUpd.top = rcUpd.bottom = 0;
CurrGO = 0L; Disp = 0L; Sc_Plots = 0L;
AxisTempl = 0; nscp = 0; CurrDisp = 0L;
- ToolMode = TM_STANDARD;
- zoom_def = 0L; tl_pts = 0L; tl_nPts = 0;
- tickstyle = zoom_level = 0;
- frm_g = frm_d = 0L; filename = 0L;
+ ToolMode = TM_STANDARD; zoom_def = 0L;
+ tl_pts = 0L; tl_nPts = 0; tickstyle = zoom_level = 0;
+ frm_g = frm_d = 0L; PasteObj = 0L; filename = 0L;
rc_mrk.left = rc_mrk.right = rc_mrk.top = rc_mrk.bottom = -1;
return true;
case FILE_READ:
@@ -3469,7 +3580,10 @@ DefsRW::FileIO(int rw)
{"dUnits", typINT, &defs.dUnits, 0L},
{"cUnits", typINT, &defs.dUnits, 0L},
{"dtHeight", typINT, &dlgtxtheight, 0L},
- {"ss_txt", typLFLOAT, &defs.ss_txt, 0L},
+ {"ss_txt", typLFLOAT, &defs.ss_txt, 0L},
+ {"fmt_date", typTEXT, &defs.fmt_date, 0L},
+ {"fmt_datetime", typTEXT, &defs.fmt_datetime, 0L},
+ {"fmt_time", typTEXT, &defs.fmt_time, 0L},
{"File1", typTEXT, &defs.File1, 0L},
{"File2", typTEXT, &defs.File2, 0L},
{"File3", typTEXT, &defs.File3, 0L},
diff --git a/ODbuttons.cpp b/ODbuttons.cpp
index 7a22b70..e328796 100755
--- a/ODbuttons.cpp
+++ b/ODbuttons.cpp
@@ -1,4 +1,4 @@
-//ODbuttons.cpp, Copyright (c) 2001, 2002, 2003, 2004 R.Lackner
+//ODbuttons.cpp, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
//Property dialogs for graphic objects
//
// This file is part of RLPlot.
@@ -27,6 +27,7 @@
extern int ODtickstyle;
extern int AxisTempl3D;
+extern Default defs;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Common code to modify drawing order in any dialog
@@ -650,7 +651,7 @@ void OD_PlotTempl(int cmd, void *par, RECT *rec, anyOutput *o,
iy = (rec->top +rec->bottom)>>1;
switch(id) {
case 560: case 561: case 562: case 563: case 564: //3D axes
- case 565:
+ case 565: case 566:
OD_AxisTempl3D(cmd, par, rec, o, data, 410+AxisTempl3D);
break;
default:
@@ -859,7 +860,7 @@ void OD_PlotTempl(int cmd, void *par, RECT *rec, anyOutput *o,
memcpy(&otd, &o->TxtSet, sizeof(TextDEF));
td.Align = TXA_HLEFT | TXA_VCENTER;
td.Style = TXS_BOLD; td.Mode = TXM_TRANSPARENT;
- td.fSize = 7.0; td.iSize = 0;
+ td.fSize = defs.GetSize(SIZE_TEXT)*1.75; td.iSize = 0;
td.ColTxt = cmd == OD_DRAWSELECTED ? 0x0000f0f0L : 0x00c00000;
o->SetTextSpec(&td);
o->oTextOut(ix-2, iy+3, "?", 0);
@@ -1081,7 +1082,7 @@ void OD_PlotTempl(int cmd, void *par, RECT *rec, anyOutput *o,
pts[4].x = pts[0].x; pts[4].y = pts[0].y;
o->oPolygon(pts, 5, 0L);
break;
- case 565:
+ case 565: case 566:
o->SetLine(&rLine);
pts[0].x = ix-16; pts[0].y = iy-2;
pts[1].x = ix+4; pts[1].y = iy+6;
@@ -1100,11 +1101,20 @@ void OD_PlotTempl(int cmd, void *par, RECT *rec, anyOutput *o,
memcpy(&td, &o->TxtSet, sizeof(TextDEF));
memcpy(&otd, &o->TxtSet, sizeof(TextDEF));
td.Align = TXA_HCENTER | TXA_VTOP;
- td.Style = TXS_NORMAL;
td.Mode = TXM_TRANSPARENT;
- td.ColTxt = 0x00c00000L;
- o->SetTextSpec(&td);
- o->oTextOut(ix, iy+4, "f(x,z)", 0);
+ if(id == 565) {
+ td.Style = TXS_NORMAL;
+ td.ColTxt = 0x00c00000L;
+ o->SetTextSpec(&td);
+ o->oTextOut(ix, iy+4, "f(x,z)", 0);
+ }
+ else {
+ td.Style = TXS_BOLD;
+ td.fSize = defs.GetSize(SIZE_TEXT)*1.75; td.iSize = 0;
+ td.ColTxt = cmd == OD_DRAWSELECTED ? 0x0000cb00L : 0x00cb00c0L;
+ o->SetTextSpec(&td);
+ o->oTextOut(ix-10, iy-6, "?", 0);
+ }
o->SetTextSpec(&otd);
break;
}
diff --git a/Output.cpp b/Output.cpp
index 54d6576..6ee7048 100755
--- a/Output.cpp
+++ b/Output.cpp
@@ -1,4 +1,4 @@
-//Output.cpp, Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005 R.Lackner
+//Output.cpp, Copyright (c) 2000-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -407,6 +407,7 @@ anyOutput::HideMark()
}
else CurrGraph->Command(CMD_REDRAW, 0L, this);
}
+ else ((GraphObj*)MrkRect)->DoMark(this, false);
return true;
case MRK_SSB_DRAW:
MrkMode = MRK_NONE;
@@ -639,7 +640,7 @@ anyOutput::oGetTextExtent(char *text, int cb, int *width, int *height)
}
if(!cb && text) cb = strlen(text);
for(i = w = 0; i < cb; i++) w += CharWidth[text[i]];
- *width = (w * TxtSet.iSize)>>6;
+ *width = iround(((double)w * (double)TxtSet.iSize)/52.0);
*height = TxtSet.iSize;
return true;
}
@@ -825,7 +826,7 @@ HatchOut::oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam)
v[0] = 0.0; v[1] = 1.0; v[2] = 0.0;
for (i = 0; i < 3; i++) for(j = 0, vec[i] = 0.0; j < 3; j++)
vec[i] += (light_vec[i][j] * v[j]);
- circ_grad.cx = cx - iround(vec[0]*((double)r));
+ circ_grad.cx = cx + iround(vec[0]*((double)r));
circ_grad.cy = cy - iround(vec[2]*((double)r));
circ_grad.r = r;
if(pts && cp) return oPolygon(pts, cp, nam);
@@ -924,12 +925,14 @@ HatchOut::DoHatch()
case FILL_WAVES1: Arcs(FILL_WAVES1); break;
case FILL_SCALES: Arcs(FILL_SCALES); break;
case FILL_SHINGLES: Arcs(FILL_SHINGLES); break;
- case FILL_WAVES2: Waves2(); break;
+ case FILL_WAVES2: Waves2(0); break;
case FILL_HERRING: Herringbone(); break;
case FILL_CIRCLES: Circles(); break;
case FILL_GRASS: Grass(); break;
case FILL_FOAM: Foam(); break;
case FILL_RECS: Recs(); break;
+ case FILL_HASH: Hash(); break;
+ case FILL_WATER: Waves2(1); break;
case FILL_LIGHT3D: CircGrad(); break;
}
@@ -1504,7 +1507,7 @@ HatchOut::Arcs(int type)
iy = iround(ybase*.8); ix = iround(xbase*.8);
}
if(iy < 2) iy = 2; if(ix < 2) ix = 2;
- UseRect.right += ix; UseRect.top -= 2*iy; UseRect.bottom += 2*iy;
+ UseRect.right += ix; UseRect.top -= (iy<<1); UseRect.bottom += (iy<<1);
for(i = UseRect.top, level = 0; i < UseRect.bottom; i+= iy, level++) {
if(type == FILL_WAVES1) {
HatchArc(UseRect.left, i, ix, 0, true);
@@ -1528,26 +1531,45 @@ HatchOut::Arcs(int type)
}
void
-HatchOut::Waves2() //hatch using sine waves
+HatchOut::Waves2(int type) //hatch using sine waves
{
- int i, j, y, ix, yinc, *pts;
+ int i, j, level, y, ix, yinc, *pts;
POINT Line[2];
double dtmp;
- if(3>(yinc = iround(ybase*.8)))yinc = 3; if(14>(ix = iround(xbase*2.5)))ix = 14;
+ if(3>(yinc = iround(type?ybase*.8 : ybase*1.2)))yinc = 3;
+ if(type == 0 && 14>(ix = iround(xbase*2.5)))ix = 14;
+ else if(type == 1 && 7>(ix = iround(xbase*1.2)))ix = 7;
if(!(pts = (int *)malloc(ix * sizeof(int))))return;
for(i = 0; i < ix; i++) {
dtmp = sin(6.283185307/((double)ix/(double)i));
+ if(type == 1) dtmp /= 2.0;
pts[i] = dtmp > 0.0 ? iround(0.3*ybase*dtmp) : iround(0.3*ybase*dtmp);
}
- for(y = UseRect.top; y <= UseRect.bottom + yinc; y += yinc){
- Line[0].x = UseRect.left; Line[1].x = UseRect.left+1;
- Line[0].y = y; Line[1].y = y+pts[1];
- for(j = 2; Line[0].x < UseRect.right+1; j++) {
+ UseRect.bottom += yinc; UseRect.right++;
+ for(y = UseRect.top, level = 0; y <= UseRect.bottom; y += yinc, level++){
+ Line[0].x = UseRect.left; Line[1].x = UseRect.left+1;
+ Line[0].y = y; Line[1].y = y+pts[1];
+ if(type == 0) for(j = 2; Line[0].x < UseRect.right; j++) {
HatchLine(Line[0], Line[1]);
Line[0].x = Line[1].x; Line[1].x++;
Line[0].y = Line[1].y; Line[1].y = y + pts[j%ix];
}
+ else if(type == 1) {
+ if(level & 1) {
+ Line[0].x += (ix + (ix>>1)); Line[1].x = Line[0].x +1;
+ }
+ for(j = 2; Line[0].x < UseRect.right; j++){
+ HatchLine(Line[0], Line[1]);
+ Line[0].x = Line[1].x;
+ Line[0].y = Line[1].y; Line[1].y = y + pts[j%ix];
+ if((j-1) % ix) Line[1].x++;
+ else {
+ HatchLine(Line[0], Line[1]);
+ Line[1].x += (ix << 1); Line[0].x = Line[1].x -1;
+ }
+ }
+ }
}
free(pts);
}
@@ -1660,13 +1682,49 @@ HatchOut::Recs()
}
void
+HatchOut::Hash()
+{
+ int i, dh, dw, cx, cy, xinc, yinc;
+ double xsize, ysize, mix, miy;
+ long idum = -1;
+ POINT Line[5];
+
+ xsize = xbase * 0.9; ysize = ybase * 0.9;
+ xinc = iround(xsize * 3.3); yinc = iround(ysize * 2.2);
+ mix = xbase *.5; miy = ybase *.5;
+ dw = iround(xbase > 5 ? xbase/2.0 : 2.0); dh = iround(ybase > 5 ? xbase/2.0 : 2.0);
+ if(xsize < 2.0) xsize = 2.0; if(ysize < 2.0) ysize = 2.0;
+ IncrementMinMaxRect(&UseRect, (int)xsize);
+ for(i = 0, cy = UseRect.top; cy < UseRect.bottom; i++, cy += yinc) {
+ for(cx = (i & 1) ? UseRect.left:UseRect.left+xinc/2; cx < UseRect.right; cx += xinc) {
+ Line[0].x = Line[1].x = cx;
+ Line[0].y = cy - iround(ran2(&idum) * ysize + miy);
+ Line[1].y = cy + iround(ran2(&idum) * ysize + miy);
+ HatchLine(Line[0], Line[1]);
+ Line[0].x = Line[1].x = cx + dw;
+ Line[0].y = cy - iround(ran2(&idum) * ysize + miy);
+ Line[1].y = cy + iround(ran2(&idum) * ysize + miy);
+ HatchLine(Line[0], Line[1]);
+ Line[0].y = Line[1].y = cy;
+ Line[0].x = cx - iround(ran2(&idum) * xsize + mix);
+ Line[1].x = cx + iround(ran2(&idum) * xsize + mix);
+ HatchLine(Line[0], Line[1]);
+ Line[0].y = Line[1].y = cy + dh;
+ Line[0].x = cx - iround(ran2(&idum) * xsize + mix);
+ Line[1].x = cx + iround(ran2(&idum) * xsize + mix);
+ HatchLine(Line[0], Line[1]);
+ }
+ }
+}
+
+void
HatchOut::CircGrad()
{
int i;
double f;
LineDEF ld = {0.0, 1.0, 0x0, 0x0};
- for(i = 1; i < this->circ_grad.r; i++) {
+ for(i = 1; i < circ_grad.r; i++) {
f = (((double)i)/((double)circ_grad.r));
f = f*f;
ld.color = IpolCol(dFillCol, dFillCol2, f);
diff --git a/PlotObs.cpp b/PlotObs.cpp
index 2af0276..9a8324b 100755
--- a/PlotObs.cpp
+++ b/PlotObs.cpp
@@ -1,4 +1,4 @@
-//PlotObs.cpp, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
+//PlotObs.cpp, Copyright (c) 2001-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -422,6 +422,8 @@ PlotScatt::Command(int cmd, void *tmpl, anyOutput *o)
if(TheLine && TheLine->Id == GO_DATAPOLYGON) TheLine->Command(cmd, tmpl, o);
}
else if(TheLine) TheLine->Command(cmd, tmpl, o);
+ if(Errors) for (i = 0; i < nPoints; i++)
+ if(Errors[i]) Errors[i]->Command(cmd, tmpl, o);
break;
case CMD_MRK_DIRTY:
dirty = true;
@@ -488,7 +490,7 @@ PlotScatt::Command(int cmd, void *tmpl, anyOutput *o)
if(DropLines) for(i = 0; i < nPoints; i++)
if(DropLines[i]) DropLines[i]->Command(cmd, tmpl, o);
return true;
- case CMD_ERR_TYPE: case CMD_WHISKER_STYLE:
+ case CMD_ERR_TYPE: case CMD_WHISKER_STYLE: case CMD_ERRDESC:
if(Errors) for(i = 0; i < nPoints; i++) {
if(Errors[i]) Errors[i]->Command(cmd, tmpl, o);
}
@@ -803,12 +805,7 @@ xyStat::CreateData()
switch(type & 0x1f00) {
case 0x0100: case 0x0200: case 0x1000: //SD, SEM, conf. int.
if(ny[i] > 1) {
- y = d_amean(ny[i], ay[i]);
- for(k = 0, ss = 0.0; k < (ny[i]); k++) {
- ss += ((d=ay[i][k]-y)*d);
- ny[i] = ny[i];
- }
- ss = ss/(double)(ny[i]-1);
+ ss = d_variance(ny[i], ay[i], &y);
switch(type & 0x1f00) {
case 0x0100:
curr_data->SetValue(i, 2, sqrt(ss));
@@ -1082,7 +1079,7 @@ FreqDist::ProcData(int sel)
cb += sprintf(fo+cb,"f_xy=\"A=%g; SD=%g; M=%g\\n", nv*step, sd, mean);
cb += sprintf(fo+cb,"ex=(x-M)/SD; ex=-0.5*ex*ex\\n");
cb += sprintf(fo+cb,"y=(A/(SD*2.5066283))*exp(ex)\\n\"\n");
- OpenGraph(this, 0L, (unsigned char *)fo);
+ OpenGraph(this, 0L, (unsigned char *)fo, false);
free(fo);
}
}
@@ -1662,12 +1659,10 @@ PolarPlot::Command(int cmd, void *tmpl, anyOutput *o)
return ReplaceGO(&Axes[i], tmpPlots);
}
break;
- case CMD_SETSCROLL:
- case CMD_REDRAW:
+ case CMD_SETSCROLL: case CMD_REDRAW:
if(parent) return parent->Command(cmd, tmpl, o);
return false;
- case CMD_DELOBJ_CONT:
- case CMD_DELOBJ:
+ case CMD_DELOBJ_CONT: case CMD_DELOBJ:
if(Plots && nPlots) for(i = 0; i < nPlots; i++) if(tmpl == (void*)Plots[i]) {
Undo.DeleteGO((GraphObj**)(&Plots[i]), cmd == CMD_DELOBJ_CONT ? UNDO_CONTINUE : 0L, o);
if(parent)parent->Command(CMD_REDRAW, NULL, o);
@@ -1735,12 +1730,10 @@ BoxPlot::BoxPlot(GraphObj *par, DataObj *dt, int mode, int c1, int c2, int c3):P
Bounds.Xmin = Bounds.Ymin = HUGE_VAL;
Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
if(Boxes = (Box**)calloc(nr, sizeof(Box*))) for(i = 0; i < nr; i++) {
- if(mode == 1) Boxes[i] = new Box(this, data, fp, fp, 0, c1, i, c2, i, c1, i, c3, i);
- else Boxes[i] = new Box(this, data, fp, fp, 0, c2, i, c1, i, c3, i, c1, i);
- if(Boxes[i]) Boxes[i]->Command(CMD_AUTOSCALE, 0L, 0L);
+ if(mode == 1) Boxes[i] = new Box(this, data, fp, fp, BAR_RELWIDTH, c1, i, c2, i, c1, i, c3, i);
+ else Boxes[i] = new Box(this, data, fp, fp, BAR_RELWIDTH, c2, i, c1, i, c3, i, c1, i);
}
}
- BoxDist.fx = BoxDist.fy = GetSize(mode == 2 ? SIZE_BOXMINY : SIZE_BOXMINX);
}
BoxPlot::~BoxPlot()
@@ -1882,7 +1875,6 @@ BoxPlot::Command(int cmd, void *tmpl, anyOutput *o)
return false;
case CMD_LEGEND:
if(((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
- if(Boxes) for (i = 0; i < nPoints; i++) if(Boxes[i]) Boxes[i]->Command(cmd, tmpl, o);
if(Symbols) {
if(TheLine && TheLine->Id == GO_DATALINE) {
for (i = 0; i < nPoints && i < 100; i++)
@@ -1895,6 +1887,8 @@ BoxPlot::Command(int cmd, void *tmpl, anyOutput *o)
if(TheLine && TheLine->Id == GO_DATAPOLYGON) TheLine->Command(cmd, tmpl, o);
}
else if(TheLine) TheLine->Command(cmd, tmpl, o);
+ if(Boxes) for (i = 0; i < nPoints; i++) if(Boxes[i]) Boxes[i]->Command(cmd, tmpl, o);
+ if(Whiskers) for (i = 0; i < nPoints; i++) if(Whiskers[i]) Whiskers[i]->Command(cmd, tmpl, o);
break;
case CMD_SET_DATAOBJ:
Id = GO_BOXPLOT; data = (DataObj *)tmpl; dirty = true;
@@ -1975,7 +1969,7 @@ BoxPlot::Command(int cmd, void *tmpl, anyOutput *o)
if(Boxes) for (i = 0; i < nPoints; i++)
if(Boxes[i]) Boxes[i]->Command(cmd, tmpl, o);
return true;
- case CMD_WHISKER_STYLE:
+ case CMD_WHISKER_STYLE: case CMD_ERRDESC:
if(Whiskers) for (i = 0; i < nPoints; i++)
if(Whiskers[i]) Whiskers[i]->Command(cmd, tmpl, o);
return true;
@@ -2129,12 +2123,7 @@ BoxPlot::CreateData()
|| (type & 0x0f0f) == 0x0201 || (type & 0x0f0f) == 0x0501) for(i = 0; i < j; i++) {
// set SD, SE, Conf. Intervall
if(ny[i] > 1) {
- y = d_amean(ny[i], ay[i]);
- for(k = 0, ss = 0.0; k < (ny[i]); k++) {
- ss += ((d=ay[i][k]-y)*d);
- ny[i] = ny[i];
- }
- ss = sqrt(ss/(double)(ny[i]-1));
+ ss = sqrt(d_variance(ny[i], ay[i], &y));
}
else {
y = *ay[i]; ss = 0.0;
@@ -2483,8 +2472,7 @@ StackBar::SetSize(int select, double value)
if(xyPlots) for(i = 0; i < numXY; i++)
if(xyPlots[i]) xyPlots[i]->SetSize(select, value);
return true;
- case SIZE_BOX:
- case SIZE_BOX_LINE:
+ case SIZE_BOX: case SIZE_BOX_LINE:
if(Boxes) for(i = 0; i < numPlots; i++)
if(Boxes[i]) Boxes[i]->SetSize(select, value);
return true;
@@ -3709,7 +3697,7 @@ Grid3D::DoPlot(anyOutput *o)
{
int i;
- if(!lines && !planes) CreateObs();
+ if(!lines && !planes) CreateObs(false);
if(lines) for(i = 0; i < nLines; i++) if(lines[i]) lines[i]->DoPlot(o);
if(planes) for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->DoPlot(o);
dirty = false;
@@ -3752,6 +3740,8 @@ Grid3D::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_LEGEND:
if(!hidden) ((Legend*)tmpl)->HasFill(&Line, planes ? &Fill : 0L);
break;
+ case CMD_CONFIG:
+ return Configure();
case CMD_MRK_DIRTY:
dirty = true;
case CMD_SET_GO3D: case CMD_SETSCROLL: case CMD_REDRAW:
@@ -3766,7 +3756,7 @@ Grid3D::Command(int cmd, void *tmpl, anyOutput *o)
if(planes) for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->Command(cmd, tmpl, o);
return dirty = true;
case CMD_AUTOSCALE:
- if(!lines && !planes) CreateObs();
+ if(!lines && !planes) CreateObs(false);
if(dirty) {
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
@@ -3800,7 +3790,7 @@ Grid3D::Command(int cmd, void *tmpl, anyOutput *o)
}
void
-Grid3D::CreateObs()
+Grid3D::CreateObs(bool set_undo)
{
int i, ir, ic, idx, w, h;
fPOINT3D *vec;
@@ -3866,6 +3856,10 @@ Grid3D::CreateObs()
SetSize(SIZE_SYM_LINE, Line.width); SetColor(COL_POLYLINE, Line.color);
free(vec);
}
+ if(set_undo) {
+ if(planes && nPlanes)Undo.StoreListGO(parent, (GraphObj***)&planes, &nPlanes, UNDO_CONTINUE);
+ if(lines && nLines)Undo.StoreListGO(parent, (GraphObj***)&lines, &nLines, UNDO_CONTINUE);
+ }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -4044,21 +4038,10 @@ Function::Update(anyOutput *o, DWORD flags)
// Calculate and display a user defined function
FitFunc::FitFunc(GraphObj *par, DataObj *d):Plot(par, d)
{
- int width, height;
-
FileIO(INIT_VARS);
x1 = 0.0; x2 = 100.0; xstep = 0.5; dl = 0L;
cmdxy = strdup("a+b*x^c");
parxy = strdup("a=1; b=1; c=0.1;");
- data->GetSize(&width, &height);
- if(!ssXref) {
- sprintf(TmpTxt, "a1:a%d", height);
- ssXref = strdup(TmpTxt);
- }
- if(!ssYref) {
- sprintf(TmpTxt, "b1:b%d", height);
- ssYref = strdup(TmpTxt);
- }
Id = GO_FITFUNC;
}
@@ -4126,7 +4109,18 @@ FitFunc::DoPlot(anyOutput *o)
if(!data || x1 >= x2) return;
dirty = false;
- if(dl && o) dl->DoPlot(o);
+ if(!dl && (dl = new Function(this, data))) {
+ dl->SetSize(SIZE_MIN_X, x1); dl->SetSize(SIZE_MAX_X, x2);
+ dl->SetSize(SIZE_XSTEP, xstep); dl->Command(CMD_SETFUNC, cmdxy, 0L);
+ dl->Command(CMD_SETPARAM, parxy, 0L); dl->Command(CMD_SET_LINE, &Line, 0L);
+ dl->Update(o, UNDO_CONTINUE);
+ }
+ if(dl && o) {
+ dl->SetSize(SIZE_MIN_X, x1); dl->SetSize(SIZE_MAX_X, x2);
+ dl->SetSize(SIZE_XSTEP, xstep); dl->Command(CMD_SETFUNC, cmdxy, 0L);
+ dl->Command(CMD_SETPARAM, parxy, 0L); dl->Command(CMD_SET_LINE, &Line, 0L);
+ dl->DoPlot(o);
+ }
if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->DoPlot(o);
}
@@ -4166,8 +4160,16 @@ FitFunc::Command(int cmd, void *tmpl, anyOutput *o)
return false;
case CMD_AUTOSCALE:
if(dirty) {
- if(dl) dl->Command(cmd, tmpl, o);
- memcpy(&Bounds, &dl->Bounds, sizeof(fRECT));
+ if(!dl && (dl = new Function(this, data))) {
+ dl->SetSize(SIZE_MIN_X, x1); dl->SetSize(SIZE_MAX_X, x2);
+ dl->SetSize(SIZE_XSTEP, xstep); dl->Command(CMD_SETFUNC, cmdxy, 0L);
+ dl->Command(CMD_SETPARAM, parxy, 0L); dl->Command(CMD_SET_LINE, &Line, 0L);
+ dl->Update(o, UNDO_CONTINUE);
+ }
+ if(dl) {
+ dl->Command(cmd, tmpl, o);
+ memcpy(&Bounds, &dl->Bounds, sizeof(fRECT));
+ }
if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i])Symbols[i]->Command(cmd, tmpl, o);
dirty = false;
}
@@ -4177,6 +4179,7 @@ FitFunc::Command(int cmd, void *tmpl, anyOutput *o)
SavVarObs((GraphObj**)Symbols, nPoints, UNDO_CONTINUE);
for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->Command(cmd, tmpl, o);
}
+ Undo.String(this, &parxy, UNDO_CONTINUE);
do_fitfunc(data, ssXref, ssYref, 0L, &parxy, cmdxy, conv, maxiter, &chi2);
if(!dl) dl = new Function(this, data);
if(dl){
@@ -4189,9 +4192,11 @@ FitFunc::Command(int cmd, void *tmpl, anyOutput *o)
if(parent) parent->Command(CMD_MRK_DIRTY, 0L, o);
return true;
case CMD_DELOBJ:
- if(parent && tmpl && tmpl == dl) return parent->Command(CMD_DELOBJ, this, o);
+ if(!parent) return false;
+ if(tmpl && tmpl == dl) return parent->Command(CMD_DELOBJ, this, o);
+ else if(DeleteGOL((GraphObj***)&Symbols,nPoints,(GraphObj*)tmpl,o)) return parent->Command(CMD_REDRAW,0L,o);
else if(dl) return dl->Command(cmd, tmpl, o);
- break;
+ return false;
case CMD_MRK_DIRTY:
dirty = true;
if(dl){
@@ -5040,6 +5045,7 @@ Func3D::Command(int cmd, void *tmpl, anyOutput *o)
return true;
case CMD_UPDATE:
return Update();
+ break;
}
return Plot3D::Command(cmd, tmpl, o);
}
@@ -5073,3 +5079,83 @@ Func3D::Update()
}
return false;
}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// fit 3D function to data
+FitFunc3D::FitFunc3D(GraphObj *par, DataObj *d)
+ :Plot3D(par, d, 0x0L)
+{
+ FileIO(INIT_VARS);
+ cmdxy = strdup("a+b*x^c");
+ param = strdup("a=1; b=1; c=0.1;");
+ Id = GO_FITFUNC3D;
+}
+
+FitFunc3D::FitFunc3D(int src):Plot3D(0)
+{
+ int i;
+
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ //now set parent in all children
+ if(Axes) for(i = 0; i < nAxes; i++)
+ if(Axes[i]) Axes[i]->parent = this;
+ if(plots) for(i = 0; i < nPlots; i++)
+ if(plots[i]) plots[i]->parent = this;
+ }
+}
+
+FitFunc3D::~FitFunc3D()
+{
+ if(param) free(param); param = 0L;
+ if(cmdxy) free(cmdxy); cmdxy = 0L;
+ if(gda) delete(gda); gda = 0L;
+ if(name) free(name); name=0L;
+}
+
+bool
+FitFunc3D::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ switch(cmd) {
+ case CMD_SET_DATAOBJ:
+ Plot3D::Command(cmd, tmpl, o);
+ if(gob && gda) gob->Command(cmd, gda, o);
+ Id = GO_FITFUNC3D;
+ return true;
+ case CMD_UPDATE:
+ return Update();
+ break;
+ }
+ return Plot3D::Command(cmd, tmpl, o);
+}
+
+bool
+FitFunc3D::Update()
+{
+ if(cmdxy) {
+ dirty = true;
+ if(xstep == 0.0) xstep = 1.0; if(zstep == 0.0) zstep = 1.0;
+ if(!gda) gda = new DataObj();
+ if(gda && do_func3D(gda, x1, x2, xstep, z1, z2, zstep, cmdxy, param)) {
+ if(gob = new Grid3D(this, gda, type, x1, xstep, z1, zstep)) {
+ gob->Command(CMD_SET_LINE, &Line, 0L);
+ gob->Command(CMD_SYM_FILL, &Fill, 0L);
+ if(!plots && (plots = (GraphObj**)calloc(3, sizeof(GraphObj*)))) {
+ nPlots = 1; plots[0] = (Plot *)gob;
+ if(parent->Id == GO_GRAPH) CreateAxes();
+ return dirty = parent->Command(CMD_REDRAW, 0L, 0L);
+ }
+ else if(plots && nPlots && plots[0]->Id == GO_GRID3D) {
+ Undo.DeleteGO(&plots[0], UNDO_CONTINUE, 0L);
+ Undo.SetGO(this, &plots[0], gob, UNDO_CONTINUE);
+ return true;
+ }
+ else {
+ DeleteGO(gob); gob=0L;
+ }
+ }
+ }
+ }
+ return false;
+}
diff --git a/PropertyDlg.cpp b/PropertyDlg.cpp
index 73d8eac..4d0147e 100755
--- a/PropertyDlg.cpp
+++ b/PropertyDlg.cpp
@@ -1,4 +1,4 @@
-//PropertyDlg.cpp, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
+//PropertyDlg.cpp, Copyright (c) 2001-2006 R.Lackner
//Property dialogs for graphic objects
//
// This file is part of RLPlot.
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <time.h>
#include "TheDialog.h"
extern tag_Units Units[];
@@ -1013,7 +1014,7 @@ ErrorBar::PropertyDlg()
{4, 0, 5, ISPARENT | CHECKED, GROUP, 0L, 138, 40, 55, 12},
{5, 6, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 90, 100},
{6, 7, 200, ISPARENT, SHEET, &tab2, 5, 10, 90, 100},
- {7, 0, 300, ISPARENT, SHEET, &tab3, 5, 10, 90, 100},
+ {7, 0, 300, TOUCHEXIT | ISPARENT, SHEET, &tab3, 5, 10, 90, 100},
{100, 101, 0, 0x0L, RTEXT, (void*)"cap width", 15, 40, 28, 8},
{101, 102, 0, 0x0L, EDVAL1, &SizeBar, 46, 40, 25, 10},
{102, 103, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 73, 40, 20, 8},
@@ -1023,12 +1024,14 @@ ErrorBar::PropertyDlg()
{106, 107, 0, 0x0L, RTEXT, (void*)"line color", 15, 70, 28, 8},
{107, 0, 0, OWNDIALOG, COLBUTTON, (void *)ErrLine.color, 46, 70, 25, 10},
{200, 0, 500, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
- {300, 301, 0, 0x0L, RTEXT, (void*)"x-value", 15, 40, 28, 8},
- {301, 302, 0, 0x0L, EDVAL1, &fPos.fx, 46, 40, 35, 10},
- {302, 303, 0, 0x0L, RTEXT, (void*)"y-value", 15, 55, 28, 8},
- {303, 304, 0, 0x0L, EDVAL1, &fPos.fy, 46, 55, 35, 10},
- {304, 305, 0, 0x0L, RTEXT, (void*)"error", 15, 70, 28, 8},
- {305, 0, 0, 0x0L, EDVAL1, &ferr, 46, 70, 35, 10},
+ {300, 301, 0, 0x0L, RTEXT, (void*)"x-value", 15, 30, 28, 8},
+ {301, 302, 0, 0x0L, EDVAL1, &fPos.fx, 46, 30, 35, 10},
+ {302, 303, 0, 0x0L, RTEXT, (void*)"y-value", 15, 45, 28, 8},
+ {303, 304, 0, 0x0L, EDVAL1, &fPos.fy, 46, 45, 35, 10},
+ {304, 305, 0, 0x0L, RTEXT, (void*)"error", 15, 60, 28, 8},
+ {305, 306, 0, 0x0L, EDVAL1, &ferr, 46, 60, 35, 10},
+ {306, 307, 0, 0x0L, LTEXT, (void*)"description:", 10, 80, 70, 8},
+ {307, 0, 0, 0x0L, EDTEXT, (void*)name, 10, 90, 80, 10},
{500, 501, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_ErrBarTempl), 12, 40, 25, 25},
{501, 502, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_ErrBarTempl), 37, 40, 25, 25},
{502, 503, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_ErrBarTempl), 62, 40, 25, 25},
@@ -1043,8 +1046,10 @@ ErrorBar::PropertyDlg()
DWORD n_col, undo_flags = 0L;
anyOutput *cdisp = Undo.cdisp;
bool bRet = false;
+ char desc[80];
if(!parent) return false;
+ desc[0] = 0;
if(!(Dlg = new DlgRoot(ErrDlg)))return false;
Dlg->SetCheck(500 + (type & 0x7), 0L, true);
if(!(Dlg->GetValue(101, &o_sb))) o_sb = SizeBar;
@@ -1062,12 +1067,12 @@ ErrorBar::PropertyDlg()
switch (res) {
case 500: case 501: case 502:
case 503: case 504: case 505:
- tmpType = res-500;
- res = -1;
- break;
+ tmpType = res-500; res = -1; break;
+ case 7: //edit tab
+ Dlg->Activate(307, true); res = -1; break;
case 1: //accept for this object
case 2: // or all objects of plot
- Undo.SetDisp(cdisp);
+ Undo.SetDisp(cdisp); Dlg->GetText(307, desc);
Dlg->GetValue(101, &n_sb); Dlg->GetValue(104, &n_lw);
Dlg->GetColor(107, &n_col); Dlg->GetValue(305, &n_err);
Dlg->GetValue(301, &n_pos.fx); Dlg->GetValue(303, &n_pos.fy);
@@ -1076,6 +1081,20 @@ ErrorBar::PropertyDlg()
}while (res <0);
switch (res) {
case 1: //new setting for current error bar only
+ if(desc[0] && name && name[0] && strcmp(desc, name)) {
+ Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, strlen(desc)+2);
+ strcpy(name, desc); undo_flags |= UNDO_CONTINUE;
+ }
+ else if(desc[0]) {
+ Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, strlen(desc)+2);
+ strcpy(name, desc); undo_flags |= UNDO_CONTINUE;
+ }
+ else if(name && name[0]) {
+ Undo.String(this, &name, undo_flags);
+ name[0] = 0; undo_flags |= UNDO_CONTINUE;
+ }
undo_flags = CheckNewFloat(&SizeBar, o_sb, n_sb, parent, undo_flags);
undo_flags = CheckNewFloat(&ErrLine.width, o_lw, n_lw, parent, undo_flags);
undo_flags = CheckNewDword(&ErrLine.color, ErrLine.color, n_col, parent, undo_flags);
@@ -1086,6 +1105,7 @@ ErrorBar::PropertyDlg()
break;
case 2: //new settings to all error bars of plot
parent->Command(CMD_SAVE_ERRS, 0L, 0L);
+ if(desc[0] || name) parent->Command(CMD_ERRDESC, desc, 0L);
parent->SetSize(SIZE_ERRBAR, n_sb);
parent->SetSize(SIZE_ERRBAR_LINE, n_lw);
parent->SetColor(COL_ERROR_LINE, n_col);
@@ -1388,41 +1408,49 @@ Box::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Whisker properties dialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *WhiskerDlgTmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,1,100,10,64,12\n"
+ "2,3,,,PUSHBUTTON,2,100,25,64,12\n"
+ "3,4,,,PUSHBUTTON,-2, 100, 40, 64, 12\n"
+ "4,,5,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "5,6,100,ISPARENT | CHECKED,SHEET,3, 5, 10, 90, 100\n"
+ "6,7,500,ISPARENT,SHEET,4,5,10,90,100\n"
+ "7,,300,ISPARENT,SHEET,5,5,10,90,100\n"
+ "100,101,,,RTEXT,6,15,40,28,8\n"
+ "101,102,,,EDVAL1,7,46,40,25,10\n"
+ "102,103,,,LTEXT,-3,73,40,20,8\n"
+ "103,104,,,RTEXT,8,15,55,28,8\n"
+ "104,105,,,EDVAL1,9,46,55,25,10\n"
+ "105,106,,,LTEXT,-3,73,55,20,8\n"
+ "106,107,,,RTEXT,10,15,70,28,8\n"
+ "107,,,OWNDIALOG,COLBUTT,11,46,70,25,10\n"
+ "300,301,,,RTEXT,12,15,30,28,8\n"
+ "301,302,,,EDVAL1,13,46,30,35,10\n"
+ "302,303,,,RTEXT,-5,15,42,28,8\n"
+ "303,304,,,EDVAL1,14,46,42,35,10\n"
+ "304,305,,,RTEXT,15,15,55,28,8\n"
+ "305,306,,,EDVAL1,16,46,55,35,10\n"
+ "306,307,,,RTEXT,-5,15,67,28,8\n"
+ "307,308,,,EDVAL1,17,46,67,35,10\n"
+ "308,309,,,LTEXT,18,10,85,70,8\n"
+ "309,,,,EDTEXT,19,10,95,80,10\n"
+ "500,501,,EXRADIO,ODBUTTON,20,32,40,18,18\n"
+ "501,502,,EXRADIO,ODBUTTON,20,14,40,18,18\n"
+ "502,503,,EXRADIO,ODBUTTON,20,50,40,18,18\n"
+ "503,504,,EXRADIO,ODBUTTON,20,68,40,18,18\n"
+ "504,,,LASTOBJ,LTEXT,21,14,30,30,9";
bool
Whisker::PropertyDlg()
{
TabSHEET tab1 = {0, 38, 10, "Whisker"};
TabSHEET tab2 = {65, 90, 10, "Edit"};
TabSHEET tab3 = {38, 65, 10, "Style"};
- DlgInfo ErrDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"Apply to WHISKER", 100, 10, 64, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Apply to PLOT", 100, 25, 64, 12},
- {3, 4, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 100, 40, 64, 12},
- {4, 0, 5, ISPARENT | CHECKED, GROUP, 0L, 138, 40, 55, 12},
- {5, 6, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 90, 100},
- {6, 7, 500, ISPARENT, SHEET, &tab3, 5, 10, 90, 100},
- {7, 0, 300, ISPARENT, SHEET, &tab2, 5, 10, 90, 100},
- {100, 101, 0, 0x0L, RTEXT, (void*)"cap width", 15, 40, 28, 8},
- {101, 102, 0, 0x0L, EDVAL1, &size, 46, 40, 25, 10},
- {102, 103, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 73, 40, 20, 8},
- {103, 104, 0, 0x0L, RTEXT, (void*)"line width", 15, 55, 28, 8},
- {104, 105, 0, 0x0L, EDVAL1, &LineDef.width, 46, 55, 25, 10},
- {105, 106, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 73, 55, 20, 8},
- {106, 107, 0, 0x0L, RTEXT, (void*)"line color", 15, 70, 28, 8},
- {107, 0, 0, OWNDIALOG, COLBUTTON, (void *)LineDef.color, 46, 70, 25, 10},
- {300, 301, 0, 0x0L, RTEXT, (void*)"point 1 x", 15, 40, 28, 8},
- {301, 302, 0, 0x0L, EDVAL1, &pos1.fx, 46, 40, 35, 10},
- {302, 303, 0, 0x0L, RTEXT, (void*)"y", 15, 52, 28, 8},
- {303, 304, 0, 0x0L, EDVAL1, &pos1.fy, 46, 52, 35, 10},
- {304, 305, 0, 0x0L, RTEXT, (void*)"point 2 x", 15, 70, 28, 8},
- {305, 306, 0, 0x0L, EDVAL1, &pos2.fx, 46, 70, 35, 10},
- {306, 307, 0, 0x0L, RTEXT, (void*)"y", 15, 82, 28, 8},
- {307, 0, 0, 0x0L, EDVAL1, &pos2.fy, 46, 82, 35, 10},
- {500, 501, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_WhiskerTempl),32,40,18,18},
- {501, 502, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_WhiskerTempl), 14, 40, 18, 18},
- {502, 503, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_WhiskerTempl), 50, 40, 18, 18},
- {503, 504, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_WhiskerTempl), 68, 40, 18, 18},
- {504, 0, 0, LASTOBJ, LTEXT, (void*)"select style:", 14, 30, 30, 9}};
+ void *dyndata[] = {(void*)"Apply to WHISKER", (void*)"Apply to PLOT", (void*)&tab1,
+ (void*)&tab3, (void*)&tab2, (void*)"cap width", (void*)&size, (void*)"line width",
+ (void*)&LineDef.width, (void*)"line color", (void *)&LineDef.color, (void*)"point 1 x",
+ (void*)&pos1.fx, (void*)&pos1.fy, (void*)"point 2 x", (void*)&pos2.fx, (void*)&pos2.fy,
+ (void*)"description:", (void*)name, (void*)(OD_WhiskerTempl), (void*)"select style:"};
+ DlgInfo *ErrDlg = CompileDialog(WhiskerDlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
int res, tmp_type;
@@ -1431,9 +1459,10 @@ Whisker::PropertyDlg()
lfPOINT n_pos;
double tmpVal, o_size, n_size, o_lw, n_lw;
bool bRet = false;
+ char desc[80];
if(!parent) return false;
- tmp_type = type;
+ desc[0] = 0; tmp_type = type;
Dlg = new DlgRoot(ErrDlg);
Dlg->SetCheck(500 + (tmp_type & 0x03), 0L, true);
Dlg->GetValue(101, &o_size); Dlg->GetValue(104, &o_lw);
@@ -1451,11 +1480,26 @@ Whisker::PropertyDlg()
case 2: // or all objects of plot
Undo.SetDisp(cdisp); Dlg->GetValue(101, &n_size);
Dlg->GetValue(104, &n_lw); Dlg->GetColor(107, &n_col);
+ Dlg->GetText(309, desc);
break;
}
}while (res <0);
switch (res) {
case 1: //new setting for current whisker
+ if(desc[0] && name && name[0] && strcmp(desc, name)) {
+ Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, strlen(desc)+2);
+ strcpy(name, desc); undo_flags |= UNDO_CONTINUE;
+ }
+ else if(desc[0]) {
+ Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, strlen(desc)+2);
+ strcpy(name, desc); undo_flags |= UNDO_CONTINUE;
+ }
+ else if(name && name[0]) {
+ Undo.String(this, &name, undo_flags);
+ name[0] = 0; undo_flags |= UNDO_CONTINUE;
+ }
if(Dlg->GetValue(301, &tmpVal)) n_pos.fx = tmpVal;
else n_pos.fx = pos1.fx;
if(Dlg->GetValue(303, &tmpVal)) n_pos.fy = tmpVal;
@@ -1474,8 +1518,9 @@ Whisker::PropertyDlg()
break;
case 2: //new settings to all whiskers of plot
if(o_size == n_size && type == tmp_type && o_lw == n_lw
- && n_col == LineDef.color) break;
+ && n_col == LineDef.color && !desc[0] && !name) break;
parent->Command(CMD_SAVE_ERRS, 0L, 0L);
+ if(desc[0] || name) parent->Command(CMD_ERRDESC, desc, 0L);
parent->SetSize(SIZE_WHISKER, n_size);
parent->SetSize(SIZE_WHISKER_LINE, n_lw);
parent->SetColor(COL_WHISKER, n_col);
@@ -1483,8 +1528,7 @@ Whisker::PropertyDlg()
bRet = true;
break;
}
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(ErrDlg);
return bRet;
}
@@ -1812,6 +1856,7 @@ Plane3D::PropertyDlg()
double o_lsize, n_lsize, o_rbw, n_rbw, o_rbz, n_rbz;
if(!parent) return false;
+ if(parent->Id == GO_GRID3D) return parent->PropertyDlg();
memcpy(&newFill, &Fill, sizeof(FillDEF));
if(parent->Id == GO_RIBBON && parent->type == 1) {
rb_width = parent->GetSize(SIZE_CELLWIDTH) *100.0;
@@ -2125,6 +2170,7 @@ Line3D::PropertyDlg()
anyOutput *cdisp = Undo.cdisp;
if(!parent) return false;
+ if(parent->Id == GO_GRID3D) return parent->PropertyDlg();
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
if(!(Dlg = new DlgRoot(LineDlg)))return false;
sprintf(TmpTxt, "Line of %s", parent->name);
@@ -2954,10 +3000,10 @@ PlotScatt::PropertyDlg()
{1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 140, 10, 45, 12},
{2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 140, 25, 45, 12},
{3, 0, 4, ISPARENT | CHECKED, GROUP, 0L, 138, 40, 55, 12},
- {4, 5, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 131, 100},
+ {4, 5, 100, TOUCHEXIT | ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 131, 100},
{5, 6, 200, TOUCHEXIT | ISPARENT, SHEET, &tab2, 5, 10, 131, 100},
- {6, 7, 300, ISPARENT, SHEET, &tab3, 5, 10, 131, 100},
- {7, 10, 400, ISPARENT, SHEET, &tab4, 5, 10, 131, 100},
+ {6, 7, 300, TOUCHEXIT | ISPARENT, SHEET, &tab3, 5, 10, 131, 100},
+ {7, 10, 400, TOUCHEXIT | ISPARENT, SHEET, &tab4, 5, 10, 131, 100},
{10, 0, 0, CHECKED, CHECKPIN, 0L, 5, 0, 12, 8},
{100, 101, 0, 0x0L, LTEXT, (void*)"range for X Data", 10, 30, 60, 8},
{101, 102, 0, 0x0L, RANGEINPUT, text1, 20, 40, 100, 10},
@@ -2993,7 +3039,7 @@ PlotScatt::PropertyDlg()
DlgRoot *Dlg;
void *hDlg;
int c, i, j, k, l, i1, j1, k1, l1, m, n, o, p, ic;
- int ErrType = 0, res, width, height, BarType;
+ int ErrType = 0, res, BarType;
double x, y, e;
lfPOINT fp1, fp2;
bool bRet = false, bLayout = false, bContinue = false;
@@ -3003,24 +3049,18 @@ PlotScatt::PropertyDlg()
if(!parent || !data) return false;
if(Id == GO_BARCHART) return CreateBarChart();
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
- sprintf(text3, "c1:c%d", height); sprintf(text4, "b1:b%d", height);
+ UseRangeMark(data, 1, text1, text2, text3, text4);
rX = rY = rE = rL = 0L;
if(!(Dlg = new DlgRoot(XYDlg)))return false;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data);
- Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
- Dlg->ItemCmd(304, CMD_SET_DATAOBJ, data);
- Dlg->ItemCmd(402, CMD_SET_DATAOBJ, data);
+ Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
+ Dlg->ItemCmd(304, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(402, CMD_SET_DATAOBJ, data);
#ifdef _WINDOWS
for(i = 104; i <= 107; i++) Dlg->TextSize(i, 12);
#else
for(i = 104; i <= 107; i++) Dlg->TextSize(i, 10);
#endif
- if(DefSel & 0x01)Dlg->SetCheck(200, 0L, true);
- if(DefSel & 0x02)Dlg->SetCheck(250, 0L, true);
- if(DefSel & 0x04)Dlg->SetCheck(255, 0L, true);
- if(DefSel & 0x08)Dlg->SetCheck(256, 0L, true);
+ if(DefSel & 0x01)Dlg->SetCheck(200, 0L, true); if(DefSel & 0x02)Dlg->SetCheck(250, 0L, true);
+ if(DefSel & 0x04)Dlg->SetCheck(255, 0L, true); if(DefSel & 0x08)Dlg->SetCheck(256, 0L, true);
hDlg = CreateDlgWnd("XY Plot properties", 50, 50, 388, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -3039,10 +3079,14 @@ PlotScatt::PropertyDlg()
Dlg->SetCheck(301, 0L, true);
res = -1;
break;
+ case 4: // the data tab sheet
+ Dlg->Activate(101, true); res = -1; break;
case 5: // the layout tab sheet
- bLayout = true;
- res = -1;
- break;
+ bLayout = true; res = -1; break;
+ case 6: // the error tab sheet
+ Dlg->Activate(304, true); res = -1; break;
+ case 7: // the label tab sheet
+ Dlg->Activate(402, true); res = -1; break;
case 1: // OK
if(rX) delete rX; if(rY) delete rY; if(rE) delete rE;
rX = rY = rE = 0L; // check x-range
@@ -3230,12 +3274,12 @@ xyStat::PropertyDlg()
int i, res, width, height;
double x, y, e, f, dx, dy;
lfPOINT fp1, fp2;
+ char errdesc[40];
TextDEF lbdef = {defs.Color(COL_TEXT), defs.Color(COL_BG), defs.GetSize(SIZE_TEXT), 0.0f, 0.0f, 0,
TXA_HLEFT | TXA_VBOTTOM, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, TmpTxt};
if(!parent || !data) return false;
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
+ UseRangeMark(data, 1, text1, text2);
if(!(Dlg = new DlgRoot(StatDlg)))return false;
Dlg->ItemCmd(102, CMD_SET_DATAOBJ, data);
Dlg->ItemCmd(104, CMD_SET_DATAOBJ, data);
@@ -3268,8 +3312,8 @@ xyStat::PropertyDlg()
if(Dlg->GetText(404, TmpTxt) && TmpTxt[0]) case_prefix = strdup(TmpTxt);
CreateData();
if(type && curr_data) {
- data->GetSize(&width, &height); nPoints = height;
- sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
+ curr_data->GetSize(&width, &height); nPoints = height;
+ sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
for(i= 0; i < height; i++) {
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 1, &y))
@@ -3291,12 +3335,24 @@ xyStat::PropertyDlg()
Bars[i] = new Bar(this, curr_data, x, y, BAR_VERTB | BAR_RELWIDTH, 0, i, 1, i);
}
}
- if(type & 0x1f00) Errors = (ErrorBar**)calloc(nPoints, sizeof(ErrorBar*));
+ if(type & 0x1f00) {
+ Errors = (ErrorBar**)calloc(nPoints, sizeof(ErrorBar*));
+ switch(type & 0x1f00) {
+ case 0x0100: strcpy(errdesc, "Std. Dev."); break;
+ case 0x0200: strcpy(errdesc, "Std. Err."); break;
+ case 0x0400: strcpy(errdesc, "25, 75% Perc."); break;
+ case 0x0800: strcpy(errdesc, "Min./Max."); break;
+ case 0x1000: sprintf(errdesc, "'%g%% CI", ci); break;
+ default: strcpy(errdesc, "error");
+ }
+ }
if((type & 0x1300) && Errors) {
for(i = 0; i < height; i++) {
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 1, &y)
- && curr_data->GetValue(i, 2, &e))
+ && curr_data->GetValue(i, 2, &e)) {
Errors[i]= new ErrorBar(this, curr_data, x, y, e, 0, 0, i, 1, i, 2, i);
+ if(Errors[i]) Errors[i]->Command(CMD_ERRDESC, errdesc, 0L);
+ }
}
}
if((type & 0x0c00) && Errors) {
@@ -3304,6 +3360,7 @@ xyStat::PropertyDlg()
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 2, &e) && curr_data->GetValue(i, 3, &f)){
fp1.fx = fp2.fx = x; fp1.fy = e; fp2.fy = f;
Errors[i]= (ErrorBar*)new Whisker(this, curr_data, fp1, fp2, 0, 0, i, 2, i, 0, i, 3, i);
+ if(Errors[i]) Errors[i]->Command(CMD_ERRDESC, errdesc, 0L);
}
}
}
@@ -3318,7 +3375,7 @@ xyStat::PropertyDlg()
dx = -dy;
}
for(i = 0; i < height; i++) {
- if(curr_data->GetValue(i, 0, &x) && curr_data->GetText(i, 5, TmpTxt, TMP_TXT_SIZE)){
+ if(curr_data->GetValue(i, 0, &x) && curr_data->GetText(i, 5, TmpTxt, TMP_TXT_SIZE, false)){
if((type & 0x2000) && curr_data->GetValue(i, 4, &y))
Labels[i] = new Label(this, curr_data, x, y, &lbdef,
LB_X_DATA | LB_Y_DATA, 0, i, 4, i, 5, i);
@@ -3450,7 +3507,7 @@ Regression::PropertyDlg()
{214, 0, 0, LASTOBJ, RADIO1, (void*)"y = sqrt(y)", 82, 64, 30, 8}};
DlgRoot *Dlg;
void *hDlg;
- int c, i, j, k, l, ic, res, width, height, n;
+ int c, i, j, k, l, ic, res, n;
double x, y;
AccRange *rX, *rY;
bool bRet = false, bContinue = false, dValid;
@@ -3458,9 +3515,7 @@ Regression::PropertyDlg()
if(!parent || !data) return false;
rX = rY = 0L;
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height);
- sprintf(text2, "b1:b%d", height);
+ UseRangeMark(data, 1, text1, text2);
if(!(Dlg = new DlgRoot(RegDlg)))return false;
Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd("Linear regression analysis step 1/2", 50, 50, 380, 225, Dlg, 0x0L);
@@ -3617,7 +3672,7 @@ BubblePlot::PropertyDlg()
{412, 0, 0, LASTOBJ, RADIO1, (void*)"area", 40, 105, 45, 8}};
DlgRoot *Dlg;
void *hDlg;
- int i, j, k, l, m, n, ic, res, width, height, BubbleType;
+ int i, j, k, l, m, n, ic, res, BubbleType;
double x, y, s;
double tmp;
bool bRetVal = false, bFillChanged, bContinue = false;
@@ -3625,10 +3680,7 @@ BubblePlot::PropertyDlg()
LineDEF ShowFillLine ={0.2f, 1.0f, 0x0L, 0x0L};
if(!parent || !data) return false;
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height);
- sprintf(text2, "b1:b%d", height);
- sprintf(text3, "c1:c%d", height);
+ UseRangeMark(data, 1, text1, text2, text3);
memcpy(&ShowFill, &BubbleFill, sizeof(FillDEF));
if(BubbleFill.hatch) memcpy(&ShowFillLine, BubbleFill.hatch, sizeof(LineDEF));
ShowFill.hatch = &ShowFillLine;
@@ -3896,7 +3948,7 @@ PolarPlot::PropertyDlg()
{213, 0, 0, LASTOBJ, RANGEINPUT, (void*)text2, 20, 92, 100, 10}};
DlgRoot *Dlg;
void *hDlg;
- int res, width, height, i, j, k, l, n, ic, cType = 200;
+ int res, i, j, k, l, n, ic, cType = 200;
double x, y;
bool bRet = false, bType = false;
AccRange *rX = 0L, *rY = 0L;
@@ -3910,9 +3962,7 @@ PolarPlot::PropertyDlg()
frad = (parent->GetSize(SIZE_DRECT_BOTTOM) - parent->GetSize(SIZE_DRECT_TOP))/2.0f;
fcx = parent->GetSize(SIZE_GRECT_LEFT) + parent->GetSize(SIZE_DRECT_LEFT)*1.5 + frad;
fcy = parent->GetSize(SIZE_GRECT_TOP) + parent->GetSize(SIZE_DRECT_TOP) + frad;
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height);
- sprintf(text2, "b1:b%d", height);
+ UseRangeMark(data, 1, text1, text2);
tlbdef.ColTxt = defs.Color(COL_AXIS);
tlbdef.ColBg = 0x00ffffffL;
tlbdef.RotBL = tlbdef.RotCHAR = 0.0f;
@@ -4113,6 +4163,7 @@ BoxPlot::PropertyDlg()
bool bRet = false;
int i, j, k, k1, l, l1, n, ic, c, res, width, height;
double x, y1, y2, dx, dy;
+ char errdesc[40];
lfPOINT fp1, fp2;
TextDEF lbdef = {defs.Color(COL_TEXT), defs.Color(COL_BG), defs.GetSize(SIZE_TEXT), 0.0f, 0.0f, 0,
TXA_HLEFT | TXA_VBOTTOM, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, TmpTxt};
@@ -4120,10 +4171,7 @@ BoxPlot::PropertyDlg()
int it_racc[] = {102, 104, 202, 253, 263, 273, 275, 283, 285};
if(!parent || !data) return false;
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
- sprintf(text3, "c1:c%d", height); sprintf(text4, "d1:d%d", height);
- sprintf(text5, "e1:e%d", height); sprintf(text6, "f1:f%d", height);
+ UseRangeMark(data, 1, text1, text2, text3, text4, text5, text6);
ci_box = ci_err = 95.0;
if(!(Dlg = new DlgRoot(PlotDlg)))return false;
for(i=0; i < 9; i++) Dlg->ItemCmd(it_racc[i], CMD_SET_DATAOBJ, data);
@@ -4253,11 +4301,20 @@ BoxPlot::PropertyDlg()
bRet = true;
}
if(nPoints > 0 && (type & 0x0f00) && (Whiskers = (Whisker**)calloc(nPoints, sizeof(Whisker*)))) {
+ switch(type & 0x1f00) {
+ case 0x0100: strcpy(errdesc, "Std. Dev."); break;
+ case 0x0200: strcpy(errdesc, "Std. Err."); break;
+ case 0x0300: strcpy(errdesc, "25, 75% Perc."); break;
+ case 0x0400: strcpy(errdesc, "Min./Max."); break;
+ case 0x0500: sprintf(errdesc, "'%g%% CI", ci_err); break;
+ default: strcpy(errdesc, "error");
+ }
for(i = 0; i < height; i++) {
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 4, &y1)
&& curr_data->GetValue(i, 5, &y2)) {
fp1.fy = y1; fp2.fy = y2; fp1.fx = fp2.fx = x;
Whiskers[i] = new Whisker(this, curr_data, fp1, fp2, 0, 0, i, 4, i, 0, i, 5, i);
+ if(Whiskers[i]) Whiskers[i]->Command(CMD_ERRDESC, errdesc, 0L);
}
}
bRet = true;
@@ -4323,16 +4380,14 @@ DensDisp::PropertyDlg()
{203, 0, 0, TOUCHEXIT | LASTOBJ, RADIO1, 0L, 25, 96, 60, 9}};
DlgRoot *Dlg;
void *hDlg;
- int n, res, width, height, align = 0;
+ int n, res, align = 0;
bool bRet = false, bContinue = false, bVert;
AccRange *rX = 0L, *rY = 0L;
if(!parent || !data) return false;
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)defs.GetOutLine(), 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)defs.GetFill(), 0);
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height);
- sprintf(text2, "b1:b%d", height);
+ UseRangeMark(data, 1, text1, text2);
if(!(Dlg = new DlgRoot(PlotDlg)))return false;
Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd("Density profile", 50, 50, 420, 260, Dlg, 0x0L);
@@ -4572,6 +4627,7 @@ StackBar::PropertyDlg()
Boxes[i]->Command(CMD_UPDATE, 0L, 0L);
Boxes[i]->Command(CMD_AUTOSCALE, 0L, 0L);
Boxes[i]->Command(CMD_BOX_FILL, GetSchemeFill(&sc), 0L);
+ Boxes[i]->SetSize(SIZE_BOX, 60.0);
}
}
}
@@ -5067,6 +5123,47 @@ MultiLines::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Pie and ring chart properties
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *PieDlgTmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,-1,130,10,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,130,25,45,12\n"
+ "3,,4,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "4,5,100,ISPARENT | CHECKED,SHEET,1,5,10,120,103\n"
+ "5,6,200,ISPARENT,SHEET,2,5,10,120,103\n"
+ "6,10,300,ISPARENT,SHEET,3,5,10,120,103\n"
+ "10,,,CHECKED,CHECKPIN,0,5,0,12,8\n"
+ "100,101,,,LTEXT,4,10,25,60,8\n"
+ "101,105,,,RANGEINPUT,5,15,35,100,10\n"
+ "105,106,500,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "106,107,600,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "107,108,,,EDVAL1,6,58,59,30,10\n"
+ "108,,,,LTEXT,-3,89,59,15,8\n"
+ "200,,,,LTEXT,7,15,30,60,8\n"
+ "201,202,,,RTEXT,-4,2,42,20,8\n"
+ "202,204,,,EDVAL1,8,23,42,30,10\n"
+ "204,205,,,RTEXT,-5,47,42,20,8\n"
+ "205,206,,,EDVAL1,9,68,42,30,10\n"
+ "206,207,,,LTEXT,-3,99,42,15,8\n"
+ "207,208,,,RTEXT,10,27,58,20,8\n"
+ "208,209,,,EDVAL1,11,48,58,30,10\n"
+ "209,210,,,LTEXT,12,79,58,15,8\n"
+ "210,211,400,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "211,212,410,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "212,,,,LTEXT,13,15,80,30,8\n"
+ "300,,,NOSELECT,ODBUTTON,14,20,35,80,60\n"
+ "400,401,,EXRADIO | CHECKED,ODBUTTON,15,40,75,30,30\n"
+ "401,,,EXRADIO,ODBUTTON,15,70,75,30,30\n"
+ "410,411,,EXRADIO | CHECKED,ODBUTTON,15,40,75,30,30\n"
+ "411,,,EXRADIO,ODBUTTON,15,70,75,30,30\n"
+ "500,501,,CHECKED,RADIO1,16,10,59,20,8\n"
+ "501,502,,,RADIO1,17,10,71,40,8\n"
+ "502,503,,,RANGEINPUT,18,15,82,100,10\n"
+ "503,504,,,LTEXT,19,15,94,10,8\n"
+ "504,505,,,EDVAL1,20,42,94,25,10\n"
+ "505,,,,LTEXT,21,70,94,15,8\n"
+ "600,601,,,RTEXT,22,8,59,45,8\n"
+ "601,602,,,RTEXT,23,8,74,45,8\n"
+ "602,603,,,EDVAL1,24,58,74,30,10\n"
+ "603,,,LASTOBJ,LTEXT,-3,89,74,15,8";
bool
PieChart::PropertyDlg()
{
@@ -5075,50 +5172,16 @@ PieChart::PropertyDlg()
TabSHEET tab3 = {55, 90, 10, "Scheme"};
double fcx =10.0, fcy = 20.0, frad=40.0, firad = 30.0;
char txt2[80];
- DlgInfo PieDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 130, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 130, 25, 45, 12},
- {3, 0, 4, ISPARENT | CHECKED, GROUP, NULL, 138, 40, 55, 12},
- {4, 5, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 120, 103},
- {5, 6, 200, ISPARENT, SHEET, &tab2, 5, 10, 120, 103},
- {6, 10, 300, ISPARENT, SHEET, &tab3, 5, 10, 120, 103},
- {10, 0, 0, CHECKED, CHECKPIN, 0L, 5, 0, 12, 8},
- {100, 101, 0, 0x0L, LTEXT, (void*)"spread sheet range for values", 10, 25, 60, 8},
- {101, 105, 0, 0x0L, RANGEINPUT, TmpTxt, 15, 35, 100, 10},
- {105, 106, 500, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
- {106, 107, 600, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
- {107, 108, 0, 0x0L, EDVAL1, &frad, 58, 59, 30, 10},
- {108, 0, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 89, 59, 15, 8},
- {200, 201, 0, 0x0L, LTEXT, (void*)"position of center:", 15, 30, 60, 8},
- {201, 202, 0, 0x0L, RTEXT, (void*)"x", 2, 42, 20, 8},
- {202, 204, 0, 0x0L, EDVAL1, &fcx, 23, 42, 30, 10},
- {204, 205, 0, 0x0L, RTEXT, (void*)"y", 47, 42, 20, 8},
- {205, 206, 0, 0x0L, EDVAL1, &fcy, 68, 42, 30, 10},
- {206, 207, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 99, 42, 15, 8},
- {207, 208, 0, 0x0L, RTEXT, (void*)"start angle", 27, 58, 20, 8},
- {208, 209, 0, 0x0L, EDVAL1, &CtDef.fx, 48, 58, 30, 10},
- {209, 210, 0, 0x0L, LTEXT, (void*)"degree", 79, 58, 15, 8},
- {210, 211, 400, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
- {211, 212, 410, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
- {212, 0, 0, 0x0L, LTEXT, (void*)"style:", 15, 80, 30, 8},
- {300, 0, 0, NOSELECT, ODBUTTON, (void*)(OD_scheme), 20, 35, 80, 60},
- {400, 401, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PieTempl, 40, 75, 30, 30},
- {401, 0, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PieTempl, 70, 75, 30, 30},
- {410, 411, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PieTempl, 40, 75, 30, 30},
- {411, 0, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PieTempl, 70, 75, 30, 30},
- {500, 501, 0, CHECKED, RADIO1, (void*)"fixed radius", 10, 59, 20, 8},
- {501, 502, 0, 0x0L, RADIO1, (void*)"pick radii from spreadsheet range", 10, 71, 40, 8},
- {502, 503, 0, 0x0L, RANGEINPUT, TmpTxt+100, 15, 82, 100, 10},
- {503, 504, 0, 0x0L, LTEXT, (void*)"x factor", 15, 94, 10, 8},
- {504, 505, 0, 0x0L, EDVAL1, &FacRad, 42, 94, 25, 10},
- {505, 0, 0, 0x0L, LTEXT, &txt2, 70, 94, 15, 8},
- {600, 601, 0, 0x0L, RTEXT, (void*)"outer radius", 8, 59, 45, 8},
- {601, 602, 0, 0x0L, RTEXT, (void*)"inner radius", 8, 74, 45, 8},
- {602, 603, 0, 0x0L, EDVAL1, &firad, 58, 74, 30, 10},
- {603, 0, 0, LASTOBJ, LTEXT, (void *) Units[defs.cUnits].display, 89, 74, 15, 8}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)&tab3, (void*)"spread sheet range for values",
+ (void*)TmpTxt, (void*)&frad, (void*)"position of center:", (void*)&fcx, (void*)&fcy,
+ (void*)"start angle", (void*)&CtDef.fx, (void*)"degree", (void*)"style:", (void*)(OD_scheme),
+ (void*)(OD_PieTempl), (void*)"fixed radius", (void*)"pick radii from spreadsheet range",
+ (void*)(TmpTxt+100), (void*)"x factor", (void*)&FacRad, (void*)&txt2, (void*)"outer radius",
+ (void*)"inner radius", (void*)&firad};
+ DlgInfo *PieDlg = CompileDialog(PieDlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
- int i, ix, iy, rix, riy, ny, res, width, height, cf;
+ int i, ix, iy, rix, riy, ny, res, cf;
bool bRet = false, bContinue = false;
double sum = 0.0, dang1, dang2;
double fv;
@@ -5126,9 +5189,7 @@ PieChart::PropertyDlg()
AccRange *rY = 0L, *rR = 0L;
if(!parent || !data) return false;
- data->GetSize(&width, &height);
- sprintf(TmpTxt, "a1:a%d", height);
- sprintf(TmpTxt+100, "b1:b%d", height);
+ UseRangeMark(data, 1, TmpTxt, TmpTxt+100);
sprintf(txt2, "= [%s]", Units[defs.cUnits].display);
frad = (parent->GetSize(SIZE_DRECT_BOTTOM) - parent->GetSize(SIZE_DRECT_TOP))/2.0;
fcx = parent->GetSize(SIZE_GRECT_LEFT) + (parent->GetSize(SIZE_DRECT_LEFT))/2.0 + frad;
@@ -5222,8 +5283,7 @@ PieChart::PropertyDlg()
bRet = true;
}
if(rY) delete rY; if(rR) delete rR;
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(PieDlg);
return bRet;
}
@@ -5359,8 +5419,155 @@ StarChart::PropertyDlg()
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Grid3D represents a surface in space
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+bool
+Grid3D::PropertyDlg()
+{
+ return Configure();
+}
+
+bool
+Grid3D::Configure()
+{
+ TabSHEET tab1 = {0, 37, 10, "Function"};
+ TabSHEET tab2 = {37, 65, 10, "Style"};
+ FillDEF newFill;
+ DlgInfo GridDlg[] = {
+ {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 155, 10, 50, 12},
+ {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 155, 25, 50, 12},
+ {3, 0, 300, ISPARENT | CHECKED, GROUP, 0L, 138, 40, 55, 12},
+ {300, 301, 500, HIDDEN | CHECKED, GROUPBOX, (void*)" grid lines ", 10, 10, 140, 100},
+ {301, 305, 400, HIDDEN | CHECKED, GROUPBOX, (void*)" surface ", 10, 10, 140, 100},
+ {305, 306, 0, TOUCHEXIT, RADIO1, (void*) " grid lines", 155, 45, 50, 10},
+ {306, 0, 0, TOUCHEXIT, RADIO1, (void*) " surface", 155, 57, 50, 10},
+ {400, 401, 0, 0x0L, RTEXT, (void*)"grid line width", 38, 20, 40, 8},
+ {401, 402, 0, 0x0L, EDVAL1, &Line.width, 80, 20, 25, 10},
+ {402, 403, 0, 0x0L, LTEXT, (void*)Units[defs.cUnits].display, 107, 20, 20, 8},
+ {403, 404, 0, 0x0L, RTEXT, (void*)"grid line color", 38, 32, 40, 8},
+ {404, 405, 0, OWNDIALOG, COLBUTTON, (void *)Line.color, 80, 32, 25, 10},
+ {405, 406, 0, 0x0L, RTEXT,(void*)"plane color" , 38, 44, 40, 8},
+ {406, 0, 0, OWNDIALOG, SHADE3D, &newFill, 80, 44, 25, 10},
+ {500, 0, 0, LASTOBJ | NOSELECT, ODBUTTON, (void*)OD_linedef, 15, 15, 130, 100}};
+ DlgRoot *Dlg;
+ void *hDlg;
+ int res, new_type, undo_level = *Undo.pcb;
+ bool bRet = false;
+ double tmp;
+ DWORD new_col;
+ LineDEF newLine;
+ anyOutput *cdisp = Undo.cdisp;
+
+ if(!parent) return false;
+ memcpy(&newFill, &Fill, sizeof(FillDEF));
+ OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
+ if(!(Dlg = new DlgRoot(GridDlg))) return false;
+ if(!type) {
+ Dlg->ShowItem(300, true); Dlg->SetCheck(305, 0L, true);
+ }
+ else {
+ Dlg->ShowItem(301, true); Dlg->SetCheck(306, 0L, true);
+ }
+ if(parent->name) sprintf(TmpTxt, "Grid of %s", parent->name);
+ else strcpy(TmpTxt, "3D Grid");
+ hDlg = CreateDlgWnd(TmpTxt, 50, 50, 426, 260, Dlg, 0x0L);
+ do{
+ LoopDlgWnd();
+ res = Dlg->GetResult();
+ switch (res) {
+ case 305: case 306:
+ if(Dlg->GetCheck(305)) {
+ Dlg->ShowItem(300, true); Dlg->ShowItem(301, false);
+ }
+ else {
+ Dlg->ShowItem(300, false); Dlg->ShowItem(301, true);
+ }
+ Dlg->Command(CMD_REDRAW, 0L, 0L);
+ res = -1;
+ break;
+ }
+ }while (res < 0);
+ Undo.SetDisp(cdisp);
+ while(*Undo.pcb > undo_level) Undo.Pop(cdisp);
+ if(res == 1) {
+ if(Dlg->GetCheck(305) && type == 0) {
+ OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&newLine, 0);
+ if(cmpLineDEF(&Line, &newLine)) {
+ Command(CMD_SET_LINE, &newLine, 0L);
+ bRet = true;
+ }
+ }
+ else if(Dlg->GetCheck(306) && type == 1) {
+ Dlg->GetValue(401, &tmp); Dlg->GetColor(404, &new_col);
+ if(planes && (cmpFillDEF(&Fill, &newFill) || tmp != Line.width || new_col != Line.color)) {
+ Command(CMD_SAVE_SYMBOLS, 0L, 0L);
+ Command(CMD_SYM_FILL, &newFill, 0L);
+ if(tmp != Line.width) SetSize(SIZE_SYM_LINE, tmp);
+ if(new_col != Line.color) SetColor(COL_POLYLINE, new_col);
+ bRet = true;
+ }
+ }
+ else {
+ Undo.ValInt(parent, &type, 0L);
+ Undo.Line(this, &Line, UNDO_CONTINUE); Undo.Fill(this, &Fill, UNDO_CONTINUE);
+ if(Dlg->GetCheck(305)) {
+ new_type = 0;
+ OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&Line, 0);
+ }
+ else {
+ new_type = 1;
+ memcpy(&Fill, &newFill, sizeof(FillDEF));
+ Dlg->GetValue(401, &Line.width);
+ Dlg->GetColor(404, &Line.color);
+ Line.pattern = 0L;
+ Line.patlength = 1;
+ }
+ if(planes && nPlanes) Undo.DropListGO(parent, (GraphObj***)&planes, &nPlanes, UNDO_CONTINUE);
+ if(lines && nLines) Undo.DropListGO(parent, (GraphObj***)&lines, &nLines, UNDO_CONTINUE);
+ Undo.VoidPtr(parent, (void**)&planes, 0L, 0L, UNDO_CONTINUE);
+ Undo.VoidPtr(parent, (void**)&lines, 0L, 0L, UNDO_CONTINUE);
+ type = new_type;
+ CreateObs(true);
+ bRet = true;
+ }
+ }
+ CloseDlgWnd(hDlg);
+ delete Dlg;
+ return bRet;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Scatt3D is a layer representing most simple 3D plots
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *Dlg3DTmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,-1,142,10,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,142,25,45,12\n"
+ "3,50,4,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "4,5,100,TOUCHEXIT | ISPARENT | CHECKED, SHEET,1,5,10,131,100\n"
+ "5,6,200,TOUCHEXIT | ISPARENT, SHEET,2,5,10,131,100\n"
+ "6,10,400, TOUCHEXIT | ISPARENT, SHEET,3,5,10,131,100\n"
+ "10,,,CHECKED,CHECKPIN,0,5,0,12,8\n"
+ "50,60,,NOSELECT, ODBUTTON,4,142,65,45,45\n"
+ "60,61,,,ICON,5,10,114,20,20\n"
+ "61,62,,,LTEXT,6,30,116,100,6\n"
+ "62,,,,LTEXT,7,30,122,100,6\n"
+ "100,101,,,LTEXT,8,10,30,60,8\n"
+ "101,102,,,RANGEINPUT,9,20,40,100,10\n"
+ "102,103,,,LTEXT,10,10,55,60,8\n"
+ "103,104,,,RANGEINPUT,11,20,65,100,10\n"
+ "104,105,,,LTEXT,12,10,80,60,8\n"
+ "105,,,,RANGEINPUT,13,20,90,100,10\n"
+ "200,201,,,LTEXT,14,25,30,60,8\n"
+ "201,202,,,CHECKBOX,15,30,55,60,8\n"
+ "202,203,,TOUCHEXIT,CHECKBOX,16,30,65,60,8\n"
+ "203,204,,TOUCHEXIT,CHECKBOX,17,30,45,60,8\n"
+ "204,205,,TOUCHEXIT,CHECKBOX,18,30,75,60,8\n"
+ "205,,,TOUCHEXIT,CHECKBOX,19,30,85,60,8\n"
+ "400,410,,,LTEXT,20,20,30,60,8\n"
+ "410,411,,EXRADIO,ODBUTTON,21,20,42,25,25\n"
+ "411,412,,EXRADIO,ODBUTTON,21,45,42,25,25\n"
+ "412,,,LASTOBJ | EXRADIO,ODBUTTON,21,70,42,25,25";
+
bool
Scatt3D::PropertyDlg()
{
@@ -5369,37 +5576,16 @@ Scatt3D::PropertyDlg()
TabSHEET tab3 = {50, 75, 10, "Axes"};
char text1[100], text2[100], text3[100];
int icon = ICO_INFO;
- DlgInfo Dlg3D[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 142, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 142, 25, 45, 12},
- {3, 50, 4, ISPARENT | CHECKED, GROUP, 0L, 138, 40, 55, 12},
- {4, 5, 100, TOUCHEXIT | ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 131, 100},
- {5, 6, 200, TOUCHEXIT | ISPARENT, SHEET, &tab2, 5, 10, 131, 100},
- {6, 10, 400, TOUCHEXIT | ISPARENT, SHEET, &tab3, 5, 10, 131, 100},
- {10, 0, 0, CHECKED, CHECKPIN, 0L, 5, 0, 12, 8},
- {50, 60, 0, NOSELECT, ODBUTTON, (void*)(OD_AxisDesc3D), 142, 65, 45, 45},
- {60, 61, 0, 0x0L, ICON, (void*)&icon, 10, 114, 20, 20},
- {61, 62, 0, 0x0L, LTEXT, (void*)"Use [arrow keys], [shift]+[arrow key],", 30, 116, 100, 6},
- {62, 0, 0, 0x0L, LTEXT, (void*)"and [r], [R], [l] or [L] to rotate graph.", 30, 122, 100, 6},
- {100, 101, 0, 0x0L, LTEXT, (void*)"range for X Data", 10, 30, 60, 8},
- {101, 102, 0, 0x0L, RANGEINPUT, text1, 20, 40, 100, 10},
- {102, 103, 0, 0x0L, LTEXT, (void*)"range for Y Data", 10, 55, 60, 8},
- {103, 104, 0, 0x0L, RANGEINPUT, text2, 20, 65, 100, 10},
- {104, 105, 0, 0x0L, LTEXT, (void*)"range for Z Data", 10, 80, 60, 8},
- {105, 0, 0, 0x0L, RANGEINPUT, text3, 20, 90, 100, 10},
- {200, 201, 0, 0x0L, LTEXT, (void*)"select style:", 25, 30, 60, 8},
- {201, 202, 0, 0x0L, CHECKBOX, (void*)" balls", 30, 55, 60, 8},
- {202, 203, 0, TOUCHEXIT, CHECKBOX, (void*)" columns", 30, 65, 60, 8},
- {203, 204, 0, TOUCHEXIT, CHECKBOX, (void*)" line", 30, 45, 60, 8},
- {204, 205, 0, TOUCHEXIT, CHECKBOX, (void*)" drop lines", 30, 75, 60, 8},
- {205, 0, 0, TOUCHEXIT, CHECKBOX, (void*)" arrows", 30, 85, 60, 8},
- {400, 410, 0, 0x0L, LTEXT, (void*)"select template:", 20, 30, 60, 8},
- {410, 411, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl3D), 20, 42, 25, 25},
- {411, 412, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl3D), 45, 42, 25, 25},
- {412, 0, 0, LASTOBJ | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl3D), 70, 42, 25, 25}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)&tab3, (void*)(OD_AxisDesc3D), (void*)&icon,
+ (void*)"Use [arrow keys], [shift]+[arrow key],", (void*)"and [r], [R], [l] or [L] to rotate graph.",
+ (void*)"range for X Data", (void*)text1, (void*)"range for Y Data", (void*)text2,
+ (void*)"range for Z Data", (void*)text3, (void*)"select style:", (void*)" balls", (void*)" columns",
+ (void*)" line", (void*)" drop lines", (void*)" arrows", (void*)"select template:",
+ (void*)(OD_AxisTempl3D)};
+ DlgInfo *Dlg3D = CompileDialog(Dlg3DTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
- int res, width, height, n1, n2, n3, ic = 0;
+ int res, n1, n2, n3, ic = 0;
int i, j, k, l, m, n, i2, j2, k2, l2, m2;
double x, y, z, bar_w, bar_d, rad;
bool bRet = false, bContinue = false;
@@ -5407,13 +5593,10 @@ Scatt3D::PropertyDlg()
fPOINT3D pos1, pos2;
if(!data || !parent)return false;
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
- sprintf(text3, "c1:c%d", height);
+ UseRangeMark(data, 1, text1, text2, text3);
if(!(Dlg = new DlgRoot(Dlg3D)))return false;
Dlg->SetCheck(410 + AxisTempl3D, 0L, true);
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data);
- Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
+ Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
Dlg->ItemCmd(105, CMD_SET_DATAOBJ, data);
for(i = 0; i < 5; i++) Dlg->SetCheck(201+i, 0L, (c_flags & (1<<i))!=0);
if(c_flags == 0x2000) {
@@ -5537,9 +5720,8 @@ Scatt3D::PropertyDlg()
" data triplets!");
bRet = true;
}
- CloseDlgWnd(hDlg);
- delete Dlg;
- if(rX) delete rX; if(rY) delete rY; if(rZ) delete rZ;
+ CloseDlgWnd(hDlg); delete Dlg; free(Dlg3D);
+ if(rX) delete rX; if(rY) delete rY; if(rZ) delete rZ;
return bRet;
}
@@ -5666,9 +5848,9 @@ FitFunc::PropertyDlg()
{155, 200, 0, 0x0L, EDVAL1, &iter, 119, 118, 25, 10},
{200, 0, 0, 0x0L, TEXTBOX, (void*)cmdxy, 22, 84, 122, 30},
{400, 401, 0, 0x0L, LTEXT, (void*)"range for X Data", 10, 30, 60, 8},
- {401, 402, 0, 0x0L, RANGEINPUT, (void*)ssXref, 20, 40, 100, 10},
+ {401, 402, 0, 0x0L, RANGEINPUT, (void*)text1, 20, 40, 100, 10},
{402, 403, 0, 0x0L, LTEXT, (void*)"range for Y Data", 10, 55, 60, 8},
- {403, 404, 0, 0x0L, RANGEINPUT, (void*)ssYref, 20, 65, 100, 10},
+ {403, 404, 0, 0x0L, RANGEINPUT, (void*)text2, 20, 65, 100, 10},
{404, 405, 0, CHECKED, CHECKBOX, (void*)"draw symbols", 20, 95, 60, 8},
{405, 0, 0, HIDDEN, LTEXT, 0L, 20, 95, 60, 8},
{500, 550, 501, CHECKED, GROUP, 0L, 0, 0, 0, 0},
@@ -5689,10 +5871,12 @@ FitFunc::PropertyDlg()
AccRange *rX, *rY;
char *o_cmdxy, *o_parxy, *tmp_char;
anyOutput *cdisp = Undo.cdisp;
+ anyResult *ares;
if(!parent || !data) return false;
if(!(o_cmdxy = strdup(cmdxy))) return false;
if(!(o_parxy = strdup(parxy))) return false;
+ UseRangeMark(data, 1, text1, text2);
iter = (double)maxiter;
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
if(!(Dlg = new DlgRoot(FuncDlg))) return false;
@@ -5748,6 +5932,18 @@ FitFunc::PropertyDlg()
}
Dlg->GetValue(153, &conv); Dlg->GetValue(155, &iter);
ReshapeFormula(&parxy); ReshapeFormula(&cmdxy);
+ ares = do_formula(data, parxy);
+ if(ares->type != ET_VALUE) {
+ ErrorBox("Syntax Error in parameters.");
+ bContinue = true; res = -1;
+ break;
+ }
+ ares = do_formula(data, cmdxy);
+ if(ares->type != ET_VALUE) {
+ ErrorBox("Syntax Error in formula.");
+ bContinue = true; res = -1;
+ break;
+ }
i = do_fitfunc(data, text1, text2, 0L, &parxy, cmdxy, conv, (int)iter, &chi2);
Dlg->SetText(102, parxy);
if(i >1 || res == 7) {
@@ -5834,14 +6030,6 @@ FitFunc::PropertyDlg()
Undo.ValInt(parent, (int*)&dirty, undo_flags);
Command(CMD_MRK_DIRTY, 0L, 0L);
}
-// Dlg->GetText(200, TmpTxt);
-// if(cmdxy && strcmp(cmdxy, TmpTxt)) {
-// Undo.String(this, &cmdxy, undo_flags);
-// free(cmdxy); cmdxy = strdup(TmpTxt); undo_flags |= UNDO_CONTINUE;
-// }
-// if(undo_flags & UNDO_CONTINUE) Update(0L, UNDO_CONTINUE);
-// cmdxy = strdup(TmpTxt);
-// bRet = Update(0L, 0L);
OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&newLine, 0);
if(cmpLineDEF(&Line, &newLine)) {
Undo.Line(parent, &Line, undo_flags); undo_flags |= UNDO_CONTINUE;
@@ -5859,19 +6047,22 @@ FitFunc::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Create a three dimensional graph
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *AddPlot3Dtmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,-1,150,10,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,150,25,45,12\n"
+ "3,,560,ISPARENT | CHECKED,GROUPBOX,1,5,10,140,70\n"
+ "560,561,,EXRADIO | CHECKED,ODBUTTON,2,12,20,25,25\n"
+ "561,562,,EXRADIO,ODBUTTON,2,37,20,25,25\n"
+ "562,563,,EXRADIO,ODBUTTON,2,62,20,25,25\n"
+ "563,564,,EXRADIO,ODBUTTON,2,87,20,25,25\n"
+ "564,565,,EXRADIO,ODBUTTON,2,112,20,25,25\n"
+ "565,,,LASTOBJ | EXRADIO,ODBUTTON,2,12,45,25,25";
+
bool
Plot3D::AddPlot(int family)
{
- DlgInfo PlotsDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 150, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 150, 25, 45, 12},
- {3, 0, 560, ISPARENT | CHECKED, GROUPBOX, (void *)" select template ", 5, 10, 140, 70},
- {560, 561, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 12, 20, 25, 25},
- {561, 562, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 37, 20, 25, 25},
- {562, 563, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 62, 20, 25, 25},
- {563, 564, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 87, 20, 25, 25},
- {564, 565, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 112, 20, 25, 25},
- {565, 0, 0, LASTOBJ | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 12, 45, 25, 25}};
+ void *dyndata[] = {(void *)" select template ", (void*)(OD_PlotTempl)};
+ DlgInfo *PlotsDlg = CompileDialog(AddPlot3Dtmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
int res, cSel = 560;
@@ -5887,26 +6078,27 @@ Plot3D::AddPlot(int family)
case 560: case 561: case 562: case 563: case 564: case 565:
if(res == cSel) res = 1;
else {
- cSel = res;
- res = -1;
+ cSel = res; res = -1;
}
break;
}
}while (res < 0);
if(res == 1){ //OK pressed
- if(Dlg->GetCheck(560)) p = new Scatt3D(this, data, 0x01);
- else if(Dlg->GetCheck(561)) p = new Scatt3D(this, data, 0x02);
- else if(Dlg->GetCheck(562)) p = new Scatt3D(this, data, 0x04);
- else if(Dlg->GetCheck(563)) p = new BubblePlot3D(this, data);
- else if(Dlg->GetCheck(564)) p = new Scatt3D(this, data, 0x2000);
- else if(Dlg->GetCheck(565)) p = new Func3D(this, data);
+ switch (cSel) {
+ case 560: p = new Scatt3D(this, data, 0x01); break;
+ case 561: p = new Scatt3D(this, data, 0x02); break;
+ case 562: p = new Scatt3D(this, data, 0x04); break;
+ case 563: p = new BubblePlot3D(this, data); break;
+ case 564: p = new Scatt3D(this, data, 0x2000); break;
+ case 565: p = new Func3D(this, data); break;
+ default: p = 0L; break;
+ }
if(p && p->PropertyDlg()) {
if(!(bRet = Command(CMD_DROP_PLOT, p, (anyOutput *)NULL))) delete p;
}
else if(p) delete p;
}
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(PlotsDlg);
return bRet;
}
@@ -5927,8 +6119,39 @@ Plot3D::PropertyDlg()
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Create a 2.5 dimensional chart
+// Create a 2.5 dimensional bar chart
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *Base25D_DlgTmpl =
+ "1,2,,DEFAULT, PUSHBUTTON,-1,158,10,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,158,25,45,12\n"
+ "3,,10,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "10,11,100,ISPARENT | CHECKED,SHEET,1,5,10,140,100\n"
+ "11,12,200,ISPARENT,SHEET,2,5,10,140,100\n"
+ "12,20,300,ISPARENT,SHEET,3,5,10,140,100\n"
+ "20,,,CHECKED,CHECKPIN,0,5,0,12,8\n"
+ "100,101,,,LTEXT,4,15,30,60,8\n"
+ "101,152,,,RANGEINPUT,5,25,40,100,10\n"
+ "152,153,,ISPARENT | CHECKED,GROUPBOX,6,12,60,128,45\n"
+ "153,154,,,LTEXT,0,25,65,60,8\n"
+ "154,155,,,RANGEINPUT,0,25,75,100,10\n"
+ "155,156,,,PUSHBUTTON,-8,95,87,30,12\n"
+ "156,,,,PUSHBUTTON,-9,60,87,35,12\n"
+ "200,201,,,LTEXT,7,20,35,80,8\n"
+ "201,202,,,RTEXT,8,48,45,13,8\n"
+ "202,203,,,EDVAL1,9,65,45,25,10\n"
+ "203,204,,,RTEXT,10,48,57,13,8\n"
+ "204,,,,EDVAL1,11,65,57,25,10\n"
+ "300,301,,CHECKED, RADIO1,12,15,35,80,9\n"
+ "301,302,,OWNDIALOG | TOUCHEXIT,COLBUTT,13,110,35,20,10\n"
+ "302,303,,,RADIO1,14,15,55,80,9\n"
+ "303,304,,OWNDIALOG | TOUCHEXIT,COLBUTT,15,25,70,10,10\n"
+ "304,305,,OWNDIALOG | TOUCHEXIT,COLBUTT,16,37,70,10,10\n"
+ "305,306,,OWNDIALOG | TOUCHEXIT,COLBUTT,17,49,70,10,10\n"
+ "306,307,,OWNDIALOG | TOUCHEXIT,COLBUTT,18,61,70,10,10\n"
+ "307,308,,OWNDIALOG | TOUCHEXIT,COLBUTT,19,73,70,10,10\n"
+ "308,309,,OWNDIALOG | TOUCHEXIT,COLBUTT,20,85,70,10,10\n"
+ "309,310,,OWNDIALOG | TOUCHEXIT,COLBUTT,21,97,70,10,10\n"
+ "310,,,LASTOBJ | OWNDIALOG | TOUCHEXIT,COLBUTT,22,109,70,10,10";
bool
Chart25D::PropertyDlg()
{
@@ -5940,38 +6163,13 @@ Chart25D::PropertyDlg()
static DWORD defcol = 0x00ffffffL;
char text1[100];
double start_z = 1.0;
- DlgInfo Bar3D_Dlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 158, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 158, 25, 45, 12},
- {3, 0, 10, ISPARENT | CHECKED, GROUP, NULL, 138, 40, 55, 12},
- {10, 11, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 140, 100},
- {11, 12, 200, ISPARENT, SHEET, &tab2, 5, 10, 140, 100},
- {12, 20, 300, ISPARENT, SHEET, &tab3, 5, 10, 140, 100},
- {20, 0, 0, CHECKED, CHECKPIN, 0L, 5, 0, 12, 8},
- {100, 101, 0, 0x0L, LTEXT, (void*)"range for common x values", 15, 30, 60, 8},
- {101, 152, 0, 0x0L, RANGEINPUT, text1, 25, 40, 100, 10},
- {152, 153, 0, ISPARENT | CHECKED, GROUPBOX, (void*)" ranges for y values ", 12, 60, 128, 45},
- {153, 154, 0, 0x0L, LTEXT, 0L, 25, 65, 60, 8},
- {154, 155, 0, 0x0L, RANGEINPUT, 0L, 25, 75, 100, 10},
- {155, 156, 0, 0x0L, PUSHBUTTON, (void*)"Next >>", 95, 87, 30, 12},
- {156, 0, 0, 0x0L, PUSHBUTTON, (void*)"<< Prev.", 60, 87, 35, 12},
- {200, 201, 0, 0x0L, LTEXT, (void*)"distances:", 20, 35, 80, 8},
- {201, 202, 0, 0x0L, RTEXT, (void*)"start z =", 48, 45, 13, 8},
- {202, 203, 0, 0x0L, EDVAL1, &start_z, 65, 45, 25, 10},
- {203, 204, 0, 0x0L, RTEXT, (void*)"step =", 48, 57, 13, 8},
- {204, 0, 0, 0x0L, EDVAL1, &dspm.fz, 65, 57, 25, 10},
- {300, 301, 0, CHECKED, RADIO1, (void*)" common color for columns:", 15, 35, 80, 9},
- {301, 302, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)defcol, 110, 35, 20, 10},
- {302, 303, 0, 0x0L, RADIO1, (void*)" increment color scheme:", 15, 55, 80, 9},
- {303, 304, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[0], 25, 70, 10, 10},
- {304, 305, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[1], 37, 70, 10, 10},
- {305, 306, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[2], 49, 70, 10, 10},
- {306, 307, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[3], 61, 70, 10, 10},
- {307, 308, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[4], 73, 70, 10, 10},
- {308, 309, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[5], 85, 70, 10, 10},
- {309, 310, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[6], 97, 70, 10, 10},
- {310, 0, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[7], 109, 70, 10, 10},
- {500, 0, 0, LASTOBJ, NONE, 0L, 0, 0, 0, 0}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)&tab3, (void*)"range for common x values",
+ (void*)text1, (void*)" ranges for y values ", (void*)"distances:", (void*)"start z =",
+ (void*)&start_z, (void*)"step =", (void*)&dspm.fz, (void*)" common color for columns:",
+ (void*)&defcol, (void*)" increment color scheme:", (void*)&colarr[0], (void*)&colarr[1],
+ (void*)&colarr[2], (void*)&colarr[3], (void*)&colarr[4], (void*)&colarr[5], (void*)&colarr[6],
+ (void*)&colarr[7]};
+ DlgInfo *Bar3D_Dlg = CompileDialog(Base25D_DlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
int i, ic, res, width, height, currYR=0, maxYR=0, nx=0, ny, rx, cx, ry, cy, oax;
@@ -6086,10 +6284,8 @@ Chart25D::PropertyDlg()
for (i = 0; i < maxYR; i++) if(rd[i]) free(rd[i]);
free(rd);
}
- if(rX) delete rX; if(rY) delete rY;
- if(bRet) {
- Command(CMD_MRK_DIRTY, 0L, 0L);
- }
+ if(rX) delete rX; if(rY) delete rY; free(Bar3D_Dlg);
+ if(bRet) Command(CMD_MRK_DIRTY, 0L, 0L);
return bRet;
}
@@ -6107,38 +6303,13 @@ Ribbon25D::PropertyDlg()
static DWORD defcol = 0x00ffffffL;
char text1[100];
double start_z = 1.0;
- DlgInfo Bar3D_Dlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 158, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 158, 25, 45, 12},
- {3, 0, 10, ISPARENT | CHECKED, GROUP, NULL, 138, 40, 55, 12},
- {10, 11, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 140, 100},
- {11, 12, 200, ISPARENT, SHEET, &tab2, 5, 10, 140, 100},
- {12, 20, 300, ISPARENT, SHEET, &tab3, 5, 10, 140, 100},
- {20, 0, 0, CHECKED, CHECKPIN, 0L, 5, 0, 12, 8},
- {100, 101, 0, 0x0L, LTEXT, (void*)"range for common x values", 15, 30, 60, 8},
- {101, 152, 0, 0x0L, RANGEINPUT, text1, 25, 40, 100, 10},
- {152, 153, 0, ISPARENT | CHECKED, GROUPBOX, (void*)" ranges for y values ", 12, 60, 128, 45},
- {153, 154, 0, 0x0L, LTEXT, 0L, 25, 65, 60, 8},
- {154, 155, 0, 0x0L, RANGEINPUT, 0L, 25, 75, 100, 10},
- {155, 156, 0, 0x0L, PUSHBUTTON, (void*)"Next >>", 95, 87, 30, 12},
- {156, 0, 0, 0x0L, PUSHBUTTON, (void*)"<< Prev.", 60, 87, 35, 12},
- {200, 201, 0, 0x0L, LTEXT, (void*)"distances:", 20, 35, 80, 8},
- {201, 202, 0, 0x0L, RTEXT, (void*)"start z =", 48, 45, 13, 8},
- {202, 203, 0, 0x0L, EDVAL1, &start_z, 65, 45, 25, 10},
- {203, 204, 0, 0x0L, RTEXT, (void*)"step =", 48, 57, 13, 8},
- {204, 0, 0, 0x0L, EDVAL1, &dspm.fz, 65, 57, 25, 10},
- {300, 301, 0, CHECKED, RADIO1, (void*)" common color for ribbons:", 15, 35, 80, 9},
- {301, 302, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)defcol, 110, 35, 20, 10},
- {302, 303, 0, 0x0L, RADIO1, (void*)" increment color scheme:", 15, 55, 80, 9},
- {303, 304, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[0], 25, 70, 10, 10},
- {304, 305, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[1], 37, 70, 10, 10},
- {305, 306, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[2], 49, 70, 10, 10},
- {306, 307, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[3], 61, 70, 10, 10},
- {307, 308, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[4], 73, 70, 10, 10},
- {308, 309, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[5], 85, 70, 10, 10},
- {309, 310, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[6], 97, 70, 10, 10},
- {310, 0, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)colarr[7], 109, 70, 10, 10},
- {500, 0, 0, LASTOBJ, NONE, 0L, 0, 0, 0, 0}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)&tab3, (void*)"range for common x values",
+ (void*)text1, (void*)" ranges for y values ", (void*)"distances:", (void*)"start z =",
+ (void*)&start_z, (void*)"step =", (void*)&dspm.fz, (void*)" common color for ribbons:",
+ (void*)&defcol, (void*)" increment color scheme:", (void*)&colarr[0], (void*)&colarr[1],
+ (void*)&colarr[2], (void*)&colarr[3], (void*)&colarr[4], (void*)&colarr[5], (void*)&colarr[6],
+ (void*)&colarr[7]};
+ DlgInfo *Bar3D_Dlg = CompileDialog(Base25D_DlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
int i, res, width, height, currYR=0, maxYR=0, nx=0, ny, oax;
@@ -6232,10 +6403,8 @@ Ribbon25D::PropertyDlg()
for (i = 0; i < maxYR; i++) if(rd[i]) free(rd[i]);
free(rd);
}
- if(rX) delete rX; if(rY) delete rY;
- if(bRet) {
- Command(CMD_MRK_DIRTY, 0L, 0L);
- }
+ if(rX) delete rX; if(rY) delete rY; free(Bar3D_Dlg);
+ if(bRet) Command(CMD_MRK_DIRTY, 0L, 0L);
return bRet;
}
@@ -6276,7 +6445,7 @@ BubblePlot3D::PropertyDlg()
{412, 0, 0, LASTOBJ | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl3D), 70, 42, 25, 25}};
DlgRoot *Dlg;
void *hDlg;
- int i, res, width, height, count;
+ int i, res, count;
int cx, rx, cy, ry, cz, rz, cr, rr, s_type = 5;
bool bRet = false;
double fx, fy, fz, fr;
@@ -6286,9 +6455,7 @@ BubblePlot3D::PropertyDlg()
int etracc[] = {101, 103, 105, 151};
if(!data || !parent)return false;
- data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
- sprintf(text3, "c1:c%d", height); sprintf(text4, "d1:d%d", height);
+ UseRangeMark(data, 1, text1, text2, text3, text4);
if(!(Dlg = new DlgRoot(BubDlg3D)))return false;
for(i = 0; i < 4; i++) Dlg->ItemCmd(etracc[i], CMD_SET_DATAOBJ, data);
rX = rY = rZ = rR = 0L;
@@ -6337,7 +6504,7 @@ BubblePlot3D::PropertyDlg()
}
}
sc_plot = new Scatt3D(this, data, Balls, count);
- if(parent->Id == GO_PLOT3D || parent->Id == GO_FUNC3D) {
+ if(parent->Id == GO_PLOT3D || parent->Id == GO_FUNC3D || parent->Id == GO_FITFUNC3D) {
if(!(parent->Command(CMD_DROP_PLOT, sc_plot, 0L))) delete(sc_plot);
bRet = true;
}
@@ -6456,6 +6623,7 @@ Func3D::PropertyDlg()
Dlg->GetValue(108, &z1); Dlg->GetValue(109, &z2);
Dlg->GetValue(110, &zstep); type = Dlg->GetCheck(305) ? 0 : 1;
if(Dlg->GetText(200, TmpTxt)) {
+ if(cmdxy) free(cmdxy);
cmdxy = strdup(TmpTxt); ReshapeFormula(&cmdxy);
bRet = Update();
}
@@ -6486,6 +6654,247 @@ Func3D::PropertyDlg()
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Fit data to a 3D function
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+bool
+FitFunc3D::PropertyDlg()
+{
+ TabSHEET tab1 = {0, 22, 10, "Data"};
+ TabSHEET tab2 = {22, 59, 10, "Function"};
+ TabSHEET tab3 = {59, 87, 10, "Style"};
+ char text1[100], text2[100], text3[100];
+ FillDEF newFill;
+ double iter;
+// bool bNew = (dl == 0L);
+ bool bNew = true;
+ DlgInfo FuncDlg[] = {
+ {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 160, 10, 45, 12},
+ {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 160, 25, 45, 12},
+ {3, 10, 4, ISPARENT | CHECKED, GROUP, 0L, 138, 40, 55, 12},
+ {4, 5, 400, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 149, 134},
+ {5, 6, 100, ISPARENT, SHEET, &tab2, 5, 10, 149, 134},
+ {6, 7, 300, ISPARENT, SHEET, &tab3, 5, 10, 149, 134},
+ {7, 0, 0, 0x0L, PUSHBUTTON, (void*)"Fit", 160, 132, 45, 12},
+ {10, 50, 0, CHECKED, CHECKPIN, 0L, 5, 0, 12, 8},
+ {50, 0, 0, NOSELECT, ODBUTTON, (void*)(OD_AxisDesc3D), 160, 65, 45, 45},
+ {100, 101, 0, 0x0L, LTEXT, (void*)"fit function by nonlinear regression", 10, 24, 100, 8},
+ {101, 102, 0, 0x0L, LTEXT, (void*)"parameters and initial values:", 10, 34, 100, 8},
+ {102, 150, 0, 0x0L, TEXTBOX, (void*)param, 22, 44, 122, 30},
+ {150, 151, 0, 0x0L, LTEXT, (void*)"function, y=f(x,z):", 10, 77, 10, 8},
+ {151, 152, 0, 0x0L, RTEXT, (void*)"y=", 10, 91, 10, 8},
+ {152, 153, 0, 0x0L, RTEXT, (void*)"converg.:", 20, 128, 26, 8},
+ {153, 154, 0, 0x0L, EDVAL1, &conv, 46, 128, 25, 10},
+ {154, 155, 0, 0x0L, RTEXT, (void*)"iterations:", 72, 128, 47, 8},
+ {155, 200, 0, 0x0L, EDVAL1, &iter, 119, 128, 25, 10},
+ {200, 0, 0, 0x0L, TEXTBOX, (void*)cmdxy, 22, 89, 122, 30},
+ {300, 301, 550, CHECKED, GROUPBOX, (void*)" grid ", 10, 40, 140, 100},
+ {301, 305, 350, HIDDEN | CHECKED, GROUPBOX, (void*)" surface ", 10, 40, 140, 100},
+ {305, 306, 0, CHECKED | TOUCHEXIT, RADIO1, (void*) " grid lines", 15, 25, 50, 10},
+ {306, 0, 0, TOUCHEXIT, RADIO1, (void*) " surface", 85, 25, 50, 10},
+ {350, 351, 0, 0x0L, RTEXT, (void*)"grid line width", 38, 50, 40, 8},
+ {351, 352, 0, 0x0L, EDVAL1, &Line.width, 80, 50, 25, 10},
+ {352, 353, 0, 0x0L, LTEXT, (void*)Units[defs.cUnits].display, 107, 50, 20, 8},
+ {353, 354, 0, 0x0L, RTEXT, (void*)"grid line color", 38, 62, 40, 8},
+ {354, 355, 0, OWNDIALOG, COLBUTTON, (void *)Line.color, 80, 62, 25, 10},
+ {355, 356, 0, 0x0L, RTEXT,(void*)"plane color" , 38, 74, 40, 8},
+ {356, 0, 0, OWNDIALOG, SHADE3D, &newFill, 80, 74, 25, 10},
+ {400, 401, 0, 0x0L, LTEXT, (void*)"range for X data", 10, 30, 60, 8},
+ {401, 402, 0, 0x0L, RANGEINPUT, (void*)text1, 20, 40, 100, 10},
+ {402, 403, 0, 0x0L, LTEXT, (void*)"range for Y data", 10, 55, 60, 8},
+ {403, 404, 0, 0x0L, RANGEINPUT, (void*)text2, 20, 65, 100, 10},
+ {404, 405, 0, 0x0L, LTEXT, (void*)"range for Z data", 10, 80, 60, 8},
+ {405, 406, 0, 0x0L, RANGEINPUT, (void*)text3, 20, 90, 100, 10},
+ {406, 407, 0, CHECKED, CHECKBOX, (void*)"draw symbols", 20, 110, 60, 8},
+ {407, 0, 0, HIDDEN, LTEXT, 0L, 20, 110, 60, 8},
+ {500, 550, 501, CHECKED, GROUP, 0L, 0, 0, 0, 0},
+ {501, 502, 0, 0x0L, RTEXT, (void*)"plot x=", 10, 30, 28, 8},
+ {502, 503, 0, 0x0L, EDVAL1, &x1, 38, 30, 25, 10},
+ {503, 504, 0, 0x0L, RTEXT, (void*)"until", 61, 30, 17, 8},
+ {504, 505, 0, 0x0L, EDVAL1, &x2, 78, 30, 25, 10},
+ {505, 506, 0, 0x0L, RTEXT, (void*)"step", 102, 30, 17, 8},
+ {506, 0, 0, 0x0L, EDVAL1, &xstep, 119, 30, 25, 10},
+ {550, 0, 0, LASTOBJ | NOSELECT, ODBUTTON, (void*)OD_linedef, 15, bNew ? 45:45, 130, 100}};
+ DlgRoot *Dlg;
+ void *hDlg;
+ int res, undo_level = *Undo.pcb, i, j, k, l, m, n, ns = 0;
+ bool bRet = false, bContinue = false;
+ DWORD undo_flags = 0L;
+ LineDEF newLine;
+ double x, y, z, o_x1, n_x1, o_x2, n_x2, o_xstep, n_xstep, n_chi2=chi2, rad;
+ AccRange *rX, *rY, *rZ;
+ char *o_cmdxy, *o_param;
+ anyOutput *cdisp = Undo.cdisp;
+ anyResult *ares;
+ Sphere **Balls;
+
+ if(!parent || !data) return false;
+ UseRangeMark(data, 1, text1, text2, text3);
+ if(!(o_cmdxy = strdup(cmdxy))) return false;
+ if(!(o_param = strdup(param))) return false;
+ rX = rY = rZ = 0L; iter = (double)maxiter;
+ OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
+ memcpy(&newFill, &Fill, sizeof(FillDEF));
+ memcpy(&newLine, &Line, sizeof(LineDEF));
+ if(!(Dlg = new DlgRoot(FuncDlg))) return false;
+ if(!bNew){
+ Dlg->ShowItem(10, false); Dlg->Activate(401, false);
+ Dlg->Activate(403, false); Dlg->Activate(405, false);
+ Dlg->SetCheck(6, 0L, true);
+ Dlg->SetCheck(4, 0L, false); Dlg->ShowItem(404, false);
+ if(chi2 > 0.0) {
+ sprintf(TmpTxt, "Chi 2 = %g", chi2);
+ Dlg->SetText(405,TmpTxt); Dlg->ShowItem(405, true);
+ }
+ }
+ else {
+ Dlg->ItemCmd(401, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(403, CMD_SET_DATAOBJ, data);
+ Dlg->ItemCmd(405, CMD_SET_DATAOBJ, data); Dlg->ShowItem(500, false);
+ }
+ Dlg->GetValue(502, &o_x1); n_x1 = o_x1;
+ Dlg->GetValue(504, &o_x2); n_x2 = o_x2;
+ Dlg->GetValue(506, &o_xstep); n_xstep = o_xstep;
+ hDlg = CreateDlgWnd("Fit Function to Data in 3D Space", 50, 50, 426, 320, Dlg, 0x0L);
+ if(bNew) Dlg->SetCheck(4, 0L, true);
+ do{
+ LoopDlgWnd();
+ res = Dlg->GetResult();
+ switch (res) {
+ case 0:
+ if(Dlg->GetCheck(10)) res = -1;
+ if(bContinue) res = -1;
+ bContinue = false;
+ break;
+ case 305: case 306:
+ if(Dlg->GetCheck(305)) {
+ Dlg->ShowItem(300, true); Dlg->ShowItem(301, false);
+ }
+ else {
+ Dlg->ShowItem(300, false); Dlg->ShowItem(301, true);
+ }
+ Dlg->DoPlot(0L);
+ res = -1;
+ break;
+ case 1:
+ if(!bNew){
+ if(Dlg->GetText(102, TmpTxt) && param) {
+ free(param); param = strdup(TmpTxt);
+ }
+ if(Dlg->GetText(200, TmpTxt) && cmdxy) {
+ free(cmdxy); cmdxy = strdup(TmpTxt);
+ }
+ ReshapeFormula(¶m); ReshapeFormula(&cmdxy);
+ dirty = true;
+ break;
+ }
+ case 7: //Start: do nonlinear regression
+ Undo.SetDisp(cdisp);
+ if(!Dlg->GetText(401, text1) || !Dlg->GetText(403, text2) || !Dlg->GetText(405, text3)) {
+ Dlg->SetCheck(4, 0L, true); bContinue = true;
+ InfoBox("Invalid or missing range");
+ res = -1;
+ }
+ else if(Dlg->GetCheck(5)) { // the function tab must be shown
+ if(Dlg->CurrDisp) Dlg->CurrDisp->MouseCursor(MC_WAIT, true);
+ if(Dlg->GetText(102, TmpTxt) && param) {
+ free(param); param = strdup(TmpTxt);
+ }
+ if(Dlg->GetText(200, TmpTxt) && cmdxy) {
+ free(cmdxy); cmdxy = strdup(TmpTxt);
+ }
+ Dlg->GetValue(153, &conv); Dlg->GetValue(155, &iter);
+ ReshapeFormula(¶m); ReshapeFormula(&cmdxy);
+ ares = do_formula(data, param);
+ if(ares->type != ET_VALUE) {
+ ErrorBox("Syntax Error in parameters.");
+ bContinue = true; res = -1;
+ break;
+ }
+ ares = do_formula(data, cmdxy);
+ if(ares->type != ET_VALUE) {
+ ErrorBox("Syntax Error in formula.");
+ bContinue = true; res = -1;
+ break;
+ }
+ i = do_fitfunc(data, text1, text2, text3, ¶m, cmdxy, conv, (int)iter, &chi2);
+ Dlg->SetText(102, param);
+ if(i >1 || res == 7) {
+ sprintf(TmpTxt, "The Levenberg-Marquart algorithm\nexited after %d iterations.\n\nChi2 = %g", i, chi2);
+ InfoBox(TmpTxt);
+ }
+ bContinue = true;
+ if(res == 7) res = -1;
+ if(Dlg->CurrDisp) Dlg->CurrDisp->MouseCursor(MC_ARROW, true);
+ }
+ else { //diplay function tab first
+ Dlg->SetCheck(5, 0L, true);
+ res = -1;
+ }
+ break;
+ }
+ }while (res < 0);
+ Undo.SetDisp(cdisp);
+ while(*Undo.pcb > undo_level) Undo.Pop(cdisp);
+ if(res == 1 && (rX=new AccRange(text1)) && (rY=new AccRange(text2)) && (rZ=new AccRange(text3))){
+ //OK pressed
+ if(bNew) { //create function
+ if(Dlg->GetCheck(305)) {
+ type = 0;
+ OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&Line, 0);
+ }
+ else {
+ type = 1;
+ memcpy(&Fill, &newFill, sizeof(FillDEF));
+ Dlg->GetValue(401, &Line.width);
+ Dlg->GetColor(404, &Line.color);
+ Line.pattern = 0L; Line.patlength = 1;
+ }
+ rX->GetFirst(&i, &j); rX->GetNext(&i, &j);
+ rY->GetFirst(&k, &l); rY->GetNext(&k, &l);
+ rZ->GetFirst(&m, &n); rZ->GetNext(&m, &n);
+ do {
+ if(data->GetValue(j, i, &x) && data->GetValue(l, k, &y) && data->GetValue(n, m, &z))
+ CheckBounds3D(x,y,z);
+ }while(rX->GetNext(&i, &j) && rY->GetNext(&k, &l) && rZ->GetNext(&m, &n));
+ x1 = xBounds.fx; x2 = xBounds.fy; xstep = (x2-x1)/10.0;
+ z1 = zBounds.fx; z2 = zBounds.fy; zstep = (z2-z1)/10.0;
+ if(Dlg->GetText(102, TmpTxt)) {
+ if(param) free(param); param = strdup(TmpTxt); ReshapeFormula(¶m);
+ }
+ if(Dlg->GetText(200, TmpTxt)) {
+ if(cmdxy) free(cmdxy); cmdxy = strdup(TmpTxt); ReshapeFormula(&cmdxy);
+ }
+ if((bRet = Update()) && gob && nPlots == 1 && (Balls=(Sphere**)calloc(rX->CountItems(), sizeof(Sphere*)))) {
+ rX->GetFirst(&i, &j); rX->GetNext(&i, &j);
+ rY->GetFirst(&k, &l); rY->GetNext(&k, &l);
+ rZ->GetFirst(&m, &n); rZ->GetNext(&m, &n);
+ rad = defs.GetSize(SIZE_SYMBOL);
+ do {
+ if(data->GetValue(j, i, &x) && data->GetValue(l, k, &y) && data->GetValue(n, m, &z)) {
+ Balls[ns++] = new Sphere(this, data, 0, x, y, z, rad, i, j, k, l, m, n);
+ }
+ }while(rX->GetNext(&i, &j) && rY->GetNext(&k, &l) && rZ->GetNext(&m, &n));
+ if(ns) {
+ plots[1] = (GraphObj*) new Scatt3D(this, data, Balls, ns);
+ nPlots = 2;
+ }
+ else free(Balls);
+ }
+ }
+ else { //edit existing function
+ Dlg->GetValue(102, &x1); Dlg->GetValue(104, &x2);
+ Dlg->GetValue(106, &xstep);
+ Dlg->GetValue(108, &z1); Dlg->GetValue(109, &z2);
+ Dlg->GetValue(110, &zstep); type = Dlg->GetCheck(305) ? 0 : 1;
+ InfoBox("Not Implemented");
+ }
+ }
+ if(rX) delete(rX); if(rY) delete(rY); if(rZ) delete(rZ);
+ CloseDlgWnd(hDlg);
+ delete Dlg;
+ return bRet;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Grid line properties
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool
@@ -6764,28 +7173,35 @@ Tick::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Axis properties dialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *ssTickTmpl =
+ "1,2,,DEFAULT, PUSHBUTTON,-1,113,10,45,12\n"
+ "2,3,,, PUSHBUTTON,-2,113,25,45,12\n"
+ "3,4,,, LTEXT,1,5,10,100,9\n"
+ "4,5,,TOUCHEXIT,RANGEINPUT,4,10,20,90,10\n"
+ "5,6,,, LTEXT,2,5, 32, 100, 9\n"
+ "6,7,,TOUCHEXIT,RANGEINPUT,5,10,42,90,10\n"
+ "7, 8,,,LTEXT,3, 5, 54, 80, 8\n"
+ "8,,,LASTOBJ | TOUCHEXIT,RANGEINPUT,6,10,64,90,10";
+
bool
Axis::ssTicks()
{
- DlgInfo TickDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 113, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 113, 25, 45, 12},
- {3, 4, 0, 0x0L, LTEXT, (void*)"range for major tick VALUES:", 5, 10, 100, 9},
- {4, 5, 0, 0x0L, EDTEXT, (void*)ssMATval, 10, 20, 90, 10},
- {5, 6, 0, 0x0L, LTEXT, (void*)"range for major tick LABELS:", 5, 32, 100, 9},
- {6, 7, 0, 0x0L, EDTEXT, (void*)ssMATlbl, 10, 42, 90, 10},
- {7, 8, 0, 0x0L, LTEXT, (void*)"minor tick VALUES:", 5, 54, 80, 8},
- {8, 0, 0, LASTOBJ, EDTEXT, (void*)ssMITval, 10, 64, 90, 10}};
+ void *dyndata[] ={(void*)"range for major tick VALUES:", (void*)"range for major tick LABELS:",
+ (void*)"minor tick VALUES:", (void*)ssMATval, (void*)ssMATlbl, (void*)ssMITval};
+ DlgInfo *TickDlg = CompileDialog(ssTickTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
int res, n, n1, n2, n3;
- bool bRet = false, bContinue = false;
+ bool bRet = false, bContinue = true;
AccRange *rT, *rL, *rMT;
if(!data) return false;
n = n1 = n2 = n3 = 0; rT = rL = rMT = 0L;
if(!(Dlg = new DlgRoot(TickDlg)))return false;
+ Dlg->ItemCmd(4, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(6, CMD_SET_DATAOBJ, data);
+ Dlg->ItemCmd(8, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd("choose ticks from spreadsheet", 50, 50, 330, 190, Dlg, 0x0L);
+ Dlg->Activate(4, true);
do{
LoopDlgWnd();
res = Dlg->GetResult();
@@ -6793,9 +7209,9 @@ Axis::ssTicks()
case 0: // focus lost
if(bContinue) res = -1;
break;
- case -1:
- bContinue = false;
- break;
+ case 4: case 6: case 8:
+ bContinue = true;
+ res = -1; break;
case 1:
if(rT) delete rT; if(rL) delete rL; if(rMT) delete rMT;
n = n1 = n2 = n3 = 0; rT = rL = rMT = 0L;
@@ -6829,7 +7245,7 @@ Axis::ssTicks()
bRet = true;
}
CloseDlgWnd(hDlg);
- delete Dlg;
+ delete Dlg; free(TickDlg);
if(rT) delete rT; if(rL) delete rL; if(rMT) delete rMT;
return bRet;
}
@@ -7386,27 +7802,30 @@ Axis::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Graph dialogs
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *AddPlotTmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,-1,150,10,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,150,25,45,12\n"
+ "3,,520,ISPARENT | CHECKED,GROUPBOX,1,5,10,135,95\n"
+ "520,521,,EXRADIO | CHECKED,ODBUTTON,2,10,20,25,25\n"
+ "521,522,,EXRADIO,ODBUTTON,2,35,20,25,25\n"
+ "522,523,,EXRADIO,ODBUTTON,2,60,20,25,25\n"
+ "523,524,,EXRADIO,ODBUTTON,2,85,20,25,25\n"
+ "524,525,,EXRADIO,ODBUTTON,2,110,20,25,25\n"
+ "525,526,,EXRADIO,ODBUTTON,2,10,45,25,25\n"
+ "526,528,,EXRADIO,ODBUTTON,2,35,45,25,25\n"
+ "528,529,,EXRADIO,ODBUTTON,2,60,45,25,25\n"
+ "529,530,,EXRADIO,ODBUTTON,2,85,45,25,25\n"
+ "530,531,,EXRADIO,ODBUTTON,2,110,45,25,25\n"
+ "531,532,,EXRADIO,ODBUTTON,2,10,70,25,25\n"
+ "532,540,,EXRADIO,ODBUTTON,2,35,70,25,25\n"
+ "540,541,,EXRADIO,ODBUTTON,2,60,70,25,25\n"
+ "541,,,LASTOBJ | EXRADIO,ODBUTTON, 2, 85,70,25,25";
+
bool
Graph::AddPlot(int family)
{
- DlgInfo GraphDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 150, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 150, 25, 45, 12},
- {3, 0, 520, ISPARENT | CHECKED, GROUPBOX, (void *)" select template ", 5, 10, 135, 95},
- {520, 521, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 10, 20, 25, 25},
- {521, 522, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 35, 20, 25, 25},
- {522, 523, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 60, 20, 25, 25},
- {523, 524, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 85, 20, 25, 25},
- {524, 525, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 110, 20, 25, 25},
- {525, 526, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 10, 45, 25, 25},
- {526, 528, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 35, 45, 25, 25},
- {528, 529, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 60, 45, 25, 25},
- {529, 530, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 85, 45, 25, 25},
- {530, 531, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 110, 45, 25, 25},
- {531, 532, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 10, 70, 25, 25},
- {532, 540, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 35, 70, 25, 25},
- {540, 541, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 60, 70, 25, 25},
- {541, 0, 0, LASTOBJ | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 85, 70, 25, 25}};
+ void *dyndata[] = {(void *)" select template ",(void*)OD_PlotTempl};
+ DlgInfo *GraphDlg = CompileDialog(AddPlotTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
int i, res, cSel = 520;
@@ -7465,11 +7884,92 @@ Graph::AddPlot(int family)
}
else if(p) delete p;
}
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(GraphDlg);
return bRet;
}
+static char *GraphDlgTmpl =
+ "1,2,,DEFAULT, PUSHBUTTON, -1, 170,10,45,12\n"
+ "2,3,,,PUSHBUTTON, -2, 170,25,45,12\n"
+ "3,0,4,ISPARENT | CHECKED,GROUP, 0, 138,40,55,12\n"
+ "4,5,100,ISPARENT | CHECKED,SHEET, 1, 5,10,157,122\n"
+ "5,6,200,ISPARENT,SHEET, 2, 5,10,157,122\n"
+ "6,7,300,ISPARENT,SHEET, 3, 5,10,157,122\n"
+ "100,101,,,LTEXT, 4, 10,25,60,8\n"
+ "101,102,500,TOUCHEXIT | ISPARENT,SHEET, 5, 10,37,147,90\n"
+ "102,103,520,TOUCHEXIT | ISPARENT | CHECKED,SHEET, 6, 10,37,147,90\n"
+ "103,104,540,TOUCHEXIT | ISPARENT,SHEET, 7, 10,37,147,90\n"
+ "104,0,560, TOUCHEXIT | ISPARENT,SHEET, 8, 10,37,147,90\n"
+ "200,201,,,LTEXT, 9, 10,35,60,8\n"
+ "201,202,,,RTEXT, 10, 5,47,58,8\n"
+ "202,203,,,EDVAL1, 11, 64,47,30,10\n"
+ "203,204,,,RTEXT, -5, 95,47,10,8\n"
+ "204,205,,,EDVAL1, 12, 107,47,30,10\n"
+ "205,206,,,LTEXT, -3, 140,47,20,8\n"
+ "206,207,,,RTEXT, 13, 5,59,58,8\n"
+ "207,208,,,EDVAL1, 14, 64,59,30,10\n"
+ "208,209,,,RTEXT, -5, 95,59,10,8\n"
+ "209,210,,,EDVAL1, 15, 107,59,30,10\n"
+ "210,211,,,LTEXT, -3, 140,59,20,8\n"
+ "211,212,,,LTEXT, 16, 10,84,60,8\n"
+ "212,213,,,RTEXT, 17, 5,96,58,8\n"
+ "213,214,,,EDVAL1, 18, 64,96,30,10\n"
+ "214,215,,,RTEXT, -5, 95,96,10,8\n"
+ "215,216,,,EDVAL1, 19, 107,96,30,10\n"
+ "216,217,,,LTEXT, -3, 140,96,20,8\n"
+ "217,218,,,RTEXT, 20, 5,108,58,8\n"
+ "218,219,,,EDVAL1, 21, 64,108,30,10\n"
+ "219,220,,,RTEXT, -5, 95,108,10,8\n"
+ "220,221,,,EDVAL1, 22, 107,108,30,10\n"
+ "221,,,,LTEXT, -3, 140,108,20,8\n"
+ "300,301,,,LTEXT, 23, 20,30,60,8\n"
+ "301,400,310,CHECKED | ISPARENT, GROUP, 0L, 0,0,0,0\n"
+ "310,311,,TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, 24, 20,42,25,25\n"
+ "311,312,,EXRADIO, ODBUTTON, 24, 45,42,25,25\n"
+ "312,313,,EXRADIO, ODBUTTON, 24, 70,42,25,25\n"
+ "313,314,,EXRADIO, ODBUTTON, 24, 95,42,25,25\n"
+ "314,315,,EXRADIO, ODBUTTON, 24, 120,42,25,25\n"
+ "315,316,,CHECKED | TOUCHEXIT, RADIO1, 25, 12,85,40,8\n"
+ "316,317,,TOUCHEXIT, RADIO1, 26, 12,93,40,8\n"
+ "317,318,,TOUCHEXIT, RADIO1, 27, 12,101,40,8\n"
+ "318,319,,TOUCHEXIT, CHECKBOX, 28, 80,85,40,8\n"
+ "319,,,TOUCHEXIT, CHECKBOX, 29, 80,93,40,8\n"
+ "400,,410,HIDDEN | CHECKED | ISPARENT, GROUP, 0L, 0,0,0,0\n"
+ "410,411,,EXRADIO, ODBUTTON, 30, 20,42,25,25\n"
+ "411,412,,EXRADIO, ODBUTTON, 30, 45,42,25,25\n"
+ "412,,,EXRADIO, ODBUTTON, 30, 70,42,25,25\n"
+ "500,501,,EXRADIO | CHECKED, ODBUTTON, 31, 25,60,25,25\n"
+ "501,502,,EXRADIO, ODBUTTON, 31, 50,60,25,25\n"
+ "502,503,,EXRADIO, ODBUTTON, 31, 75,60,25,25\n"
+ "503,504,,EXRADIO, ODBUTTON, 31, 25,85,25,25\n"
+ "504,505,,EXRADIO, ODBUTTON, 31, 50,85,25,25\n"
+ "505,,,EXRADIO, ODBUTTON, 31, 75,85,25,25\n"
+ "520,521,,EXRADIO | CHECKED, ODBUTTON, 31, 20,50,25,25\n"
+ "521,522,,EXRADIO, ODBUTTON, 31, 45,50,25,25\n"
+ "522,523,,EXRADIO, ODBUTTON, 31, 70,50,25,25\n"
+ "523,524,,EXRADIO, ODBUTTON, 31, 95,50,25,25\n"
+ "524,525,,EXRADIO, ODBUTTON, 31, 120,50,25,25\n"
+ "525,526,,EXRADIO, ODBUTTON, 31, 20,75,25,25\n"
+ "526,527,,EXRADIO, ODBUTTON, 31, 45,75,25,25\n"
+ "527,528,,EXRADIO, ODBUTTON, 31, 70,75,25,25\n"
+ "528,529,,EXRADIO, ODBUTTON, 31, 95,75,25,25\n"
+ "529,530,,EXRADIO, ODBUTTON, 31, 120,75,25,25\n"
+ "530,531,,EXRADIO, ODBUTTON, 31, 20,100,25,25\n"
+ "531,532,,EXRADIO, ODBUTTON, 31, 45,100,25,25\n"
+ "532,,,EXRADIO, ODBUTTON, 31, 70,100,25,25\n"
+ "540,541,,EXRADIO | CHECKED, ODBUTTON, 31, 20,60,25,25\n"
+ "541,542,,EXRADIO, ODBUTTON, 31, 45,60,25,25\n"
+ "542,543,,EXRADIO, ODBUTTON, 31, 70,60,25,25\n"
+ "543,544,,EXRADIO, ODBUTTON, 31, 95,60,25,25\n"
+ "544,,,TOUCHEXIT | ISRADIO, ODBUTTON, 31, 120,60,25,25\n"
+ "560,561,,EXRADIO | CHECKED, ODBUTTON, 31,20,60,25,25\n"
+ "561,562,,EXRADIO, ODBUTTON, 31, 45,60,25,25\n"
+ "562,563,,EXRADIO, ODBUTTON, 31, 70,60,25,25\n"
+ "563,564,,EXRADIO, ODBUTTON, 31, 95,60,25,25\n"
+ "564,565,,EXRADIO, ODBUTTON, 31, 120,60,25,25\n"
+ "565,566,,EXRADIO, ODBUTTON, 31, 20,85,25,25\n"
+ "566,,,LASTOBJ | EXRADIO, ODBUTTON, 31, 45,85,25,25";
+
bool
Graph::PropertyDlg()
{
@@ -7480,86 +7980,15 @@ Graph::PropertyDlg()
TabSHEET tab_B = {27, 65, 10, "XY values"};
TabSHEET tab_C = {65, 104, 10, "X, many Y"};
TabSHEET tab_D = {104, 147, 10, "XYZ values"};
- DlgInfo GraphDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 170, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 170, 25, 45, 12},
- {3, 0, 4, ISPARENT | CHECKED, GROUP, 0L, 138, 40, 55, 12},
- {4, 5, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 157, 122},
- {5, 6, 200, ISPARENT, SHEET, &tab2, 5, 10, 157, 122},
- {6, 7, 300, ISPARENT, SHEET, &tab3, 5, 10, 157, 122},
- {100, 101, 0, 0x0L, LTEXT, (void*)"arrangement of data: select plot", 10, 25, 60, 8},
- {101, 102, 500, TOUCHEXIT | ISPARENT, SHEET, &tab_A, 10, 37, 147, 90},
- {102, 103, 520, TOUCHEXIT | ISPARENT | CHECKED, SHEET, &tab_B, 10, 37, 147, 90},
- {103, 104, 540, TOUCHEXIT | ISPARENT, SHEET, &tab_C, 10, 37, 147, 90},
- {104, 0, 560, TOUCHEXIT | ISPARENT, SHEET, &tab_D, 10, 37, 147, 90},
- {200, 201, 0, 0x0L, LTEXT, (void*)"bounding rectangle (relative to page)", 10, 35, 60, 8},
- {201, 202, 0, 0x0L, RTEXT, (void*)"upper left corner x", 5, 47, 58, 8},
- {202, 203, 0, 0x0L, EDVAL1, &GRect.Xmin, 64, 47, 30, 10},
- {203, 204, 0, 0x0L, RTEXT, (void*)"y", 95, 47, 10, 8},
- {204, 205, 0, 0x0L, EDVAL1, &GRect.Ymin, 107, 47, 30, 10},
- {205, 206, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 140, 47, 20, 8},
- {206, 207, 0, 0x0L, RTEXT, (void*)"lower right x", 5, 59, 58, 8},
- {207, 208, 0, 0x0L, EDVAL1, &GRect.Xmax, 64, 59, 30, 10},
- {208, 209, 0, 0x0L, RTEXT, (void*)"y", 95, 59, 10, 8},
- {209, 210, 0, 0x0L, EDVAL1, &GRect.Ymax, 107, 59, 30, 10},
- {210, 211, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 140, 59, 20, 8},
- {211, 212, 0, 0x0L, LTEXT, (void*)"plotting rectangle (relative to bounding rectangle)", 10, 84, 60, 8},
- {212, 213, 0, 0x0L, RTEXT, (void*)"upper left corner x", 5, 96, 58, 8},
- {213, 214, 0, 0x0L, EDVAL1, &DRect.Xmin, 64, 96, 30, 10},
- {214, 215, 0, 0x0L, RTEXT, (void*)"y", 95, 96, 10, 8},
- {215, 216, 0, 0x0L, EDVAL1, &DRect.Ymin, 107, 96, 30, 10},
- {216, 217, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 140, 96, 20, 8},
- {217, 218, 0, 0x0L, RTEXT, (void*)"lower right x", 5, 108, 58, 8},
- {218, 219, 0, 0x0L, EDVAL1, &DRect.Xmax, 64, 108, 30, 10},
- {219, 220, 0, 0x0L, RTEXT, (void*)"y", 95, 108, 10, 8},
- {220, 221, 0, 0x0L, EDVAL1, &DRect.Ymax, 107, 108, 30, 10},
- {221, 0, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 140, 108, 20, 8},
- {300, 301, 0, 0x0L, LTEXT, (void*)"select template:", 20, 30, 60, 8},
- {301, 400, 310, CHECKED | ISPARENT, GROUP, 0L, 0, 0, 0, 0,},
- {310, 311, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl), 20, 42, 25, 25},
- {311, 312, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl), 45, 42, 25, 25},
- {312, 313, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl), 70, 42, 25, 25},
- {313, 314, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl), 95, 42, 25, 25},
- {314, 315, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl), 120, 42, 25, 25},
- {315, 316, 0, CHECKED | TOUCHEXIT, RADIO1, (void*)"ticks outside", 12, 85, 40, 8},
- {316, 317, 0, TOUCHEXIT, RADIO1, (void*)"ticks inside", 12, 93, 40, 8},
- {317, 318, 0, TOUCHEXIT, RADIO1, (void*)"ticks symmetrical", 12, 101, 40, 8},
- {318, 319, 0, TOUCHEXIT, CHECKBOX, (void*)"horizontal grid lines", 80, 85, 40, 8},
- {319, 0, 0, TOUCHEXIT, CHECKBOX, (void*)"vertical grid lines", 80, 93, 40, 8},
- {400, 0, 410, HIDDEN | CHECKED | ISPARENT, GROUP, 0L, 0, 0, 0, 0,},
- {410, 411, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl3D), 20, 42, 25, 25},
- {411, 412, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl3D), 45, 42, 25, 25},
- {412, 0, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_AxisTempl3D), 70, 42, 25, 25},
- {500, 501, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 25, 60, 25, 25},
- {501, 502, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 50, 60, 25, 25},
- {502, 503, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 75, 60, 25, 25},
- {503, 504, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 25, 85, 25, 25},
- {504, 505, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 50, 85, 25, 25},
- {505, 0, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 75, 85, 25, 25},
- {520, 521, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 20, 50, 25, 25},
- {521, 522, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 45, 50, 25, 25},
- {522, 523, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 70, 50, 25, 25},
- {523, 524, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 95, 50, 25, 25},
- {524, 525, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 120, 50, 25, 25},
- {525, 526, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 20, 75, 25, 25},
- {526, 527, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 45, 75, 25, 25},
- {527, 528, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 70, 75, 25, 25},
- {528, 529, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 95, 75, 25, 25},
- {529, 530, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 120, 75, 25, 25},
- {530, 531, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 20, 100, 25, 25},
- {531, 532, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 45, 100, 25, 25},
- {532, 0, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 70, 100, 25, 25},
- {540, 541, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 20, 60, 25, 25},
- {541, 542, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 45, 60, 25, 25},
- {542, 543, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 70, 60, 25, 25},
- {543, 544, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 95, 60, 25, 25},
- {544, 0, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 120, 60, 25, 25},
- {560, 561, 0, TOUCHEXIT | CHECKED | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 20, 60, 25, 25},
- {561, 562, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 45, 60, 25, 25},
- {562, 563, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 70, 60, 25, 25},
- {563, 564, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 95, 60, 25, 25},
- {564, 565, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 120, 60, 25, 25},
- {565, 0, 0, LASTOBJ | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PlotTempl, 20, 85, 25, 25}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)&tab3, (void*)"arrangement of data: select plot",
+ (void*)&tab_A, (void*)&tab_B, (void*)&tab_C, (void*)&tab_D, (void*)"bounding rectangle (relative to page)",
+ (void*)"upper left corner x", (void*)&GRect.Xmin, (void*)&GRect.Ymin, (void*)"lower right x",
+ (void*)&GRect.Xmax, (void*)&GRect.Ymax, (void*)"plotting rectangle (relative to bounding rectangle)",
+ (void*)"upper left corner x", (void*)&DRect.Xmin, (void*)&DRect.Ymin, (void*)"lower right x",
+ (void*)&DRect.Xmax, (void*)&DRect.Ymax, (void*)"select template:", (void*)(OD_AxisTempl),
+ (void*)"ticks outside", (void*)"ticks inside", (void*)"ticks symmetrical", (void*)"horizontal grid lines",
+ (void*)"vertical grid lines", (void*)(OD_AxisTempl3D), (void*)(OD_PlotTempl)};
+ DlgInfo *GraphDlg = CompileDialog(GraphDlgTmpl, dyndata);
DlgRoot *Dlg;
GraphObj *p;
void *hDlg;
@@ -7636,7 +8065,7 @@ Graph::PropertyDlg()
case 540: case 541: case 542: case 543:
case 544:
case 560: case 561: case 562: case 563:
- case 564: case 565:
+ case 564: case 565: case 566:
if(res != selPlt) {
selPlt = res;
res = -1;
@@ -7716,6 +8145,7 @@ Graph::PropertyDlg()
else if(Dlg->GetCheck(563)) p = new BubblePlot3D(this, data);
else if(Dlg->GetCheck(564)) p = new Plot3D(this, data, 0x2000);
else if(Dlg->GetCheck(565)) p = new Func3D(this, data);
+ else if(Dlg->GetCheck(566)) p = new FitFunc3D(this, data);
}
if(p && p->PropertyDlg()) {
if(!Command(CMD_DROP_PLOT, p, 0L)) DeleteGO(p);
@@ -7735,8 +8165,7 @@ Graph::PropertyDlg()
}while(res <0);
if(!bRet) parent->Command(CMD_DELOBJ, this, NULL);
else Command(CMD_SET_DATAOBJ, (void*)data, 0L);
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(GraphDlg);
return bRet;
}
@@ -7908,6 +8337,49 @@ Graph::Configure()
return bRet;
}
+static char *AddAxisTmpl =
+ "1,2,,DEFAULT, PUSHBUTTON,-1,148,10,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,148,25,45,12\n"
+ "3,,4,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "4,5,50,TOUCHEXIT | ISPARENT,SHEET,1,5,10,130,130\n"
+ "5,6,200,ISPARENT | CHECKED,SHEET,2,5,10,130,130\n"
+ "6,,300,ISPARENT,SHEET,3,5,10,130,130\n"
+ "50,51,100,ISPARENT | CHECKED,GROUPBOX,4,10,30,120,36\n"
+ "51,120,,,CHECKBOX,5,17,37,80,8\n"
+ "100,101,,,RTEXT,6,10,51,35,8\n"
+ "101,102,,,EDVAL1,7,48,51,32,10\n"
+ "102,103,,,CTEXT,8,81,51,11,8\n"
+ "103,,,,EDVAL1,9,93,51,32,10\n"
+ "120,,121,ISPARENT | CHECKED,GROUPBOX,10,10,72,120,20\n"
+ "121,122,,,RTEXT,11,10,77,25,8\n"
+ "122,123,,,EDVAL1,12,37,77,25,10\n"
+ "123,124,,,LTEXT,-3,63,77,10,8\n"
+ "124,125,,,RTEXT,13,73,77,25,8\n"
+ "125,130,,OWNDIALOG,COLBUTT,14,100,77,25,10\n"
+ "130,131,,ISPARENT | CHECKED,GROUPBOX,15,10,98,120,20\n"
+ "131,,,,EDTEXT,0,15,103,110,10\n"
+ "200,201,,,LTEXT,16,10,30,70,9\n"
+ "201,202,,CHECKED | EXRADIO,ODBUTTON,17,20,42,25,25\n"
+ "202,203,,EXRADIO,ODBUTTON,17,45,42,25,25\n"
+ "203,204,,EXRADIO,ODBUTTON,17,70,42,25,25\n"
+ "204,205,,EXRADIO,ODBUTTON,17,95,42,25,25\n"
+ "205,206,,EXRADIO,ODBUTTON,17,20,67,25,25\n"
+ "206,207,,EXRADIO,ODBUTTON,17,45,67,25,25\n"
+ "207,208,,EXRADIO,ODBUTTON,17,70,67,25,25\n"
+ "208,210,,EXRADIO,, ODBUTTON,17,95,67,25,25\n"
+ "210,,220,ISPARENT | CHECKED, GROUPBOX,18,10,97,120,35\n"
+ "220,221,,,RTEXT,-4,10,105,15,8\n"
+ "221,222,,,EDVAL1,19,27,105,35,10\n"
+ "222,223,,,LTEXT,-7,65,105,5,8\n"
+ "223,224,,,EDVAL1,20,71,105,35,10\n"
+ "224,225,,,LTEXT,-3,109,105,15,8\n"
+ "225,226,,,RTEXT,-5,10,117,15,8\n"
+ "226,227,,,EDVAL1,21,27,117,35,10\n"
+ "227,228,,,LTEXT,-7,65,117,5,8\n"
+ "228,229,,,EDVAL1,22,71,117,35,10\n"
+ "229,,,,LTEXT,-3,109,117,15,8\n"
+ "300,,,LASTOBJ | NOSELECT,ODBUTTON,23,15,30,110,140\n";
+
bool
Graph::AddAxis()
{
@@ -7917,49 +8389,12 @@ Graph::AddAxis()
AxisDEF axis;
double sizAxLine = defs.GetSize(SIZE_AXIS_LINE);
DWORD colAxis = ColAX;
- DlgInfo NewAxisDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 148, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 148, 25, 45, 12},
- {3, 0, 4, ISPARENT | CHECKED, GROUP, NULL, 138, 40, 55, 12},
- {4, 5, 50, TOUCHEXIT | ISPARENT, SHEET, &tab1, 5, 10, 130, 130},
- {5, 6, 200, ISPARENT | CHECKED, SHEET, &tab2, 5, 10, 130, 130},
- {6, 0, 300, ISPARENT, SHEET, &tab3, 5, 10, 130, 130},
- {50, 51, 100, ISPARENT | CHECKED, GROUPBOX, (void*)" scaling ", 10, 30, 120, 36},
- {51, 120, 0, 0x0L, CHECKBOX, (void*)" automatic scaling", 17, 37, 80, 8},
- {100, 101, 0, 0x0L, RTEXT, (void*)"axis from", 10, 51, 35, 8},
- {101, 102, 0, 0x0L, EDVAL1, &y_axis.min, 48, 51, 32, 10},
- {102, 103, 0, 0x0L, CTEXT, (void*)"to", 81, 51, 11, 8},
- {103, 0, 0, 0x0L, EDVAL1, &y_axis.max, 93, 51, 32, 10},
- {120, 0, 121, ISPARENT | CHECKED, GROUPBOX, (void*)" line ", 10, 72, 120, 20},
- {121, 122, 0, 0x0L, RTEXT, (void*)"width", 10, 77, 25, 8},
- {122, 123, 0, 0x0L, EDVAL1, &sizAxLine, 37, 77, 25, 10},
- {123, 124, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 63, 77, 10, 8},
- {124, 125, 0, 0x0L, RTEXT, (void*)"color", 73, 77, 25, 8},
- {125, 130, 0, OWNDIALOG, COLBUTTON, (void *)colAxis, 100, 77, 25, 10},
- {130, 131, 0, ISPARENT | CHECKED, GROUPBOX, (void*)" axis label ", 10, 98, 120, 20},
- {131, 0, 0, 0x0L, EDTEXT, (void*)0L, 15, 103, 110, 10},
- {200, 201, 0, 0x0L, LTEXT, (void*)"select a template:", 10, 30, 70, 9},
- {201, 202, 0, CHECKED | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 20, 42, 25, 25},
- {202, 203, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 45, 42, 25, 25},
- {203, 204, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 70, 42, 25, 25},
- {204, 205, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 95, 42, 25, 25},
- {205, 206, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 20, 67, 25, 25},
- {206, 207, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 45, 67, 25, 25},
- {207, 208, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 70, 67, 25, 25},
- {208, 210, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_NewAxisTempl), 95, 67, 25, 25},
- {210, 0, 220, ISPARENT | CHECKED, GROUPBOX, (void*)" placement ", 10, 97, 120, 35},
- {220, 221, 0, 0x0L, RTEXT, (void*)"x", 10, 105, 15, 8},
- {221, 222, 0, 0x0L, EDVAL1, &axis.loc[0].fx, 27, 105, 35, 10},
- {222, 223, 0, 0x0L, LTEXT, (void*)"-", 65, 105, 5, 8},
- {223, 224, 0, 0x0L, EDVAL1, &axis.loc[1].fx, 71, 105, 35, 10},
- {224, 225, 0, 0x0L, LTEXT, (void*)Units[units].display, 109, 105, 15, 8},
- {225, 226, 0, 0x0L, RTEXT, (void*)"y", 10, 117, 15, 8},
- {226, 227, 0, 0x0L, EDVAL1, &axis.loc[0].fy, 27, 117, 35, 10},
- {227, 228, 0, 0x0L, LTEXT, (void*)"-", 65, 117, 5, 8},
- {228, 229, 0, 0x0L, EDVAL1, &axis.loc[1].fy, 71, 117, 35, 10},
- {229, 0, 0, 0x0L, LTEXT, (void*)Units[units].display, 109, 117, 15, 8},
- {300, 0, 0, NOSELECT, ODBUTTON, (void*)OD_axisplot, 15, 30, 110, 140},
- {400, 0, 0, LASTOBJ, NONE, 0L, 0, 0, 0, 0}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)&tab3, (void*)" scaling ", (void*)" automatic scaling",
+ (void*)"axis from", (void*)&y_axis.min, (void*)"to", (void*)&y_axis.max, (void*)" line ", (void*)"width",
+ (void*)&sizAxLine, (void*)"color", (void *)&colAxis, (void*)" axis label ", (void*)"select a template:",
+ (void*)(OD_NewAxisTempl), (void*)" placement ", (void*)&axis.loc[0].fx, (void*)&axis.loc[1].fx,
+ (void*)&axis.loc[0].fy, (void*)&axis.loc[1].fy, (void*)OD_axisplot};
+ DlgInfo *NewAxisDlg = CompileDialog(AddAxisTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
int i, j, res, currTempl = 201;
@@ -8138,8 +8573,7 @@ Graph::AddAxis()
}
}
}
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(NewAxisDlg);
if(names) {
for(j = 0; names[j]; j++) if(names[j]) free(names[j]);
free(names);
@@ -8201,24 +8635,41 @@ Page::Configure()
bool
Default::PropertyDlg()
{
- TabSHEET tab1 = {0, 25, 10, "Line"};
- TabSHEET tab2 = {25, 60, 10, "Shapes"};
- TabSHEET tab3 = {60, 93, 10, "Dialogs"};
- TabSHEET tab4 = {93, 128, 10, "Internat."};
+ TabSHEET tab1 = {0, 22, 10, "Line"};
+ TabSHEET tab2 = {22, 52, 10, "Shapes"};
+ TabSHEET tab3 = {52, 82, 10, "Dialogs"};
+ TabSHEET tab4 = {82, 116, 10, "Internat."};
+ TabSHEET tab5 = {116, 155, 10, "Date/Time"};
double ts = dlgtxtheight;
+ time_t ti = time(0L);
+ char dt_info[50], date_info[50], datetime_info[50], time_info[50];
DlgInfo DefsDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 150, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 150, 25, 45, 12},
+ {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 180, 10, 40, 12},
+ {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 180, 25, 40, 12},
{3, 0, 4, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
- {4, 5, 100, TOUCHEXIT | ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 139, 120},
- {5, 6, 200, TOUCHEXIT | ISPARENT, SHEET, &tab2, 5, 10, 139, 120},
- {6, 7, 300, ISPARENT, SHEET, &tab3, 5, 10, 139, 120},
- {7, 0, 400, ISPARENT, SHEET, &tab4, 5, 10, 139, 120},
+ {4, 5, 100, TOUCHEXIT | ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 170, 130},
+ {5, 6, 200, TOUCHEXIT | ISPARENT, SHEET, &tab2, 5, 10, 170, 130},
+ {6, 7, 300, TOUCHEXIT | ISPARENT, SHEET, &tab3, 5, 10, 170, 130},
+ {7, 8, 400, TOUCHEXIT | ISPARENT, SHEET, &tab4, 5, 10, 170, 130},
+ {8, 0, 350, TOUCHEXIT | ISPARENT, SHEET, &tab5, 5, 10, 170, 130},
{100, 0, 0, NOSELECT, ODBUTTON, (void*)OD_linedef, 10, 38, 130, 100},
{200, 0, 0, NOSELECT, ODBUTTON, (void*)OD_filldef, 25, 40, 90, 50},
{300, 301, 0, 0x0L, RTEXT, (void*)"text size", 20, 30, 38, 8},
{301, 302, 0, 0x0L, EDVAL1, (void*)&ts, 60, 30, 20, 10},
{302, 0, 0, 0x0L, LTEXT, (void*)"pixel", 82, 30, 20, 8},
+ {350, 351, 0, 0x0L, LTEXT, (void*)dt_info, 10, 30, 120, 8},
+ {351, 352, 0, 0x0L, LTEXT, (void*)"date format:", 10, 43, 70, 8},
+ {352, 353, 0, 0x0L, EDTEXT, (void*)defs.fmt_date, 10, 53, 60, 10},
+ {353, 354, 0, 0x0L, LTEXT, (void*)date_info, 80, 54, 40, 10},
+ {354, 355, 0, 0x0L, LTEXT, (void*)"date + time format:", 10, 65, 70, 8},
+ {355, 356, 0, 0x0L, EDTEXT, (void*)defs.fmt_datetime, 10, 75, 60, 10},
+ {356, 357, 0, 0x0L, LTEXT, (void*)datetime_info, 80, 76, 40, 10},
+ {357, 358, 0, 0x0L, LTEXT, (void*)"time format:", 10, 87, 70, 8},
+ {358, 359, 0, 0x0L, EDTEXT, (void*)defs.fmt_time, 10, 97, 60, 10},
+ {359, 360, 0, 0x0L, LTEXT, (void*)time_info, 80, 98, 40, 10},
+ {360, 361, 0, 0x0L, LTEXT, (void*)"For further information about formats see", 10, 119, 140, 8},
+ {361, 362, 0, HREF | TOUCHEXIT, LTEXT, (void*)"http://rlplot.sourceforge.net/Docs/functions/datetime.html", 10, 127, 140, 8},
+ {362, 0, 0, 0x0L, PUSHBUTTON, (void*)"Test", 130, 107, 40, 12},
{400, 401, 0, 0x0L, LTEXT, (void*)"edit country specific information", 20, 30, 100, 8},
{401, 402, 0, 0x0L, RTEXT, (void*)"decimal point", 45, 45, 40, 8},
{402, 403, 0, 0x0L, EDTEXT, (void*)DecPoint, 90, 45, 10, 10},
@@ -8231,27 +8682,61 @@ Default::PropertyDlg()
{422, 0, 0, LASTOBJ, RADIO1, (void*)Units[2].display, 75, 91, 20, 8}};
DlgRoot *Dlg;
void *hDlg;
- int res, tmpUnits = cUnits;
- bool bRet = false;
+ int i, res, tmpUnits = cUnits;
+ bool bRet = false, bContinue = false;
+ double dt;
LineDEF LineDef;
FillDEF FillDef;
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)GetLine(), 0);
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)GetOutLine(), 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)GetFill(), 0);
+ sprintf(dt_info, "today is %s", ctime(&ti));
+ dt_info[33] = 0;
+ date_value(dt_info+13, "x z H:M:S Y", &dt);
+ strcpy(date_info, value_date(dt, defs.fmt_date));
+ strcpy(datetime_info, value_date(dt, defs.fmt_datetime));
+ strcpy(time_info, value_date(dt, defs.fmt_time));
Dlg = new DlgRoot(DefsDlg);
switch(dUnits) {
case 1: Dlg->SetCheck(421, 0L, true); break;
case 2: Dlg->SetCheck(422, 0L, true); break;
default: Dlg->SetCheck(420, 0L, true); break;
}
- hDlg = CreateDlgWnd("Edit Global Preferences", 50, 50, 410, 300, Dlg, 0x0L);
+#ifdef _WINDOWS
+ for(i = 360; i <= 361; i++) Dlg->TextSize(i, 12);
+#else
+ for(i = 360; i <= 361; i++) Dlg->TextSize(i, 10);
+#endif
+ hDlg = CreateDlgWnd("Edit Global Preferences", 50, 50, 460, 316, Dlg, 0x0L);
do{
LoopDlgWnd();
res = Dlg->GetResult();
switch(res) {
- case 4: case 5:
- res = -1;
+ case 0:
+ if(bContinue) res = -1;
+ break;
+ case 362: //update date/time display
+ ti = time(0L);
+ sprintf(dt_info, "today is %s", ctime(&ti));
+ dt_info[33] = 0; Dlg->SetText(350, dt_info);
+ date_value(dt_info+13, "x z H:M:S Y", &dt);
+ if(!(Dlg->GetText(352, date_info))) strcpy(date_info, defs.fmt_date);
+ strcpy(date_info, value_date(dt, date_info)); Dlg->SetText(353, date_info);
+ if(!(Dlg->GetText(355, datetime_info))) strcpy(datetime_info, defs.fmt_datetime);
+ strcpy(datetime_info, value_date(dt, datetime_info)); Dlg->SetText(356, datetime_info);
+ if(!(Dlg->GetText(358, time_info))) strcpy(time_info, defs.fmt_time);
+ strcpy(time_info, value_date(dt, time_info)); Dlg->SetText(359, time_info);
+ bContinue = false; res = -1;
+ break;
+ case 361: //call browser
+ bContinue = true; res = -1;
+ break;
+ case 4: case 5: case 6: case 7:
+ bContinue = false; res = -1;
+ break;
+ case 8:
+ bContinue = true; res = -1;
break;
case 1:
if(Dlg->GetCheck(421)) dUnits = 1;
@@ -8262,7 +8747,6 @@ Default::PropertyDlg()
if(res == 1) {
if(Dlg->GetText(402, TmpTxt)) DecPoint[0] = TmpTxt[0];
if(Dlg->GetText(404, TmpTxt)) ColSep[0] = TmpTxt[0];
- bRet = true;
OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
SetLine(tmpUnits, &LineDef, 0);
OD_filldef(OD_GETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
@@ -8270,6 +8754,19 @@ Default::PropertyDlg()
OD_filldef(OD_GETFILL, 0L, 0L, 0L, (void *)&FillDef, 0);
SetFill(tmpUnits, &FillDef);
Dlg->GetInt(301, &dlgtxtheight);
+ if(Dlg->GetText(352, date_info) && date_info[0] && strcmp(date_info, defs.fmt_date)) {
+ if(defs.fmt_date) free(defs.fmt_date);
+ defs.fmt_date = strdup(date_info);
+ }
+ if(Dlg->GetText(355, datetime_info) && datetime_info[0] && strcmp(datetime_info, defs.fmt_datetime)) {
+ if(defs.fmt_datetime) free(defs.fmt_datetime);
+ defs.fmt_datetime = strdup(datetime_info);
+ }
+ if(Dlg->GetText(358, time_info) && time_info[0] && strcmp(time_info, defs.fmt_time)) {
+ if(defs.fmt_time) free(defs.fmt_time);
+ defs.fmt_time = strdup(time_info);
+ }
+ bRet = true;
}
CloseDlgWnd(hDlg);
delete Dlg;
diff --git a/QT_Spec.cpp b/QT_Spec.cpp
index 221de54..b9314ca 100755
--- a/QT_Spec.cpp
+++ b/QT_Spec.cpp
@@ -1,4 +1,4 @@
-//QT_Spec.cpp, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
+//QT_Spec.cpp, Copyright (c) 2001-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -27,7 +27,8 @@
#include <qcstring.h>
#include <qclipboard.h>
#include <qbuffer.h>
-#include <qbitmap.h>
+#include <qbitmap.h>
+#include <qtextstream.h>
#include <stdio.h>
#include <stdlib.h>
@@ -71,39 +72,58 @@ POINT CurrWidgetPos = {0,0};
#define CM_PRINT 517
#define CM_EXPORT 518
#define CM_DELOBJ 519
-#define CM_DEFAULTS 520
-#define CM_COPY 521
-#define CM_PASTE 522
-#define CM_UPDATE 523
-#define CM_ADDAXIS 524
-#define CM_UNDO 525
-#define CM_ZOOMIN 526
-#define CM_ZOOMOUT 527
-#define CM_ZOOMFIT 528
-#define CM_FILE1 529
-#define CM_FILE2 530
-#define CM_FILE3 531
-#define CM_FILE4 532
-#define CM_FILE5 533
-#define CM_FILE6 534
-#define CM_FILLRANGE 535
-#define CM_CUT 536
-#define CM_LEGEND 537
-#define CM_LAYERS 538
-#define CM_INSROW 539
-#define CM_INSCOL 540
-#define CM_DELROW 541
-#define CM_DELCOL 542
+#define CM_DEFAULTS 522
+#define CM_COPY 523
+#define CM_PASTE 524
+#define CM_UPDATE 525
+#define CM_ADDAXIS 526
+#define CM_UNDO 527
+#define CM_ZOOMIN 528
+#define CM_ZOOMOUT 529
+#define CM_ZOOMFIT 530
+#define CM_FILE1 531
+#define CM_FILE2 532
+#define CM_FILE3 533
+#define CM_FILE4 534
+#define CM_FILE5 535
+#define CM_FILE6 536
+#define CM_FILLRANGE 537
+#define CM_CUT 538
+#define CM_LEGEND 539
+#define CM_LAYERS 540
+#define CM_INSROW 541
+#define CM_INSCOL 542
+#define CM_DELROW 543
+#define CM_DELCOL 544
+#define CM_SAVEDATA 545
-#define CM_T_STANDARD 560
-#define CM_T_DRAW 561
-#define CM_T_POLYLINE 562
-#define CM_T_POLYGON 563
-#define CM_T_RECTANGLE 564
-#define CM_T_ROUNDREC 565
-#define CM_T_ELLIPSE 566
-#define CM_T_ARROW 567
-#define CM_T_TEXT 568
+#define CM_T_STANDARD 550
+#define CM_T_DRAW 551
+#define CM_T_POLYLINE 552
+#define CM_T_POLYGON 553
+#define CM_T_RECTANGLE 554
+#define CM_T_ROUNDREC 555
+#define CM_T_ELLIPSE 556
+#define CM_T_ARROW 557
+#define CM_T_TEXT 558
+
+#define CM_DELKEY 600
+#define CM_LEFTARRKEY 601
+#define CM_RIGHTARRKEY 602
+#define CM_UPARRKEY 603
+#define CM_DOWNARRKEY 604
+#define CM_TAB 605
+#define CM_SHTAB 606
+#define CM_PGUP 607
+#define CM_PGDOWN 608
+#define CM_POS_FIRST 609
+#define CM_POS_LAST 610
+#define CM_SHLEFT 611
+#define CM_SHRIGHT 612
+#define CM_SHUP 613
+#define CM_SHDOWN 614
+#define CM_SHPGUP 615
+#define CM_SHPGDOWN 616
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Exute a file open dialog for the different situations
@@ -111,15 +131,23 @@ POINT CurrWidgetPos = {0,0};
static char UserFileName[600];
// Get a new file name to store data in
char *SaveDataAsName(char *oldname)
-{
- QString fileName = QFileDialog::getSaveFileName(oldname?oldname:defs.currPath,
- "RLPlot workbook (*.rlw)\ndata files (*.csv)\ntab separated (*.tsv)\nXML (*.xml)", QAppl->focusWidget());
- if(!fileName.isEmpty()){
- strcpy(UserFileName, fileName);
- defs.FileHistory(UserFileName);
- return UserFileName;
- }
- return 0L;
+{
+ QFileDialog qf(0,0,true);
+ QString filters("RLPlot workbook (*.rlw);;data files (*.csv);;"
+ "tab separated (*.tsv);;XML (*.xml)");
+
+ qf.setFilters(filters); qf.setDir(defs.currPath);
+ qf.setSelection(oldname); qf.setMode(QFileDialog::AnyFile);
+ if(qf.exec() == QDialog::Accepted) {
+// InfoBox((char*)qf.selectedFilter().ascii());
+// InfoBox((char*)qf.selectedFile().ascii());
+ if(!qf.selectedFile().isEmpty()) {
+ strcpy(UserFileName, (char*)qf.selectedFile().ascii());
+ defs.FileHistory(UserFileName);
+ return UserFileName;
+ }
+ }
+ return 0L;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -376,238 +404,281 @@ TxtCurBlink::timerEvent(QTimerEvent *ev)
}
}
}
-
-#define MIME_KSPREAD "application/x-kspread-snippet"
-#define MIME_RLPLOT "application/x-rlplot-snippet"
-#define MIME_RLPGRAPH "application/x-rlplot-graph"
-#define MIME_RLPOBJ "application/x-rlplot-object"
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Clipboard support
-// based on KDEs KSpread source: kspread_table.cc
-// copyright (C) 1998, 1999 Torben Weis
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-KSpreadTextDrag::KSpreadTextDrag(QWidget *dragSource, const char *name )
- :QTextDrag(dragSource, name)
-{
- go = 0L;
-}
-
-KSpreadTextDrag::~KSpreadTextDrag()
-{
-}
-
-bool
-KSpreadTextDrag::provides(const char *mimeType)
-{
- if(0 == strcmp(mimeType, "text/plain")) return true;
- if(0 == strcmp(mimeType, MIME_RLPLOT)) return true;
- if(0 == strcmp(mimeType, selectionMimeType())) return true;
- return false;
-}
-
-QByteArray
-KSpreadTextDrag::encodedData(const char *mime) const
-{
- static QByteArray b;
- char *ptr = 0L;
- long cb;
-
- if(!go || go->Id != GO_SPREADDATA) return 0L;
- if(0 == strcmp(mime, MIME_RLPLOT)) {
- go->Command(CMD_COPY_XML, &ptr, 0L);
- }
- else if(0 == strcmp(mime, "text/plain")) {
- go->Command(CMD_COPY_TSV, &ptr, 0L);
- }
- else if(0 == strcmp(mime, selectionMimeType())){
- go->Command(CMD_COPY_XML, &ptr, 0L);
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Clipboard support: the clipboard server uses sockets
+// code based on Qt example code
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#define MIME_KSPREAD "application/x-kspread-snippet"
+
+#ifdef RLP_PORT
+static RLPserver *rlpsrv = 0L;
+
+ReadCB::ReadCB(QObject *parent, const char *name, GraphObj *g):QSocket(parent, name)
+{
+ par = parent; DestGO = g; res= 0L; level = 0; format = 0L;
+ connect(this, SIGNAL(connected()), SLOT(isConnected()));
+ connect(this, SIGNAL(readyRead()), SLOT(receiveData()));
+ connect(this, SIGNAL(connectionClosed()), SLOT(endData()));
+ connect(this, SIGNAL(error(int)), SLOT(isError(int)));
+ connectToHost("localhost", RLP_PORT);
+}
+
+ReadCB::~ReadCB()
+{
+ if(res) delete res; res= 0L;
+ if(format) free(format); format = 0L;
+}
+
+void
+ReadCB::isConnected()
+{
+ QTextStream ts(this);
+ ts << "enum formats\n";
+ res = new QString();
+}
+
+void
+ReadCB::receiveData()
+{
+ char *line;
+
+ QTextStream ts(this);
+ if(!level) while(canReadLine()){
+ QString s = ts.readLine();
+ if(DestGO && (DestGO->Id == GO_SPREADDATA || DestGO->Id == GO_PAGE || DestGO->Id == GO_GRAPH)) {
+ if(s == "text/xml" || s == "text/rlp-graph" || s == "text/rlp-page") {
+ while(bytesAvailable()) getch();
+ format = strdup(s.ascii()); level = 1;
+ ts << "get " << s << "\n";
+ }
+ }
}
- else return 0L;
- if(!ptr) ptr = (char*)calloc(cb = 4, 1);
- else cb = strlen(ptr)+1;
- if(ptr && b.resize(cb)) {
- memcpy(b.data(), ptr, cb);
- free (ptr);
- return (b);
- }
- return 0L;
-}
-
-bool
-KSpreadTextDrag::canDecode(QMimeSource *e)
-{
- if(e->provides(selectionMimeType())) return true;
- return false;
-}
-
-const char *
-KSpreadTextDrag::format(int i) const
-{
- static const char *fmt;
-
- switch(i) {
- case 0: case 1:
- fmt = "text/plain";
- return fmt;
- case 2:
- case 3: case 4:
- return selectionMimeType();
- default:
- return 0L;
- }
-}
-
-const char *
-KSpreadTextDrag::selectionMimeType()
-{
- return(MIME_RLPLOT);
-}
-
-RLPGraphDrag::RLPGraphDrag(QWidget *dragSource, const char *name)
- :QTextDrag(dragSource, name)
-{
- go1 = go2 = 0L;
-}
-
-RLPGraphDrag::~RLPGraphDrag()
-{
-}
-
-bool
-RLPGraphDrag::provides(const char *mimeType)
-{
- if(go1 && 0 == strcmp(mimeType, MIME_RLPGRAPH)) return true;
- if(go2 && 0 == strcmp(mimeType, MIME_RLPOBJ)) return true;
- return false;
-}
-
-void
-RLPGraphDrag::setGraphData(GraphObj *g)
-{
- go1 = g;
- if(CurrGraph && CurrGraph != g) go2 = CurrGraph;
- else go2 = 0L;
-}
-
-QByteArray
-RLPGraphDrag::encodedData(const char* mime) const
-{
- static QByteArray b;
- char *ptr = 0L;
- long cb;
-
- if(0 == strcmp(mime, "text/plain")) return 0L;
- else if(go1 && 0 == strcmp(mime, MIME_RLPGRAPH)) ptr = GraphToMem(go1, &cb);
- else if(go2 && 0 == strcmp(mime, MIME_RLPOBJ)) ptr = GraphToMem(go2, &cb);
- else return 0L;
- if(ptr && b.resize(cb+1)) {
- memcpy(b.data(), ptr, cb+1);
- free (ptr);
- return (b);
- }
- return 0L;
-}
-
-const char*
-RLPGraphDrag::format(int i) const
-{
- switch(i) {
- case 0: return("text/plain");
- case 1: return MIME_RLPGRAPH;
- case 2: return MIME_RLPOBJ;
- default: return 0L;
- }
-}
-
-bool
-RLPGraphDrag::canDecode(QMimeSource *e)
-{
- if(e->provides(MIME_RLPGRAPH)) return true;
- if(e->provides(MIME_RLPOBJ)) return true;
- return false;
-}
-
-const char*
-RLPGraphDrag::selectionMimeType()
-{
- return(MIME_RLPGRAPH);
-}
-
+ else while(canReadLine()) {
+ res->append(ts.readLine());
+ res->append("\n");
+ }
+}
+
+void
+ReadCB::endData()
+{
+ receiveData();
+ if(res && res->length() > 5 && DestGO && DestGO->Id == GO_SPREADDATA) {
+ if(strcmp(format, "text/xml") == 0) DestGO->Command(CMD_PASTE_XML, (void*)res->ascii(), 0L);
+ if(strcmp(format, "text/rlp-graph") == 0) OpenGraph(DestGO, 0L, (unsigned char*)res->ascii(), true);
+ if(strcmp(format, "text/rlp-page") == 0) OpenGraph(DestGO, 0L, (unsigned char*)res->ascii(), true);
+ }
+ else if(res && res->length() > 5 && DestGO && (DestGO->Id == GO_PAGE || DestGO->Id == GO_GRAPH)) {
+ if(strcmp(format, "text/rlp-graph") == 0) OpenGraph(DestGO, 0L, (unsigned char*)res->ascii(), true);
+ if(strcmp(format, "text/rlp-page") == 0) OpenGraph(DestGO, 0L, (unsigned char*)res->ascii(), true);
+ }
+ if(res) delete res; res= 0L;
+ delete this;
+}
+
+void
+ReadCB::isError(int)
+{
+ QClipboard *cb;
+ QDragObject *mime;
+
+ if((cb = QAppl->clipboard()) && (mime = (QDragObject *)cb->data())) {
+ if(DestGO && DestGO->Id == GO_SPREADDATA) {
+ if(mime->provides(MIME_KSPREAD)){
+ QByteArray b = mime->encodedData(MIME_KSPREAD);
+ if(b) DestGO->Command(CMD_PASTE_XML, (void*)b.data(), 0L);
+ delete this; return;
+ }
+ else if(mime->provides("text/plain")){
+ ProcMemData(DestGO, (unsigned char*)cb->text().latin1(), true);
+ delete this; return;
+ }
+ }
+ }
+ delete this;
+}
+
+RLPsock::RLPsock(int sock, QObject *parent, const char *name, GraphObj *g):QSocket(parent, name)
+{
+ par = parent; SourceGO = g;
+ connect(this, SIGNAL(readyRead()), SLOT(readClient()));
+ connect(this, SIGNAL(connectionClosed()), SLOT(deleteLater()));
+ setSocket(sock);
+}
+
+void
+RLPsock::readClient()
+{
+ char *ptr = 0L;
+ const char *cmd;
+
+ //allow only connetions from local host
+ /*
+ if(peerAddress().toString() != "127.0.0.1") {close(); return;}
+ */
+ QTextStream ts(this);
+ while(canReadLine()) {
+ QString str = ts.readLine();
+ cmd = str.ascii();
+ if(strcmp(cmd, "close") == 0) {
+ close();
+ if(rlpsrv && par) delete par;
+ return;
+ }
+ else if(strcmp(cmd, "exit") == 0) {
+ close();
+ if(rlpsrv && par) delete par;
+ return;
+ }
+ else if(strcmp(cmd, "enum formats") == 0) {
+ if(SourceGO && SourceGO->Id == GO_SPREADDATA) {
+ ts << "text/xml\n";
+ if(((RLPserver*)par)->GetTXT()) ts << "text/plain\n";
+ }
+ else if(SourceGO && SourceGO->Id == GO_GRAPH) ts << "text/rlp-graph\n";
+ else if(SourceGO && SourceGO->Id == GO_PAGE) ts << "text/rlp-page\n";
+ else close();
+ }
+ else if(strcmp(cmd, "get text/xml") == 0) {
+ if(SourceGO && SourceGO->Id == GO_SPREADDATA) {
+ if(ptr = ((RLPserver*)par)->GetXML()) ts << ptr;
+ }
+ close();
+ }
+ else if(strcmp(cmd, "get text/rlp-graph") == 0 || strcmp(cmd, "get text/rlp-page") == 0) {
+ if(SourceGO && (SourceGO->Id == GO_GRAPH || SourceGO->Id == GO_PAGE)) {
+ if(ptr = ((RLPserver*)par)->GetRLP()) ts << ptr;
+ }
+ close();
+ }
+ else if(strcmp(cmd, "get text/plain") == 0) {
+ if(SourceGO && SourceGO->Id == GO_SPREADDATA) {
+ if(ptr = ((RLPserver*)par)->GetTXT()) ts << ptr;
+ }
+ close();
+ }
+ else close();
+ }
+}
+
+
+RLPserver::RLPserver(QObject* parent, GraphObj *g):QServerSocket(RLP_PORT, 4, parent)
+{
+ text_xml = text_rlp = text_plain = 0L;
+ SetGO(g);
+}
+
+RLPserver::~RLPserver()
+{
+ rlpsrv = 0L;
+ HideCopyMark();
+ if(text_xml) free(text_xml); text_xml = 0L;
+ if(text_rlp) free(text_rlp); text_rlp = 0L;
+ if(text_plain) free(text_plain); text_plain = 0L;
+}
+
+void
+RLPserver::SetGO(GraphObj *g)
+{
+ QClipboard *cb;
+
+ SourceGO = g;
+ if(text_xml) free(text_xml); text_xml = 0L;
+ if(text_rlp) free(text_rlp); text_rlp = 0L;
+ if(text_plain) free(text_plain); text_plain = 0L;
+ if(SourceGO && SourceGO->Id == GO_SPREADDATA) {
+ SourceGO->Command(CMD_COPY_TSV, &text_plain, 0L);
+ if(text_plain && text_plain[0]){
+ cb = QAppl->clipboard();
+ cb->clear();
+#ifdef Q_CHECK_PTR //n.a. in Qt version 2
+ cb->setText(text_plain, QClipboard::Clipboard);
+ cb->setText(text_plain, QClipboard::Selection);
+#else
+ cb->setText(text_plain);
+#endif
+ }
+ }
+}
+
+char *
+RLPserver::GetXML()
+{
+ if(SourceGO && SourceGO->Id == GO_SPREADDATA) {
+ if(!text_xml) SourceGO->Command(CMD_COPY_XML, &text_xml, 0L);
+ return text_xml;
+ }
+ return 0L;
+}
+
+char *
+RLPserver::GetRLP()
+{
+ long cb;
+
+ if(SourceGO && (SourceGO->Id == GO_GRAPH || SourceGO->Id == GO_PAGE)) {
+ text_rlp = GraphToMem(SourceGO, &cb);
+ return text_rlp;
+ }
+ return 0L;
+}
+
+#endif //RLP_PORT
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Process paste command: check for clipboard contents
void TestClipboard(GraphObj *g)
-{
-
- QClipboard *cb;
- QDragObject *mime;
-
- if(!(cb = QAppl->clipboard()))return;
- if(!(mime = (QDragObject *)cb->data()))return;
- if(g->Id == GO_SPREADDATA) {
- if(mime->provides(MIME_RLPLOT)){
- QByteArray b = mime->encodedData(MIME_RLPLOT);
- if(b) g->Command(CMD_PASTE_XML, (void*)b.data(), 0L);
- return;
- }
- else if(mime->provides(MIME_KSPREAD)){
- QByteArray b = mime->encodedData(MIME_KSPREAD);
- if(b) g->Command(CMD_PASTE_XML, (void*)b.data(), 0L);
- return;
- }
- else if(QByteArray b = mime->encodedData(MIME_RLPOBJ)){
- OpenGraph(g, 0L, (unsigned char*)b.data());
- return;
- }
- else if(QByteArray b = mime->encodedData(MIME_RLPGRAPH)){
- OpenGraph(g, 0L, (unsigned char*)b.data());
- return;
- }
- else if(mime->provides("text/plain")){
- QString _text = cb->text();
- ProcMemData(g, (unsigned char*)_text.latin1(), true);
- return;
- }
- }
- else if(g->Id == GO_PAGE){
- if(QByteArray b = mime->encodedData(MIME_RLPOBJ)){
- OpenGraph(g, 0L, (unsigned char*)b.data());
- return;
- }
- else if(QByteArray b = mime->encodedData(MIME_RLPGRAPH)){
- OpenGraph(g, 0L, (unsigned char*)b.data());
- return;
- }
- }
- else if(g->Id == GO_GRAPH)TestClipboard(g->parent);
+{
+ if(!g) return;
+#ifdef RLP_PORT
+ if(rlpsrv && rlpsrv->SourceGO) {
+ if(rlpsrv->SourceGO->Id == GO_GRAPH || rlpsrv->SourceGO->Id == GO_PAGE)
+ OpenGraph(g, 0L, (unsigned char*)rlpsrv->GetRLP(), true);
+ else if(rlpsrv->SourceGO->Id == GO_SPREADDATA && g->Id == GO_SPREADDATA)
+ g->Command(CMD_PASTE_XML, (void*)rlpsrv->GetXML(), 0L);
+ }
+ else new ReadCB(0, 0, g);
+#endif //RLP_PORT
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copy spreadsheet or graph to clipboard
void CopyData(GraphObj *g)
-{
- EmptyClip();
- KSpreadTextDrag *kd = new KSpreadTextDrag(0L);
- kd->setText(QString("RLPlot snippet"));
- kd->setSpreadData(g);
-#ifdef Q_CHECK_PTR //n.a. in Qt version 2
- if(QAppl->clipboard()->supportsSelection())
- QAppl->clipboard()->setSelectionMode(TRUE);
-#endif
- QAppl->clipboard()->setData(kd);
+{
+ HideCopyMark();
+ QAppl->clipboard()->clear();
+#ifdef RLP_PORT
+ if(rlpsrv) {
+ if(rlpsrv->ok()) rlpsrv->SetGO(g);
+ else {
+ delete rlpsrv;
+ rlpsrv = new RLPserver(0, g);
+ }
+ }
+ else rlpsrv = new RLPserver(0, g);
+#endif //RLP_PORT
}
void CopyGraph(GraphObj *g)
-{
- EmptyClip();
- RLPGraphDrag *gd = new RLPGraphDrag(0L);
- gd->setText(QString("RLPlot graph"));
- gd->setGraphData(g);
- //no support for X11 clipboard possible
- QAppl->clipboard()->setData(gd);
+{
+ CopyData(g);
}
void EmptyClip()
-{
+{
+#ifdef RLP_PORT
+ if(rlpsrv) {
+ delete(rlpsrv); rlpsrv = 0;
+ }
+ else {
+ QSocket *socket = new QSocket(0);
+ socket->connectToHost("localhost", RLP_PORT);
+ QTextStream os(socket);
+ os << "close\n";
+ socket->close();
+ }
+#endif //RLP_PORT
HideCopyMark();
QAppl->clipboard()->clear();
}
@@ -615,17 +686,14 @@ void EmptyClip()
void CopyText(char *txt, int len)
{
QClipboard *cb;
- char tmp_txt[90];
- if(!(cb = QAppl->clipboard()) || !txt || !txt[0])return;
+ if(!(cb = QAppl->clipboard()) || !txt || !txt[0]) return;
EmptyClip();
- if(!len) len = strlen(txt);
- memcpy(tmp_txt, txt, len); tmp_txt[len] = 0;
#ifdef Q_CHECK_PTR //n.a. in Qt version 2
- cb->setText(tmp_txt, QClipboard::Clipboard);
- cb->setText(tmp_txt, QClipboard::Selection);
+ cb->setText(txt, QClipboard::Clipboard);
+ cb->setText(txt, QClipboard::Selection);
#else
- cb->setText(tmp_txt);
+ cb->setText(txt);
#endif
}
@@ -1488,7 +1556,40 @@ unsigned char zoom_mask[] = { //zoom cursor mask
0xf0, 0x1f, 0xf8, 0x3f, 0xf8, 0x3f, 0xf4, 0x7e,
0x7c, 0x7c, 0xfc, 0x7e, 0xf8, 0x3f, 0xf8, 0x3f,
0xf0, 0x1f, 0xe0, 0x0f, 0x80, 0x03, 0x00, 0x00};
-
+
+unsigned char paste_bits[] = { //paste cursor bitmap
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0xc4, 0x7f, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f,
+ 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80,
+ 0x20, 0x80, 0x20, 0x80, 0xc0, 0x7f, 0x00, 0x00};
+
+unsigned char paste_mask[] = { //paste cursor mask
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0xc4, 0x7f, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff,
+ 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff,
+ 0xe0, 0xff, 0xe0, 0xff, 0xc0, 0x7f, 0x00, 0x00};
+
+//display 16x16 cursor data: developers utility
+/*
+void disp_bm(unsigned char *tb)
+{
+ char txt[512];
+ unsigned char currbyte;
+ int i, j, pos;
+
+ for(i = pos = 0; i < 32; i++) {
+ currbyte = tb[i];
+ for (j = 0; j < 8; j++) {
+ if(currbyte & 0x01) pos += sprintf(txt+pos, "1");
+ else pos += sprintf(txt+pos, "0");
+ currbyte >>= 1;
+ }
+ if(i & 1)pos += sprintf(txt+pos, "\n");
+ }
+ InfoBox(txt);
+}
+*/
+
void
OutputQT::MouseCursor(int cid, bool force)
{
@@ -1496,6 +1597,7 @@ OutputQT::MouseCursor(int cid, bool force)
if(cid == MC_LAST) cid = cCursor;
QBitmap cb(16, 16, hand_bits, TRUE); QBitmap cm(16, 16, hand_mask, TRUE);
QBitmap zb(16, 16, zoom_bits, TRUE); QBitmap zm(16, 16, zoom_mask, TRUE);
+ QBitmap pb(16, 16, paste_bits, TRUE); QBitmap pm(16, 16, paste_mask, TRUE);
switch(cid) {
#ifdef Q_CHECK_PTR //Qt version 3
case MC_ARROW: widget->setCursor(QCursor(Qt::ArrowCursor)); break;
@@ -1519,11 +1621,14 @@ OutputQT::MouseCursor(int cid, bool force)
case MC_SALL: widget->setCursor(QCursor(SizeAllCursor)); break;
#endif
case MC_MOVE:
- widget->setCursor(QCursor(cb, cm));
+ widget->setCursor(QCursor(cb, cm, 7, 7));
break;
case MC_ZOOM:
- widget->setCursor(QCursor(zb, zm));
+ widget->setCursor(QCursor(zb, zm, 7, 7));
break;
+ case MC_PASTE:
+ widget->setCursor(QCursor(pb, pm, 2, 2));
+ break;
default: return;
}
cCursor = cid;
@@ -1628,11 +1733,12 @@ OutputQT::SetMenu(int type)
if(type == MENU_SPREAD){
QPopupMenu *file = new QPopupMenu(widget);
file->insertItem("&Open", widget, SLOT(cmOpen()));
+ file->insertItem("&Save", widget, SLOT(cmSaveData()));
file->insertItem("Save &as", widget, SLOT(cmSaveDataAs()));
file->insertSeparator();
file->insertItem("&Print", widget, SLOT(cmPrint()));
file->insertSeparator();
- file->insertItem("E&xit", widget, SLOT(cmExit()));
+ file->insertItem("E&xit", widget, SLOT(cmExitRLP()));
file->insertSeparator();
file->insertItem("n.a.", widget, SLOT(cmFile1()), 0, CM_FILE1);
file->insertItem("n.a.", widget, SLOT(cmFile2()), 0, CM_FILE2);
@@ -1910,11 +2016,7 @@ RLPwidget::RLPwidget(QWidget *par, const char *name, anyOutput *o, GraphObj *g)
RLPwidget::~RLPwidget()
{
if(OutputClass)((OutputQT*)OutputClass)->widget = 0L;
- OutputClass = 0L;
- if(BaseObj){
- BaseObj->Command(CMD_CAN_DELETE, 0L, 0L);
- BaseObj = 0L;
- }
+ OutputClass = 0L; BaseObj = 0L;
}
//public slots: menu items, events
@@ -1943,6 +2045,12 @@ RLPwidget::cmOpen()
if(BaseObj)BaseObj->Command(CMD_OPEN, (void *)NULL, OutputClass);
}
+void
+RLPwidget::cmSaveData()
+{
+ if(BaseObj)BaseObj->Command(CMD_SAVEDATA, (void *)NULL, OutputClass);
+}
+
void
RLPwidget::cmSaveDataAs()
{
@@ -1952,14 +2060,19 @@ RLPwidget::cmSaveDataAs()
void
RLPwidget::cmExit()
{
- if(BaseObj) {
- if(BaseObj->Command(CMD_CAN_CLOSE, 0L, 0L)){
- BaseObj = 0L;
- delete this;
- }
+ if(BaseObj && BaseObj->Command(CMD_CAN_CLOSE, 0L, 0L)){
+ if(BaseObj->parent) BaseObj->parent->Command(CMD_DELOBJ, BaseObj, 0L);
}
- else delete(this);
}
+
+void
+RLPwidget::cmExitRLP()
+{
+ if(BaseObj) {
+ if(!BaseObj->Command(CMD_CAN_CLOSE, 0L, 0L)) return;
+ }
+ QAppl->exit(0);
+}
void
RLPwidget::cmNewGraph()
@@ -2033,7 +2146,7 @@ RLPwidget::cmPaste()
if(BaseObj) {
OutputClass->MouseCursor(MC_WAIT, true);
TestClipboard(BaseObj);
- OutputClass->MouseCursor(MC_ARROW, true);
+ BaseObj->Command(CMD_MOUSECURSOR, 0L, OutputClass);
}
}
@@ -2130,7 +2243,7 @@ RLPwidget::cmPrint()
void
RLPwidget::cmExport()
{
- OpenExportName(BaseObj, "hello.svg");
+ OpenExportName(BaseObj, 0L);
BaseObj->DoPlot(0L);
}
@@ -2286,8 +2399,7 @@ RLPwidget::closeEvent(QCloseEvent *e)
if(BaseObj){
if(BaseObj->Command(CMD_CAN_CLOSE, 0L, 0L)) {
if(OutputClass)((OutputQT*)OutputClass)->widget = 0L;
- OutputClass = 0L;
- BaseObj = 0L;
+ OutputClass = 0L; BaseObj = 0L;
e->accept();
}
}
@@ -2706,10 +2818,6 @@ int main (int argc, char **argv)
drw->FileIO(FILE_WRITE); delete drw;
}
}
- SpreadMain(false);
- InitTextCursor(false);
- if(WWWbrowser) free(WWWbrowser);
- if(LoadFile) free(LoadFile);
return 0;
}
diff --git a/QT_Spec.h b/QT_Spec.h
index 0f4b425..2340a85 100755
--- a/QT_Spec.h
+++ b/QT_Spec.h
@@ -47,41 +47,70 @@ private:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// based on KDEs KSpread source: kspread_table.h
-// copyright (C) 1998, 1999 Torben Weis
-class KSpreadTextDrag:public QTextDrag {
+//use sockets for to exchange clipboard data
+#ifdef RLP_PORT
+
+#include <qsocket.h>
+#include <qserversocket.h>
+
+class ReadCB:public QSocket {
Q_OBJECT
public:
- KSpreadTextDrag(QWidget *dragSource = 0L, const char *name = 0L);
- virtual ~KSpreadTextDrag();
- virtual bool provides(const char *mimeType);
- void setSpreadData(GraphObj *g) {go = g;};
- virtual QByteArray encodedData(const char* mime) const;
- virtual const char* format(int i) const;
- static bool canDecode(QMimeSource *e);
- static const char* selectionMimeType();
+ ReadCB(QObject *parent=0, const char *name=0, GraphObj *g=0);
+ ~ReadCB();
-protected:
- GraphObj *go;
+private slots:
+ void isConnected();
+ void receiveData();
+ void endData();
+ void isError(int);
+
+private:
+ int level;
+ char *format;
+ QObject *par;
+ GraphObj *DestGO;
+ QString *res;
};
-class RLPGraphDrag:public QTextDrag {
+class RLPsock:public QSocket {
Q_OBJECT
public:
- RLPGraphDrag(QWidget *dragSource = 0L, const char *name = 0L);
- virtual ~RLPGraphDrag();
- virtual bool provides(const char *mimeType);
- void setGraphData(GraphObj *g);
- virtual QByteArray encodedData(const char* mime) const;
- virtual const char* format(int i) const;
- static bool canDecode(QMimeSource *e);
- static const char* selectionMimeType();
+ RLPsock(int sock, QObject *parent=0, const char *name=0, GraphObj *g=0);
-protected:
- GraphObj *go1, *go2;
+private slots:
+ void readClient();
+
+private:
+ QObject *par;
+ GraphObj *SourceGO;
};
+class RLPserver:public QServerSocket {
+ Q_OBJECT
+public:
+ GraphObj *SourceGO;
+
+ RLPserver(QObject* parent=0, GraphObj *g=0);
+ ~RLPserver();
+ void newConnection(int socket){new RLPsock(socket, this, 0, SourceGO);};
+
+ void SetGO(GraphObj *g);
+ char *GetXML();
+ char *GetRLP();
+ char *GetTXT() {return text_plain; };
+
+signals:
+ void newConnect(RLPsock *);
+
+private:
+ char *text_xml, *text_rlp, *text_plain;
+};
+
+#endif //RLP_PORT
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The Qt widget class implementet for RLPlot
class RLPwidget:public QWidget {
Q_OBJECT
@@ -96,8 +125,10 @@ public slots:
void hScrollEvent(int pos);
void vScrollEvent(int pos);
void cmOpen();
+ void cmSaveData();
void cmSaveDataAs();
void cmExit();
+ void cmExitRLP();
void cmNewGraph();
void cmNewPage();
void cmDelGraph();
diff --git a/RLPLOT.RC b/RLPLOT.RC
index 2be39ca..9c502ec 100755
--- a/RLPLOT.RC
+++ b/RLPLOT.RC
@@ -1,4 +1,4 @@
-//RLPlot.RC, (C)2000, 2001, 2002, 2003, 2004, 2005 R.Lackner
+//RLPlot.RC, (C)2000-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -36,39 +36,40 @@
#define CM_PRINT 517
#define CM_EXPORT 518
#define CM_DELOBJ 519
-#define CM_DEFAULTS 520
-#define CM_COPY 521
-#define CM_PASTE 522
-#define CM_UPDATE 523
-#define CM_ADDAXIS 524
-#define CM_UNDO 525
-#define CM_ZOOMIN 526
-#define CM_ZOOMOUT 527
-#define CM_ZOOMFIT 528
-#define CM_FILE1 529
-#define CM_FILE2 530
-#define CM_FILE3 531
-#define CM_FILE4 532
-#define CM_FILE5 533
-#define CM_FILE6 534
-#define CM_FILLRANGE 535
-#define CM_CUT 536
-#define CM_LEGEND 537
-#define CM_LAYERS 538
-#define CM_INSROW 539
-#define CM_INSCOL 540
-#define CM_DELROW 541
-#define CM_DELCOL 542
+#define CM_DEFAULTS 522
+#define CM_COPY 523
+#define CM_PASTE 524
+#define CM_UPDATE 525
+#define CM_ADDAXIS 526
+#define CM_UNDO 527
+#define CM_ZOOMIN 528
+#define CM_ZOOMOUT 529
+#define CM_ZOOMFIT 530
+#define CM_FILE1 531
+#define CM_FILE2 532
+#define CM_FILE3 533
+#define CM_FILE4 534
+#define CM_FILE5 535
+#define CM_FILE6 536
+#define CM_FILLRANGE 537
+#define CM_CUT 538
+#define CM_LEGEND 539
+#define CM_LAYERS 540
+#define CM_INSROW 541
+#define CM_INSCOL 542
+#define CM_DELROW 543
+#define CM_DELCOL 544
+#define CM_SAVEDATA 545
-#define CM_T_STANDARD 560
-#define CM_T_DRAW 561
-#define CM_T_POLYLINE 562
-#define CM_T_POLYGON 563
-#define CM_T_RECTANGLE 564
-#define CM_T_ROUNDREC 565
-#define CM_T_ELLIPSE 566
-#define CM_T_ARROW 567
-#define CM_T_TEXT 568
+#define CM_T_STANDARD 550
+#define CM_T_DRAW 551
+#define CM_T_POLYLINE 552
+#define CM_T_POLYGON 553
+#define CM_T_RECTANGLE 554
+#define CM_T_ROUNDREC 555
+#define CM_T_ELLIPSE 556
+#define CM_T_ARROW 557
+#define CM_T_TEXT 558
#define CM_DELKEY 600
#define CM_LEFTARRKEY 601
@@ -112,7 +113,7 @@ BEGIN
MENUITEM "&Print", CM_PRINT
MENUITEM "&Export", CM_EXPORT
MENUITEM SEPARATOR
- MENUITEM "E&xit", CM_EXIT
+ MENUITEM "&Close", CM_EXIT
END
POPUP "&Edit"
BEGIN
@@ -174,7 +175,8 @@ BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Open", CM_OPEN
- MENUITEM "&Save as", CM_SAVEDATAAS
+ MENUITEM "&Save", CM_SAVEDATA
+ MENUITEM "Save &as", CM_SAVEDATAAS
MENUITEM SEPARATOR
MENUITEM "&Print", CM_PRINT
MENUITEM SEPARATOR
@@ -226,7 +228,7 @@ BEGIN
MENUITEM "&Print", CM_PRINT
MENUITEM "&Export", CM_EXPORT
MENUITEM SEPARATOR
- MENUITEM "E&xit", CM_EXIT
+ MENUITEM "&Close", CM_EXIT
END
POPUP "&Edit"
BEGIN
diff --git a/TheDialog.cpp b/TheDialog.cpp
index d6721ee..5e07427 100755
--- a/TheDialog.cpp
+++ b/TheDialog.cpp
@@ -1,4 +1,4 @@
-//TheDialog.cpp, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
+//TheDialog.cpp, Copyright (c) 2001-2006 R.Lackner
//Operating system independent code for dialog boxes
//
// This file is part of RLPlot.
@@ -42,7 +42,7 @@ static int ybase = 2;
int dlgtxtheight = 10;
static unsigned long DlgBGcolor = 0x00e0e0e0L;
static unsigned long DlgBGhigh = 0x00e8e8e8L;
-TextDEF DlgText = {0x00000000L, 0x00ffffffL, 4.0, 0.0f, 0.0f, 0,
+TextDEF DlgText = {0x00000000L, 0x00ffffffL, 4.0, 0.0, 0.0, 0,
TXA_HLEFT | TXA_VTOP, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, 0L};
//prototypes: WinSpec.cpp
@@ -63,6 +63,7 @@ DlgRoot::DlgRoot(DlgInfo *tmpl)
dlg = 0L; flags = 0L; tabstops = 0L;
DlgText.iSize = dlgtxtheight; DlgText.ColBg = DlgBGcolor;
+ DlgText.fSize = defs.GetSize(SIZE_TEXT);
type = NONE; Id = -2; cContinue = 0;
bActive = false; Result = -1; c_go = CurrGO;
CurrDisp = 0L; oldFocus = DialogFocus; DialogFocus = 0L;
@@ -98,6 +99,9 @@ DlgRoot::DlgRoot(DlgInfo *tmpl)
case COLBUTTON:
dlg[i]->dialog = new ColorButton(this, &tmpl[i],rc, (unsigned long)tmpl[i].ptype);
break;
+ case COLBUTT:
+ dlg[i]->dialog = new ColorButton(this, &tmpl[i],rc, (DWORD *)tmpl[i].ptype);
+ break;
case FILLBUTTON:
dlg[i]->dialog = new FillButton(this, &tmpl[i],rc, (FillDEF *)tmpl[i].ptype);
break;
@@ -202,6 +206,7 @@ DlgRoot::~DlgRoot()
case TEXTBOX: delete((TextBox*)dlg[i]->dialog); break;
case ARROWBUTT: delete((ArrowButton*)dlg[i]->dialog); break;
case COLBUTTON: delete((ColorButton*)dlg[i]->dialog); break;
+ case COLBUTT: delete((ColorButton*)dlg[i]->dialog); break;
case FILLBUTTON: delete((FillButton*)dlg[i]->dialog); break;
case SHADE3D: delete((Shade3D*)dlg[i]->dialog); break;
case LINEBUTT: delete((LineButton*)dlg[i]->dialog); break;
@@ -461,7 +466,7 @@ DlgRoot::GetColor(int id, DWORD *color)
int i;
i = FindIndex(id);
- if(i && dlg[i]) return dlg[i]->dialog->GetColor(id, color);
+ if(i && dlg[i] && dlg[i]->dialog) return dlg[i]->dialog->GetColor(id, color);
return false;
}
@@ -621,8 +626,13 @@ DlgRoot::ForEach(int cmd, int start, anyOutput *o)
dlg[next]->dialog->Command(CMD_FLUSH, 0L, 0L);
//if j equals cDlgs we are caught in a circular reference
for(j = 0, i = dlg[next]->first; i && j < cDlgs; j++) {
- dlg[next]->dialog->Command(CMD_ADDCHILD, (void*)dlg[i = FindIndex(i)]->dialog, 0L);
- if(i) i = dlg[i]->next;
+ if(i = FindIndex(i)) {
+ dlg[next]->dialog->Command(CMD_ADDCHILD, (void*)dlg[i]->dialog, 0L);
+ i = dlg[i]->next;
+ }
+ else{
+ i=i;
+ }
}
}
else return; //error bad structured template
@@ -1007,6 +1017,12 @@ ColorButton::ColorButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, unsigned lon
col = color;
}
+ColorButton::ColorButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, DWORD *color)
+ :Dialog(par, desc, rec)
+{
+ col = *color;
+}
+
void
ColorButton::DoPlot(anyOutput *o)
{
@@ -1692,15 +1708,17 @@ bool
Text::Select(int x, int y, anyOutput *o)
{
if(WWWbrowser && WWWbrowser[0] && txt && (flags & HREF) && IsInRect(&cr, x, y)) {
+ o->MouseCursor(MC_WAIT, false);
sprintf(TmpTxt, "%s %s", WWWbrowser, txt);
- if(parent)parent->Command(CMD_CONTINUE, 0L, o);
+ if(parent && (flags & TOUCHEXIT))parent->Command(CMD_ENDDIALOG, 0L, o);
+ else if(parent)parent->Command(CMD_CONTINUE, 0L, o);
#ifdef _WINDOWS
WinExec(TmpTxt, SW_SHOWMAXIMIZED);
#else
strcat(TmpTxt, " &");
system(TmpTxt);
#endif
- if(parent)parent->Command(CMD_ENDDIALOG, 0L, o);
+ o->MouseCursor(MC_ARROW, false);
return true;
}
return false;
@@ -1926,7 +1944,10 @@ RangeInput::Select(int x, int y, anyOutput *o)
bRes = InputText::Select(x, y, o);
if(bRes && data) {
- if(DialogFocus == this) data->Command(CMD_ETRACC, Text, 0L);
+ if(DialogFocus == this){
+ data->Command(CMD_ETRACC, Text, 0L);
+ if(Text) Text->Update(1, o, 0L);
+ }
else data->Command(CMD_ETRACC, 0L, 0L);
}
return bRes;
@@ -3115,28 +3136,171 @@ LinePat::MBtrack(MouseEvent *mev, anyOutput *o)
}
}
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Dialog meta compiler
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *std_text[] = {"OK", "Cancel", "", "x", "y", "z", "-", "Next >>", "<< Prev."};
+
+DlgInfo *CompileDialog(char* tmpl, void **ptypes)
+{
+ char **lines, **fields, **flags;
+ int i, j, nlines, nfields, nflags;
+ unsigned int hv;
+ DlgInfo *Dlg;
+
+ std_text[2] = Units[defs.cUnits].display;
+ lines = split(tmpl, '\n', &nlines);
+ if(!lines || nlines <1 ||(!(Dlg = (DlgInfo*)malloc(nlines*sizeof(DlgInfo))))) return 0L;
+ for(i = 0; i < nlines; i++) if(lines[i] && lines[i][0]){
+ if(fields = split(lines[i], ',', &nfields)) {
+ if(nfields == 10) {
+ Dlg[i].id = Dlg[i].next = Dlg[i].first = 0;
+ sscanf(fields[0], "%d", &Dlg[i].id); sscanf(fields[1], "%d", &Dlg[i].next);
+ sscanf(fields[2], "%d", &Dlg[i].first); Dlg[i].flags = 0L;
+ if(flags = split(fields[3], '|', &nflags)) {
+ for(j = 0; j < nflags; j++){
+ hv = HashValue((unsigned char *)str_trim(flags[j]));
+ switch(hv) {
+ case 196904: Dlg[i].flags |= CHECKED; break;
+ case 4444568: Dlg[i].flags |= TOUCHEXIT; break;
+ case 284491160: Dlg[i].flags |= TOUCHSELEXIT; break;
+ case 235859: Dlg[i].flags |= ISRADIO; break;
+ case 942268: Dlg[i].flags |= ISPARENT; break;
+ case 4220131: Dlg[i].flags |= OWNDIALOG; break;
+ case 198260: Dlg[i].flags |= DEFAULT; break;
+ case 54530: Dlg[i].flags |= HIDDEN; break;
+ case 1011472: Dlg[i].flags |= NOSELECT; break;
+ case 3546: Dlg[i].flags |= HREF; break;
+ case 62296: Dlg[i].flags |= NOEDIT; break;
+ case 231330: Dlg[i].flags |= LASTOBJ; break;
+ case 224595: Dlg[i].flags |= EXRADIO; break;
+ }
+ free(flags[j]);
+ }
+ free(flags);
+ }
+ hv = HashValue((unsigned char *)str_trim(fields[4]));
+ switch(hv) {
+ case 17108522: Dlg[i].type = PUSHBUTTON; break;
+ case 3252180: Dlg[i].type = ARROWBUTT; break;
+ case 3296810: Dlg[i].type = COLBUTTON; break;
+ case 206036: Dlg[i].type = COLBUTT; break;
+ case 13602346: Dlg[i].type = FILLBUTTON; break;
+ case 261312: Dlg[i].type = SHADE3D; break;
+ case 948692: Dlg[i].type = LINEBUTT; break;
+ case 282068: Dlg[i].type = SYMBUTT; break;
+ case 3403091: Dlg[i].type = FILLRADIO; break;
+ case 1130835: Dlg[i].type = SYMRADIO; break;
+ case 787668: Dlg[i].type = CHECKBOX; break;
+ case 62812: Dlg[i].type = RADIO0; break;
+ case 62813: Dlg[i].type = RADIO1; break;
+ case 62814: Dlg[i].type = RADIO2; break;
+ case 15460: Dlg[i].type = LTEXT; break;
+ case 16996: Dlg[i].type = RTEXT; break;
+ case 13156: Dlg[i].type = CTEXT; break;
+ case 51300: Dlg[i].type = EDTEXT; break;
+ case 16235656: Dlg[i].type = RANGEINPUT; break;
+ case 51281: Dlg[i].type = EDVAL1; break;
+ case 14534481: Dlg[i].type = INCDECVAL1; break;
+ case 229196: Dlg[i].type = HSCROLL; break;
+ case 286540: Dlg[i].type = VSCROLL; break;
+ case 71804: Dlg[i].type = TXTHSP; break;
+ case 3418: Dlg[i].type = ICON; break;
+ case 14196: Dlg[i].type = GROUP; break;
+ case 909332: Dlg[i].type = GROUPBOX; break;
+ case 16408: Dlg[i].type = SHEET; break;
+ case 970282: Dlg[i].type = ODBUTTON; break;
+ case 957537: Dlg[i].type = LISTBOX1; break;
+ case 1108443: Dlg[i].type = TREEVIEW; break;
+ case 237304: Dlg[i].type = LINEPAT; break;
+ case 269332: Dlg[i].type = TEXTBOX; break;
+ case 787858: Dlg[i].type = CHECKPIN; break;
+ case 17284: Dlg[i].type = TRASH; break;
+ case 51627: Dlg[i].type = CONFIG; break;
+ default: Dlg[i].type = NONE; break;
+ }
+ sscanf(fields[5], "%d", &j);
+ if(j < 0) Dlg[i].ptype = (void*)std_text[(-j)-1];
+ else if(j > 0) Dlg[i].ptype = ptypes[j-1];
+ else Dlg[i].ptype = (void*)0L;
+ sscanf(fields[6], "%d", &Dlg[i].x); sscanf(fields[7], "%d", &Dlg[i].y);
+ sscanf(fields[8], "%d", &Dlg[i].w); sscanf(fields[9], "%d", &Dlg[i].h);
+ }
+ for(j = 0; j < nfields; j++)free(fields[j]);
+ free(fields);
+ }
+ free(lines[i]);
+ }
+ free(lines);
+ return Dlg;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Use marked ranges as default for dialog ranges
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void UseRangeMark(DataObj *d, int type, char *r0, char *r1, char *r2, char *r3,
+ char *r4, char *r5, char *r6, char *r7, char *r8, char *r9, char *r10)
+{
+ char *dst[] = {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10};
+ char *mrk, **ra =0L;;
+ int i, ranges=0;
+ bool success = false;
+ RECT vrc;
+ AccRange *ar;
+
+ if(d && type) {
+ d->ValueRec(&vrc);
+ if(d->Command(CMD_GETMARK, &mrk, 0L)) {
+ ra = split(mrk, ';', &ranges);
+ ar = new AccRange(mrk); ar->BoundRec(&vrc); delete ar;
+ }
+ switch(type) {
+ case 1:
+ if(ranges > 1) {
+ for(i = 0; i < 11; i++) if(dst[i]) {
+ if(i < ranges) sprintf(dst[i], "%s", ra[i]);
+ else sprintf(dst[i], "%c%d:%c%d", 'a'+i+vrc.left, vrc.top+1, 'a'+i+vrc.left, vrc.bottom+1);
+ }
+ success = true;
+ }
+ break;
+ }
+ }
+ else {
+ vrc.left = vrc.top = 0; vrc.right = vrc.bottom = 9;
+ }
+ if(!success) for(i = 0; i < 11; i++) {
+ if(dst[i])sprintf(dst[i], "%c%d:%c%d", 'a'+i+vrc.left, vrc.top+1, 'a'+i+vrc.left, vrc.bottom+1);
+ }
+ if(ra) {
+ for(i = 0; i < ranges; i++) if(ra[i]) free(ra[i]);
+ free(ra);
+ }
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Select color out of predefined palette
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DWORD GetNewColor(DWORD oldColor)
{
- DlgInfo *ColDlg, ColDlgTmpl[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 200, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 200, 25, 45, 12},
- {3, 7, 4, CHECKED | ISPARENT, GROUPBOX, (void*)" RGB ", 200, 55, 45, 40},
- {4, 5, 0, 0x0L, LTEXT, (void*)0L, 210, 60, 45, 8},
- {5, 6, 0, 0x0L, LTEXT, (void*)0L, 210, 70, 45, 8},
- {6, 0, 0, 0x0L, LTEXT, (void*)0L, 210, 80, 45, 8},
- {7, 0, 8, CHECKED | ISPARENT, GROUP, 0L, 0, 0, 0, 0}};
+ char *NewColorTmpl =
+ "1, 2, 0, DEFAULT, PUSHBUTTON, -1, 200, 10, 45, 12\n"
+ "2, 3, 0, 0x0L, PUSHBUTTON, -2, 200, 25, 45, 12\n"
+ "3, 7, 4, CHECKED | ISPARENT, GROUPBOX, 1, 200, 55, 45, 40\n"
+ "4, 5, 0, 0x0L, LTEXT, 0, 210, 60, 45, 8\n"
+ "5, 6, 0, 0x0L, LTEXT, 0, 210, 70, 45, 8\n"
+ "6, 0, 0, 0x0L, LTEXT, 0, 210, 80, 45, 8\n"
+ "7, 0, 8, CHECKED | ISPARENT, GROUP, 0, 0, 0, 0, 0";
+ void *ptypes[] = {(void*)" RGB "};
+ DlgInfo *ColDlg = CompileDialog(NewColorTmpl, ptypes);
DWORD currcol, newcol;
int ilevels[] = {0x0, 0x40, 0x80, 0xc0, 0xe0, 0xff};
int i, ir, ig, ib, col, row, res;
DlgRoot *Dlg;
void *hDlg;
- if(!(ColDlg = (DlgInfo *)malloc(230 * sizeof(DlgInfo))))return oldColor;
- memcpy(ColDlg, ColDlgTmpl, 14 * sizeof(DlgInfo));
+ if(!(ColDlg = (DlgInfo *)realloc(ColDlg, 230 * sizeof(DlgInfo))))return oldColor;
for(ir=row=col=0, i= 7; ir<6; ir++) for(ig=0; ig<6; ig++) for(ib=0; ib<6; ib++) {
ColDlg[i].id = i+1; ColDlg[i].next = i+2;
ColDlg[i].type = COLBUTTON; ColDlg[i].first = 0;
@@ -3232,7 +3396,7 @@ void ConfShade(FillDEF *oldfill)
}
hDlg = CreateDlgWnd("Shade and Fill Color", 50, 50, 300, 180, Dlg, 0x0L);
bRedraw = true;
- o = Dlg->GetOutputClass(); o->LightSource(8.0, -16.0);
+ o = Dlg->GetOutputClass(); o->LightSource(32.0, 16.0);
rc_prev.left =240; rc_prev.right = 280;
rc_prev.top = 100; rc_prev.bottom = 140;
do {
@@ -3281,7 +3445,8 @@ void GetNewFill(FillDEF *oldfill)
FILL_DCROSS, FILL_STIPPLE1, FILL_STIPPLE2, FILL_STIPPLE3, FILL_STIPPLE4,
FILL_STIPPLE5, FILL_ZIGZAG, FILL_COMBS, FILL_BRICKH, FILL_BRICKV, FILL_BRICKDU,
FILL_BRICKDD, FILL_TEXTURE1, FILL_TEXTURE2, FILL_WAVES1, FILL_SCALES, FILL_SHINGLES,
- FILL_WAVES2, FILL_HERRING, FILL_CIRCLES, FILL_GRASS, FILL_FOAM, FILL_RECS};
+ FILL_WAVES2, FILL_HERRING, FILL_CIRCLES, FILL_GRASS, FILL_FOAM, FILL_RECS, FILL_HASH,
+ FILL_WATER};
double fscale;
DlgInfo FillDlgBase[] = {
{1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 170, 10, 45, 12},
@@ -3478,7 +3643,8 @@ bool ShowLayers(GraphObj *root)
else {
Dlg->ShowItem(500, false); Dlg->ShowItem(501, false);
}
- if(cgo->Id == GO_GRAPH || cgo->Id == GO_PAGE || cgo->Id == GO_POLARPLOT){
+ if(cgo->Id == GO_GRAPH || cgo->Id == GO_PAGE || cgo->Id == GO_POLARPLOT
+ || cgo->Id == GO_GRID3D){
Dlg->ShowItem(550, true);
if(res == 550) if(cgo->Command(CMD_CONFIG, 0L, 0L))
cgo->Command(CMD_REDRAW, 0L, 0L);
@@ -3520,6 +3686,7 @@ void ShowBanner(bool show)
{5, 0, 0, LASTOBJ, LTEXT, (void*)"... is loading", 45, 25, 50, 9}};
DlgRoot *Dlg;
void *hDlg;
+ bool init = true;
int res, cnt = 5;
if(!show) return;
@@ -3533,8 +3700,6 @@ void ShowBanner(bool show)
Dlg->TextFont(3, FONT_TIMES);
Dlg->SetColor(3, 0x00ff0000L);
hDlg = CreateDlgWnd("RLPlot", 50, 50, 200, 80, Dlg, 0x7L);
- FindBrowser();
- SpreadMain(true);
ShowDlgWnd(hDlg);
do{
LoopDlgWnd();
@@ -3542,9 +3707,14 @@ void ShowBanner(bool show)
switch (res) {
case 0: //loose focus: get it again
ShowDlgWnd(hDlg);
- res = -1;
+ cnt = 5; res = -1;
break;
case -2: //Timer event
+ if(init) {
+ init = false;
+ FindBrowser(); SpreadMain(true);
+ ShowDlgWnd(hDlg); cnt = 4;
+ }
if((cnt--) <=0) res = 1;
break;
}
@@ -3567,7 +3737,7 @@ void RLPlotInfo()
{4, 5, 0, 0x0L, CTEXT, (void*)"scientific plotting program", 10, 30, 100, 8},
{5, 6, 0, 0x0L, CTEXT, (void*)"version "SZ_VERSION, 10, 38, 100, 8},
{6, 7, 0, HREF, CTEXT, (void*)"http://rlplot.sourceforge.net/", 5, 46, 110, 8},
- {7, 8, 0, 0x0L, CTEXT, (void*)"Copyright (C) 2002-2005 R. Lackner", 5, 54, 110, 8},
+ {7, 8, 0, 0x0L, CTEXT, (void*)"Copyright (C) 2002-2006 R. Lackner", 5, 54, 110, 8},
{8, 9, 0, 0x0L, CTEXT, (void*)"reinhard.lackner at uibk.ac.at", 5, 62, 110, 9},
{9, 10, 0, 0x0L, CTEXT, (void*)"This is free software published", 5, 80, 110, 8},
{10, 11, 0, 0x0L, CTEXT, (void*)"under the GNU general public.", 5, 88, 110, 8},
@@ -3581,7 +3751,7 @@ void RLPlotInfo()
{4, 5, 0, 0x0L, CTEXT, (void*)"scientific plotting program", 10, 30, 100, 8},
{5, 6, 0, 0x0L, CTEXT, (void*)"version "SZ_VERSION, 10, 38, 100, 8},
{6, 7, 0, HREF, CTEXT, (void*)"http://rlplot.sourceforge.net/", 5, 46, 110, 8},
- {7, 8, 0, 0x0L, CTEXT, (void*)"Copyright (C) 2002-2005 R. Lackner", 5, 54, 110, 8},
+ {7, 8, 0, 0x0L, CTEXT, (void*)"Copyright (C) 2002-2006 R. Lackner", 5, 54, 110, 8},
{8, 9, 0, 0x0L, CTEXT, (void*)"reinhard.lackner at uibk.ac.at", 5, 62, 110, 9},
{9, 10, 0, 0x0L, LTEXT, (void*)"powered by Trolltech\'s Qt", 35, 72, 80, 8},
{10, 11, 0, HREF, LTEXT, (void*)"http://www.trolltech.com", 35, 80, 80, 9},
@@ -3724,7 +3894,7 @@ bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go)
double startval = 1.0, stepval = 1.0;
static char *formula = 0L;
if(!formula && CurrText && CurrText->isFormula()) {
- if(CurrText->GetText(TmpTxt,TMP_TXT_SIZE)) formula = strdup(TmpTxt);
+ if(CurrText->GetText(TmpTxt,TMP_TXT_SIZE, false)) formula = strdup(TmpTxt);
}
if(!formula) formula = strdup("=a1");
DlgInfo RangeDlg[] = {
diff --git a/TheDialog.h b/TheDialog.h
index e41ffcf..d3ac27d 100755
--- a/TheDialog.h
+++ b/TheDialog.h
@@ -1,4 +1,4 @@
-//TheDialog.h, Copyright (c) 2001, 2002, 2003, 2004, 2005 R.Lackner
+//TheDialog.h, Copyright (c) 2001-2006 R.Lackner
//Definitions for TheDialog.cpp
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
@@ -37,7 +37,7 @@ typedef struct {
} TabSHEET;
//types of dialogs
-enum {NONE, PUSHBUTTON, ARROWBUTT, COLBUTTON, FILLBUTTON, SHADE3D, LINEBUTT, SYMBUTT,
+enum {NONE, PUSHBUTTON, ARROWBUTT, COLBUTTON, COLBUTT, FILLBUTTON, SHADE3D, LINEBUTT, SYMBUTT,
FILLRADIO, SYMRADIO, CHECKBOX, RADIO0, RADIO1, RADIO2, LTEXT, RTEXT, CTEXT, EDTEXT,
RANGEINPUT, EDVAL1, INCDECVAL1, HSCROLL, VSCROLL, TXTHSP, ICON, GROUP,
GROUPBOX, SHEET, ODBUTTON, LISTBOX1, TREEVIEW, LINEPAT, TEXTBOX, CHECKPIN, TRASH,
@@ -57,6 +57,8 @@ enum {NONE, PUSHBUTTON, ARROWBUTT, COLBUTTON, FILLBUTTON, SHADE3D, LINEBUTT, SYM
#define NOEDIT 0x00000400L
#define LASTOBJ 0x00100000L
+#define EXRADIO TOUCHEXIT|ISRADIO
+
//owner draw button commands
enum {OD_CREATE, OD_DELETE, OD_DRAWNORMAL, OD_DRAWSELECTED, OD_SELECT, OD_MBTRACK,
OD_SETLINE, OD_GETLINE, OD_SETFILL, OD_GETFILL, OD_ACCEPT};
@@ -180,6 +182,7 @@ private:
class ColorButton:public Dialog {
public:
ColorButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, unsigned long color);
+ ColorButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, DWORD *color);
void DoPlot(anyOutput *o);
bool Select(int x, int y, anyOutput *o);
bool GetColor(int id, DWORD *color) {*color = col; return true;};
@@ -524,6 +527,11 @@ private:
DWORD *pPattern;
};
+//prototypes TheDialog.cpp
+void UseRangeMark(DataObj *d, int type, char* =0L, char* =0L, char* =0L, char* =0L,
+ char* =0L, char* =0L, char* =0L, char* =0L, char* =0L, char* =0L, char* =0L);
+DlgInfo *CompileDialog(char* tmpl, void **ptypes);
+
//prototypes ODbutton.cpp
void OD_DrawOrder(int cmd, void *par, RECT *rec, anyOutput *o, void *data, int id);
int ExecDrawOrderButt(GraphObj *parent, GraphObj *obj, int id);
diff --git a/UtilObj.cpp b/UtilObj.cpp
index 7950b37..0913bb5 100755
--- a/UtilObj.cpp
+++ b/UtilObj.cpp
@@ -1,4 +1,4 @@
-//UtilObj.cpp, (c)2000, 2001, 2002, 2003, 2004, 2005 by R. Lackner
+//UtilObj.cpp, (c) 2000-2006 by R. Lackner
//
// This file is part of RLPlot.
//
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <ctype.h>
#include <fcntl.h> //file open flags
#include <sys/stat.h> //I/O flags
@@ -81,7 +82,7 @@ EditText::~EditText()
HideCopyMark();
if(CurrText == this) CurrText = 0L;
if(text) free(text); text = 0L;
- if(ftext) free(ftext); ftext = 0L;
+// if(ftext) free(ftext); ftext = 0L;
}
bool
@@ -168,11 +169,12 @@ EditText::Update(int select, anyOutput *Out, POINT *MousePos)
}
break;
case 2: //inactive spreadsheet cell
- if((type & 0xff) == ET_FORMULA) Align = TXA_VCENTER | TXA_HRIGHT;
+ if(CurrText == this) {
+ FindType();
+ }
if(crb.x > rb.x) {
crb.x = rb.x; crb.y = rb.y;
}
- if(CurrText == this) FindType();
bgLine = &ETbgnn; bgFill = &ETfbnn; TextCol = 0x00000000L;
if(Out) Redraw(Out, true);
break;
@@ -194,18 +196,18 @@ EditText::Redraw(anyOutput *Out, bool display)
{
RECT rc;
POINT MyPos;
- char *txt, tmptxt[80];
+ char *txt, tmptxt[500];
int w, h, o_crbx;
bool b_clip = false;
anyOutput *opc;
- anyResult *fmres;
+ anyResult cres;
if(!parent && disp) Out = disp;
if(loc.x <1 || rb.x < 1 || loc.y <1 || rb.y <1) return false;
o_crbx = crb.x; crb.x = rb.x; crb.y = rb.y;
if (Out) {
if (m1 >m2) Swap(m1, m2);
- if(((type & 0xff) == ET_UNKNOWN) && text && text[0]) FindType();
+ if(((type & 0xff) == ET_UNKNOWN) && text && text[0] && (bgLine == &ETbgnn || bgLine == &ETbgmn)) FindType();
Out->TxtSet.Align = Align; Out->TxtSet.ColTxt = TextCol;
Out->TxtSet.ColBg = bgLine->color;
if(text && text[0]) {
@@ -227,42 +229,35 @@ EditText::Redraw(anyOutput *Out, bool display)
}
if(ftext) free(ftext); ftext = 0L;
if(text && text[0]){
- if((type & 0xff) == ET_FORMULA && (bgLine == &ETbgnn || bgLine == &ETbgmn)) {
+ if(bgLine == &ETbgnn || bgLine == &ETbgmn) {
Out->TxtSet.Align = TXA_HLEFT | TXA_VCENTER;
- if(type & ET_CIRCULAR) strcpy (tmptxt, "#CIRC.");
- else if((fmres = do_formula((DataObj*)parent, text+1)) && fmres->type != ET_ERROR) {
- b_clip = false;
- if(fmres->type == ET_VALUE) {
- sprintf(tmptxt, "%g", Value = fmres->value);
- fit_num_rect(Out, rb.x - loc.x, tmptxt);
- Out->TxtSet.Align = TXA_HRIGHT | TXA_VCENTER;
- }
- else if(fmres->type == ET_TEXT) {
- if(ftext) free (ftext); ftext = 0L;
- if(fmres->text) ftext = strdup(fmres->text);
- if(fmres->text && strlen(fmres->text)<sizeof(tmptxt)) strcpy(tmptxt, fmres->text);
- else if(fmres->text) sprintf(tmptxt,"#SIZE");
- else tmptxt[0] = 0;
- }
- else strcpy(tmptxt, "#VALUE");
- }
- else sprintf(tmptxt, "#ERROR");
- txt = tmptxt;
- }
- else if((type &0xff) == ET_VALUE) {
- Out->oGetTextExtent(text, strlen(text), &w, &h);
- if(w >= (rb.x - loc.x-8) && (bgLine == &ETbgnn || bgLine == &ETbgmn)) {
- sprintf(tmptxt, "%g", Value);
+ GetResult(&cres, false); TranslateResult(&cres);
+ Value = cres.value;
+ switch (cres.type) {
+ case ET_VALUE:
+ Out->TxtSet.Align = TXA_HRIGHT | TXA_VCENTER;
+ b_clip = false; strcpy(tmptxt, cres.text);
fit_num_rect(Out, rb.x - loc.x, tmptxt);
- txt = tmptxt; b_clip = false;
- }
- else txt = text;
- }
- else if((type & 0xff) == ET_TEXT) {
- if(text && text[0] == '\'' && (bgLine == &ETbgnn || bgLine == &ETbgmn)) {
- txt = text+1;
+ Int2Nat(tmptxt); break;
+ case ET_BOOL: case ET_DATE: case ET_TIME: case ET_DATETIME:
+ case ET_TEXT:
+ Out->TxtSet.Align = cres.type == ET_TEXT ?
+ TXA_HLEFT | TXA_VCENTER : TXA_HRIGHT | TXA_VCENTER;
+ if(ftext) free (ftext); ftext = 0L;
+ if(cres.text) ftext = strdup(cres.text);
+ if(cres.text && strlen(cres.text)<sizeof(tmptxt))
+ strcpy(tmptxt, cres.text[0] != '\'' ? cres.text : cres.text +1);
+ else if(cres.text) sprintf(tmptxt,"#SIZE");
+ else tmptxt[0] = 0;
+ Out->oGetTextExtent(tmptxt, strlen(tmptxt), &w, &h);
+ b_clip = (crb.x - loc.x) < (w+(h>>1)) ? true : false;
+ break;
+ case ET_ERROR:
+ strcpy(tmptxt, "#ERROR"); break;
+ default:
+ strcpy(tmptxt, "#VALUE"); break;
}
- else txt = text;
+ txt = tmptxt;
}
else txt = text;
MyPos.y = (loc.y+rb.y)>>1;
@@ -459,16 +454,18 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
}
return false;
case CMD_ADDTXT:
- if(data_obj && *((char*)data_obj) && text &&
+ if((tag1 = (char*)data_obj) && *tag1 && text &&
(type == ET_TEXT || type == ET_UNKNOWN || type == ET_FORMULA)){
if(hasMark()) Command(CMD_DELETE, 0L, 0L);
else Undo.TextCell(this, Out, text, &CursorPos, &m1, &m2, parent, 0L);
if(m1 > -1 && m2 > -1) Command(CMD_DELETE, 0L, 0L);
+ for(k = 0; tag1[k] && tag1[k] == text[k]; k++);
+ if(tag1[k]!=';') k = 0;
for(i = 0; i < CursorPos && text[i]; i++) TmpTxt[i] = text[i];
- j = i + sprintf(TmpTxt+i, "%s", (char*)data_obj);
+ j = i + sprintf(TmpTxt+i, "%s", tag1+k);
if(text[i]) sprintf(TmpTxt+j, "%s", text+i);
if(text = (char*)realloc(text, strlen(TmpTxt)+2)) strcpy(text, TmpTxt);
- CursorPos += strlen((char*)data_obj);
+ CursorPos += strlen(tag1+k);
Out->Focus();
Update(1, Out, 0L);
}
@@ -484,9 +481,6 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
CursorPos--; //continue as if delete
case CMD_DELETE:
if(!text) return false;
- if(parent) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
if(cmd == CMD_DELETE) Undo.TextCell(this, Out, text, &CursorPos, &m1, &m2, parent, 0L);
if(parent) {
((DataObj*)parent)->Command(CMD_MRK_DIRTY, 0L, 0L);
@@ -512,6 +506,9 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
}
if(Out)Redraw(Out, (bRet = true));
}
+ if(parent) {
+ ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
+ }
if(Out)Out->TextCursor(text, MyPos, (POINT *) NULL, &CursorPos,
scroll_et == this ? scroll_dist : scroll_dist=0);
return bRet;
@@ -734,7 +731,8 @@ EditText::GetValue(double *v)
return false;
}
if(CurrText == this && !(type & ET_BUSY)) FindType();
- if((type & 0xff) == ET_VALUE){
+ if((type & 0xff) == ET_VALUE || (type & 0xff) == ET_BOOL || (type & 0xff) == ET_DATE
+ || (type & 0xff) == ET_TIME || (type & 0xff) == ET_DATETIME){
*v = Value; return true;
}
if((type & 0xff) == ET_FORMULA && text && text[0]){
@@ -757,15 +755,30 @@ EditText::GetValue(double *v)
}
bool
-EditText::GetText(char *tx, int size)
+EditText::GetText(char *tx, int size, bool bTranslate)
{
- char *t;
+ char *t = 0L;
+ static char tmp_txt[40];
+ anyResult res;
- if(text && text[0]) {
+ if((type & 0xff) == ET_TEXT && text && text[0]) {
if(text[0] =='\'' && text[1]) t = text + 1;
else t = text;
}
- else t = 0L;
+ else if(bTranslate) {
+ GetResult(&res, false); TranslateResult(&res);
+ switch (res.type) {
+ case ET_VALUE:
+ strcpy(tmp_txt, res.text); t = tmp_txt;
+ Int2Nat(tmp_txt); break;
+ case ET_BOOL: case ET_DATE: case ET_TIME:
+ case ET_DATETIME: case ET_TEXT:
+ t = res.text; break;
+ default:
+ t = 0L; break;
+ }
+ }
+ else if(text && text[0]) t = (text[0] =='\'' && text[1]) ? text+1 : text;
if(t) {
if((int)strlen(t) < size) strcpy(tx, t);
else {
@@ -773,9 +786,9 @@ EditText::GetText(char *tx, int size)
}
return true;
}
- if((type & 0xff) == ET_VALUE) {
+ else if((type & 0xff) == ET_VALUE) {
if(text = (char*)realloc(text, 20)) sprintf(text, "%g", Value);
- if(text && text[0]) return(GetText(tx, size));
+ if(text && text[0]) return(GetText(tx, size, false));
}
return false;
}
@@ -796,8 +809,9 @@ EditText::GetResult(anyResult *r, bool use_last)
return true;
}
if((type & 0xff) == ET_UNKNOWN) FindType();
- if((type & 0xff) == ET_VALUE) {
- r->text = 0L; r->value = Value; r->type = ET_VALUE;
+ if((type & 0xff) == ET_VALUE || (type & 0xff) == ET_BOOL || (type & 0xff) == ET_DATE
+ || (type & 0xff) == ET_TIME || (type & 0xff) == ET_DATETIME){
+ r->text = 0L; r->value = Value; r->type = (type & 0xff);
return true;
}
if((type & 0xff) == ET_TEXT) {
@@ -818,8 +832,10 @@ EditText::GetResult(anyResult *r, bool use_last)
type |= ET_BUSY;
if(res = do_formula((DataObj*)parent, text+1)) {
if(res->type == ET_VALUE) Value = res->value;
- else Value = 0.0;
- type &= ~ET_BUSY;
+ else if(res->type == ET_ERROR) {
+ res->text = "#ERROR"; res->type = ET_TEXT;
+ }
+ else Value = 0.0; type &= ~ET_BUSY;
memcpy(r, res, sizeof(anyResult));
return true;
}
@@ -854,43 +870,6 @@ EditText::SetText(char *t)
return false;
}
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// return the ASCII reprentation of value of text if applicable. If not return
-// the text with double quotes: comma separated file syntax.
-bool
-EditText::GetItem(char *dest, int size)
-{
- char tmp[50];
- int i;
-
- if(!text || !text[0] || !dest || size < 3) return false;
- if((type & 0xff) == ET_UNKNOWN) FindType();
- if(CurrText == this) FindType();
- //its a value
- if((type & 0xff) == ET_VALUE){
- if(text && strlen(text) < (sizeof(tmp)-1)){
- strcpy(tmp, text);
- if(defs.DecPoint[0] != '.') {
- for(i = 0; tmp[i]; i++)
- if(tmp[i] == defs.DecPoint[0]) tmp[i]='.';
- }
- }
- else {
- sprintf(tmp, "%f", Value); RmTrail(tmp);
- }
- for(i = 0; i < (size-1) && tmp[i]; i++) dest[i] = tmp[i];
- dest[i] = 0;
- }
- //else its a string
- else {
- dest[0] = '"';
- for(i = 1; i < (size-2) && text[i-1]; i++) dest[i] = text[i-1];
- dest[i++] = '"';
- dest[i] = 0;
- }
- return true;
-}
-
void
EditText::SetRec(RECT *rc)
{
@@ -903,7 +882,8 @@ bool
EditText::isValue()
{
if((type & 0xff)==ET_UNKNOWN) FindType();
- return (type == ET_VALUE || type == ET_FORMULA);
+ return (type == ET_VALUE || type == ET_FORMULA || type == ET_BOOL
+ || type == ET_DATE || type == ET_TIME || type == ET_DATETIME);
}
bool
@@ -916,25 +896,59 @@ EditText::isFormula()
void
EditText::FindType()
{
- if(text && text[0] == '=') {
+ int i, c1, c2, c3, c4;
+
+ if(!text || !text[0]) {
Align = TXA_VCENTER | TXA_HRIGHT;
- type = ET_FORMULA;
+ if ((type && 0xff) == ET_VALUE) type = ET_VALUE;
+ else type = ET_UNKNOWN;
+ return;
}
- else if(text && (Txt2Flt(text, &Value))) {
+ if(text[0] == '=') {
Align = TXA_VCENTER | TXA_HRIGHT;
- type = ET_VALUE;
- }
- else if (text && text[0]) {
- Align = TXA_VCENTER | TXA_HLEFT;
- type = ET_TEXT;
+ type = ET_FORMULA;
}
- else if ((type && 0xff) == ET_VALUE) {
- Align = TXA_VCENTER | TXA_HRIGHT;
- type = ET_VALUE;
+ else if(isdigit(text[0]) || text[0] == '.' || text[0] == defs.DecPoint[0]) {
+ for(i = c1 = c2 = c3 = c4 = 0; text[i]; i++) {
+ switch(text[i]) {
+ case '.': c1++; break;
+ case '-': c2++; break;
+ case '/': c3++; break;
+ case ':': c4++; break;
+ }
+ }
+ if(c1 < 2 && c2 < 2 && !c3 && !c4 && Txt2Flt(text, &Value)) {
+ Align = TXA_VCENTER | TXA_HRIGHT;
+ type = ET_VALUE;
+ }
+ else if((c1 == 2 || c2 == 2 || c3 == 2) && date_value(text, 0L, &Value)) {
+ Align = TXA_VCENTER | TXA_HRIGHT;
+ type = c4 == 2 ? ET_DATETIME : ET_DATE;
+ }
+ else if((c4 == 1 || c4 == 2) && date_value(text, "H:M:S", &Value)) {
+ Align = TXA_VCENTER | TXA_HRIGHT;
+ type = ET_TIME;
+ }
+ else {
+ Align = TXA_VCENTER | TXA_HLEFT;
+ type = ET_TEXT;
+ }
}
else {
- Align = TXA_VCENTER | TXA_HRIGHT;
- type = ET_UNKNOWN;
+ if(0 == strcmp(text, "true")) {
+ Value = 1.0;
+ Align = TXA_VCENTER | TXA_HRIGHT;
+ type = ET_BOOL;
+ }
+ else if(0 == strcmp(text, "false")) {
+ Value = 0.0;
+ Align = TXA_VCENTER | TXA_HRIGHT;
+ type = ET_BOOL;
+ }
+ else {
+ Align = TXA_VCENTER | TXA_HLEFT;
+ type = ET_TEXT;
+ }
}
}
@@ -1353,10 +1367,10 @@ DataObj::GetValue(int row, int col, double *v)
}
bool
-DataObj::GetText(int row, int col, char *txt, int len)
+DataObj::GetText(int row, int col, char *txt, int len, bool bTranslate)
{
if(row < 0 || row >= cRows || col < 0 || col >= cCols) return false;
- if(txt && etRows[row][col]) return etRows[row][col]->GetText(txt, len);
+ if(txt && etRows[row][col]) return etRows[row][col]->GetText(txt, len, bTranslate);
return false;
}
@@ -1398,6 +1412,37 @@ DataObj::FlushData()
etRows = 0L;
}
+bool
+DataObj::ValueRec(RECT *rc)
+{
+ int r, c;
+ double val;
+
+ if(etRows && rc){
+ rc->left = cCols; rc->right = 0;
+ rc->bottom = 0; rc->top = cRows;
+ for(r = 0; r < cRows; r++) if(etRows[r]) {
+ for (c = 0; c< cCols; c++) {
+ if(etRows[r][c] && etRows[r][c]->GetValue(&val)) {
+ if(c < rc->left) rc->left = c;
+ if(c > rc->right) rc->right = c;
+ else c = rc->right;
+ if(r > rc->bottom) rc->bottom = r;
+ else c = rc->right;
+ if(r < rc->top) rc->top = r;
+ }
+ }
+ }
+ if(rc->right < rc->left) rc->right = rc->left < cCols ? rc->left : rc->left = 0;
+ if(rc->bottom < rc->top) rc->bottom = rc->top < cRows ? rc->top : rc->top = 0;
+ if(!rc->bottom && !rc->top && !rc->right && !rc->left) {
+ rc->right = cCols-1; rc->bottom = cRows-1;
+ }
+ return true;
+ }
+ return false;
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Store Data Object as strings: less memory required than with DataObj
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1876,6 +1921,9 @@ Default::Default()
axis_color = 0x0L;
svgAttr = svgScript = currPath = IniFile = 0L;
File1 = File2 = File3 = File4 = File5 = File6 = 0L;
+ fmt_date = strdup("Z.V.Y");
+ fmt_time = strdup("H:M:S");
+ fmt_datetime = strdup("Z.V.Y H:M:S");
}
Default::~Default()
@@ -1889,6 +1937,8 @@ Default::~Default()
if(File1) free(File1); if(File2) free(File2);
if(File3) free(File3); if(File4) free(File4);
if(File5) free(File5); if(File6) free(File6);
+ if(fmt_date) free(fmt_date); if(fmt_time) free(fmt_time);
+ if(fmt_datetime) free(fmt_datetime);
}
void
@@ -2128,7 +2178,8 @@ Default::FileHistory(char *path)
char **history[] = {&File1, &File2, &File3, &File4, &File5, &File6};
int i;
- if(path && (tmp_path=strdup(path))){
+ if(path && (tmp_path=(char*)malloc(strlen(path)+10))){
+ strcpy(tmp_path, path);
for(i=strlen(path); i > 0 && tmp_path[i] != '/' && tmp_path[i] != '\\'; i--);
tmp_path[i] = 0;
if(currPath) free(currPath);
@@ -2584,7 +2635,7 @@ UndoObj::Restore(bool redraw, anyOutput*o)
if((ul = (UndoList *)(buff[idx]->data)) && (ul->array)){
gol = (GraphObj**)(*(ul->loc_arr));
if(gol) for (i = 0; i < *(ul->loc_count); i++) if(gol[i]) ::DeleteGO(gol[i]);
- *(ul->loc_count) = ul->count; free(gol);
+ *(ul->loc_count) = ul->count; if(gol) free(gol);
*(ul->loc_arr) = ul->array; free(ul);
}
break;
@@ -2729,7 +2780,7 @@ UndoObj::DeleteGO(GraphObj **go, DWORD flags, anyOutput *o)
SetDisp(o); o->HideMark();
}
if(CurrGO == *go) CurrGO = 0L;
- if((*go)->Id == GO_POLYLINE || (*go)->Id == GO_POLYGON){
+ if((*go)->Id == GO_POLYLINE || (*go)->Id == GO_POLYGON || (*go)->Id == GO_BEZIER){
if(CurrHandle && CurrHandle->parent==*go) {
if((*go)->Command(CMD_DELOBJ, CurrHandle, 0l)) return;
}
@@ -2780,7 +2831,7 @@ UndoObj::DropListGO(GraphObj *parent, GraphObj ***go, long *count, DWORD flags)
UndoList *ul;
if(ul = (UndoList *)malloc(sizeof(UndoList))) {
- if(ul->array = memdup(*go, *count * sizeof(GraphObj*), 0)){
+ if(ul->array = *go) {
ul->loc_arr = (void **)go; *go = 0L;
ul->count = *count; *count = 0;
ul->loc_count = count;
@@ -2826,10 +2877,10 @@ UndoObj::Point(GraphObj *parent, POINT *pt, anyOutput * o, DWORD flags)
}
void
-UndoObj::VoidPtr(GraphObj *parent, void **pptr, void *ptr, anyOutput * o, DWORD flags)
+UndoObj::VoidPtr(GraphObj *parent, void **pptr, void *ptr, anyOutput *o, DWORD flags)
{
if(o) SetDisp(o);
- if(0 > NewItem(UNDO_VOIDPTR, flags, parent, ptr, pptr)) free(ptr);
+ NewItem(UNDO_VOIDPTR, flags, parent, ptr, pptr);
}
void
@@ -3147,7 +3198,7 @@ UndoObj::RestoreConf(UndoInfo *inf)
// of the tree finalizing undo.
if(!inf->data) return;
if(!(proc = new UndoUtil(inf->owner, (GraphObj*)inf->loc))) return;
- OpenGraph(proc, 0L, (unsigned char *)inf->data);
+ OpenGraph(proc, 0L, (unsigned char *)inf->data, false);
if(proc->res) for(i = 0; i < UNDO_RING_SIZE; i++) {
if(buff[i] && buff[i]->owner == (GraphObj*)inf->loc) FreeInfo(&buff[i]);
if(buff[i] && buff[i]->cmd == UNDO_OBJCONF){
diff --git a/Utils.cpp b/Utils.cpp
index a3bc6da..9d2b6dd 100755
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -1,4 +1,4 @@
-//Utils.cpp, Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005 R.Lackner
+//Utils.cpp, Copyright (c) 2000-2006 R.Lackner
//Collection of utility functions and classes for RLPlot
//
// This file is part of RLPlot.
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <errno.h>
#include "rlplot.h"
extern GraphObj *CurrGO; //Selected Graphic Objects
@@ -245,6 +246,28 @@ double GetAxisFac(AxisDEF *axis, double delta, int direc)
//----------------------------------------------------------------------------
// Text utility functions: internationalization and formats
//----------------------------------------------------------------------------
+//remove leading/trailing whitespace
+char *str_ltrim(char *str) {
+ int i, j;
+
+ if(!str || !str[0]) return str;
+ for(i = 0; str[i] && str[i] <= ' '; i++);
+ for(j = 0; str[i]; str[j++] = str[i++]);
+ str[j++] = '\0'; return str;
+ }
+
+char *str_rtrim(char *str) {
+ int i;
+
+ i = strlen(str);
+ while(i > 0 && str[i-1] <= ' ') str[--i] = '\0';
+ return str;
+}
+
+char *str_trim(char *str) {
+ str = str_ltrim(str); return str_rtrim(str);
+}
+
// restyle formula
void ReshapeFormula(char **text)
{
@@ -264,6 +287,34 @@ void ReshapeFormula(char **text)
}
}
+//translate anyResult to output format
+void TranslateResult(anyResult *res)
+{
+ static char tr_text[80];
+
+ switch (res->type) {
+ case ET_VALUE:
+ sprintf(tr_text, "%g", res->value);
+ res->text = tr_text; return;
+ case ET_BOOL:
+ sprintf(tr_text, "%s", ((int)res->value) ? "true" : "false");
+ res->text = tr_text; return;
+ case ET_DATE:
+ sprintf(tr_text, "%s", value_date(res->value, defs.fmt_date));
+ res->text = tr_text; return;
+ case ET_TIME:
+ sprintf(tr_text, "%s", value_date(res->value, defs.fmt_time));
+ res->text = tr_text; return;
+ case ET_DATETIME:
+ sprintf(tr_text, "%s", value_date(res->value, defs.fmt_datetime));
+ res->text = tr_text; return;
+ case ET_TEXT:
+ if(res->text && res->text[0]) return;
+ }
+ if(!(res->text)) res->text="";
+}
+
+//remove invalid tag combinations from string
void CleanTags(char *txt, int *i1, int *i2, int *i3)
{
char *no_tags[] = {"<b></b>", "</b><b>", "<b><b>", "</b></b>",
@@ -627,8 +678,7 @@ void AddToPolygon(long *cp, POINT *pts, POINT *np)
if(np->y == pts[i-1].y) return;
if((np->y > pts[i-1].y && pts[i-1].y > pts[i-2].y) ||
(np->y < pts[i-1].y && pts[i-1].y < pts[i-2].y)) {
- pts[i-1].x = np->x;
- pts[i-1].y = np->y;
+ pts[i-1].x = np->x; pts[i-1].y = np->y;
return;
}
}
@@ -636,8 +686,7 @@ void AddToPolygon(long *cp, POINT *pts, POINT *np)
if(np->x == pts[i-1].x) return;
if((np->x > pts[i-1].x && pts[i-1].x > pts[i-2].x) ||
(np->x < pts[i-1].x && pts[i-1].x < pts[i-2].x)) {
- pts[i-1].x = np->x;
- pts[i-1].y = np->y;
+ pts[i-1].x = np->x; pts[i-1].y = np->y;
return;
}
}
@@ -648,20 +697,61 @@ void AddToPolygon(long *cp, POINT *pts, POINT *np)
(pts[i-1].x - pts[i-2].x))/(pts[i-1].y - pts[i-2].y)) : 0;
iy = (pts[i-1].x != pts[i-2].x) ? (pts[i-2].y + ((np->x - pts[i-2].x) *
(pts[i-1].y - pts[i-2].y))/(pts[i-1].x - pts[i-2].x)) : 0;
- if((ix && ix == np->x) || (iy && iy == np->y)) {
- pts[i-1].x = np->x;
- pts[i-1].y = np->y;
+ if((ix && ix == np->x) && (iy && iy == np->y)) {
+ pts[i-1].x = np->x; pts[i-1].y = np->y;
return;
}
}
//not explained by extrapolation, accept new point
- pts[i].x = np->x;
- pts[i].y = np->y;
+ pts[i].x = np->x; pts[i].y = np->y;
*cp = i+1;
return;
}
//----------------------------------------------------------------------------
+// create a Bezier polygon
+void DrawBezier(long *cp, POINT *pts, POINT p0, POINT p1, POINT p2, POINT p3, int depth)
+{
+#define MIN_SEG 11
+#define MAX_DEPTH 5
+ int i;
+ POINT np, p01, p12, p23, p012, p123, p0123;
+ POINT *ap[] = {&p0, &p1, &p2, &p3};
+
+ depth ++;
+ if(depth > MAX_DEPTH) {
+ for(i= 0; i < 4; i++) {
+ np.x = (*ap[i]).x >> 2; np.y = (*ap[i]).y >> 2;
+ AddToPolygon(cp, pts, &np);
+ }
+ return;
+ }
+ else if(depth == 1) for(i=0; i < 4; i++) {
+ (*ap[i]).x <<= 2; (*ap[i]).y <<= 2;
+ }
+ p01.x = (p0.x + p1.x) >> 1; p01.y = (p0.y + p1.y) >> 1;
+ p12.x = (p1.x + p2.x) >> 1; p12.y = (p1.y + p2.y) >> 1;
+ p23.x = (p2.x + p3.x) >> 1; p23.y = (p2.y + p3.y) >> 1;
+ p012.x = (p01.x + p12.x) >> 1; p012.y = (p01.y + p12.y) >> 1;
+ p123.x = (p12.x + p23.x) >> 1; p123.y = (p12.y + p23.y) >> 1;
+ p0123.x = (p012.x + p123.x) >> 1; p0123.y = (p012.y + p123.y) >> 1;
+ if(abs(p0.x - p0123.x)> MIN_SEG || abs(p0.y - p0123.y)> MIN_SEG) {
+ DrawBezier(cp, pts, p0, p01, p012, p0123, depth); //recursion: refine
+ }
+ else {
+ DrawBezier(cp, pts, p0, p01, p012, p0123, MAX_DEPTH); //recursion: store data
+ }
+ if(abs(p3.x - p0123.x)> MIN_SEG || abs(p3.y - p0123.y)> MIN_SEG) {
+ DrawBezier(cp, pts, p0123, p123, p23, p3, depth); //recursion: refine
+ }
+ else {
+ DrawBezier(cp, pts, p0123, p123, p23, p3, MAX_DEPTH); //recursion: store data
+ }
+#undef MAX_DEPTH
+#undef MIN_SEG
+}
+
+//----------------------------------------------------------------------------
// create a circular polygon
//use circular Bresenham's algorithm to draw arcs
//Ref: C. Montani, R. Scopigno (1990) "Speres-To-Voxel Conversion", in:
@@ -975,6 +1065,8 @@ void DeleteGO(GraphObj *go)
case GO_GRID3D: delete((Grid3D*)go); break;
case GO_FUNC3D: delete((Func3D*)go); break;
case GO_XYSTAT: delete((xyStat*)go); break;
+ case GO_FITFUNC3D: delete((FitFunc3D*)go); break;
+ case GO_BEZIER: delete((Bezier*)go); break;
default:
sprintf(TmpTxt, "Cannot delete Object\nwith Id %ld", go->Id);
ErrorBox(TmpTxt);
@@ -1078,7 +1170,11 @@ bool FileExist(char *FileName)
{
FILE *TheFile;
- if(0L ==(TheFile = fopen(FileName, "r"))) return false;
+
+ if(0L ==(TheFile = fopen(FileName, "r"))) {
+ if(errno == ENOENT) return false;
+ return true;
+ }
fclose(TheFile);
return true;
}
@@ -1137,17 +1233,31 @@ bool ReplaceGO(GraphObj **oldobj, GraphObj **newobj)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//calculate a 'unique' hash value for a string
+//Ref: Corman T.H., Leiserson C.E. & Rivest R.L. (1990) Hash Functions.
+// in: Introduction to Algorithms (MIT Press & McGraw-Hill)
+// ISBN 0-262-03141-8 and ISBN 0-07-013143-0, pp. 226ff
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unsigned int HashValue(unsigned char *str)
{
- unsigned int i = 0, ret=0;
+ unsigned int i = 0, ret = 0;
- if(!str) return 0;
+ if(!str || !str[0]) return 0;
do {
if(str[i] > 32) ret = ((str[i]-32) + (ret <<2));
i++;
}while(str[i]);
- if(i < 4) memcpy(&ret, str, i);
+ return ret;
+}
+
+unsigned int Hash2(unsigned char * str)
+{
+ unsigned int i = 0, ret = 0, c;
+
+ if(!str) return 0;
+ do {
+ c = str[i++];
+ ret = ((ret * c)<<2) | c;
+ }while(str[i]);
return ret;
}
@@ -1532,7 +1642,6 @@ double *ppg_vec = 0L;
//Ref: P.S. Heckbert (1990) "Digital Line Drawing", in: Graphic Gems
// (A.S. Glassner, ed.); Academic Press, Inc.,
// ISBN 0-12-286165-5
-// void AddToPolygon(long *cp, POINT *pts, POINT *np);
bool IsOnLine(POINT *p1, POINT *p2, int x, int y)
{
int d, ax, ay, sx, sy, dx, dy;
@@ -1570,7 +1679,6 @@ bool IsOnLine(POINT *p1, POINT *p2, int x, int y)
//Ref: P.S. Heckbert (1990) "Digital Line Drawing", in: Graphic Gems
// (A.S. Glassner, ed.); Academic Press, Inc.,
// ISBN 0-12-286165-5
-// void AddToPolygon(long *cp, POINT *pts, POINT *np);
bool ShadowPolygon(POINT *p1, POINT *p2, POINT *tp, int ntp, POINT *pts, long *cp, POINT *lim)
{
int d, ax, ay, sx, sy, dx, dy;
diff --git a/Version.h b/Version.h
index aca17f5..ecd91f5 100755
--- a/Version.h
+++ b/Version.h
@@ -1,4 +1,4 @@
-//RLPlot.h, Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005 R.Lackner
+//RLPlot.h, Copyright (c) 2000-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -16,4 +16,4 @@
// along with RLPlot; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-#define SZ_VERSION "1.0"
+#define SZ_VERSION "1.1"
diff --git a/WinSpec.cpp b/WinSpec.cpp
index ff11d6e..9e9de14 100755
--- a/WinSpec.cpp
+++ b/WinSpec.cpp
@@ -1,4 +1,4 @@
-//WinSpec.cpp, Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005 R.Lackner
+//WinSpec.cpp, Copyright (c) 2000-2006 R.Lackner
//the entire code of this module is highly specific to Windows!
//
// This file is part of RLPlot.
@@ -427,15 +427,15 @@ void TestClipboard(GraphObj *g)
else if((hmem = GetClipboardData(CF_TEXT)) &&
(ptr = (unsigned char*) GlobalLock(hmem))) ProcMemData(g, ptr, true);
else if((hmem = GetClipboardData(cf_rlpobj)) &&
- (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr);
+ (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr, true);
else if((hmem = GetClipboardData(cf_rlpgraph)) &&
- (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr);
+ (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr, true);
}
else if(g->Id == GO_PAGE) {
if((hmem = GetClipboardData(cf_rlpobj)) &&
- (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr);
+ (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr, true);
else if((hmem = GetClipboardData(cf_rlpgraph)) &&
- (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr);
+ (ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr, true);
}
else if(g->Id == GO_GRAPH) TestClipboard(g->parent);
if(hmem) GlobalUnlock(hmem);
@@ -1037,6 +1037,39 @@ unsigned char zoom_mask[] = { //zoom cursor mask
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+unsigned char paste_bits[] = { //paste cursor bitmap
+ 0x20, 0x00, 0x20, 0x00, 0xf8, 0x00, 0x20, 0x00,
+ 0x23, 0xfe, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff,
+ 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff,
+ 0x07, 0xff, 0x07, 0xff, 0x03, 0xfe, 0x00, 0x00};
+
+unsigned char paste_mask[] = { //paste cursor mask
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xfc, 0x05, 0xfd, 0x05, 0xfd, 0xf9,
+ 0xfc, 0x01, 0xfc, 0x01, 0xfc, 0x01, 0xfc, 0x01,
+ 0xfc, 0x01, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff};
+
+//display 16x16 cursor data: developers utility
+/*
+void disp_bm(unsigned char *tb)
+{
+ char txt[512];
+ unsigned char currbyte;
+ int i, j, pos;
+
+ for(i = pos = 0; i < 32; i++) {
+ currbyte = tb[i];
+ for (j = 0; j < 8; j++) {
+ if(currbyte & 0x80) pos += sprintf(txt+pos, "1");
+ else pos += sprintf(txt+pos, "0");
+ currbyte <<= 1;
+ }
+ if(i & 1) pos += sprintf(txt+pos, "\n");
+ }
+ InfoBox(txt);
+}
+*/
+
void
OutputWin::MouseCursor(int cid, bool force)
{
@@ -1057,11 +1090,15 @@ OutputWin::MouseCursor(int cid, bool force)
case MC_SE: hoc = SetCursor(LoadCursor(NULL, IDC_SIZENWSE));break;
case MC_SALL: hoc = SetCursor(LoadCursor(NULL, IDC_SIZEALL)); break;
case MC_MOVE:
- hc = CreateCursor(hInstance, 8, 8, 16, 16, hand_mask, hand_bits);
+ hc = CreateCursor(hInstance, 7, 7, 16, 16, hand_mask, hand_bits);
hoc = SetCursor(hc);
break;
case MC_ZOOM:
- hc = CreateCursor(hInstance, 8, 8, 16, 16, zoom_mask, zoom_bits);
+ hc = CreateCursor(hInstance, 7, 7, 16, 16, zoom_mask, zoom_bits);
+ hoc = SetCursor(hc);
+ break;
+ case MC_PASTE:
+ hc = CreateCursor(hInstance, 2, 2, 16, 16, paste_mask, paste_bits);
hoc = SetCursor(hc);
break;
default: return;
@@ -1257,14 +1294,20 @@ OutputWin::FileHistory()
void
OutputWin::CreateNewWindow(void *g)
{
+ RECT ClientRect;
+
hWnd = CreateWindow(name, "RLPlot",
WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
SetWindowLong(hWnd, 0, (long)g); // g is the parent graphic obj
SetWindowLong(hWnd, GWL_USERDATA, (long)this);
- ShowWindow(hWnd, SW_SHOW);
+ if(BitMapWin::Erase(0x00cbcbcb)) {
+ GetClientRect(hWnd, &ClientRect);
+ InvalidateRect(hWnd, &ClientRect, FALSE);
+ }
UpdateWindow(hWnd);
+ ShowWindow(hWnd, SW_SHOW);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2047,8 +2090,8 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
case CM_PASTE:
w->MouseCursor(MC_WAIT, true);
if(g->Id == GO_SPREADDATA || g->Id == GO_PAGE ||
- g->Id == GO_GRAPH)TestClipboard(g);
- w->MouseCursor(MC_ARROW, true);
+ g->Id == GO_GRAPH) TestClipboard(g);
+ g->Command(CMD_MOUSECURSOR, 0L, w);
return 0;
case CM_COPY: case CM_CUT:
EmptyClip();
@@ -2127,6 +2170,9 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
case CM_DELGRAPH:
g->Command(CMD_DELGRAPH, 0L, w);
return 0;
+ case CM_SAVEDATA:
+ g->Command(CMD_SAVEDATA, 0L, w);
+ return 0;
case CM_SAVEDATAAS:
g->Command(CMD_SAVEDATAAS, 0L, w);
return 0;
@@ -2145,7 +2191,7 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
SaveGraphAs(g);
return 0;
case CM_EXPORT:
- OpenExportName(g, "hello.svg");
+ OpenExportName(g, 0L);
g->DoPlot(w);
return 0;
case CM_PRINT:
@@ -2257,8 +2303,7 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
return 0;
case WM_CLOSE:
if(g && g->Command(CMD_CAN_CLOSE, 0L, 0L)) {
- SetWindowLong(hwnd, 0, 0L);
- SetWindowLong(hwnd, GWL_USERDATA, 0L);
+ SetWindowLong(hwnd, 0, 0L); SetWindowLong(hwnd, GWL_USERDATA, 0L);
w->go = 0L;
DestroyWindow(hwnd);
}
@@ -2399,7 +2444,6 @@ void *CreateDlgWnd(char *title, int x, int y, int width, int height, tag_DlgObj
if(hDlg && w && w->Erase(0x00e0e0e0L)) {
SetWindowLong(hDlg, GWL_USERDATA, (long)w);
SetWindowLong(hDlg, 0, (long)d);
- ShowWindow(hDlg, SW_SHOW);
if(flags & 0x01) { //center on screen
GetWindowRect(hDlg, &BoxRec);
GetClientRect(GetDesktopWindow(), &DeskRect);
@@ -2410,6 +2454,7 @@ void *CreateDlgWnd(char *title, int x, int y, int width, int height, tag_DlgObj
}
if(flags & 0x04) SetTimer(hDlg, 1, 100, 0L);
UpdateWindow(hDlg); d->DoPlot(w);
+ ShowWindow(hDlg, SW_SHOW);
}
else {
if(w) delete (w); return 0L;
diff --git a/exprlp.cpp b/exprlp.cpp
index fbccddb..5a291a9 100755
--- a/exprlp.cpp
+++ b/exprlp.cpp
@@ -260,6 +260,16 @@ bool StarChart::PropertyDlg()
bool Function::PropertyDlg()
{
return false;
+}
+
+bool Grid3D::PropertyDlg()
+{
+ return false;
+}
+
+bool Grid3D::Configure()
+{
+ return false;
}
bool Scatt3D::PropertyDlg()
@@ -297,6 +307,11 @@ bool Func3D::PropertyDlg()
return false;
}
+bool FitFunc3D::PropertyDlg()
+{
+ return false;
+}
+
bool BubblePlot3D::PropertyDlg()
{
return false;
@@ -410,7 +425,7 @@ ExpRoot::ExpRoot(char *file1, char *file2):GraphObj(0L, 0L)
if(file2 && strcmp("-", file2)) name2 = file2;
else name2 = 0L;
go = 0L;
- OpenGraph(this, name1, 0L);
+ OpenGraph(this, name1, 0L, false);
if(bDelete && name1 && name1[0]) unlink(name1);
}
diff --git a/mfcalc.cpp b/mfcalc.cpp
old mode 100644
new mode 100755
index 9144a14..2e3360c
--- a/mfcalc.cpp
+++ b/mfcalc.cpp
@@ -5,42 +5,56 @@
#define YYBISON 1 /* Identify Bison output. */
#define NUM 257
-#define STR 258
-#define ARR 259
-#define BLOCK 260
-#define PI 261
-#define E 262
-#define CLVAL 263
-#define PSEP 264
-#define IF 265
-#define ELSE 266
-#define VAR 267
-#define FNCT 268
-#define AFNCT 269
-#define SFNCT 270
-#define FUNC2 271
-#define TXT 272
-#define CLAUSE 273
-#define SER 274
-#define COLR 275
-#define COLC 276
-#define AND 277
-#define OR 278
-#define EQ 279
-#define NE 280
-#define GT 281
-#define GE 282
-#define LT 283
-#define LE 284
-#define NEG 285
-#define INC 286
-#define DEC 287
-#define PINC 288
-#define PDEC 289
+#define BOOLVAL 258
+#define STR 259
+#define ARR 260
+#define BLOCK 261
+#define PI 262
+#define E 263
+#define CLVAL 264
+#define PSEP 265
+#define IF 266
+#define ELSE 267
+#define BTRUE 268
+#define BFALSE 269
+#define DATE1 270
+#define TIME1 271
+#define DATETIME1 272
+#define DIM 273
+#define VAR 274
+#define FNCT 275
+#define BFNCT 276
+#define AFNCT 277
+#define SFNCT 278
+#define FUNC1 279
+#define FUNC2 280
+#define FUNC3 281
+#define TXT 282
+#define SRFUNC 283
+#define YYFNC 284
+#define FUNC4 285
+#define CLAUSE 286
+#define SER 287
+#define COLR 288
+#define COLC 289
+#define AND 290
+#define OR 291
+#define EQ 292
+#define NE 293
+#define GT 294
+#define GE 295
+#define LT 296
+#define LE 297
+#define NEG 298
+#define INC 299
+#define DEC 300
+#define PINC 301
+#define PDEC 302
+#define PDIM 303
/*
- mfcalc.y, mfcalc.cpp, Copyright (c) 2004, 2005 R.Lackner
+ mfcalc.y, mfcalc.cpp, Copyright (c) 2004, 2005, 2006 R.Lackner
parse string and simple math: based on the bison 'mfcalc' example
This file is part of RLPlot.
@@ -68,14 +82,14 @@
class symrec {
public:
- int type, row, col;
- unsigned int h_name;
+ int type, row, col, a_count;
+ unsigned int h_name, h2_name;
char *name, *text;
double (*fnctptr)(...);
symrec *next;
- double var;
+ double var, *a_data;
- symrec(unsigned int h_n, int typ, symrec *nxt);
+ symrec(unsigned int h_n, unsigned int h2_n, int typ, symrec *nxt);
~symrec();
double GetValue();
void GetValue(void *res);
@@ -109,18 +123,22 @@ typedef struct{
}YYSTYPE;
-static symrec *putsym (unsigned int h_name, int sym_type);
-static symrec *getsym (unsigned int h_name, char *sym_name = 0L);
+static symrec *putsym (unsigned int h_name, unsigned int h2_name, int sym_type);
+static symrec *getsym (unsigned int h_name, unsigned int h2_name, char *sym_name = 0L);
static int push(YYSTYPE *res, YYSTYPE *val);
static void store_res(YYSTYPE *res);
static char *PushString(char *text);
+static double *PushArray(double *arr);
+static double *ReallocArray(double *arr, int size);
static char *add_strings(char *st1, char *st2);
static char *string_value(YYSTYPE *exp);
-static double eval(YYSTYPE *sr, YYSTYPE *dst);
+static double eval(YYSTYPE *sr, YYSTYPE *dst, char* dum);
static int range_array(YYSTYPE * res, char *range);
+static int range_array2(YYSTYPE *res1, YYSTYPE *res2);
static void exec_clause(YYSTYPE *res);
static YYSTYPE *proc_clause(YYSTYPE *res);
static void yyerror(char *s);
+static void make_time(YYSTYPE *dst, double h, double m, double s);
static int yylex(void);
static double nop() {return 0.0;};
@@ -145,23 +163,23 @@ static int parse_level = 0; //count reentrances into parser
-#define YYFINAL 131
+#define YYFINAL 222
#define YYFLAG -32768
-#define YYNTBASE 48
+#define YYNTBASE 65
-#define YYTRANSLATE(x) ((unsigned)(x) <= 289 ? yytranslate[x] : 54)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 303 ? yytranslate[x] : 72)
static const char yytranslate[] = { 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 44,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 59,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 46,
- 47, 36, 35, 20, 34, 2, 37, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 45, 2,
- 19, 2, 25, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 61,
+ 62, 49, 48, 33, 47, 2, 50, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 64, 60, 2,
+ 32, 2, 38, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 43, 2, 2, 2, 2, 2, 2,
+ 51, 2, 63, 58, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -179,244 +197,413 @@ static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 21, 22, 23, 24, 26, 27, 28, 29,
- 30, 31, 32, 33, 38, 39, 40, 41, 42
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 34, 35, 36, 37, 39,
+ 40, 41, 42, 43, 44, 45, 46, 52, 53, 54,
+ 55, 56, 57
};
#if YYDEBUG != 0
static const short yyprhs[] = { 0,
0, 1, 4, 6, 8, 10, 13, 16, 19, 22,
- 25, 28, 30, 34, 38, 42, 44, 48, 50, 52,
- 56, 60, 62, 66, 68, 70, 72, 74, 76, 78,
- 80, 84, 88, 93, 98, 105, 114, 119, 124, 131,
- 140, 146, 154, 158, 162, 166, 170, 174, 178, 182,
- 186, 190, 194, 198, 202, 205, 208, 211, 214, 217,
- 221, 225, 231, 237, 243
+ 25, 28, 30, 34, 38, 42, 47, 54, 61, 68,
+ 75, 77, 81, 83, 85, 89, 93, 95, 99, 101,
+ 106, 108, 110, 114, 118, 122, 126, 130, 134, 138,
+ 142, 144, 146, 148, 150, 152, 154, 156, 158, 162,
+ 166, 171, 176, 183, 192, 197, 202, 209, 216, 223,
+ 230, 237, 244, 251, 258, 265, 274, 281, 290, 301,
+ 308, 312, 317, 323, 331, 335, 339, 343, 347, 350,
+ 353, 356, 359, 362, 366, 370, 376, 381, 388, 394,
+ 400, 404, 408, 414, 420, 426
};
static const short yyrhs[] = { -1,
- 48, 49, 0, 44, 0, 45, 0, 20, 0, 53,
- 44, 0, 53, 45, 0, 53, 20, 0, 50, 44,
- 0, 50, 45, 0, 1, 44, 0, 4, 0, 50,
- 35, 53, 0, 53, 35, 50, 0, 50, 35, 50,
- 0, 50, 0, 13, 23, 13, 0, 5, 0, 53,
- 0, 52, 20, 52, 0, 52, 21, 53, 0, 51,
- 0, 3, 22, 3, 0, 3, 0, 18, 0, 9,
- 0, 7, 0, 8, 0, 13, 0, 6, 0, 13,
- 19, 53, 0, 13, 19, 50, 0, 14, 46, 53,
- 47, 0, 15, 46, 52, 47, 0, 15, 46, 53,
- 10, 53, 47, 0, 15, 46, 53, 10, 53, 10,
- 53, 47, 0, 16, 46, 50, 47, 0, 16, 46,
- 53, 47, 0, 17, 46, 52, 10, 52, 47, 0,
- 17, 46, 52, 10, 52, 10, 51, 47, 0, 11,
- 46, 53, 47, 6, 0, 11, 46, 53, 47, 6,
- 12, 6, 0, 53, 26, 53, 0, 53, 27, 53,
- 0, 53, 28, 53, 0, 53, 29, 53, 0, 53,
- 30, 53, 0, 53, 31, 53, 0, 53, 32, 53,
- 0, 53, 33, 53, 0, 53, 35, 53, 0, 53,
- 34, 53, 0, 53, 36, 53, 0, 53, 37, 53,
- 0, 34, 53, 0, 13, 39, 0, 13, 40, 0,
- 39, 13, 0, 40, 13, 0, 53, 43, 53, 0,
- 46, 52, 47, 0, 53, 25, 53, 24, 53, 0,
- 53, 25, 4, 24, 4, 0, 53, 25, 4, 24,
- 53, 0, 53, 25, 53, 24, 4, 0
+ 65, 66, 0, 59, 0, 60, 0, 33, 0, 71,
+ 59, 0, 71, 60, 0, 71, 33, 0, 67, 59,
+ 0, 67, 60, 0, 1, 59, 0, 5, 0, 67,
+ 48, 71, 0, 71, 48, 67, 0, 67, 48, 67,
+ 0, 29, 61, 71, 62, 0, 29, 61, 71, 11,
+ 67, 62, 0, 29, 61, 71, 11, 71, 62, 0,
+ 29, 61, 71, 33, 67, 62, 0, 29, 61, 71,
+ 33, 71, 62, 0, 67, 0, 20, 36, 20, 0,
+ 6, 0, 71, 0, 69, 33, 69, 0, 69, 34,
+ 71, 0, 68, 0, 3, 35, 3, 0, 4, 0,
+ 22, 61, 71, 62, 0, 14, 0, 15, 0, 71,
+ 39, 71, 0, 71, 40, 71, 0, 71, 41, 71,
+ 0, 71, 42, 71, 0, 71, 43, 71, 0, 71,
+ 44, 71, 0, 71, 45, 71, 0, 71, 46, 71,
+ 0, 3, 0, 70, 0, 28, 0, 10, 0, 8,
+ 0, 9, 0, 20, 0, 7, 0, 20, 32, 71,
+ 0, 20, 32, 67, 0, 21, 61, 71, 62, 0,
+ 23, 61, 69, 62, 0, 23, 61, 71, 11, 69,
+ 62, 0, 23, 61, 71, 11, 71, 11, 71, 62,
+ 0, 24, 61, 67, 62, 0, 24, 61, 71, 62,
+ 0, 24, 61, 67, 11, 67, 62, 0, 24, 61,
+ 71, 11, 67, 62, 0, 24, 61, 71, 11, 71,
+ 62, 0, 24, 61, 67, 11, 71, 62, 0, 24,
+ 61, 67, 33, 67, 62, 0, 24, 61, 71, 33,
+ 67, 62, 0, 24, 61, 67, 33, 71, 62, 0,
+ 24, 61, 71, 33, 71, 62, 0, 26, 61, 68,
+ 11, 68, 62, 0, 26, 61, 68, 11, 68, 11,
+ 68, 62, 0, 27, 61, 69, 11, 69, 62, 0,
+ 27, 61, 69, 11, 69, 11, 68, 62, 0, 31,
+ 61, 71, 11, 71, 11, 69, 11, 68, 62, 0,
+ 25, 61, 69, 11, 68, 62, 0, 30, 61, 62,
+ 0, 30, 61, 69, 62, 0, 12, 61, 71, 62,
+ 7, 0, 12, 61, 71, 62, 7, 13, 7, 0,
+ 71, 48, 71, 0, 71, 47, 71, 0, 71, 49,
+ 71, 0, 71, 50, 71, 0, 47, 71, 0, 20,
+ 53, 0, 20, 54, 0, 53, 20, 0, 54, 20,
+ 0, 71, 58, 71, 0, 61, 69, 62, 0, 19,
+ 20, 51, 71, 63, 0, 71, 51, 71, 63, 0,
+ 71, 51, 71, 63, 32, 71, 0, 3, 36, 3,
+ 36, 3, 0, 3, 64, 3, 64, 3, 0, 3,
+ 36, 3, 0, 3, 64, 3, 0, 71, 38, 71,
+ 37, 71, 0, 71, 38, 5, 37, 5, 0, 71,
+ 38, 5, 37, 71, 0, 71, 38, 71, 37, 5,
+ 0
};
#endif
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 121, 122, 125, 125, 125, 126, 127, 128, 129, 130,
- 131, 134, 136, 137, 138, 141, 143, 146, 147, 148,
- 149, 150, 151, 155, 156, 157, 158, 159, 160, 161,
- 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
- 173, 174, 175, 176, 177, 178, 179, 180, 181, 182,
- 183, 184, 185, 186, 188, 189, 190, 191, 192, 193,
- 194, 195, 196, 197, 198
+ 128, 129, 132, 132, 132, 133, 134, 135, 136, 137,
+ 138, 141, 143, 144, 145, 146, 147, 148, 149, 150,
+ 153, 155, 158, 159, 160, 161, 162, 163, 167, 168,
+ 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
+ 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 195, 198, 199, 200, 201, 202, 203,
+ 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
+ 214, 215, 216, 217, 218, 222, 226, 227, 229, 230,
+ 231, 232, 233, 234, 235, 236, 238, 240, 242, 243,
+ 244, 245, 246, 247, 248, 249
};
#endif
#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
-static const char * const yytname[] = { "$","error","$undefined.","NUM","STR",
-"ARR","BLOCK","PI","E","CLVAL","PSEP","IF","ELSE","VAR","FNCT","AFNCT","SFNCT",
-"FUNC2","TXT","'='","','","CLAUSE","SER","COLR","COLC","'?'","AND","OR","EQ",
-"NE","GT","GE","LT","LE","'-'","'+'","'*'","'/'","NEG","INC","DEC","PINC","PDEC",
-"'^'","'\\n'","';'","'('","')'","input","line","str_exp","range","arr","exp", NULL
+static const char * const yytname[] = { "$","error","$undefined.","NUM","BOOLVAL",
+"STR","ARR","BLOCK","PI","E","CLVAL","PSEP","IF","ELSE","BTRUE","BFALSE","DATE1",
+"TIME1","DATETIME1","DIM","VAR","FNCT","BFNCT","AFNCT","SFNCT","FUNC1","FUNC2",
+"FUNC3","TXT","SRFUNC","YYFNC","FUNC4","'='","','","CLAUSE","SER","COLR","COLC",
+"'?'","AND","OR","EQ","NE","GT","GE","LT","LE","'-'","'+'","'*'","'/'","'['",
+"NEG","INC","DEC","PINC","PDEC","PDIM","'^'","'\\n'","';'","'('","')'","']'",
+"':'","input","line","str_exp","range","arr","bool","exp", NULL
};
#endif
static const short yyr1[] = { 0,
- 48, 48, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 50, 50, 50, 50, 51, 51, 52, 52, 52,
- 52, 52, 52, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53
+ 65, 65, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+ 68, 68, 69, 69, 69, 69, 69, 69, 70, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71
};
static const short yyr2[] = { 0,
0, 2, 1, 1, 1, 2, 2, 2, 2, 2,
- 2, 1, 3, 3, 3, 1, 3, 1, 1, 3,
- 3, 1, 3, 1, 1, 1, 1, 1, 1, 1,
- 3, 3, 4, 4, 6, 8, 4, 4, 6, 8,
- 5, 7, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 2, 2, 2, 2, 2, 3,
- 3, 5, 5, 5, 5
+ 2, 1, 3, 3, 3, 4, 6, 6, 6, 6,
+ 1, 3, 1, 1, 3, 3, 1, 3, 1, 4,
+ 1, 1, 3, 3, 3, 3, 3, 3, 3, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 4, 4, 6, 8, 4, 4, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 8, 6, 8, 10, 6,
+ 3, 4, 5, 7, 3, 3, 3, 3, 2, 2,
+ 2, 2, 2, 3, 3, 5, 4, 6, 5, 5,
+ 3, 3, 5, 5, 5, 5
};
static const short yydefact[] = { 1,
- 0, 0, 24, 12, 30, 27, 28, 26, 0, 29,
- 0, 0, 0, 0, 25, 5, 0, 0, 0, 3,
- 4, 0, 2, 0, 0, 11, 0, 0, 56, 57,
- 0, 0, 0, 0, 55, 58, 59, 24, 18, 29,
- 16, 22, 0, 19, 0, 9, 10, 8, 0, 0,
+ 0, 0, 41, 29, 12, 48, 45, 46, 44, 0,
+ 31, 32, 0, 47, 0, 0, 0, 0, 0, 0,
+ 0, 43, 0, 0, 0, 5, 0, 0, 0, 3,
+ 4, 0, 2, 0, 42, 0, 11, 0, 0, 0,
+ 0, 0, 80, 81, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 79, 82, 83, 41, 23, 47,
+ 21, 27, 0, 24, 0, 9, 10, 8, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 6, 7, 0, 32, 31, 0, 0, 19,
- 0, 0, 0, 0, 0, 0, 0, 0, 61, 15,
- 13, 0, 0, 43, 44, 45, 46, 47, 48, 49,
- 50, 52, 14, 51, 53, 54, 60, 0, 33, 34,
- 0, 37, 38, 0, 51, 23, 17, 20, 21, 0,
- 0, 41, 0, 0, 63, 64, 65, 62, 0, 0,
- 35, 0, 39, 42, 0, 0, 0, 36, 40, 0,
- 0
+ 0, 0, 0, 6, 7, 91, 92, 0, 0, 50,
+ 49, 0, 0, 0, 24, 0, 0, 0, 0, 0,
+ 0, 0, 71, 0, 0, 0, 0, 0, 0, 0,
+ 85, 15, 13, 0, 0, 33, 34, 35, 36, 37,
+ 38, 39, 40, 76, 14, 75, 77, 78, 0, 84,
+ 0, 0, 0, 0, 51, 30, 52, 0, 0, 0,
+ 55, 0, 0, 56, 0, 0, 0, 0, 0, 16,
+ 72, 0, 75, 28, 22, 25, 26, 0, 0, 87,
+ 89, 90, 73, 86, 0, 24, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 94, 95, 96, 93, 0, 0, 53, 0,
+ 57, 60, 61, 63, 58, 59, 62, 64, 70, 0,
+ 65, 0, 67, 17, 18, 19, 20, 0, 88, 74,
+ 0, 0, 0, 0, 54, 66, 68, 0, 0, 69,
+ 0, 0
};
static const short yydefgoto[] = { 1,
- 23, 41, 42, 43, 44
+ 33, 61, 62, 63, 35, 64
};
static const short yypact[] = {-32768,
- 88, -39,-32768,-32768,-32768,-32768,-32768,-32768, -33, 2,
- -26, -24, -18, -17,-32768,-32768, 378, 21, 24,-32768,
--32768, 132,-32768, -27, 419,-32768, 378, 173,-32768,-32768,
- 378, 132, 173, 132, 3,-32768,-32768, 23,-32768, 0,
- 8,-32768, -14, 331, 173,-32768,-32768,-32768, 214, 378,
- 378, 378, 378, 378, 378, 378, 378, 378, 173, 378,
- 378, 378,-32768,-32768, 126, 8, 331, 167, -11, 400,
- -32, 208, 4, 378, 67, 58, 132, 378,-32768,-32768,
- 32, 52, 291, 456, 456, 29, 29, 29, 29, 29,
- 29, 32,-32768, 32, 3, 3, 3, 72,-32768,-32768,
- 378,-32768,-32768, 132, 32,-32768,-32768, 59, 440, 255,
- 296, 69, 372, -9,-32768, 440,-32768, 440, 76, 378,
--32768, 337,-32768,-32768, 249, 36, 331,-32768,-32768, 84,
--32768
+ 204, -44, -26,-32768,-32768,-32768,-32768,-32768,-32768, -45,
+-32768,-32768, 5, 33, -42, -25, 6, 22, 24, 32,
+ 39,-32768, 41, 49, 54,-32768, 646, 36, 38,-32768,
+-32768, 323,-32768, 105,-32768, 799,-32768, 14, 57, 646,
+ 10, 378,-32768,-32768, 646, 646, 323, 378, 323, 433,
+ 323, 646, 263, 646, 8,-32768,-32768, -27,-32768, 63,
+ 55,-32768, -20, 994, 378,-32768,-32768,-32768, 488, 646,
+ 646, 646, 646, 646, 646, 646, 646, 646, 378, 646,
+ 646, 646, 646,-32768,-32768, 83, 76, 372, 646, 55,
+ 994, 427, 482, -12, 85, 0, 670, 1, 111, 994,
+ 78, 711,-32768, -10, 736, 646, 146, 130, 323, 646,
+-32768,-32768, 129, 118, 973, 197, 197, 125, 125, 125,
+ 125, 125, 125, 129,-32768, 129, -31, -31, 257, 8,
+ 153, 156, 154, 317,-32768,-32768,-32768, 323, 378, 378,
+-32768, 378, 378,-32768, 433, 433, 323, 378, 378,-32768,
+-32768, 646, 129,-32768,-32768, 132, 1015, 543, 598, 131,
+-32768,-32768, 155,-32768, -3, 757, -30, 537, -8, 822,
+ 46, 847, 56, 872, 107, -7, -5, 58, 897, 98,
+ 922, 778,-32768, 1015,-32768, 1015, 646, 160,-32768, 646,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 433,
+-32768, 433,-32768,-32768,-32768,-32768,-32768, 323, 1015,-32768,
+ 947, 109, 115, 80,-32768,-32768,-32768, 433, 126,-32768,
+ 192,-32768
};
static const short yypgoto[] = {-32768,
--32768, 34, -37, -30, -1
+-32768, 42, -48, -46,-32768, -1
};
-#define YYLAST 499
-
-
-static const short yytable[] = { 25,
- 122, 69, 45, 73, 26, 77, 78, 45, 77, 78,
- 77, 78, 27, 104, 102, 35, 46, 47, 28, 31,
- 28, 32, 76, 77, 78, 65, 67, 33, 34, 68,
- 70, 72, 79, 36, 24, 100, 37, 123, 29, 30,
- 29, 30, 45, 81, 75, 62, 108, 83, 84, 85,
- 86, 87, 88, 89, 90, 91, 92, 94, 95, 96,
- 97, 66, 58, 74, 60, 61, 71, 60, 61, 106,
- 107, 62, 105, 114, 62, 110, 109, 112, 80, 78,
- 119, 124, 129, 131, 126, 0, 0, 130, 2, 0,
- 3, 4, 93, 5, 6, 7, 8, 0, 9, 113,
- 10, 11, 12, 13, 14, 15, 0, 16, 116, 118,
- 0, 0, 0, 0, 0, 0, 0, 0, 125, 0,
- 127, 17, 0, 0, 0, 0, 18, 19, 0, 0,
- 0, 20, 21, 22, 38, 4, 39, 5, 6, 7,
- 8, 0, 9, 0, 40, 11, 12, 13, 14, 15,
- 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- 74, 60, 61, 0, 0, 17, 0, 0, 62, 0,
- 18, 19, 98, 0, 0, 3, 4, 22, 5, 6,
- 7, 8, 0, 9, 0, 10, 11, 12, 13, 14,
- 15, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 74, 60, 61, 0, 0, 17, 0, 0, 62,
- 0, 18, 19, 99, 0, 0, 3, 82, 22, 5,
- 6, 7, 8, 0, 9, 0, 10, 11, 12, 13,
- 14, 15, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 0, 0, 17, 0, 0,
- 62, 0, 18, 19, 103, 0, 0, 3, 115, 22,
- 5, 6, 7, 8, 0, 9, 0, 10, 11, 12,
- 13, 14, 15, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 74, 60, 61, 0, 0, 17, 0,
- 0, 62, 0, 18, 19, 128, 0, 0, 3, 117,
- 22, 5, 6, 7, 8, 0, 9, 0, 10, 11,
- 12, 13, 14, 15, 111, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 74, 60, 61, 0, 17,
- 0, 0, 0, 62, 18, 19, 0, 0, 0, 3,
- 4, 22, 5, 6, 7, 8, 0, 9, 0, 40,
- 11, 12, 13, 14, 15, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 0, 0,
- 17, 0, 0, 62, 0, 18, 19, 0, 0, 0,
- 3, 120, 22, 5, 6, 7, 8, 0, 9, 0,
- 10, 11, 12, 13, 14, 15, 49, 50, 51, 52,
- 53, 54, 55, 56, 57, 58, 74, 60, 61, 101,
- 0, 17, 0, 0, 62, 0, 18, 19, 121, 0,
- 0, 0, 0, 22, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 0, 48, 0,
- 0, 0, 62, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 0, 0, 0, 0,
- 0, 62, 63, 64, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 74, 60, 61, 0, 0, 0,
- 0, 0, 62, 52, 53, 54, 55, 56, 57, 58,
- 74, 60, 61, 0, 0, 0, 0, 0, 62
+#define YYLAST 1073
+
+
+static const short yytable[] = { 36,
+ 94, 99, 98, 200, 101, 202, 104, 107, 38, 38,
+ 139, 145, 109, 110, 37, 40, 86, 65, 45, 82,
+ 109, 110, 109, 110, 41, 55, 83, 109, 110, 109,
+ 110, 191, 140, 109, 110, 46, 39, 39, 88, 65,
+ 91, 111, 34, 92, 93, 95, 97, 65, 100, 137,
+ 102, 151, 105, 193, 201, 56, 203, 57, 189, 87,
+ 89, 141, 156, 113, 42, 83, 47, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 126, 127, 128,
+ 129, 130, 48, 90, 49, 43, 44, 134, 147, 96,
+ 218, 165, 50, 65, 42, 138, 175, 176, 108, 51,
+ 177, 52, 65, 65, 153, 65, 112, 195, 157, 53,
+ 109, 110, 109, 110, 54, 43, 44, 197, 131, 204,
+ 125, 146, 69, 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 166, 168, 170, 132,
+ 172, 174, 83, 100, 100, 65, 179, 181, 154, 155,
+ 182, 212, 65, 213, 158, 161, 184, 186, 162, 206,
+ 163, 214, 187, 66, 67, 110, 210, 188, 199, 219,
+ 216, 78, 106, 80, 81, 82, 217, 80, 81, 82,
+ 167, 169, 83, 171, 173, 209, 83, 220, 211, 178,
+ 180, 222, 0, 0, 0, 0, 0, 0, 100, 0,
+ 100, 0, 0, 221, 2, 0, 3, 4, 5, 0,
+ 6, 7, 8, 9, 0, 10, 100, 11, 12, 0,
+ 0, 0, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 0, 26, 72, 73, 74,
+ 75, 76, 77, 78, 106, 80, 81, 82, 0, 0,
+ 27, 0, 0, 0, 83, 0, 28, 29, 0, 0,
+ 0, 0, 30, 31, 32, 58, 4, 5, 59, 6,
+ 7, 8, 9, 0, 10, 0, 11, 12, 0, 0,
+ 0, 13, 60, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 106, 80, 81, 82, 0, 27,
+ 0, 0, 0, 0, 83, 28, 29, 0, 0, 160,
+ 0, 0, 0, 32, 103, 58, 4, 5, 59, 6,
+ 7, 8, 9, 0, 10, 0, 11, 12, 0, 0,
+ 0, 13, 60, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 106, 80, 81, 82, 0, 27,
+ 0, 0, 0, 0, 83, 28, 29, 0, 0, 164,
+ 3, 4, 5, 32, 6, 7, 8, 9, 0, 10,
+ 0, 11, 12, 0, 0, 0, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 106,
+ 80, 81, 82, 0, 27, 0, 0, 0, 0, 83,
+ 28, 29, 0, 133, 0, 3, 4, 5, 32, 6,
+ 7, 8, 9, 0, 10, 0, 11, 12, 0, 0,
+ 0, 13, 60, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 106, 80, 81, 82, 0, 27,
+ 0, 0, 0, 0, 83, 28, 29, 0, 135, 0,
+ 3, 4, 114, 32, 6, 7, 8, 9, 0, 10,
+ 0, 11, 12, 0, 0, 0, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 0, 24, 25, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 106,
+ 80, 81, 82, 0, 27, 0, 0, 0, 0, 83,
+ 28, 29, 0, 136, 0, 3, 4, 183, 32, 6,
+ 7, 8, 9, 0, 10, 0, 11, 12, 0, 0,
+ 0, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 0, 24, 25, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 0, 27,
+ 0, 0, 0, 0, 83, 28, 29, 0, 192, 0,
+ 3, 4, 185, 32, 6, 7, 8, 9, 0, 10,
+ 0, 11, 12, 0, 0, 0, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 0, 24, 25, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 27, 0, 0, 0, 3, 4,
+ 28, 29, 6, 7, 8, 9, 0, 10, 32, 11,
+ 12, 0, 0, 0, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 0, 24, 25, 0, 0, 0,
+ 142, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 27, 0, 0, 0, 0, 0, 28, 29,
+ 0, 0, 143, 0, 0, 0, 32, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 148, 0, 0, 0, 0, 0, 83, 0, 0,
+ 0, 144, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 149, 0, 0, 152, 0, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 106, 80,
+ 81, 82, 0, 0, 0, 0, 0, 190, 83, 0,
+ 0, 0, 150, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 106, 80, 81, 82, 0, 208, 0,
+ 0, 0, 0, 83, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 0, 0,
+ 0, 0, 0, 0, 83, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 106, 80, 81, 82, 0,
+ 0, 68, 0, 0, 0, 83, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 0, 0, 0, 0, 0, 0, 83, 84, 85, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 0, 0, 0, 0, 0, 0, 83,
+ 0, 0, 0, 194, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 0, 0,
+ 0, 0, 0, 0, 83, 0, 0, 0, 196, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 0, 0, 0, 0, 0, 0, 83,
+ 0, 0, 0, 198, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 0, 0,
+ 0, 0, 0, 0, 83, 0, 0, 0, 205, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 0, 0, 0, 0, 0, 0, 83,
+ 0, 0, 0, 207, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 106, 80, 81, 82, 0, 0,
+ 0, 0, 0, 0, 83, 0, 0, 0, 215, 159,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 106, 80, 81, 82, 0, 0, 0, 0, 0, 0,
+ 83, 69, 70, 71, 72, 73, 74, 75, 76, 77,
+ 78, 79, 80, 81, 82, 0, 0, 0, 0, 0,
+ 0, 83, 69, 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 106, 80, 81, 82, 0, 0, 0, 0,
+ 0, 0, 83
};
static const short yycheck[] = { 1,
- 10, 32, 35, 34, 44, 20, 21, 35, 20, 21,
- 20, 21, 46, 10, 47, 17, 44, 45, 19, 46,
- 19, 46, 23, 20, 21, 27, 28, 46, 46, 31,
- 32, 33, 47, 13, 1, 47, 13, 47, 39, 40,
- 39, 40, 35, 45, 22, 43, 77, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- 62, 28, 34, 35, 36, 37, 33, 36, 37, 3,
- 13, 43, 74, 104, 43, 24, 78, 6, 45, 21,
- 12, 6, 47, 0, 122, -1, -1, 0, 1, -1,
- 3, 4, 59, 6, 7, 8, 9, -1, 11, 101,
- 13, 14, 15, 16, 17, 18, -1, 20, 110, 111,
- -1, -1, -1, -1, -1, -1, -1, -1, 120, -1,
- 122, 34, -1, -1, -1, -1, 39, 40, -1, -1,
- -1, 44, 45, 46, 3, 4, 5, 6, 7, 8,
- 9, -1, 11, -1, 13, 14, 15, 16, 17, 18,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, -1, -1, 34, -1, -1, 43, -1,
- 39, 40, 47, -1, -1, 3, 4, 46, 6, 7,
- 8, 9, -1, 11, -1, 13, 14, 15, 16, 17,
- 18, 25, 26, 27, 28, 29, 30, 31, 32, 33,
- 34, 35, 36, 37, -1, -1, 34, -1, -1, 43,
- -1, 39, 40, 47, -1, -1, 3, 4, 46, 6,
- 7, 8, 9, -1, 11, -1, 13, 14, 15, 16,
- 17, 18, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, -1, -1, 34, -1, -1,
- 43, -1, 39, 40, 47, -1, -1, 3, 4, 46,
- 6, 7, 8, 9, -1, 11, -1, 13, 14, 15,
- 16, 17, 18, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, -1, -1, 34, -1,
- -1, 43, -1, 39, 40, 47, -1, -1, 3, 4,
- 46, 6, 7, 8, 9, -1, 11, -1, 13, 14,
- 15, 16, 17, 18, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, -1, 34,
- -1, -1, -1, 43, 39, 40, -1, -1, -1, 3,
- 4, 46, 6, 7, 8, 9, -1, 11, -1, 13,
- 14, 15, 16, 17, 18, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35, 36, 37, -1, -1,
- 34, -1, -1, 43, -1, 39, 40, -1, -1, -1,
- 3, 10, 46, 6, 7, 8, 9, -1, 11, -1,
- 13, 14, 15, 16, 17, 18, 25, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 10,
- -1, 34, -1, -1, 43, -1, 39, 40, 47, -1,
- -1, -1, -1, 46, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, -1, 20, -1,
- -1, -1, 43, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, -1, -1, -1, -1,
- -1, 43, 44, 45, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, -1, -1, -1,
- -1, -1, 43, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, -1, -1, -1, -1, -1, 43
+ 47, 50, 49, 11, 51, 11, 53, 35, 36, 36,
+ 11, 11, 33, 34, 59, 61, 3, 48, 61, 51,
+ 33, 34, 33, 34, 20, 27, 58, 33, 34, 33,
+ 34, 62, 33, 33, 34, 61, 64, 64, 40, 48,
+ 42, 62, 1, 45, 46, 47, 48, 48, 50, 62,
+ 52, 62, 54, 62, 62, 20, 62, 20, 62, 3,
+ 51, 62, 109, 65, 32, 58, 61, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 61, 42, 61, 53, 54, 89, 11, 48,
+ 11, 138, 61, 48, 32, 11, 145, 146, 36, 61,
+ 147, 61, 48, 48, 106, 48, 65, 62, 110, 61,
+ 33, 34, 33, 34, 61, 53, 54, 62, 36, 62,
+ 79, 11, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 138, 139, 140, 64,
+ 142, 143, 58, 145, 146, 48, 148, 149, 3, 20,
+ 152, 200, 48, 202, 37, 3, 158, 159, 3, 62,
+ 7, 208, 32, 59, 60, 34, 7, 13, 62, 218,
+ 62, 47, 48, 49, 50, 51, 62, 49, 50, 51,
+ 139, 140, 58, 142, 143, 187, 58, 62, 190, 148,
+ 149, 0, -1, -1, -1, -1, -1, -1, 200, -1,
+ 202, -1, -1, 0, 1, -1, 3, 4, 5, -1,
+ 7, 8, 9, 10, -1, 12, 218, 14, 15, -1,
+ -1, -1, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, -1, 33, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
+ 47, -1, -1, -1, 58, -1, 53, 54, -1, -1,
+ -1, -1, 59, 60, 61, 3, 4, 5, 6, 7,
+ 8, 9, 10, -1, 12, -1, 14, 15, -1, -1,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, 47,
+ -1, -1, -1, -1, 58, 53, 54, -1, -1, 63,
+ -1, -1, -1, 61, 62, 3, 4, 5, 6, 7,
+ 8, 9, 10, -1, 12, -1, 14, 15, -1, -1,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, 47,
+ -1, -1, -1, -1, 58, 53, 54, -1, -1, 63,
+ 3, 4, 5, 61, 7, 8, 9, 10, -1, 12,
+ -1, 14, 15, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, 47, -1, -1, -1, -1, 58,
+ 53, 54, -1, 62, -1, 3, 4, 5, 61, 7,
+ 8, 9, 10, -1, 12, -1, 14, 15, -1, -1,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, 47,
+ -1, -1, -1, -1, 58, 53, 54, -1, 62, -1,
+ 3, 4, 5, 61, 7, 8, 9, 10, -1, 12,
+ -1, 14, 15, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, -1, 30, 31, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, 47, -1, -1, -1, -1, 58,
+ 53, 54, -1, 62, -1, 3, 4, 5, 61, 7,
+ 8, 9, 10, -1, 12, -1, 14, 15, -1, -1,
+ -1, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, -1, 30, 31, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, 47,
+ -1, -1, -1, -1, 58, 53, 54, -1, 62, -1,
+ 3, 4, 5, 61, 7, 8, 9, 10, -1, 12,
+ -1, 14, 15, -1, -1, -1, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, -1, 30, 31, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 47, -1, -1, -1, 3, 4,
+ 53, 54, 7, 8, 9, 10, -1, 12, 61, 14,
+ 15, -1, -1, -1, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, -1, 30, 31, -1, -1, -1,
+ 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 47, -1, -1, -1, -1, -1, 53, 54,
+ -1, -1, 33, -1, -1, -1, 61, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 11, -1, -1, -1, -1, -1, 58, -1, -1,
+ -1, 62, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 33, -1, -1, 11, -1, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, -1, -1, -1, -1, -1, 11, 58, -1,
+ -1, -1, 62, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, -1, 11, -1,
+ -1, -1, -1, 58, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
+ -1, -1, -1, -1, 58, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, -1,
+ -1, 33, -1, -1, -1, 58, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ -1, -1, -1, -1, -1, -1, 58, 59, 60, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, -1, -1, -1, -1, -1, 58,
+ -1, -1, -1, 62, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
+ -1, -1, -1, -1, 58, -1, -1, -1, 62, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, -1, -1, -1, -1, -1, 58,
+ -1, -1, -1, 62, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
+ -1, -1, -1, -1, 58, -1, -1, -1, 62, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, -1, -1, -1, -1, -1, 58,
+ -1, -1, -1, 62, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
+ -1, -1, -1, -1, 58, -1, -1, -1, 62, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, -1, -1, -1, -1, -1, -1,
+ 58, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, 58, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, -1, -1, -1, -1,
+ -1, -1, 58
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
@@ -983,161 +1170,263 @@ case 12:
{;;
break;}
case 13:
-{yyval.text=add_strings(yyvsp[-2].text, string_value(&yyvsp[0]));;
+{yyval.text=add_strings(yyvsp[-2].text, string_value(&yyvsp[0])); yyval.type = STR;;
break;}
case 14:
-{yyval.text=add_strings(string_value(&yyvsp[-2]), yyvsp[0].text);;
+{yyval.text=add_strings(string_value(&yyvsp[-2]), yyvsp[0].text); yyval.type = STR;;
break;}
case 15:
-{yyval.text=add_strings(yyvsp[-2].text, yyvsp[0].text);;
+{yyval.text=add_strings(yyvsp[-2].text, yyvsp[0].text); yyval.type = STR;;
break;}
case 16:
-{;;
+{((yyvsp[-3].tptr->fnctptr)(&yyval, &yyvsp[-1], 0L)); yyval.type = STR;;
break;}
case 17:
-{if(yyval.text =(char*)malloc(strlen(yyvsp[-2].tptr->name) +strlen(yyvsp[0].tptr->name) + 2)) sprintf(yyval.text, "%s:%s", yyvsp[-2].tptr->name, yyvsp[0].tptr->name);;
+{((yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;;
+ break;}
+case 18:
+{((yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;;
break;}
case 19:
-{if(!yyval.a_data) {yyval.a_data = (double*)malloc(sizeof(double)); yyval.a_count = 1; yyval.a_data[0] = yyval.val;};
+{((yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;;
break;}
case 20:
-{push(&yyval, &yyvsp[0]);;
+{((yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;;
break;}
case 21:
-{exec_clause(&yyval);;
+{;;
break;}
case 22:
-{range_array(&yyval, yyvsp[0].text);;
- break;}
-case 23:
-{if(yyvsp[-2].val < yyvsp[0].val && (yyval.a_data = (double*)malloc((int)(yyvsp[0].val-yyvsp[-2].val+2)*sizeof(double))))
- for(yyval.a_count=0; yyvsp[-2].val<=yyvsp[0].val; yyval.a_data[yyval.a_count++] = yyvsp[-2].val, yyvsp[-2].val += 1.0 );;
+{if(yyval.text = PushString((char*)malloc(strlen(yyvsp[-2].tptr->name) +strlen(yyvsp[0].tptr->name) + 2))) sprintf(yyval.text, "%s:%s", yyvsp[-2].tptr->name, yyvsp[0].tptr->name);;
break;}
case 24:
-{yyval.val = yyvsp[0].val; yyval.type = NUM;;
+{if(!yyval.a_data) {yyval.a_data = PushArray((double*)malloc(sizeof(double))); yyval.a_count = 1; yyval.a_data[0] = yyval.val;};
break;}
case 25:
-{yyval.val = 0.0;;
+{push(&yyval, &yyvsp[0]);yyval.type = ARR;;
break;}
case 26:
-{yyval.val = syntax_level ? syntax_level->clval : 0.0; ;
+{exec_clause(&yyval);yyval.type = ARR;;
break;}
case 27:
-{yyval.val = _PI; yyval.type = NUM;;
+{range_array(&yyval, yyvsp[0].text);yyval.type = ARR;;
break;}
case 28:
-{yyval.val = 2.71828182845905; yyval.type = NUM;;
- break;}
-case 29:
-{yyvsp[0].tptr->GetValue(&yyval);;
+{if(yyvsp[-2].val < yyvsp[0].val && (yyval.a_data = PushArray((double*)malloc((int)(yyvsp[0].val-yyvsp[-2].val+2)*sizeof(double)))))
+ for(yyval.a_count=0; yyvsp[-2].val<=yyvsp[0].val; yyval.a_data[yyval.a_count++] = yyvsp[-2].val, yyvsp[-2].val += 1.0 ); yyval.type = ARR;;
break;}
case 30:
-{eval(&yyvsp[0], &yyval);;
+{yyval.val = ((yyvsp[-3].tptr->fnctptr)(yyvsp[-1].val)); yyval.type = BOOLVAL;;
break;}
case 31:
-{yyvsp[-2].tptr->SetValue(&yyval, &yyvsp[0]);;
+{yyval.val = 1.0; yyval.type = BOOLVAL;;
break;}
case 32:
-{yyvsp[-2].tptr->SetValue(&yyval, &yyvsp[0]);;
+{yyval.val = 0.0; yyval.type = BOOLVAL;;
break;}
case 33:
-{yyval.val = ((yyvsp[-3].tptr->fnctptr)(yyvsp[-1].val));;
+{yyval.val = ((yyvsp[-2].val != 0) && (yyvsp[0].val != 0))? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 34:
-{yyval.val = ((yyvsp[-3].tptr->fnctptr)(proc_clause(&yyvsp[-1])));;
+{yyval.val = ((yyvsp[-2].val != 0) || (yyvsp[0].val != 0))? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 35:
-{push(&yyvsp[-2], &yyvsp[0]); yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-2]));;
+{yyval.val = (yyvsp[-2].val == yyvsp[0].val) ? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 36:
-{push(&yyvsp[-4], &yyvsp[-2]); push(&yyvsp[-4], &yyvsp[0]); yyval.val = ((yyvsp[-7].tptr->fnctptr)(&yyvsp[-4]));;
+{yyval.val = (yyvsp[-2].val != yyvsp[0].val) ? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 37:
-{yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval));;
+{yyval.val = (yyvsp[-2].val > yyvsp[0].val) ? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 38:
-{yyvsp[-1].text = string_value(&yyvsp[-1]); yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval));;
+{yyval.val = (yyvsp[-2].val >= yyvsp[0].val) ? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 39:
-{yyval.val = ((*yyvsp[-5].tptr->fnctptr)(proc_clause(&yyvsp[-3]), proc_clause(&yyvsp[-1]), 0L));;
+{yyval.val = (yyvsp[-2].val < yyvsp[0].val) ? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 40:
-{yyval.val = ((*yyvsp[-7].tptr->fnctptr)(proc_clause(&yyvsp[-5]), proc_clause(&yyvsp[-3]), yyvsp[-1].text));;
+{yyval.val = (yyvsp[-2].val <= yyvsp[0].val) ? 1 : 0; yyval.type = BOOLVAL;;
break;}
case 41:
-{yyval.val = yyvsp[-2].val != 0 ? eval(&yyvsp[0], &yyval) : 0.0;;
+{yyval.val = yyvsp[0].val; yyval.type = NUM;;
break;}
case 42:
-{yyval.val = yyvsp[-4].val != 0 ? eval(&yyvsp[-2], &yyval) : eval(&yyvsp[0], &yyval);;
+{yyval.val = yyvsp[0].val; yyval.type = BOOLVAL;;
break;}
case 43:
-{yyval.val = ((yyvsp[-2].val != 0) && (yyvsp[0].val != 0))? 1 : 0;;
+{yyval.val = 0.0;;
break;}
case 44:
-{yyval.val = ((yyvsp[-2].val != 0) || (yyvsp[0].val != 0))? 1 : 0;;
+{yyval.val = syntax_level ? syntax_level->clval : 0.0; yyval.type = NUM;;
break;}
case 45:
-{yyval.val = (yyvsp[-2].val == yyvsp[0].val) ? 1 : 0;;
+{yyval.val = _PI; yyval.type = NUM;;
break;}
case 46:
-{yyval.val = (yyvsp[-2].val != yyvsp[0].val) ? 1 : 0;;
+{yyval.val = 2.71828182845905; yyval.type = NUM;;
break;}
case 47:
-{yyval.val = (yyvsp[-2].val > yyvsp[0].val) ? 1 : 0;;
+{yyvsp[0].tptr->GetValue(&yyval);;
break;}
case 48:
-{yyval.val = (yyvsp[-2].val >= yyvsp[0].val) ? 1 : 0;;
+{eval(&yyvsp[0], &yyval, 0L);;
break;}
case 49:
-{yyval.val = (yyvsp[-2].val < yyvsp[0].val) ? 1 : 0;;
+{yyvsp[-2].tptr->SetValue(&yyval, &yyvsp[0]);;
break;}
case 50:
-{yyval.val = (yyvsp[-2].val <= yyvsp[0].val) ? 1 : 0;;
+{yyvsp[-2].tptr->SetValue(&yyval, &yyvsp[0]);;
break;}
case 51:
-{yyval.val = yyvsp[-2].val + yyvsp[0].val;;
+{yyval.val = ((yyvsp[-3].tptr->fnctptr)(yyvsp[-1].val)); yyval.type = NUM;;
break;}
case 52:
-{yyval.val = yyvsp[-2].val - yyvsp[0].val;;
+{yyval.val = ((yyvsp[-3].tptr->fnctptr)(proc_clause(&yyvsp[-1]))); yyval.type = NUM;;
break;}
case 53:
-{yyval.val = yyvsp[-2].val * yyvsp[0].val;;
+{ if(!yyval.a_data){yyval.a_data=PushArray((double*)malloc(sizeof(double)));yyval.a_data[0]=yyvsp[-3].val;yyval.a_count=1;}
+ push(&yyval, &yyvsp[-1]);yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyval)); yyval.type = NUM;;
break;}
case 54:
-{if(yyvsp[0].val != 0.0) yyval.val = yyvsp[-2].val / yyvsp[0].val;
- else yyval.val = (getsym(HashValue((unsigned char*)"zdiv")))->GetValue(); ;
+{ yyval.a_data = PushArray((double*)malloc(3*sizeof(double)));
+ yyval.a_count = 3; yyval.a_data[0] = yyvsp[-5].val; yyval.a_data[1] = yyvsp[-3].val; yyval.a_data[2] = yyvsp[-1].val;
+ yyval.val = ((yyvsp[-7].tptr->fnctptr)(&yyval)); yyval.type = NUM;;
break;}
case 55:
-{yyval.val = -yyvsp[0].val;;
+{yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval, 0L)); yyval.type = NUM;;
break;}
case 56:
-{yyval.val=yyvsp[-1].tptr->GetValue(); yyvsp[-1].tptr->SetValue(yyval.val+1.0); yyval.val -= 1.0; yyval.type = NUM;;
+{yyvsp[-1].text = string_value(&yyvsp[-1]); yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval, 0L)); yyval.type = NUM;;
break;}
case 57:
-{yyval.val=yyvsp[-1].tptr->GetValue(); yyvsp[-1].tptr->SetValue(yyval.val-1.0); yyval.val += 1.0; yyval.type = NUM;;
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 58:
-{yyval.val=yyvsp[0].tptr->GetValue(); yyvsp[0].tptr->SetValue(yyval.val+1.0); yyval.type = NUM;;
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 59:
-{yyval.val=yyvsp[0].tptr->GetValue(); yyvsp[0].tptr->SetValue(yyval.val-1.0); yyval.type = NUM;;
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 60:
-{yyval.val = pow(yyvsp[-2].val, yyvsp[0].val);;
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 61:
-{memcpy(&yyval, &yyvsp[-1], sizeof(YYSTYPE)); yyvsp[-1].a_data = 0L; yyvsp[-1].a_count = 0;;
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 62:
-{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 63:
-{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 64:
-{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
+{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
break;}
case 65:
+{range_array2(&yyvsp[-3], &yyvsp[-1]);yyval.val = ((*yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyvsp[-1], 0L)); yyval.type = NUM;;
+ break;}
+case 66:
+{range_array2(&yyvsp[-5], &yyvsp[-3]); yyval.val = ((*yyvsp[-7].tptr->fnctptr)(&yyvsp[-5], &yyvsp[-3], yyvsp[-1].text)); yyval.type = NUM;;
+ break;}
+case 67:
+{yyval.val=((*yyvsp[-5].tptr->fnctptr)(proc_clause(&yyvsp[-3]), proc_clause(&yyvsp[-1]), 0L));;
+ break;}
+case 68:
+{yyval.val=((*yyvsp[-7].tptr->fnctptr)(proc_clause(&yyvsp[-5]), proc_clause(&yyvsp[-3]), yyvsp[-1].text));;
+ break;}
+case 69:
+{proc_clause(&yyvsp[-3]); yyval.val=(*yyvsp[-9].tptr->fnctptr)(yyvsp[-7].val, yyvsp[-5].val, &yyvsp[-3], &yyvsp[-1]); yyval.type = NUM;;
+ break;}
+case 70:
+{yyval.val = ((*yyvsp[-5].tptr->fnctptr)(proc_clause(&yyvsp[-3]), yyvsp[-1].text)); yyval.type = NUM;;
+ break;}
+case 71:
+{(*yyvsp[-2].tptr->fnctptr)(&yyval, 0L);;
+ break;}
+case 72:
+{(*yyvsp[-3].tptr->fnctptr)(&yyval, &yyvsp[-1]);;
+ break;}
+case 73:
+{yyval.val = yyvsp[-2].val != 0 ? eval(&yyvsp[0], &yyval, 0L) : 0.0;;
+ break;}
+case 74:
+{yyval.val = yyvsp[-4].val != 0.0 ? eval(&yyvsp[-2], &yyval, 0L) : eval(&yyvsp[0], &yyval, 0L);;
+ break;}
+case 75:
+{yyval.val = yyvsp[-2].val + yyvsp[0].val; yyval.type = NUM;
+ if(yyvsp[0].type == DATE1 || yyvsp[-2].type == DATE1) yyval.type = DATE1;
+ else if(yyvsp[0].type == TIME1 || yyvsp[-2].type == TIME1) yyval.type = TIME1;
+ else if(yyvsp[0].type == DATETIME1 || yyvsp[-2].type == DATETIME1) yyval.type = DATETIME1;;
+ break;}
+case 76:
+{yyval.val = yyvsp[-2].val - yyvsp[0].val; yyval.type = NUM;
+ if(yyvsp[0].type == DATE1 || yyvsp[-2].type == DATE1) yyval.type = DATE1;
+ else if(yyvsp[0].type == TIME1 || yyvsp[-2].type == TIME1) yyval.type = TIME1;
+ else if(yyvsp[0].type == DATETIME1 || yyvsp[-2].type == DATETIME1) yyval.type = DATETIME1;;
+ break;}
+case 77:
+{yyval.val = yyvsp[-2].val * yyvsp[0].val; yyval.type = NUM;;
+ break;}
+case 78:
+{yyval.type = NUM; if(yyvsp[0].val != 0.0) yyval.val = yyvsp[-2].val / yyvsp[0].val;
+ else yyval.val = (getsym(HashValue((unsigned char*)"zdiv"), Hash2((unsigned char*)"zdiv")))->GetValue(); ;
+ break;}
+case 79:
+{yyval.val = -yyvsp[0].val;;
+ break;}
+case 80:
+{yyval.val=yyvsp[-1].tptr->GetValue(); yyvsp[-1].tptr->SetValue(yyval.val+1.0); yyval.val -= 1.0; yyval.type = NUM;;
+ break;}
+case 81:
+{yyval.val=yyvsp[-1].tptr->GetValue(); yyvsp[-1].tptr->SetValue(yyval.val-1.0); yyval.val += 1.0; yyval.type = NUM;;
+ break;}
+case 82:
+{yyval.val=yyvsp[0].tptr->GetValue(); yyvsp[0].tptr->SetValue(yyval.val+1.0); yyval.type = NUM;;
+ break;}
+case 83:
+{yyval.val=yyvsp[0].tptr->GetValue(); yyvsp[0].tptr->SetValue(yyval.val-1.0); yyval.type = NUM;;
+ break;}
+case 84:
+{yyval.val = pow(yyvsp[-2].val, yyvsp[0].val);;
+ break;}
+case 85:
+{memcpy(&yyval, &yyvsp[-1], sizeof(YYSTYPE)); yyvsp[-1].a_data = 0L; yyvsp[-1].a_count = 0;;
+ break;}
+case 86:
+{yyval.a_data = PushArray((double*)calloc((int)yyvsp[-1].val, sizeof(double))); yyval.a_count=(int)(yyvsp[-1].val);
+ yyval.type = ARR; yyvsp[-3].tptr->SetValue(&yyval,&yyval);;
+ break;}
+case 87:
+{if(yyvsp[-3].a_data && yyvsp[-1].val >= 0.0 && yyvsp[-1].val < yyvsp[-3].a_count) yyval.val = yyvsp[-3].a_data[(int)yyvsp[-1].val];
+ else {yyval.val = 0.0; last_err_desc = "#INDEX";} yyval.type = NUM;;
+ break;}
+case 88:
+{if(yyvsp[-5].a_data && yyvsp[-3].val >= 0.0 && yyvsp[-3].val < yyvsp[-5].a_count) yyval.val = yyvsp[-5].a_data[(int)yyvsp[-3].val] = yyvsp[0].val;
+ else {yyval.val = 0.0; last_err_desc = "#INDEX";} yyval.type = NUM;;
+ break;}
+case 89:
+{make_time(&yyval, yyvsp[-4].val, yyvsp[-2].val, yyvsp[0].val+1.0e-10);;
+ break;}
+case 90:
+{make_time(&yyval, yyvsp[-4].val, yyvsp[-2].val, yyvsp[0].val+1.0e-10);;
+ break;}
+case 91:
+{make_time(&yyval, yyvsp[-2].val, yyvsp[0].val, 1.0e-10);;
+ break;}
+case 92:
+{make_time(&yyval, yyvsp[-2].val, yyvsp[0].val, 1.0e-10);;
+ break;}
+case 93:
+{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
+ break;}
+case 94:
+{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
+ break;}
+case 95:
+{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
+ break;}
+case 96:
{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
break;}
}
@@ -1365,15 +1654,12 @@ yyerrhandle:
// The symrec class
-symrec::symrec(unsigned int h_n, int typ, symrec *nxt)
-{
- h_name = h_n;
- type = typ;
- next = nxt;
- row = col = -1;
- name = text = 0L;
- var = 0.0;
- isSSval = false;
+symrec::symrec(unsigned int h_n, unsigned int h2_n, int typ, symrec *nxt)
+{
+ h_name = h_n; h2_name = h2_n; type = typ;
+ next = nxt; row = col = -1; name = text = 0L;
+ var = 0.0; isSSval = false;
+ a_data = 0L; a_count = 0;
fnctptr = (double (*)(...))nop;
}
@@ -1412,18 +1698,29 @@ symrec::GetValue(void *re)
//GetResult( , , ,true) inhibits reentrance into parser !
if(curr_data->GetResult(&ares, row, col, parse_level > MAX_PARSE)){
if(text) free(text); text = 0L;
- if(ares.type == ET_VALUE) {
- res->type = VAR; res->val = ares.value;
- res->text = 0L;
- }
- else if(ares.type == ET_TEXT && ares.text) {
+ switch(ares.type) {
+ case ET_VALUE:
+ res->type = NUM; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_BOOL:
+ res->type = BOOLVAL; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_DATE:
+ res->type = DATE1; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_TIME:
+ res->type = TIME1; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_DATETIME:
+ res->type = DATETIME1; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_TEXT:
res->type = STR; res->val = 0.0;
- text = strdup(ares.text);
- res->text = text;
- }
- else {
+ if(ares.text) res->text = PushString(text = strdup(ares.text));
+ else res->text = 0L; break;
+ default:
res->type = NUM; res->val = var;
- res->text = 0L;
+ res->text = 0L; break;
}
var = res->val;
return;
@@ -1431,15 +1728,18 @@ symrec::GetValue(void *re)
isSSval = false;
row = col = -1;
}
- if(text && text[0]) {
- res->text = strdup(text);
+ if(a_data && a_count) {
+ res->a_data = a_data; res->a_count = a_count;
+ res->val = 0.0; res->type = ARR;
+ }
+ else if(text && text[0]) {
+ res->text = PushString(text);
res->val = var; res->type = STR;
}
else {
res->type = NUM; res->val = var;
res->text = 0L;
}
- res->a_data = 0L; res->a_count = 0L;
}
double
@@ -1454,6 +1754,7 @@ symrec::SetValue(double v)
isSSval = false;
row = col = -1;
}
+ a_data = 0L; a_count = 0;
return var = v;
}
@@ -1475,6 +1776,7 @@ symrec::SetValue(void* d, void* s)
var = src->val;
if(text) free(text); text = 0L;
if(src->text && src->text[0]) text = strdup(src->text);
+ a_data = src->a_data; a_count = src->a_count;
GetValue(d);
return;
}
@@ -1512,6 +1814,15 @@ static void yyargserr(char *s)
last_err_desc = "#ARGS";
}
+static void make_time(YYSTYPE *dst, double h, double m, double s)
+{
+ if(!dst || h < 0.0 || 24.0 < h || m < 0.0 || 60.0 < m || s < 0.0 || 60.0 < s) {
+ yyerror("parse error"); return;
+ }
+ dst->val = s/60.0 + m; dst->val = dst->val/60.0 + h;
+ dst->val /= 24.0; dst->type = TIME1;
+}
+
static void store_res(YYSTYPE *res)
{
if(last_err_desc) {
@@ -1519,7 +1830,27 @@ static void store_res(YYSTYPE *res)
line_res.value = 0.0;
strcpy(res_txt, last_err_desc);
}
- else if(res->type == STR) {
+ else if(res->type == NUM){
+ line_res.type = ET_VALUE;
+ line_res.value = res->val;
+ }
+ else if(res->type == BOOLVAL){
+ line_res.type = ET_BOOL;
+ line_res.value = res->val;
+ }
+ else if(res->type == DATE1){
+ line_res.type = ET_DATE;
+ line_res.value = res->val;
+ }
+ else if(res->type == TIME1){
+ line_res.type = ET_TIME;
+ line_res.value = res->val;
+ }
+ else if(res->type == DATETIME1){
+ line_res.type = ET_DATETIME;
+ line_res.value = res->val;
+ }
+ else if(res->type == STR) {
line_res.type = ET_TEXT;
line_res.value = 0.0;
if(res->text) strcpy(res_txt, res->text);
@@ -1604,10 +1935,11 @@ static void pop_syntax()
}
}
-static double eval(YYSTYPE *sr, YYSTYPE *dst)
+static double eval(YYSTYPE *sr, YYSTYPE *dst, char *dum)
{
anyResult *ar;
+ if(dum) yyerror("parse error");
if(!sr || !sr->text) return 0.0;
parse_level++;
ar = do_formula(0L, sr->text);
@@ -1642,10 +1974,11 @@ static double sign(double v)
}
static long idum=0;
-
-static double rand(double v)
+static double rand1(YYSTYPE *dst, YYSTYPE *src)
{
- return ran2(&idum);
+ if(!dst) return 0.0;
+ dst->type = NUM;
+ return(dst->val = ran2(&idum));
}
static double srand(double v)
@@ -1659,14 +1992,9 @@ static double factorial(double v)
return factrl((int)v);
}
-static void close_arr_func(YYSTYPE *sr)
-{
- if(sr->a_data) free(sr->a_data);
- sr->a_data = 0L; sr->a_count = 0;
-}
-
-static double _strlen(YYSTYPE *sr, YYSTYPE *dst)
+static double _strlen(YYSTYPE *sr, YYSTYPE *dst, char *dum)
{
+ if(dum) yyerror("parse error");
if(!sr || !sr->text) return 0.0;
return (double)strlen(sr->text);
}
@@ -1680,7 +2008,6 @@ static double min(YYSTYPE *sr)
if(sr->a_data && sr->a_data){
for(i = 1, sr->val = sr->a_data[0]; i < sr->a_count; i++)
if(sr->a_data[i] < sr->val) sr->val = sr->a_data[i];
- close_arr_func(sr);
}
return sr->val;
}
@@ -1694,7 +2021,6 @@ static double max(YYSTYPE *sr)
if(sr->a_data){
for(i = 1, sr->val = sr->a_data[0]; i < sr->a_count; i++)
if(sr->a_data[i] > sr->val) sr->val = sr->a_data[i];
- close_arr_func(sr);
}
return sr->val;
}
@@ -1702,10 +2028,7 @@ static double max(YYSTYPE *sr)
static double count(YYSTYPE *sr)
{
if(!sr) return 0.0;
- if(sr->a_data){
- sr->val = (double)sr->a_count;
- close_arr_func(sr);
- }
+ if(sr->a_data) sr->val = (double)sr->a_count;
else sr->val = 0.0;
return sr->val;
}
@@ -1717,47 +2040,64 @@ static double sum(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data){
for(i = 0, sr->val = 0.0; i < sr->a_count; i++) sr->val += sr->a_data[i];
- close_arr_func(sr);
}
else sr->val = 0.0;
return sr->val;
}
-static double calc_variance(double *values, int n)
+static double mean(YYSTYPE *sr)
{
- int i;
- double ss, d, mean = d_amean(n, values);
+ if(!sr) return 0.0;
+ if(sr->a_data && sr->a_count){
+ sr->val = d_amean(sr->a_count, sr->a_data );
+ }
+ return sr->val;
+}
- for(i=0, ss=0.0; i < n; i++) ss += ((d=values[i]-mean)*d);
- return (ss/(n-1));
+static double kurt(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ if(sr->a_data && sr->a_count > 3){
+ sr->val = d_kurt(sr->a_count, sr->a_data );
+ }
+ return sr->val;
}
-static double mean(YYSTYPE *sr)
+static double skew(YYSTYPE *sr)
{
if(!sr) return 0.0;
- if(sr->a_data && sr->a_count){
- sr->val = d_amean(sr->a_count, sr->a_data );
- close_arr_func(sr);
+ if(sr->a_data && sr->a_count > 2){
+ sr->val = d_skew(sr->a_count, sr->a_data );
}
return sr->val;
}
static double gmean(YYSTYPE *sr)
{
+ int i;
+
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
+ for(i = 0; i < sr->a_count; i++) if(sr->a_data[i] <= 0.0) {
+ last_err_desc = "#VALUE";
+ return sr->val = 0.0;
+ }
sr->val = d_gmean(sr->a_count, sr->a_data );
- close_arr_func(sr);
}
return sr->val;
}
static double hmean(YYSTYPE *sr)
{
+ int i;
+
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
+ for(i = 0; i < sr->a_count; i++) if(sr->a_data[i] <= 0.0) {
+ last_err_desc = "#VALUE";
+ return sr->val = 0.0;
+ }
sr->val = d_hmean(sr->a_count, sr->a_data );
- close_arr_func(sr);
}
return sr->val;
}
@@ -1767,7 +2107,6 @@ static double quartile1(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
d_quartile(sr->a_count, sr->a_data, &sr->val, 0L, 0L);
- close_arr_func(sr);
}
return sr->val;
}
@@ -1777,7 +2116,6 @@ static double quartile2(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
d_quartile(sr->a_count, sr->a_data, 0L, &sr->val, 0L);
- close_arr_func(sr);
}
return sr->val;
}
@@ -1787,7 +2125,6 @@ static double quartile3(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
d_quartile(sr->a_count, sr->a_data, 0L, 0L, &sr->val);
- close_arr_func(sr);
}
return sr->val;
}
@@ -1797,8 +2134,7 @@ static double variance(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count){
- sr->val = calc_variance(sr->a_data, sr->a_count);
- close_arr_func(sr);
+ sr->val = d_variance(sr->a_count, sr->a_data);
}
return sr->val;
}
@@ -1808,8 +2144,7 @@ static double stdev(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count){
- sr->val = sqrt(calc_variance(sr->a_data, sr->a_count));
- close_arr_func(sr);
+ sr->val = sqrt(d_variance(sr->a_count, sr->a_data));
}
return sr->val;
}
@@ -1819,8 +2154,7 @@ static double sterr(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count){
- sr->val = sqrt(calc_variance(sr->a_data, sr->a_count))/sqrt(sr->a_count);
- close_arr_func(sr);
+ sr->val = sqrt(d_variance(sr->a_count, sr->a_data))/sqrt(sr->a_count);
}
return sr->val;
}
@@ -1831,7 +2165,6 @@ static double beta(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = betaf(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to beta(u, v).");
return sr->val;
@@ -1843,7 +2176,6 @@ static double _gammp(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = gammp(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to gammp(a, x).");
return sr->val;
@@ -1855,7 +2187,6 @@ static double _gammq(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = gammq(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to gammq(a, x).");
return sr->val;
@@ -1866,10 +2197,13 @@ static double _betai(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3){
+ if(sr->a_data[2] < 0.0 || sr->a_data[2] > 1.0) {
+ last_err_desc = "#VALUE";
+ return sr->val = 0.0;
+ }
sr->val = betai(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
- else yyargserr("Wrong number of arguments\nin call to betai(x, a, b).");
+ else yyargserr("Wrong number of arguments\nin call to betai(a, b, x).");
return sr->val;
}
@@ -1879,7 +2213,6 @@ static double _bincof(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = bincof(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to bincof(n, k).");
return sr->val;
@@ -1891,19 +2224,30 @@ static double binomdist(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3){
sr->val = binomdistf(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to binomdist(s, n, p).");
return sr->val;
}
+static double binomfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = bincof(sr->a_data[1], sr->a_data[0]);
+ sr->val *= pow(sr->a_data[2], sr->a_data[0]);
+ sr->val *= pow(1.0 - sr->a_data[2], sr->a_data[1] - sr->a_data[0]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to binomfreq(s, n, p).");
+ return sr->val;
+}
+
static double normdist(YYSTYPE *sr)
{
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3){
sr->val = norm_dist(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to normdist(x, mean, SD).");
return sr->val;
@@ -1915,19 +2259,50 @@ static double norminv(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3) {
sr->val = distinv(norm_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to norminv(p, mean, SD).");
return sr->val;
}
+static double normfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = norm_freq(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to normfreq(x, mean, SD).");
+ return sr->val;
+}
+
+static double lognormdist(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = lognorm_dist(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to lognormdist(x, mean, SD).");
+ return sr->val;
+}
+
+static double lognorminv(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3) {
+ sr->val = distinv(lognorm_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], 2.0);
+ }
+ else yyargserr("Wrong number of arguments\nin call to lognorminv(p, mean, SD).");
+ return sr->val;
+}
+
static double chidist(YYSTYPE *sr)
{
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = chi_dist(sr->a_data[0], sr->a_data[1], 1.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to chidist(x, df).");
return sr->val;
@@ -1939,7 +2314,6 @@ static double chiinv(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2) {
sr->val = distinv(chi_dist,sr->a_data[1], 1.0, sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to chiinv(p, df).");
return sr->val;
@@ -1951,7 +2325,6 @@ static double tdist(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = t_dist(sr->a_data[0], sr->a_data[1], 1.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to tdist(x, df).");
return sr->val;
@@ -1963,7 +2336,6 @@ static double tinv(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2) {
sr->val = distinv(t_dist,sr->a_data[1], 1.0, sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to tinv(p, df).");
return sr->val;
@@ -1975,19 +2347,28 @@ static double poisdist(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = pois_dist(sr->a_data[0], sr->a_data[1], 1.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to poisdist(x, mean).");
return sr->val;
}
+static double poisfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 2){
+ sr->val = exp(log(sr->a_data[1])*sr->a_data[0] - sr->a_data[1] - gammln(1.0 + sr->a_data[0]));
+ }
+ else yyargserr("Wrong number of arguments\nin call to poisfreq(x, mean).");
+ return sr->val;
+}
+
static double fdist(YYSTYPE *sr)
{
if(!sr) return 0.0;
sr->val = 0;
if(sr->a_data && sr->a_count == 3){
sr->val = f_dist(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to fdist(x, df1, df2).");
return sr->val;
@@ -1999,7 +2380,6 @@ static double finv(YYSTYPE *sr)
sr->val = 0;
if(sr->a_data && sr->a_count == 3){
sr->val = distinv(f_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to finv(p, df1, df2).");
return sr->val;
@@ -2011,7 +2391,6 @@ static double pearson(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
sr1->val = sr2->val = d_pearson(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\npearson(range1; range2 [;\"dest\"]).");
return sr1->val;
@@ -2023,12 +2402,22 @@ static double spearman(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
sr1->val = sr2->val = d_spearman(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\nspearman(range1; range2 [;\"dest\"]).");
return sr1->val;
}
+static double kendall(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
+ sr1->val = sr2->val = d_kendall(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\nkendall(range1; range2 [;\"dest\"]).");
+ return sr1->val;
+}
+
static double regression(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
{
if(!sr1 || !sr2) return 0.0;
@@ -2036,21 +2425,52 @@ static double regression(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
if(!(dest)) yyargserr("No destination range in call to function\nregression(range1; range2; \"dest\").");
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
sr1->val = sr2->val = d_regression(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\nregression(range1; range2; \"dest\").");
return sr1->val;
}
+static double covar(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
+ sr1->val = sr2->val = d_covar(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\ncovar(range1; range2).");
+ return sr1->val;
+}
+
static double ttest(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
{
if(!sr1 || !sr2) return 0.0;
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr2->a_count > 1){
sr1->val = sr2->val = d_ttest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
- else yyargserr("Bad arguments in call to function\nttest(range1; range2[;\"dest\"]).");
+ else yyargserr("Bad arguments in call to function\nttest(array1; array2[;\"dest\"]).");
+ return sr1->val;
+}
+
+static double ttest2(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr2->a_count > 1){
+ sr1->val = sr2->val = d_ttest2(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\nttest2(range1; range2[;\"dest\"]).");
+ return sr1->val;
+}
+
+static double utest(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr2->a_count > 1){
+ sr1->val = sr2->val = d_utest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\nutest2(array1; array2[;\"dest\"]).");
return sr1->val;
}
@@ -2060,80 +2480,223 @@ static double ftest(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count > 1){
sr1->val = sr2->val = d_ftest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\nftest(range1; range2[;\"dest\"]).");
return sr1->val;
}
-struct init
+static double fill(YYSTYPE *sr, char *dest)
{
- int f_type;
- unsigned int h_name;
- double (*fnct)(double);
-};
+ AccRange *ar;
+ int i, r, c;
+
+ if(!sr || !sr->a_data || !sr->a_count || !dest || !dest[0]) return 0.0;
+ if(ar = new AccRange(dest)) {
+ for(i=0, ar->GetFirst(&c, &r); ar->GetNext(&c, &r) && i < sr->a_count; i++) {
+ curr_data->SetValue(r, c, sr->a_data[i]);
+ }
+ delete ar;
+ }
+ return sr->val = i;
+}
-static struct init arith_fncts[] = {
- {FUNC2, HashValue((unsigned char*)"pearson"), (double(*)(double))&pearson},
- {FUNC2, HashValue((unsigned char*)"spearman"), (double(*)(double))&spearman},
- {FUNC2, HashValue((unsigned char*)"regression"), (double(*)(double))®ression},
- {FUNC2, HashValue((unsigned char*)"ttest"), (double(*)(double))&ttest},
- {FUNC2, HashValue((unsigned char*)"ftest"), (double(*)(double))&ftest},
- {AFNCT, HashValue((unsigned char*)"variance"), (double(*)(double))&variance},
- {AFNCT, HashValue((unsigned char*)"stdev"), (double(*)(double))&stdev},
- {AFNCT, HashValue((unsigned char*)"sterr"), (double(*)(double))&sterr},
- {AFNCT, HashValue((unsigned char*)"min"), (double(*)(double))&min},
- {AFNCT, HashValue((unsigned char*)"max"), (double(*)(double))&max},
- {AFNCT, HashValue((unsigned char*)"count"), (double(*)(double))&count},
- {AFNCT, HashValue((unsigned char*)"sum"), (double(*)(double))&sum},
- {AFNCT, HashValue((unsigned char*)"mean"), (double(*)(double))&mean},
- {AFNCT, HashValue((unsigned char*)"median"), (double(*)(double))&quartile2},
- {AFNCT, HashValue((unsigned char*)"quartile1"), (double(*)(double))&quartile1},
- {AFNCT, HashValue((unsigned char*)"quartile2"), (double(*)(double))&quartile2},
- {AFNCT, HashValue((unsigned char*)"quartile3"), (double(*)(double))&quartile3},
- {AFNCT, HashValue((unsigned char*)"gmean"), (double(*)(double))&gmean},
- {AFNCT, HashValue((unsigned char*)"hmean"), (double(*)(double))&hmean},
- {AFNCT, HashValue((unsigned char*)"tdist"), (double(*)(double))&tdist},
- {AFNCT, HashValue((unsigned char*)"tinv"), (double(*)(double))&tinv},
- {AFNCT, HashValue((unsigned char*)"poisdist"), (double(*)(double))&poisdist},
- {AFNCT, HashValue((unsigned char*)"fdist"), (double(*)(double))&fdist},
- {AFNCT, HashValue((unsigned char*)"finv"), (double(*)(double))&finv},
- {AFNCT, HashValue((unsigned char*)"gammp"), (double(*)(double))&_gammp},
- {AFNCT, HashValue((unsigned char*)"gammq"), (double(*)(double))&_gammq},
- {AFNCT, HashValue((unsigned char*)"beta"), (double(*)(double))&beta},
- {AFNCT, HashValue((unsigned char*)"betai"), (double(*)(double))&_betai},
- {AFNCT, HashValue((unsigned char*)"bincof"), (double(*)(double))&_bincof},
- {AFNCT, HashValue((unsigned char*)"binomdist"), (double(*)(double))&binomdist},
- {AFNCT, HashValue((unsigned char*)"normdist"), (double(*)(double))&normdist},
- {AFNCT, HashValue((unsigned char*)"norminv"), (double(*)(double))&norminv},
- {AFNCT, HashValue((unsigned char*)"chidist"), (double(*)(double))&chidist},
- {AFNCT, HashValue((unsigned char*)"chiinv"), (double(*)(double))&chiinv},
- {SFNCT, HashValue((unsigned char*)"strlen"), (double(*)(double))&_strlen},
- {SFNCT, HashValue((unsigned char*)"eval"), (double(*)(double))&eval},
- {FNCT, HashValue((unsigned char*)"erf"), errf},
- {FNCT, HashValue((unsigned char*)"erfc"), errfc},
- {FNCT, HashValue((unsigned char*)"sign"), sign},
- {FNCT, HashValue((unsigned char*)"gammaln"), gammln},
- {FNCT, HashValue((unsigned char*)"factorial"), factorial},
- {FNCT, HashValue((unsigned char*)"rand"), rand},
- {FNCT, HashValue((unsigned char*)"srand"), srand},
- {FNCT, HashValue((unsigned char*)"floor"), floor},
- {FNCT, HashValue((unsigned char*)"abs"), fabs},
- {FNCT, HashValue((unsigned char*)"asin"), asin},
- {FNCT, HashValue((unsigned char*)"acos"), acos},
- {FNCT, HashValue((unsigned char*)"atan"), atan},
- {FNCT, HashValue((unsigned char*)"sinh"), sinh},
- {FNCT, HashValue((unsigned char*)"cosh"), cosh},
- {FNCT, HashValue((unsigned char*)"tanh"), tanh},
- {FNCT, HashValue((unsigned char*)"sin"), sin},
- {FNCT, HashValue((unsigned char*)"cos"), cos},
- {FNCT, HashValue((unsigned char*)"atan"), atan},
- {FNCT, HashValue((unsigned char*)"log10"), log10},
- {FNCT, HashValue((unsigned char*)"ln"), log},
- {FNCT, HashValue((unsigned char*)"log"), log},
- {FNCT, HashValue((unsigned char*)"exp"), exp},
- {FNCT, HashValue((unsigned char*)"sqrt"), sqrt},
- {0, 0, 0}};
+static void datestr(YYSTYPE *dst, YYSTYPE *src, char *fmt)
+{
+ dst->text = PushString(value_date(src->val, fmt));
+}
+
+static double dateval(YYSTYPE *sr, YYSTYPE *dst, char *fmt)
+{
+ if(!sr || !sr->text) return 0.0;
+ if(fmt && fmt[0] && date_value(sr->text, fmt, &dst->val)) return dst->val;
+ if(date_value(sr->text, 0L, &dst->val)) return dst->val;
+ else return dst->val = 0.0;
+}
+
+static double leapyear(double year)
+{
+ int y = (int)year;
+
+ return (double)((y % 4 == 0 && y % 100 != 0) || y % 400 == 0);
+}
+
+static void today(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(src) yyerror("parse error");
+ if(!dst) return;
+ dst->val = floor(now_today());
+ dst->type = DATE1;
+}
+
+static void now(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(src) yyerror("parse error");
+ if(!dst) return;
+ dst->val = now_today(); dst->val -= floor(dst->val);
+ dst->type = TIME1;
+}
+
+static double year(double dv)
+{
+ int res;
+
+ split_date(dv, &res, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double month(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, &res, 0L, 0L, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double dom(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, &res, 0L, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double dow(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, &res, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double doy(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, &res, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double hours(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, 0L, &res, 0L, 0L);
+ return (double)res;
+}
+
+static double minutes(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, 0L, 0L, &res, 0L);
+ return (double)res;
+}
+
+static double seconds(double dv)
+{
+ double res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, 0L, 0L, 0L, &res);
+ if(res < 0.0005) res = 0.0;
+ return res;
+}
+
+static void fdate(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src || src->type == ARR || src->type == STR) {
+ yyerror("parse error");
+ return;
+ }
+ dst->type = DATE1; dst->val = src->val;
+}
+
+static void fdatetime(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src || src->type == ARR || src->type == STR) {
+ yyerror("parse error");
+ return;
+ }
+ dst->type = DATETIME1; dst->val = src->val;
+}
+
+static void ftime(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src || src->type == ARR || src->type == STR) {
+ yyerror("parse error");
+ return;
+ }
+ dst->type = TIME1; dst->val = src->val;
+}
+
+static void asort(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src) return;
+ dst->type = ARR;
+ switch(src->a_count) {
+ case 0:
+ dst->a_data = PushArray((double*)malloc(sizeof(double)));
+ dst->a_count = 1; dst->a_data[0] = dst->val = src->val;
+ break;
+ case 1:
+ dst->a_data = PushArray((double*)malloc(sizeof(double)));
+ dst->a_count = 1; dst->a_data[0] = dst->val = src->a_data[0];
+ break;
+ default:
+ dst->a_data = PushArray((double*)memdup(src->a_data, src->a_count * sizeof(double), 0));
+ dst->a_count = src->a_count;
+ SortArray(dst->a_count, dst->a_data);
+ }
+}
+
+static void _crank(YYSTYPE *dst, YYSTYPE *src)
+{
+ double tmp;
+
+ if(!dst || !src) return;
+ dst->type = ARR;
+ switch(src->a_count) {
+ case 0: case 1:
+ dst->a_data = PushArray((double*)malloc(sizeof(double)));
+ dst->a_count = 1; dst->a_data[0] = dst->val = 1;
+ break;
+ default:
+ dst->a_data = PushArray((double*)memdup(src->a_data, src->a_count * sizeof(double), 0));
+ dst->a_count = src->a_count;
+ crank(dst->a_count, dst->a_data, &tmp);
+ }
+}
+
+static void ltrim(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!src || !dst || !src->text) return;
+ dst->text = PushString(str_ltrim(strdup(src->text)));
+ dst->type = STR; dst->val = 0.0;
+}
+
+static void rtrim(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!src || !dst || !src->text) return;
+ dst->text = PushString(str_rtrim(strdup(src->text)));
+ dst->type = STR; dst->val = 0.0;
+}
+
+static void trim(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!src || !dst || !src->text) return;
+ dst->text = PushString(str_trim(strdup(src->text)));
+ dst->type = STR; dst->val = 0.0;
+}
+
+static double rank(YYSTYPE *sr)
+{
+ if(sr->a_count < 2 || !sr->a_data) return 0.0;
+ return d_rank(sr->a_count-1, sr->a_data+1, sr->a_data[0]);
+}
+
+static double classes(double start, double step, YYSTYPE *src, YYSTYPE *dest)
+{
+ return d_classes(curr_data, start, step, src->a_data, src->a_count, dest->text);
+}
// Store strings in a list
static char **str_list = 0L;
@@ -2149,6 +2712,36 @@ static char *PushString(char *text)
return 0L;
}
+//Store arrays in a list
+static double **arr_list = 0L;
+static int n_arr = 0;
+
+static double *PushArray(double *arr)
+{
+ if(arr) {
+ if(arr_list = (double**)realloc(arr_list, sizeof(double*)*(n_arr+1)))
+ arr_list[n_arr] = arr;
+ return arr_list[n_arr++];
+ }
+ return 0L;
+}
+
+static double *ReallocArray(double *arr, int size)
+{
+ int i;
+
+ if(arr && size) {
+ for(i = 0; i < n_arr; i++) if(arr_list[i] == arr) {
+ arr_list[i] = (double*)realloc(arr, size);
+ return arr_list[i];
+ }
+ arr = (double*)realloc(arr, size);
+ return PushArray(arr);
+ }
+ return 0L;
+}
+
+
//The symbol table: a chain of `struct symrec'
static symrec *sym_table, *sym_tab_first;
@@ -2186,8 +2779,68 @@ void ArrangeFunctions()
}
// Put arithmetic functions and predifened variables in table
+#define INIT_SYM(TYP,NAM,FNC) {TYP,NAM,(double(*)(double))&FNC}
void InitArithFuncs(DataObj *d)
{
+ struct fdef {
+ int f_type;
+ char *name;
+ double (*fnct)(double);
+ };
+ fdef fncts[] = {
+ INIT_SYM(FUNC4, "classes", classes),
+ INIT_SYM(AFNCT, "rank", rank), INIT_SYM(YYFNC, "ltrim", ltrim),
+ INIT_SYM(YYFNC, "rtrim", rtrim), INIT_SYM(YYFNC, "trim", trim),
+ INIT_SYM(YYFNC, "asort", asort), INIT_SYM(YYFNC, "crank", _crank),
+ INIT_SYM(SRFUNC, "datestr", datestr), INIT_SYM(SFNCT, "dateval", dateval),
+ INIT_SYM(BFNCT, "leapyear", leapyear), INIT_SYM(YYFNC, "today", today),
+ INIT_SYM(YYFNC, "now", now), INIT_SYM(FNCT, "year", year),
+ INIT_SYM(FNCT, "month", month), INIT_SYM(FNCT, "dom", dom),
+ INIT_SYM(FNCT, "dow", dow), INIT_SYM(FNCT, "doy", doy),
+ INIT_SYM(FNCT, "hours", hours), INIT_SYM(FNCT, "minutes", minutes),
+ INIT_SYM(FNCT, "seconds", seconds), INIT_SYM(YYFNC, "date", fdate),
+ INIT_SYM(FNCT, "datetime", fdatetime), INIT_SYM(YYFNC, "time", ftime),
+ INIT_SYM(FUNC1, "fill", fill), INIT_SYM(FUNC2, "pearson", pearson),
+ INIT_SYM(FUNC2, "spearman", spearman), INIT_SYM(FUNC2, "kendall", kendall),
+ INIT_SYM(FUNC2, "correl", pearson), INIT_SYM(FUNC2, "regression", regression),
+ INIT_SYM(FUNC2, "covar", covar),
+ INIT_SYM(FUNC3, "utest", utest), INIT_SYM(FUNC2, "ttest2", ttest2),
+ INIT_SYM(FUNC3, "ttest", ttest), INIT_SYM(FUNC3, "ftest", ftest),
+ INIT_SYM(AFNCT, "variance", variance), INIT_SYM(AFNCT, "stdev", stdev),
+ INIT_SYM(AFNCT, "sterr", sterr), INIT_SYM(AFNCT, "min", min),
+ INIT_SYM(AFNCT, "max", max), INIT_SYM(AFNCT, "count", count),
+ INIT_SYM(AFNCT, "sum", sum), INIT_SYM(AFNCT, "mean", mean),
+ INIT_SYM(AFNCT, "kurt", kurt), INIT_SYM(AFNCT, "skew", skew),
+ INIT_SYM(AFNCT, "median", quartile2), INIT_SYM(AFNCT, "quartile1", quartile1),
+ INIT_SYM(AFNCT, "quartile2",quartile2), INIT_SYM(AFNCT, "quartile3", quartile3),
+ INIT_SYM(AFNCT, "gmean", gmean), INIT_SYM(AFNCT, "hmean", hmean),
+ INIT_SYM(AFNCT, "tdist", tdist), INIT_SYM(AFNCT, "tinv", tinv),
+ INIT_SYM(AFNCT, "poisdist", poisdist), INIT_SYM(AFNCT, "poisfreq", poisfreq),
+ INIT_SYM(AFNCT, "fdist", fdist),
+ INIT_SYM(AFNCT, "finv", finv), INIT_SYM(AFNCT, "gammp", _gammp),
+ INIT_SYM(AFNCT, "gammq", _gammq), INIT_SYM(AFNCT, "beta", beta),
+ INIT_SYM(AFNCT, "betai", _betai), INIT_SYM(AFNCT, "bincof", _bincof),
+ INIT_SYM(AFNCT, "binomdist",binomdist),
+ INIT_SYM(AFNCT, "binomfreq",binomfreq),
+ INIT_SYM(AFNCT, "normdist", normdist),
+ INIT_SYM(AFNCT, "norminv", norminv),
+ INIT_SYM(AFNCT, "normfreq", normfreq),
+ INIT_SYM(AFNCT, "lognormdist", lognormdist),
+ INIT_SYM(AFNCT, "lognorminv",lognorminv), INIT_SYM(AFNCT, "chidist", chidist),
+ INIT_SYM(AFNCT, "chiinv", chiinv), INIT_SYM(SFNCT, "strlen", _strlen),
+ INIT_SYM(SFNCT, "eval", eval), INIT_SYM(FNCT, "erf", errf),
+ INIT_SYM(FNCT, "erfc", errfc), INIT_SYM(FNCT, "sign", sign),
+ INIT_SYM(FNCT, "gammaln", gammln), INIT_SYM(FNCT, "factorial", factorial),
+ INIT_SYM(YYFNC, "rand", rand1), INIT_SYM(FNCT, "srand", srand),
+ INIT_SYM(FNCT, "floor", floor), INIT_SYM(FNCT, "abs", fabs),
+ INIT_SYM(FNCT, "asin", asin), INIT_SYM(FNCT, "acos", acos),
+ INIT_SYM(FNCT, "atan", atan), INIT_SYM(FNCT, "sinh", sinh),
+ INIT_SYM(FNCT, "cosh", cosh), INIT_SYM(FNCT, "tanh", tanh),
+ INIT_SYM(FNCT, "sin", sin), INIT_SYM(FNCT, "cos", cos),
+ INIT_SYM(FNCT, "tan", tan), INIT_SYM(FNCT, "log10", log10),
+ INIT_SYM(FNCT, "ln", log), INIT_SYM(FNCT, "log", log),
+ INIT_SYM(FNCT, "exp", exp), INIT_SYM(FNCT, "sqrt", sqrt),
+ INIT_SYM(0, 0L, nop)};
int i;
symrec *ptr, *next;
@@ -2202,17 +2855,19 @@ void InitArithFuncs(DataObj *d)
}
sym_table = sym_tab_first = (symrec *) 0;
}
- for (i = 0; arith_fncts[i].h_name; i++) {
- ptr = putsym (arith_fncts[i].h_name, arith_fncts[i].f_type);
- ptr->fnctptr = (double (*)(...))arith_fncts[i].fnct;
+ for (i = 0; fncts[i].name; i++) {
+ ptr = putsym (HashValue((unsigned char*) fncts[i].name), Hash2((unsigned char*) fncts[i].name), fncts[i].f_type);
+ ptr->fnctptr = (double (*)(...))fncts[i].fnct;
}
- ptr = putsym(HashValue((unsigned char*)"zdiv"), VAR); ptr->SetValue(1.0);
+ ptr = putsym(HashValue((unsigned char*)"zdiv"), Hash2((unsigned char*)"zdiv"), VAR); ptr->SetValue(1.0);
sym_tab_first = sym_table;
}
+#undef INIT_SYM
static void init_table (void)
{
str_list = 0L; n_str = 0;
+ arr_list = 0L; n_arr = 0;
push_syntax();
}
@@ -2224,33 +2879,37 @@ static void clear_table()
for(i = 0; i < n_str; i++) if(str_list[i]) free(str_list[i]);
free(str_list); str_list = 0L; n_str = 0;
}
+ if(arr_list) {
+ for(i = 0; i < n_arr; i++) if(arr_list[i]) free(arr_list[i]);
+ free(arr_list); arr_list = 0L; n_arr = 0;
+ }
pop_syntax();
}
static symrec *
-putsym (unsigned int h_name, int sym_type)
+putsym (unsigned int h_name, unsigned int h2_name, int sym_type)
{
- sym_table = new symrec(h_name, sym_type, sym_table);
+ sym_table = new symrec(h_name, h2_name, sym_type, sym_table);
return sym_table;
}
static symrec *
-getsym (unsigned int h_name, char *sym_name)
+getsym (unsigned int h_name, unsigned int h2_name, char *sym_name)
{
symrec *ptr;
if(!h_name) return 0;
for (ptr = sym_table; ptr != (symrec *) 0; ptr = (symrec *)ptr->next) {
- if (ptr->h_name == h_name){
+ if (ptr->h_name == h_name && ptr->h2_name == h2_name){
if(sym_name && !ptr->name) {
ptr->SetName(sym_name);
bRecent = true;
}
return ptr;
}
- //predefined variables never end on a digit
+ //predefined variables rarely end on a digit
else if(ptr == sym_tab_first) {
- if(sym_name && isdigit(sym_name[strlen(sym_name)-1])) return 0;
+ if(sym_name && isdigit(sym_name[strlen(sym_name)-1]) && strlen(sym_name) < 5) return 0;
}
}
return 0;
@@ -2261,28 +2920,28 @@ push(YYSTYPE *res, YYSTYPE *val)
{
if(val->a_data) {
if(!(res->a_data)) {
- if(!(val->a_data=(double*)realloc(val->a_data, (val->a_count+2)*sizeof(double))))return 0;
+ if(!(val->a_data=ReallocArray(val->a_data, (val->a_count+2)*sizeof(double))))return 0;
val->a_data[val->a_count++] = res->val;
res->a_data = val->a_data; res->a_count = val->a_count;
val->a_data = 0L; val->a_count = 0;
val->val = res->val; return 1;
}
else {
- if(!(res->a_data=(double*)realloc(res->a_data, (val->a_count+res->a_count)*sizeof(double))))return 0;
+ if(!(res->a_data=ReallocArray(res->a_data, (val->a_count+res->a_count)*sizeof(double))))return 0;
memcpy(&res->a_data[res->a_count], val->a_data, val->a_count*sizeof(double));
- res->a_count += val->a_count; free(val->a_data);
+ res->a_count += val->a_count;
val->a_data = 0L; val->a_count = 0;
return 1;
}
}
if(!(res->a_data )){
- if(!(res->a_data = (double*)malloc(2*sizeof(double))))return 0;
+ if(!(res->a_data = PushArray((double*)malloc(2*sizeof(double)))))return 0;
res->a_data[0] = res->val; res->a_data[1] = val->val;
res->a_count = 2;
return 1;
}
else {
- if(!(res->a_data = (double*)realloc(res->a_data, (res->a_count+2)*sizeof(double))))return 0;
+ if(!(res->a_data = ReallocArray(res->a_data, (res->a_count+2)*sizeof(double))))return 0;
res->a_data[res->a_count] = val->val; res->a_count++;
return 1;
}
@@ -2297,7 +2956,7 @@ range_array(YYSTYPE * res, char *range)
anyResult ares;
if(!range || !range[0] || !(r = new AccRange(range))) return 0;
- if(!r->GetFirst(&col, &row) || !(res->a_data = (double*)malloc(r->CountItems() * sizeof(double)))) {
+ if(!r->GetFirst(&col, &row) || !(res->a_data = PushArray((double*)malloc(r->CountItems() * sizeof(double))))) {
delete(r);
return 0;
}
@@ -2305,15 +2964,9 @@ range_array(YYSTYPE * res, char *range)
for(res->a_count = 0; r->GetNext(&col, &row); ) {
if(curr_data->GetResult(&ares, row, col, parse_level > MAX_PARSE)) {
switch(ares.type) {
- case ET_VALUE:
+ case ET_VALUE: case ET_TIME: case ET_DATE: case ET_DATETIME: case ET_BOOL:
res->a_data[res->a_count++] = ares.value;
break;
- case ET_TEXT:
- if(ares.text && ares.text[0]) last_err_desc = "#ARGS";
- break;
- case ET_ERROR:
- last_err_desc = "#ARGS";
- break;
}
}
}
@@ -2322,6 +2975,40 @@ range_array(YYSTYPE * res, char *range)
return 1;
}
+static int
+range_array2(YYSTYPE *res1, YYSTYPE *res2)
+{
+ AccRange *r1, *r2;
+ int row1, col1, row2, col2;
+ anyResult ares1, ares2;
+ char *range1, *range2;
+
+ range1 = res1->text; range2 = res2->text;
+ if(!range1 || !range1[0] || !range2 || !range2[0] || !(r1 = new AccRange(range1))
+ || !(r2 = new AccRange(range2))) return 0;
+ if(!r1->GetFirst(&col1, &row1) || !(res1->a_data = PushArray((double*)malloc(r1->CountItems() * sizeof(double))))) {
+ delete(r1); delete(r2);
+ return 0;
+ }
+ if(!r2->GetFirst(&col2, &row2) || !(res2->a_data = PushArray((double*)malloc(r2->CountItems() * sizeof(double))))) {
+ delete(r1); delete(r2);
+ return 0;
+ }
+ parse_level++;
+ for(res1->a_count = res2->a_count = 0; r1->GetNext(&col1, &row1) && r2->GetNext(&col2, &row2); ) {
+ if(curr_data->GetResult(&ares1, row1, col1, parse_level > MAX_PARSE)
+ && curr_data->GetResult(&ares2, row2, col2, parse_level > MAX_PARSE)
+ && (ares1.type==ET_VALUE || ares1.type==ET_TIME || ares1.type==ET_DATE || ares1.type==ET_DATETIME || ares1.type==ET_BOOL)
+ && (ares2.type==ET_VALUE || ares2.type==ET_TIME || ares2.type==ET_DATE || ares2.type==ET_DATETIME || ares2.type==ET_BOOL)){
+ res1->a_data[res1->a_count++] = ares1.value;
+ res2->a_data[res2->a_count++] = ares2.value;
+ }
+ }
+ parse_level--;
+ delete(r1); delete(r2);
+ return 1;
+}
+
static YYSTYPE *proc_clause(YYSTYPE *res)
{
int i, n, o_pos;
@@ -2330,12 +3017,12 @@ static YYSTYPE *proc_clause(YYSTYPE *res)
if(!(syntax_level) || !syntax_level->cl1 || syntax_level->cl2 <= syntax_level->cl1) return res;
if(!res->text) return res;
- if(!res->a_data && (res->a_data = (double*)malloc(sizeof(double)))) {
+ if(!res->a_data && (res->a_data = PushArray((double*)malloc(sizeof(double))))) {
res->a_data[0] = res->type == VAR && res->tptr ? res->tptr->GetValue() : res->val;
res->a_count = 1;
}
else if(!res->a_data) return res;
- if(!(n_data = (double*)malloc(res->a_count * sizeof(double)))) return res;
+ if(!(n_data = PushArray((double*)malloc(res->a_count * sizeof(double))))) return res;
o_pos = buff_pos; o_cmd = buffer;
for(i = n = 0; i < res->a_count; i++) {
buffer = res->text; buff_pos = 0;
@@ -2344,8 +3031,8 @@ static YYSTYPE *proc_clause(YYSTYPE *res)
yyparse();
if(line_res.type == ET_VALUE && line_res.value != 0.0) n_data[n++] = res->a_data[i];
}
- free(res->a_data); res->a_data = n_data; res->a_count = n;
- free(res->text); res->text=0L;
+ res->a_data = n_data; res->a_count = n;
+ res->text=0L;
syntax_level->cl1 = syntax_level->cl2 = 0;
buffer = o_cmd; buff_pos = o_pos;
return res;
@@ -2356,6 +3043,13 @@ static void exec_clause(YYSTYPE *res)
int i, j;
char *cmd;
+ if((!res->a_data || res->a_count <2) && res->text && res->text[0]) range_array(res, res->text);
+ if(!res->a_data) {
+ if(res->a_data = PushArray((double*)malloc(2*sizeof(double)))) {
+ res->a_data[0] = res->val; res->a_count = 1;
+ InfoBox("fixed data");
+ }
+ }
if(!(syntax_level) || !syntax_level->cl1 || syntax_level->cl2 <= syntax_level->cl1) return;
if(!(cmd = (char*)malloc(syntax_level->cl2 - syntax_level->cl1 +2)))return;
while(buffer[syntax_level->cl1] <= ' ' && syntax_level->cl1 < syntax_level->cl2) syntax_level->cl1++;
@@ -2363,7 +3057,8 @@ static void exec_clause(YYSTYPE *res)
cmd[j++] = buffer[i];
}
cmd[j++] = ';'; cmd[j++] = 0;
- res->text = cmd;
+ res->text = PushString(cmd);
+ free(cmd);
}
struct parse_info {
@@ -2374,8 +3069,9 @@ struct parse_info {
YYSTYPE yylval;
struct parse_info *next;
char **str_list;
+ double **arr_list;
char *last_err_desc;
- int n_str, yychar, yynerrs;
+ int n_str, n_arr, yychar, yynerrs;
};
static parse_info *parse_stack = 0L;
@@ -2393,6 +3089,8 @@ static void push_parser()
ptr->next = parse_stack;
ptr->str_list = str_list; str_list = 0L;
ptr->n_str = n_str; n_str = 0;
+ ptr->arr_list = arr_list; arr_list = 0L;
+ ptr->n_arr = n_arr; n_arr = 0;
ptr->yychar = yychar; ptr->yynerrs = yynerrs;
parse_stack = ptr; last_err_desc = 0L;
parse_level++; //reenter ?
@@ -2416,6 +3114,7 @@ static void pop_parser()
curr_data = ptr->curr_data; last_err_desc = ptr->last_err_desc;
memcpy(&yylval, &ptr->yylval, sizeof(YYSTYPE));
str_list = ptr->str_list; n_str = ptr->n_str;
+ arr_list = ptr->arr_list; n_arr = ptr->n_arr;
yychar = ptr->yychar; yynerrs = ptr->yynerrs;
free(ptr);
parse_level--;
@@ -2423,17 +3122,39 @@ static void pop_parser()
pop_syntax();
}
-static int is_ttoken(int h_nam)
+static int is_ttoken(unsigned int h_nam, unsigned int h2_nam)
{
switch(h_nam) {
- case 101: return E;
- case 26992: return PI;
+ case 69:
+ if(h2_nam == 101) return E;
+ break;
+ case 393:
+ if(h2_nam == 47081) return PI;
+ break;
case 28381:
- if(syntax_level) syntax_level->cl1 = buff_pos;
- return CLAUSE;
- case 9252: return CLVAL;
- case 26217: return IF;
- case 6033: return ELSE;
+ if((h2_nam & 0x7fffffff) == 0x7c2706ed) {
+ if(syntax_level) syntax_level->cl1 = buff_pos;
+ return CLAUSE;
+ }
+ break;
+ case 20:
+ if(h2_nam == 5220) return CLVAL;
+ break;
+ case 362:
+ if(h2_nam == 42878) return IF;
+ break;
+ case 1457:
+ if(h2_nam == 18357885) return DIM;
+ break;
+ case 6033:
+ if((h2_nam & 0x7fffffff) == 0x6371377d) return ELSE;
+ break;
+ case 7097:
+ if((h2_nam & 0x7fffffff) == 0x550a2d65) return BTRUE;
+ break;
+ case 23697:
+ if((h2_nam & 0x7fffffff) == 0x155f977d) return BFALSE;
+ break;
}
return 0;
}
@@ -2442,7 +3163,7 @@ static symrec *curr_sym;
static int yylex (void)
{
int i, c, tok;
- unsigned int h_nam;
+ unsigned int h_nam, h2_nam;
char tmp_txt[80];
symrec *s;
@@ -2487,10 +3208,10 @@ static int yylex (void)
}
tmp_txt[i] = 0;
h_nam = HashValue((unsigned char*)tmp_txt);
- if(tok = is_ttoken(h_nam))
- return tok;
- if(!(s = getsym(h_nam, tmp_txt))){
- s = putsym(h_nam, VAR);
+ h2_nam = Hash2((unsigned char*)tmp_txt);
+ if(tok = is_ttoken(h_nam, h2_nam)) return tok;
+ if(!(s = getsym(h_nam, h2_nam, tmp_txt))){
+ s = putsym(h_nam, h2_nam, VAR);
s->SetName(tmp_txt);
}
@@ -2568,6 +3289,13 @@ static int yylex (void)
return c;
}
+static unsigned int hn_x = HashValue((unsigned char *)"x");
+static unsigned int hn_y = HashValue((unsigned char *)"y");
+static unsigned int hn_z = HashValue((unsigned char *)"z");
+static unsigned int h2_x = Hash2((unsigned char *)"x");
+static unsigned int h2_y = Hash2((unsigned char *)"y");
+static unsigned int h2_z = Hash2((unsigned char *)"z");
+
bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOINT **pts, long *npts, char *param)
{
double x, y;
@@ -2575,8 +3303,6 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
lfPOINT *new_points;
long npoints = 0;
int length, res_mode = 0;
- unsigned int hn_x = HashValue((unsigned char *)"x");
- unsigned int hn_y = HashValue((unsigned char *)"y");
if(x1 < x2) step = fabs(step);
else step = -fabs(step);
@@ -2599,7 +3325,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
free(buffer); buffer = 0L;
}
length = strlen(expr);
- buffer = expr; sx = putsym(hn_x, VAR);
+ buffer = expr; sx = putsym(hn_x, h2_x, VAR);
for(x = x1; step > 0.0 ? x <= x2 : x >= x2; x += step) {
if(sx){
sx->SetValue(x); buff_pos = 0;
@@ -2612,7 +3338,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
case 2:
y = line_res.value; break;
default:
- if(sy = getsym(hn_y)) {
+ if(sy = getsym(hn_y, h2_y)) {
y = sy->GetValue(); res_mode = 1;
}
else {
@@ -2620,7 +3346,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
}
break;
}
- new_points[npoints].fx = (getsym(hn_x))->GetValue();
+ new_points[npoints].fx = (getsym(hn_x, h2_x))->GetValue();
new_points[npoints++].fy = y;
}
}
@@ -2640,9 +3366,6 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
int length, nr, nc, r, c, res_mode=0;
symrec *sx, *sz, *sy;
double x, y, z;
- unsigned int hn_x = HashValue((unsigned char *)"x");
- unsigned int hn_y = HashValue((unsigned char *)"y");
- unsigned int hn_z = HashValue((unsigned char *)"z");
if(!d || x2 <= x1 || z2 <= z1 || xstep <= 0.0 || zstep <= 0.0) return false;
push_parser();
@@ -2661,7 +3384,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
free(buffer); buffer = 0L;
}
length = strlen(expr); buffer = expr;
- sx = putsym(hn_x, VAR); sz = putsym(hn_z, VAR);
+ sx = putsym(hn_x, h2_x, VAR); sz = putsym(hn_z, h2_z, VAR);
nr = iround((z2-z1)/zstep)+1; nc = iround((x2-x1)/xstep)+1;
d->Init(nr, nc);
for(r = 0, x = x1; r < nr; r++, x += xstep) {
@@ -2676,7 +3399,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
case 2:
y = line_res.value; break;
default:
- if(sy = getsym(hn_y)) {
+ if(sy = getsym(hn_y, h2_y)) {
y = sy->GetValue(); res_mode = 1;
}
else {
@@ -2699,7 +3422,10 @@ anyResult *do_formula(DataObj *d, char *expr)
if(d) curr_data = d;
ret.type = ET_ERROR; ret.text = 0L;
- if(!expr || !expr[0]) return &ret;
+ if(!expr || !expr[0]) {
+ if(!sym_table) InitArithFuncs(0L);
+ return &ret;
+ }
push_parser(); //make code reentrant
init_table(); length = strlen(expr);
if(!(buffer = (char*)malloc(length+2))){
@@ -2751,7 +3477,8 @@ bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
case NUM:
pos += sprintf(res+pos, "%g", yylval.val);
break;
- case FNCT: case FUNC2: case AFNCT: case SFNCT:
+ case FNCT: case FUNC1: case FUNC2: case FUNC3: case AFNCT:
+ case SFNCT: case SRFUNC: case BFNCT: case YYFNC: case FUNC4:
pos += sprintf(res+pos, "%s", curr_sym->name);
break;
case COLR: case COLC:
@@ -2799,6 +3526,12 @@ bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
case E:
pos += sprintf(res+pos, "e");
break;
+ case BTRUE:
+ pos += sprintf(res+pos, "true");
+ break;
+ case BFALSE:
+ pos += sprintf(res+pos, "false");
+ break;
case AND:
pos += sprintf(res+pos, " && ");
break;
@@ -2848,20 +3581,20 @@ static void fcurve(double x, double z, double **a, double *y, double dyda[], int
{
int i, length;
double tmp, y1, y2;
- symrec *symx, *sy=0L;
- unsigned int hn_x = HashValue((unsigned char *)"x");
- unsigned int hn_y = HashValue((unsigned char *)"y");
+ symrec *symx, *symz, *sy=0L;
- if(!(symx = getsym(hn_x))) symx = putsym(hn_x, VAR);
+ if(!(symx = getsym(hn_x, h2_x))) symx = putsym(hn_x, h2_x, VAR);
+ if(!(symz = getsym(hn_z, h2_z))) symz = putsym(hn_z, h2_z, VAR);
//swap parameters to requested set
if(a != parval) for(i = 0; i < ma; i++) {
tmp = *parval[i]; *parval[i] = *a[i]; *a[i] = tmp;
}
//calc result
- symx->SetValue(x); buffer = txt_formula;
+ symx->SetValue(x); symz->SetValue(z);
+ buffer = txt_formula;
buff_pos = 0; length = strlen(txt_formula);
do { yyparse(); }while(buff_pos < length);
- if(sy = getsym(hn_y)) *y = sy->GetValue();
+ if(sy = getsym(hn_y, h2_y)) *y = sy->GetValue();
else *y = line_res.value;
if(*y == HUGE_VAL || *y == -HUGE_VAL) {
for(i = 0, *y = 0.0; i < ma; dyda[i++] = 0.0);
@@ -2921,7 +3654,7 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
if(arz) delete arz;
free(x); delete arx; delete ary; return 0;
}
- if(rz && !(y = (double*)malloc(i * sizeof(double)))){
+ if(rz && !(z = (double*)malloc(i * sizeof(double)))){
if(arz) delete arz;
free(y); free(x); delete arx; delete ary; return 0;
}
@@ -3015,29 +3748,3 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
return itst < maxiter ? itst+1 : maxiter;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/mfcalc.y b/mfcalc.y
index 1ce5db4..eb6fb73 100755
--- a/mfcalc.y
+++ b/mfcalc.y
@@ -1,6 +1,6 @@
%{
/*
- mfcalc.y, mfcalc.cpp, Copyright (c) 2004, 2005 R.Lackner
+ mfcalc.y, mfcalc.cpp, Copyright (c) 2004, 2005, 2006 R.Lackner
parse string and simple math: based on the bison 'mfcalc' example
This file is part of RLPlot.
@@ -28,14 +28,14 @@
class symrec {
public:
- int type, row, col;
- unsigned int h_name;
+ int type, row, col, a_count;
+ unsigned int h_name, h2_name;
char *name, *text;
double (*fnctptr)(...);
symrec *next;
- double var;
+ double var, *a_data;
- symrec(unsigned int h_n, int typ, symrec *nxt);
+ symrec(unsigned int h_n, unsigned int h2_n, int typ, symrec *nxt);
~symrec();
double GetValue();
void GetValue(void *res);
@@ -69,18 +69,22 @@ typedef struct{
}YYSTYPE;
-static symrec *putsym (unsigned int h_name, int sym_type);
-static symrec *getsym (unsigned int h_name, char *sym_name = 0L);
+static symrec *putsym (unsigned int h_name, unsigned int h2_name, int sym_type);
+static symrec *getsym (unsigned int h_name, unsigned int h2_name, char *sym_name = 0L);
static int push(YYSTYPE *res, YYSTYPE *val);
static void store_res(YYSTYPE *res);
static char *PushString(char *text);
+static double *PushArray(double *arr);
+static double *ReallocArray(double *arr, int size);
static char *add_strings(char *st1, char *st2);
static char *string_value(YYSTYPE *exp);
-static double eval(YYSTYPE *sr, YYSTYPE *dst);
+static double eval(YYSTYPE *sr, YYSTYPE *dst, char* dum);
static int range_array(YYSTYPE * res, char *range);
+static int range_array2(YYSTYPE *res1, YYSTYPE *res2);
static void exec_clause(YYSTYPE *res);
static YYSTYPE *proc_clause(YYSTYPE *res);
static void yyerror(char *s);
+static void make_time(YYSTYPE *dst, double h, double m, double s);
static int yylex(void);
static double nop() {return 0.0;};
@@ -97,9 +101,10 @@ static int parse_level = 0; //count reentrances into parser
#define MAX_PARSE 20 //maximum number of reentances
%}
-%token <val> NUM STR ARR BLOCK PI E CLVAL PSEP IF ELSE
-%token <tptr> VAR FNCT AFNCT SFNCT FUNC2 TXT
-%type <val> exp str_exp arr
+%token <val> NUM BOOLVAL STR ARR BLOCK PI E CLVAL PSEP IF ELSE BTRUE BFALSE
+%token <val> DATE1 TIME1 DATETIME1 DIM
+%token <tptr> VAR FNCT BFNCT AFNCT SFNCT FUNC1 FUNC2 FUNC3 TXT SRFUNC YYFNC FUNC4
+%type <val> exp str_exp arr bool
%right '='
%left ',' /* list separator */
@@ -111,9 +116,11 @@ static int parse_level = 0; //count reentrances into parser
%left EQ NE GT GE LT LE
%left '-' '+'
%left '*' '/'
+%left '['
%left NEG /* negation-unary minus */
%left INC DEC /* increment, decrement */
%left PINC PDEC /* pre- increment, decrement */
+%left PDIM /* dimension array */
%right '^' /* exponentiation */
/* Grammar follows */
@@ -133,58 +140,92 @@ line: '\n' | ';' | ','
str_exp:
STR {;}
- |str_exp '+' exp {yyval.text=add_strings(yyvsp[-2].text, string_value(&yyvsp[0]));}
- |exp '+' str_exp {yyval.text=add_strings(string_value(&yyvsp[-2]), yyvsp[0].text);}
- |str_exp '+' str_exp {yyval.text=add_strings(yyvsp[-2].text, yyvsp[0].text);}
+ |str_exp '+' exp {yyval.text=add_strings(yyvsp[-2].text, string_value(&yyvsp[0])); yyval.type = STR;}
+ |exp '+' str_exp {yyval.text=add_strings(string_value(&yyvsp[-2]), yyvsp[0].text); yyval.type = STR;}
+ |str_exp '+' str_exp {yyval.text=add_strings(yyvsp[-2].text, yyvsp[0].text); yyval.type = STR;}
+ |SRFUNC '(' exp ')' {(($1->fnctptr)(&yyval, &yyvsp[-1], 0L)); yyval.type = STR;}
+ |SRFUNC '(' exp PSEP str_exp ')' {(($1->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;}
+ |SRFUNC '(' exp PSEP exp ')' {(($1->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;}
+ |SRFUNC '(' exp ',' str_exp ')' {(($1->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;}
+ |SRFUNC '(' exp ',' exp ')' {(($1->fnctptr)(&yyval, &yyvsp[-3], yyvsp[-1].text)); yyval.type = STR;}
;
range:
- str_exp {;}
- |VAR COLR VAR {if(yyval.text =(char*)malloc(strlen($1->name) +strlen($3->name) + 2)) sprintf(yyval.text, "%s:%s", $1->name, $3->name);}
+ str_exp {;}
+ |VAR COLR VAR {if(yyval.text = PushString((char*)malloc(strlen($1->name) +strlen($3->name) + 2))) sprintf(yyval.text, "%s:%s", $1->name, $3->name);}
;
arr: ARR
- |exp {if(!yyval.a_data) {yyval.a_data = (double*)malloc(sizeof(double)); yyval.a_count = 1; yyval.a_data[0] = yyval.val;}}
- |arr ',' arr {push(&yyval, &yyvsp[0]);}
- |arr CLAUSE exp {exec_clause(&yyval);}
- |range {range_array(&yyval, yyvsp[0].text);}
- |NUM SER NUM {if($1 < $3 && (yyval.a_data = (double*)malloc((int)($3-$1+2)*sizeof(double))))
- for(yyval.a_count=0; $1<=$3; yyval.a_data[yyval.a_count++] = $1, $1 += 1.0 );}
+ |exp {if(!yyval.a_data) {yyval.a_data = PushArray((double*)malloc(sizeof(double))); yyval.a_count = 1; yyval.a_data[0] = yyval.val;}}
+ |arr ',' arr {push(&yyval, &yyvsp[0]);yyval.type = ARR;}
+ |arr CLAUSE exp {exec_clause(&yyval);yyval.type = ARR;}
+ |range {range_array(&yyval, yyvsp[0].text);yyval.type = ARR;}
+ |NUM SER NUM {if($1 < $3 && (yyval.a_data = PushArray((double*)malloc((int)($3-$1+2)*sizeof(double)))))
+ for(yyval.a_count=0; $1<=$3; yyval.a_data[yyval.a_count++] = $1, $1 += 1.0 ); yyval.type = ARR;}
+;
+
+bool: BOOLVAL
+ |BFNCT '(' exp ')' {$$ = (($1->fnctptr)($3)); yyval.type = BOOLVAL;}
+ |BTRUE {$$ = 1.0; yyval.type = BOOLVAL;}
+ |BFALSE {$$ = 0.0; yyval.type = BOOLVAL;}
+ |exp AND exp {$$ = (($1 != 0) && ($3 != 0))? 1 : 0; yyval.type = BOOLVAL;}
+ |exp OR exp {$$ = (($1 != 0) || ($3 != 0))? 1 : 0; yyval.type = BOOLVAL;}
+ |exp EQ exp {$$ = ($1 == $3) ? 1 : 0; yyval.type = BOOLVAL;}
+ |exp NE exp {$$ = ($1 != $3) ? 1 : 0; yyval.type = BOOLVAL;}
+ |exp GT exp {$$ = ($1 > $3) ? 1 : 0; yyval.type = BOOLVAL;}
+ |exp GE exp {$$ = ($1 >= $3) ? 1 : 0; yyval.type = BOOLVAL;}
+ |exp LT exp {$$ = ($1 < $3) ? 1 : 0; yyval.type = BOOLVAL;}
+ |exp LE exp {$$ = ($1 <= $3) ? 1 : 0; yyval.type = BOOLVAL;}
;
exp: NUM {$$ = $1; yyval.type = NUM;}
+ |bool {$$ = $1; yyval.type = BOOLVAL;}
|TXT {$$ = 0.0;}
- |CLVAL {$$ = syntax_level ? syntax_level->clval : 0.0; }
+ |CLVAL {$$ = syntax_level ? syntax_level->clval : 0.0; yyval.type = NUM;}
|PI {$$ = _PI; yyval.type = NUM;}
|E {$$ = 2.71828182845905; yyval.type = NUM;}
|VAR {$1->GetValue(&yyval);}
- |BLOCK {eval(&yyvsp[0], &yyval);}
+ |BLOCK {eval(&yyvsp[0], &yyval, 0L);}
|VAR '=' exp {$1->SetValue(&yyval, &yyvsp[0]);}
|VAR '=' str_exp {$1->SetValue(&yyval, &yyvsp[0]);}
- |FNCT '(' exp ')' {$$ = (($1->fnctptr)($3));}
- |AFNCT '(' arr ')' {$$ = (($1->fnctptr)(proc_clause(&yyvsp[-1])));}
- |AFNCT '(' exp PSEP exp ')' {push(&yyvsp[-2], &yyvsp[0]); $$ = (($1->fnctptr)(&yyvsp[-2]));}
- |AFNCT '(' exp PSEP exp PSEP exp ')' {push(&yyvsp[-4], &yyvsp[-2]); push(&yyvsp[-4], &yyvsp[0]); $$ = (($1->fnctptr)(&yyvsp[-4]));}
- |SFNCT '(' str_exp ')' {$$ = (($1->fnctptr)(&yyvsp[-1], &yyval));}
- |SFNCT '(' exp ')' {yyvsp[-1].text = string_value(&yyvsp[-1]); $$ = (($1->fnctptr)(&yyvsp[-1], &yyval));}
- |FUNC2 '(' arr PSEP arr ')' {$$ = ((*$1->fnctptr)(proc_clause(&yyvsp[-3]), proc_clause(&yyvsp[-1]), 0L));}
- |FUNC2 '(' arr PSEP arr PSEP range')'
- {$$ = ((*$1->fnctptr)(proc_clause(&yyvsp[-5]), proc_clause(&yyvsp[-3]), yyvsp[-1].text));}
- |IF '(' exp ')' BLOCK {$$ = $3 != 0 ? eval(&yyvsp[0], &yyval) : 0.0;}
- |IF '(' exp ')' BLOCK ELSE BLOCK {$$ = $3 != 0 ? eval(&yyvsp[-2], &yyval) : eval(&yyvsp[0], &yyval);}
- |exp AND exp {$$ = (($1 != 0) && ($3 != 0))? 1 : 0;}
- |exp OR exp {$$ = (($1 != 0) || ($3 != 0))? 1 : 0;}
- |exp EQ exp {$$ = ($1 == $3) ? 1 : 0;}
- |exp NE exp {$$ = ($1 != $3) ? 1 : 0;}
- |exp GT exp {$$ = ($1 > $3) ? 1 : 0;}
- |exp GE exp {$$ = ($1 >= $3) ? 1 : 0;}
- |exp LT exp {$$ = ($1 < $3) ? 1 : 0;}
- |exp LE exp {$$ = ($1 <= $3) ? 1 : 0;}
- |exp '+' exp {$$ = $1 + $3;}
- |exp '-' exp {$$ = $1 - $3;}
- |exp '*' exp {$$ = $1 * $3;}
- |exp '/' exp {if($3 != 0.0) $$ = $1 / $3;
- else $$ = (getsym(HashValue((unsigned char*)"zdiv")))->GetValue(); }
+ |FNCT '(' exp ')' {$$ = (($1->fnctptr)($3)); yyval.type = NUM;}
+ |AFNCT '(' arr ')' {$$ = (($1->fnctptr)(proc_clause(&yyvsp[-1]))); yyval.type = NUM;}
+ |AFNCT '(' exp PSEP arr ')' { if(!yyval.a_data){yyval.a_data=PushArray((double*)malloc(sizeof(double)));yyval.a_data[0]=$3;yyval.a_count=1;}
+ push(&yyval, &yyvsp[-1]);$$ = (($1->fnctptr)(&yyval)); yyval.type = NUM;}
+ |AFNCT '(' exp PSEP exp PSEP exp ')' { yyval.a_data = PushArray((double*)malloc(3*sizeof(double)));
+ yyval.a_count = 3; yyval.a_data[0] = $3; yyval.a_data[1] = $5; yyval.a_data[2] = $7;
+ $$ = (($1->fnctptr)(&yyval)); yyval.type = NUM;}
+ |SFNCT '(' str_exp ')' {$$ = (($1->fnctptr)(&yyvsp[-1], &yyval, 0L)); yyval.type = NUM;}
+ |SFNCT '(' exp ')' {yyvsp[-1].text = string_value(&yyvsp[-1]); $$ = (($1->fnctptr)(&yyvsp[-1], &yyval, 0L)); yyval.type = NUM;}
+ |SFNCT '(' str_exp PSEP str_exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |SFNCT '(' exp PSEP str_exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |SFNCT '(' exp PSEP exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |SFNCT '(' str_exp PSEP exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |SFNCT '(' str_exp ',' str_exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |SFNCT '(' exp ',' str_exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |SFNCT '(' str_exp ',' exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |SFNCT '(' exp ',' exp ')' {$$ = (($1->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;}
+ |FUNC2 '(' range PSEP range ')' {range_array2(&yyvsp[-3], &yyvsp[-1]);$$ = ((*$1->fnctptr)(&yyvsp[-3], &yyvsp[-1], 0L)); yyval.type = NUM;}
+ |FUNC2 '(' range PSEP range PSEP range ')' {range_array2(&yyvsp[-5], &yyvsp[-3]); $$ = ((*$1->fnctptr)(&yyvsp[-5], &yyvsp[-3], yyvsp[-1].text)); yyval.type = NUM;}
+ |FUNC3 '(' arr PSEP arr ')' {$$=((*$1->fnctptr)(proc_clause(&yyvsp[-3]), proc_clause(&yyvsp[-1]), 0L));}
+ |FUNC3 '(' arr PSEP arr PSEP range ')' {$$=((*$1->fnctptr)(proc_clause(&yyvsp[-5]), proc_clause(&yyvsp[-3]), yyvsp[-1].text));}
+ |FUNC4 '(' exp PSEP exp PSEP arr PSEP range ')' {proc_clause(&yyvsp[-3]); $$=(*$1->fnctptr)($3, $5, &yyvsp[-3], &yyvsp[-1]); yyval.type = NUM;}
+ |FUNC1 '(' arr PSEP range ')' {$$ = ((*$1->fnctptr)(proc_clause(&yyvsp[-3]), yyvsp[-1].text)); yyval.type = NUM;}
+ |YYFNC '(' ')' {(*$1->fnctptr)(&yyval, 0L);}
+ |YYFNC '(' arr ')' {(*$1->fnctptr)(&yyval, &yyvsp[-1]);}
+ |IF '(' exp ')' BLOCK {$$ = $3 != 0 ? eval(&yyvsp[0], &yyval, 0L) : 0.0;}
+ |IF '(' exp ')' BLOCK ELSE BLOCK {$$ = $3 != 0.0 ? eval(&yyvsp[-2], &yyval, 0L) : eval(&yyvsp[0], &yyval, 0L);}
+ |exp '+' exp {$$ = $1 + $3; yyval.type = NUM;
+ if(yyvsp[0].type == DATE1 || yyvsp[-2].type == DATE1) yyval.type = DATE1;
+ else if(yyvsp[0].type == TIME1 || yyvsp[-2].type == TIME1) yyval.type = TIME1;
+ else if(yyvsp[0].type == DATETIME1 || yyvsp[-2].type == DATETIME1) yyval.type = DATETIME1;}
+ |exp '-' exp {$$ = $1 - $3; yyval.type = NUM;
+ if(yyvsp[0].type == DATE1 || yyvsp[-2].type == DATE1) yyval.type = DATE1;
+ else if(yyvsp[0].type == TIME1 || yyvsp[-2].type == TIME1) yyval.type = TIME1;
+ else if(yyvsp[0].type == DATETIME1 || yyvsp[-2].type == DATETIME1) yyval.type = DATETIME1;}
+ |exp '*' exp {$$ = $1 * $3; yyval.type = NUM;}
+ |exp '/' exp {yyval.type = NUM; if($3 != 0.0) $$ = $1 / $3;
+ else $$ = (getsym(HashValue((unsigned char*)"zdiv"), Hash2((unsigned char*)"zdiv")))->GetValue(); }
|'-' exp %prec NEG {$$ = -$2;}
|VAR INC {$$=$1->GetValue(); $1->SetValue($$+1.0); $$ -= 1.0; yyval.type = NUM;}
|VAR DEC {$$=$1->GetValue(); $1->SetValue($$-1.0); $$ += 1.0; yyval.type = NUM;}
@@ -192,6 +233,16 @@ exp: NUM {$$ = $1; yyval.type = NUM;}
|DEC VAR %prec PDEC {$$=$2->GetValue(); $2->SetValue($$-1.0); yyval.type = NUM;}
|exp '^' exp {$$ = pow($1, $3);}
|'(' arr ')' {memcpy(&yyval, &yyvsp[-1], sizeof(YYSTYPE)); yyvsp[-1].a_data = 0L; yyvsp[-1].a_count = 0;}
+ |DIM VAR %prec PDIM '[' exp ']' {yyval.a_data = PushArray((double*)calloc((int)$4, sizeof(double))); yyval.a_count=(int)($4);
+ yyval.type = ARR; $2->SetValue(&yyval,&yyval);}
+ |exp '[' exp ']' {if(yyvsp[-3].a_data && yyvsp[-1].val >= 0.0 && yyvsp[-1].val < yyvsp[-3].a_count) $$ = yyvsp[-3].a_data[(int)yyvsp[-1].val];
+ else {$$ = 0.0; last_err_desc = "#INDEX";} yyval.type = NUM;}
+ |exp '[' exp ']' '=' exp {if(yyvsp[-5].a_data && yyvsp[-3].val >= 0.0 && yyvsp[-3].val < yyvsp[-5].a_count) $$ = yyvsp[-5].a_data[(int)yyvsp[-3].val] = $6;
+ else {$$ = 0.0; last_err_desc = "#INDEX";} yyval.type = NUM;}
+ |NUM COLR NUM COLR NUM {make_time(&yyval, $1, $3, $5+1.0e-10);}
+ |NUM ':' NUM ':' NUM {make_time(&yyval, $1, $3, $5+1.0e-10);}
+ |NUM COLR NUM {make_time(&yyval, $1, $3, 1.0e-10);}
+ |NUM ':' NUM {make_time(&yyval, $1, $3, 1.0e-10);}
|exp '?' exp COLC exp {memcpy(&yyval, $1 != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE))}
|exp '?' STR COLC STR {memcpy(&yyval, $1 != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE))}
|exp '?' STR COLC exp {memcpy(&yyval, $1 != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE))}
@@ -200,15 +251,12 @@ exp: NUM {$$ = $1; yyval.type = NUM;}
%%
// The symrec class
-symrec::symrec(unsigned int h_n, int typ, symrec *nxt)
-{
- h_name = h_n;
- type = typ;
- next = nxt;
- row = col = -1;
- name = text = 0L;
- var = 0.0;
- isSSval = false;
+symrec::symrec(unsigned int h_n, unsigned int h2_n, int typ, symrec *nxt)
+{
+ h_name = h_n; h2_name = h2_n; type = typ;
+ next = nxt; row = col = -1; name = text = 0L;
+ var = 0.0; isSSval = false;
+ a_data = 0L; a_count = 0;
fnctptr = (double (*)(...))nop;
}
@@ -247,18 +295,29 @@ symrec::GetValue(void *re)
//GetResult( , , ,true) inhibits reentrance into parser !
if(curr_data->GetResult(&ares, row, col, parse_level > MAX_PARSE)){
if(text) free(text); text = 0L;
- if(ares.type == ET_VALUE) {
- res->type = VAR; res->val = ares.value;
- res->text = 0L;
- }
- else if(ares.type == ET_TEXT && ares.text) {
+ switch(ares.type) {
+ case ET_VALUE:
+ res->type = NUM; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_BOOL:
+ res->type = BOOLVAL; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_DATE:
+ res->type = DATE1; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_TIME:
+ res->type = TIME1; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_DATETIME:
+ res->type = DATETIME1; res->val = ares.value;
+ res->text = 0L; break;
+ case ET_TEXT:
res->type = STR; res->val = 0.0;
- text = strdup(ares.text);
- res->text = text;
- }
- else {
+ if(ares.text) res->text = PushString(text = strdup(ares.text));
+ else res->text = 0L; break;
+ default:
res->type = NUM; res->val = var;
- res->text = 0L;
+ res->text = 0L; break;
}
var = res->val;
return;
@@ -266,15 +325,18 @@ symrec::GetValue(void *re)
isSSval = false;
row = col = -1;
}
- if(text && text[0]) {
- res->text = strdup(text);
+ if(a_data && a_count) {
+ res->a_data = a_data; res->a_count = a_count;
+ res->val = 0.0; res->type = ARR;
+ }
+ else if(text && text[0]) {
+ res->text = PushString(text);
res->val = var; res->type = STR;
}
else {
res->type = NUM; res->val = var;
res->text = 0L;
}
- res->a_data = 0L; res->a_count = 0L;
}
double
@@ -289,6 +351,7 @@ symrec::SetValue(double v)
isSSval = false;
row = col = -1;
}
+ a_data = 0L; a_count = 0;
return var = v;
}
@@ -310,6 +373,7 @@ symrec::SetValue(void* d, void* s)
var = src->val;
if(text) free(text); text = 0L;
if(src->text && src->text[0]) text = strdup(src->text);
+ a_data = src->a_data; a_count = src->a_count;
GetValue(d);
return;
}
@@ -347,6 +411,15 @@ static void yyargserr(char *s)
last_err_desc = "#ARGS";
}
+static void make_time(YYSTYPE *dst, double h, double m, double s)
+{
+ if(!dst || h < 0.0 || 24.0 < h || m < 0.0 || 60.0 < m || s < 0.0 || 60.0 < s) {
+ yyerror("parse error"); return;
+ }
+ dst->val = s/60.0 + m; dst->val = dst->val/60.0 + h;
+ dst->val /= 24.0; dst->type = TIME1;
+}
+
static void store_res(YYSTYPE *res)
{
if(last_err_desc) {
@@ -354,7 +427,27 @@ static void store_res(YYSTYPE *res)
line_res.value = 0.0;
strcpy(res_txt, last_err_desc);
}
- else if(res->type == STR) {
+ else if(res->type == NUM){
+ line_res.type = ET_VALUE;
+ line_res.value = res->val;
+ }
+ else if(res->type == BOOLVAL){
+ line_res.type = ET_BOOL;
+ line_res.value = res->val;
+ }
+ else if(res->type == DATE1){
+ line_res.type = ET_DATE;
+ line_res.value = res->val;
+ }
+ else if(res->type == TIME1){
+ line_res.type = ET_TIME;
+ line_res.value = res->val;
+ }
+ else if(res->type == DATETIME1){
+ line_res.type = ET_DATETIME;
+ line_res.value = res->val;
+ }
+ else if(res->type == STR) {
line_res.type = ET_TEXT;
line_res.value = 0.0;
if(res->text) strcpy(res_txt, res->text);
@@ -439,10 +532,11 @@ static void pop_syntax()
}
}
-static double eval(YYSTYPE *sr, YYSTYPE *dst)
+static double eval(YYSTYPE *sr, YYSTYPE *dst, char *dum)
{
anyResult *ar;
+ if(dum) yyerror("parse error");
if(!sr || !sr->text) return 0.0;
parse_level++;
ar = do_formula(0L, sr->text);
@@ -477,10 +571,11 @@ static double sign(double v)
}
static long idum=0;
-
-static double rand(double v)
+static double rand1(YYSTYPE *dst, YYSTYPE *src)
{
- return ran2(&idum);
+ if(!dst) return 0.0;
+ dst->type = NUM;
+ return(dst->val = ran2(&idum));
}
static double srand(double v)
@@ -494,14 +589,9 @@ static double factorial(double v)
return factrl((int)v);
}
-static void close_arr_func(YYSTYPE *sr)
-{
- if(sr->a_data) free(sr->a_data);
- sr->a_data = 0L; sr->a_count = 0;
-}
-
-static double _strlen(YYSTYPE *sr, YYSTYPE *dst)
+static double _strlen(YYSTYPE *sr, YYSTYPE *dst, char *dum)
{
+ if(dum) yyerror("parse error");
if(!sr || !sr->text) return 0.0;
return (double)strlen(sr->text);
}
@@ -515,7 +605,6 @@ static double min(YYSTYPE *sr)
if(sr->a_data && sr->a_data){
for(i = 1, sr->val = sr->a_data[0]; i < sr->a_count; i++)
if(sr->a_data[i] < sr->val) sr->val = sr->a_data[i];
- close_arr_func(sr);
}
return sr->val;
}
@@ -529,7 +618,6 @@ static double max(YYSTYPE *sr)
if(sr->a_data){
for(i = 1, sr->val = sr->a_data[0]; i < sr->a_count; i++)
if(sr->a_data[i] > sr->val) sr->val = sr->a_data[i];
- close_arr_func(sr);
}
return sr->val;
}
@@ -537,10 +625,7 @@ static double max(YYSTYPE *sr)
static double count(YYSTYPE *sr)
{
if(!sr) return 0.0;
- if(sr->a_data){
- sr->val = (double)sr->a_count;
- close_arr_func(sr);
- }
+ if(sr->a_data) sr->val = (double)sr->a_count;
else sr->val = 0.0;
return sr->val;
}
@@ -552,47 +637,64 @@ static double sum(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data){
for(i = 0, sr->val = 0.0; i < sr->a_count; i++) sr->val += sr->a_data[i];
- close_arr_func(sr);
}
else sr->val = 0.0;
return sr->val;
}
-static double calc_variance(double *values, int n)
+static double mean(YYSTYPE *sr)
{
- int i;
- double ss, d, mean = d_amean(n, values);
+ if(!sr) return 0.0;
+ if(sr->a_data && sr->a_count){
+ sr->val = d_amean(sr->a_count, sr->a_data );
+ }
+ return sr->val;
+}
- for(i=0, ss=0.0; i < n; i++) ss += ((d=values[i]-mean)*d);
- return (ss/(n-1));
+static double kurt(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ if(sr->a_data && sr->a_count > 3){
+ sr->val = d_kurt(sr->a_count, sr->a_data );
+ }
+ return sr->val;
}
-static double mean(YYSTYPE *sr)
+static double skew(YYSTYPE *sr)
{
if(!sr) return 0.0;
- if(sr->a_data && sr->a_count){
- sr->val = d_amean(sr->a_count, sr->a_data );
- close_arr_func(sr);
+ if(sr->a_data && sr->a_count > 2){
+ sr->val = d_skew(sr->a_count, sr->a_data );
}
return sr->val;
}
static double gmean(YYSTYPE *sr)
{
+ int i;
+
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
+ for(i = 0; i < sr->a_count; i++) if(sr->a_data[i] <= 0.0) {
+ last_err_desc = "#VALUE";
+ return sr->val = 0.0;
+ }
sr->val = d_gmean(sr->a_count, sr->a_data );
- close_arr_func(sr);
}
return sr->val;
}
static double hmean(YYSTYPE *sr)
{
+ int i;
+
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
+ for(i = 0; i < sr->a_count; i++) if(sr->a_data[i] <= 0.0) {
+ last_err_desc = "#VALUE";
+ return sr->val = 0.0;
+ }
sr->val = d_hmean(sr->a_count, sr->a_data );
- close_arr_func(sr);
}
return sr->val;
}
@@ -602,7 +704,6 @@ static double quartile1(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
d_quartile(sr->a_count, sr->a_data, &sr->val, 0L, 0L);
- close_arr_func(sr);
}
return sr->val;
}
@@ -612,7 +713,6 @@ static double quartile2(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
d_quartile(sr->a_count, sr->a_data, 0L, &sr->val, 0L);
- close_arr_func(sr);
}
return sr->val;
}
@@ -622,7 +722,6 @@ static double quartile3(YYSTYPE *sr)
if(!sr) return 0.0;
if(sr->a_data && sr->a_count){
d_quartile(sr->a_count, sr->a_data, 0L, 0L, &sr->val);
- close_arr_func(sr);
}
return sr->val;
}
@@ -632,8 +731,7 @@ static double variance(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count){
- sr->val = calc_variance(sr->a_data, sr->a_count);
- close_arr_func(sr);
+ sr->val = d_variance(sr->a_count, sr->a_data);
}
return sr->val;
}
@@ -643,8 +741,7 @@ static double stdev(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count){
- sr->val = sqrt(calc_variance(sr->a_data, sr->a_count));
- close_arr_func(sr);
+ sr->val = sqrt(d_variance(sr->a_count, sr->a_data));
}
return sr->val;
}
@@ -654,8 +751,7 @@ static double sterr(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count){
- sr->val = sqrt(calc_variance(sr->a_data, sr->a_count))/sqrt(sr->a_count);
- close_arr_func(sr);
+ sr->val = sqrt(d_variance(sr->a_count, sr->a_data))/sqrt(sr->a_count);
}
return sr->val;
}
@@ -666,7 +762,6 @@ static double beta(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = betaf(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to beta(u, v).");
return sr->val;
@@ -678,7 +773,6 @@ static double _gammp(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = gammp(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to gammp(a, x).");
return sr->val;
@@ -690,7 +784,6 @@ static double _gammq(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = gammq(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to gammq(a, x).");
return sr->val;
@@ -701,10 +794,13 @@ static double _betai(YYSTYPE *sr)
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3){
+ if(sr->a_data[2] < 0.0 || sr->a_data[2] > 1.0) {
+ last_err_desc = "#VALUE";
+ return sr->val = 0.0;
+ }
sr->val = betai(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
- else yyargserr("Wrong number of arguments\nin call to betai(x, a, b).");
+ else yyargserr("Wrong number of arguments\nin call to betai(a, b, x).");
return sr->val;
}
@@ -714,7 +810,6 @@ static double _bincof(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = bincof(sr->a_data[0], sr->a_data[1]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to bincof(n, k).");
return sr->val;
@@ -726,19 +821,30 @@ static double binomdist(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3){
sr->val = binomdistf(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to binomdist(s, n, p).");
return sr->val;
}
+static double binomfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = bincof(sr->a_data[1], sr->a_data[0]);
+ sr->val *= pow(sr->a_data[2], sr->a_data[0]);
+ sr->val *= pow(1.0 - sr->a_data[2], sr->a_data[1] - sr->a_data[0]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to binomfreq(s, n, p).");
+ return sr->val;
+}
+
static double normdist(YYSTYPE *sr)
{
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3){
sr->val = norm_dist(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to normdist(x, mean, SD).");
return sr->val;
@@ -750,19 +856,50 @@ static double norminv(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 3) {
sr->val = distinv(norm_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to norminv(p, mean, SD).");
return sr->val;
}
+static double normfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = norm_freq(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to normfreq(x, mean, SD).");
+ return sr->val;
+}
+
+static double lognormdist(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = lognorm_dist(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to lognormdist(x, mean, SD).");
+ return sr->val;
+}
+
+static double lognorminv(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3) {
+ sr->val = distinv(lognorm_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], 2.0);
+ }
+ else yyargserr("Wrong number of arguments\nin call to lognorminv(p, mean, SD).");
+ return sr->val;
+}
+
static double chidist(YYSTYPE *sr)
{
if(!sr) return 0.0;
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = chi_dist(sr->a_data[0], sr->a_data[1], 1.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to chidist(x, df).");
return sr->val;
@@ -774,7 +911,6 @@ static double chiinv(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2) {
sr->val = distinv(chi_dist,sr->a_data[1], 1.0, sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to chiinv(p, df).");
return sr->val;
@@ -786,7 +922,6 @@ static double tdist(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = t_dist(sr->a_data[0], sr->a_data[1], 1.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to tdist(x, df).");
return sr->val;
@@ -798,7 +933,6 @@ static double tinv(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2) {
sr->val = distinv(t_dist,sr->a_data[1], 1.0, sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to tinv(p, df).");
return sr->val;
@@ -810,19 +944,28 @@ static double poisdist(YYSTYPE *sr)
sr->val = 0.0;
if(sr->a_data && sr->a_count == 2){
sr->val = pois_dist(sr->a_data[0], sr->a_data[1], 1.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to poisdist(x, mean).");
return sr->val;
}
+static double poisfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 2){
+ sr->val = exp(log(sr->a_data[1])*sr->a_data[0] - sr->a_data[1] - gammln(1.0 + sr->a_data[0]));
+ }
+ else yyargserr("Wrong number of arguments\nin call to poisfreq(x, mean).");
+ return sr->val;
+}
+
static double fdist(YYSTYPE *sr)
{
if(!sr) return 0.0;
sr->val = 0;
if(sr->a_data && sr->a_count == 3){
sr->val = f_dist(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to fdist(x, df1, df2).");
return sr->val;
@@ -834,7 +977,6 @@ static double finv(YYSTYPE *sr)
sr->val = 0;
if(sr->a_data && sr->a_count == 3){
sr->val = distinv(f_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], 2.0);
- close_arr_func(sr);
}
else yyargserr("Wrong number of arguments\nin call to finv(p, df1, df2).");
return sr->val;
@@ -846,7 +988,6 @@ static double pearson(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
sr1->val = sr2->val = d_pearson(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\npearson(range1; range2 [;\"dest\"]).");
return sr1->val;
@@ -858,12 +999,22 @@ static double spearman(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
sr1->val = sr2->val = d_spearman(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\nspearman(range1; range2 [;\"dest\"]).");
return sr1->val;
}
+static double kendall(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
+ sr1->val = sr2->val = d_kendall(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\nkendall(range1; range2 [;\"dest\"]).");
+ return sr1->val;
+}
+
static double regression(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
{
if(!sr1 || !sr2) return 0.0;
@@ -871,21 +1022,52 @@ static double regression(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
if(!(dest)) yyargserr("No destination range in call to function\nregression(range1; range2; \"dest\").");
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
sr1->val = sr2->val = d_regression(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\nregression(range1; range2; \"dest\").");
return sr1->val;
}
+static double covar(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count == sr2->a_count){
+ sr1->val = sr2->val = d_covar(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\ncovar(range1; range2).");
+ return sr1->val;
+}
+
static double ttest(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
{
if(!sr1 || !sr2) return 0.0;
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr2->a_count > 1){
sr1->val = sr2->val = d_ttest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
- else yyargserr("Bad arguments in call to function\nttest(range1; range2[;\"dest\"]).");
+ else yyargserr("Bad arguments in call to function\nttest(array1; array2[;\"dest\"]).");
+ return sr1->val;
+}
+
+static double ttest2(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr2->a_count > 1){
+ sr1->val = sr2->val = d_ttest2(sr1->a_data, sr2->a_data, sr1->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\nttest2(range1; range2[;\"dest\"]).");
+ return sr1->val;
+}
+
+static double utest(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
+{
+ if(!sr1 || !sr2) return 0.0;
+ sr1->val = 0.0;
+ if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr2->a_count > 1){
+ sr1->val = sr2->val = d_utest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data);
+ }
+ else yyargserr("Bad arguments in call to function\nutest2(array1; array2[;\"dest\"]).");
return sr1->val;
}
@@ -895,80 +1077,223 @@ static double ftest(YYSTYPE *sr1, YYSTYPE *sr2, char *dest)
sr1->val = 0.0;
if(sr1->a_data && sr1->a_count > 1 && sr2->a_data && sr1->a_count > 1){
sr1->val = sr2->val = d_ftest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data);
- close_arr_func(sr1); close_arr_func(sr2);
}
else yyargserr("Bad arguments in call to function\nftest(range1; range2[;\"dest\"]).");
return sr1->val;
}
-struct init
+static double fill(YYSTYPE *sr, char *dest)
{
- int f_type;
- unsigned int h_name;
- double (*fnct)(double);
-};
+ AccRange *ar;
+ int i, r, c;
+
+ if(!sr || !sr->a_data || !sr->a_count || !dest || !dest[0]) return 0.0;
+ if(ar = new AccRange(dest)) {
+ for(i=0, ar->GetFirst(&c, &r); ar->GetNext(&c, &r) && i < sr->a_count; i++) {
+ curr_data->SetValue(r, c, sr->a_data[i]);
+ }
+ delete ar;
+ }
+ return sr->val = i;
+}
+
+static void datestr(YYSTYPE *dst, YYSTYPE *src, char *fmt)
+{
+ dst->text = PushString(value_date(src->val, fmt));
+}
+
+static double dateval(YYSTYPE *sr, YYSTYPE *dst, char *fmt)
+{
+ if(!sr || !sr->text) return 0.0;
+ if(fmt && fmt[0] && date_value(sr->text, fmt, &dst->val)) return dst->val;
+ if(date_value(sr->text, 0L, &dst->val)) return dst->val;
+ else return dst->val = 0.0;
+}
+
+static double leapyear(double year)
+{
+ int y = (int)year;
+
+ return (double)((y % 4 == 0 && y % 100 != 0) || y % 400 == 0);
+}
+
+static void today(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(src) yyerror("parse error");
+ if(!dst) return;
+ dst->val = floor(now_today());
+ dst->type = DATE1;
+}
+
+static void now(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(src) yyerror("parse error");
+ if(!dst) return;
+ dst->val = now_today(); dst->val -= floor(dst->val);
+ dst->type = TIME1;
+}
+
+static double year(double dv)
+{
+ int res;
+
+ split_date(dv, &res, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double month(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, &res, 0L, 0L, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double dom(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, &res, 0L, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double dow(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, &res, 0L, 0L, 0L, 0L);
+ return (double)res;
+}
+
+static double doy(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, &res, 0L, 0L, 0L);
+ return (double)res;
+}
-static struct init arith_fncts[] = {
- {FUNC2, HashValue((unsigned char*)"pearson"), (double(*)(double))&pearson},
- {FUNC2, HashValue((unsigned char*)"spearman"), (double(*)(double))&spearman},
- {FUNC2, HashValue((unsigned char*)"regression"), (double(*)(double))®ression},
- {FUNC2, HashValue((unsigned char*)"ttest"), (double(*)(double))&ttest},
- {FUNC2, HashValue((unsigned char*)"ftest"), (double(*)(double))&ftest},
- {AFNCT, HashValue((unsigned char*)"variance"), (double(*)(double))&variance},
- {AFNCT, HashValue((unsigned char*)"stdev"), (double(*)(double))&stdev},
- {AFNCT, HashValue((unsigned char*)"sterr"), (double(*)(double))&sterr},
- {AFNCT, HashValue((unsigned char*)"min"), (double(*)(double))&min},
- {AFNCT, HashValue((unsigned char*)"max"), (double(*)(double))&max},
- {AFNCT, HashValue((unsigned char*)"count"), (double(*)(double))&count},
- {AFNCT, HashValue((unsigned char*)"sum"), (double(*)(double))&sum},
- {AFNCT, HashValue((unsigned char*)"mean"), (double(*)(double))&mean},
- {AFNCT, HashValue((unsigned char*)"median"), (double(*)(double))&quartile2},
- {AFNCT, HashValue((unsigned char*)"quartile1"), (double(*)(double))&quartile1},
- {AFNCT, HashValue((unsigned char*)"quartile2"), (double(*)(double))&quartile2},
- {AFNCT, HashValue((unsigned char*)"quartile3"), (double(*)(double))&quartile3},
- {AFNCT, HashValue((unsigned char*)"gmean"), (double(*)(double))&gmean},
- {AFNCT, HashValue((unsigned char*)"hmean"), (double(*)(double))&hmean},
- {AFNCT, HashValue((unsigned char*)"tdist"), (double(*)(double))&tdist},
- {AFNCT, HashValue((unsigned char*)"tinv"), (double(*)(double))&tinv},
- {AFNCT, HashValue((unsigned char*)"poisdist"), (double(*)(double))&poisdist},
- {AFNCT, HashValue((unsigned char*)"fdist"), (double(*)(double))&fdist},
- {AFNCT, HashValue((unsigned char*)"finv"), (double(*)(double))&finv},
- {AFNCT, HashValue((unsigned char*)"gammp"), (double(*)(double))&_gammp},
- {AFNCT, HashValue((unsigned char*)"gammq"), (double(*)(double))&_gammq},
- {AFNCT, HashValue((unsigned char*)"beta"), (double(*)(double))&beta},
- {AFNCT, HashValue((unsigned char*)"betai"), (double(*)(double))&_betai},
- {AFNCT, HashValue((unsigned char*)"bincof"), (double(*)(double))&_bincof},
- {AFNCT, HashValue((unsigned char*)"binomdist"), (double(*)(double))&binomdist},
- {AFNCT, HashValue((unsigned char*)"normdist"), (double(*)(double))&normdist},
- {AFNCT, HashValue((unsigned char*)"norminv"), (double(*)(double))&norminv},
- {AFNCT, HashValue((unsigned char*)"chidist"), (double(*)(double))&chidist},
- {AFNCT, HashValue((unsigned char*)"chiinv"), (double(*)(double))&chiinv},
- {SFNCT, HashValue((unsigned char*)"strlen"), (double(*)(double))&_strlen},
- {SFNCT, HashValue((unsigned char*)"eval"), (double(*)(double))&eval},
- {FNCT, HashValue((unsigned char*)"erf"), errf},
- {FNCT, HashValue((unsigned char*)"erfc"), errfc},
- {FNCT, HashValue((unsigned char*)"sign"), sign},
- {FNCT, HashValue((unsigned char*)"gammaln"), gammln},
- {FNCT, HashValue((unsigned char*)"factorial"), factorial},
- {FNCT, HashValue((unsigned char*)"rand"), rand},
- {FNCT, HashValue((unsigned char*)"srand"), srand},
- {FNCT, HashValue((unsigned char*)"floor"), floor},
- {FNCT, HashValue((unsigned char*)"abs"), fabs},
- {FNCT, HashValue((unsigned char*)"asin"), asin},
- {FNCT, HashValue((unsigned char*)"acos"), acos},
- {FNCT, HashValue((unsigned char*)"atan"), atan},
- {FNCT, HashValue((unsigned char*)"sinh"), sinh},
- {FNCT, HashValue((unsigned char*)"cosh"), cosh},
- {FNCT, HashValue((unsigned char*)"tanh"), tanh},
- {FNCT, HashValue((unsigned char*)"sin"), sin},
- {FNCT, HashValue((unsigned char*)"cos"), cos},
- {FNCT, HashValue((unsigned char*)"atan"), atan},
- {FNCT, HashValue((unsigned char*)"log10"), log10},
- {FNCT, HashValue((unsigned char*)"ln"), log},
- {FNCT, HashValue((unsigned char*)"log"), log},
- {FNCT, HashValue((unsigned char*)"exp"), exp},
- {FNCT, HashValue((unsigned char*)"sqrt"), sqrt},
- {0, 0, 0}};
+static double hours(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, 0L, &res, 0L, 0L);
+ return (double)res;
+}
+
+static double minutes(double dv)
+{
+ int res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, 0L, 0L, &res, 0L);
+ return (double)res;
+}
+
+static double seconds(double dv)
+{
+ double res;
+
+ split_date(dv, 0L, 0L, 0L, 0L, 0L, 0L, 0L, &res);
+ if(res < 0.0005) res = 0.0;
+ return res;
+}
+
+static void fdate(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src || src->type == ARR || src->type == STR) {
+ yyerror("parse error");
+ return;
+ }
+ dst->type = DATE1; dst->val = src->val;
+}
+
+static void fdatetime(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src || src->type == ARR || src->type == STR) {
+ yyerror("parse error");
+ return;
+ }
+ dst->type = DATETIME1; dst->val = src->val;
+}
+
+static void ftime(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src || src->type == ARR || src->type == STR) {
+ yyerror("parse error");
+ return;
+ }
+ dst->type = TIME1; dst->val = src->val;
+}
+
+static void asort(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src) return;
+ dst->type = ARR;
+ switch(src->a_count) {
+ case 0:
+ dst->a_data = PushArray((double*)malloc(sizeof(double)));
+ dst->a_count = 1; dst->a_data[0] = dst->val = src->val;
+ break;
+ case 1:
+ dst->a_data = PushArray((double*)malloc(sizeof(double)));
+ dst->a_count = 1; dst->a_data[0] = dst->val = src->a_data[0];
+ break;
+ default:
+ dst->a_data = PushArray((double*)memdup(src->a_data, src->a_count * sizeof(double), 0));
+ dst->a_count = src->a_count;
+ SortArray(dst->a_count, dst->a_data);
+ }
+}
+
+static void _crank(YYSTYPE *dst, YYSTYPE *src)
+{
+ double tmp;
+
+ if(!dst || !src) return;
+ dst->type = ARR;
+ switch(src->a_count) {
+ case 0: case 1:
+ dst->a_data = PushArray((double*)malloc(sizeof(double)));
+ dst->a_count = 1; dst->a_data[0] = dst->val = 1;
+ break;
+ default:
+ dst->a_data = PushArray((double*)memdup(src->a_data, src->a_count * sizeof(double), 0));
+ dst->a_count = src->a_count;
+ crank(dst->a_count, dst->a_data, &tmp);
+ }
+}
+
+static void ltrim(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!src || !dst || !src->text) return;
+ dst->text = PushString(str_ltrim(strdup(src->text)));
+ dst->type = STR; dst->val = 0.0;
+}
+
+static void rtrim(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!src || !dst || !src->text) return;
+ dst->text = PushString(str_rtrim(strdup(src->text)));
+ dst->type = STR; dst->val = 0.0;
+}
+
+static void trim(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!src || !dst || !src->text) return;
+ dst->text = PushString(str_trim(strdup(src->text)));
+ dst->type = STR; dst->val = 0.0;
+}
+
+static double rank(YYSTYPE *sr)
+{
+ if(sr->a_count < 2 || !sr->a_data) return 0.0;
+ return d_rank(sr->a_count-1, sr->a_data+1, sr->a_data[0]);
+}
+
+static double classes(double start, double step, YYSTYPE *src, YYSTYPE *dest)
+{
+ return d_classes(curr_data, start, step, src->a_data, src->a_count, dest->text);
+}
// Store strings in a list
static char **str_list = 0L;
@@ -984,6 +1309,36 @@ static char *PushString(char *text)
return 0L;
}
+//Store arrays in a list
+static double **arr_list = 0L;
+static int n_arr = 0;
+
+static double *PushArray(double *arr)
+{
+ if(arr) {
+ if(arr_list = (double**)realloc(arr_list, sizeof(double*)*(n_arr+1)))
+ arr_list[n_arr] = arr;
+ return arr_list[n_arr++];
+ }
+ return 0L;
+}
+
+static double *ReallocArray(double *arr, int size)
+{
+ int i;
+
+ if(arr && size) {
+ for(i = 0; i < n_arr; i++) if(arr_list[i] == arr) {
+ arr_list[i] = (double*)realloc(arr, size);
+ return arr_list[i];
+ }
+ arr = (double*)realloc(arr, size);
+ return PushArray(arr);
+ }
+ return 0L;
+}
+
+
//The symbol table: a chain of `struct symrec'
static symrec *sym_table, *sym_tab_first;
@@ -1021,8 +1376,68 @@ void ArrangeFunctions()
}
// Put arithmetic functions and predifened variables in table
+#define INIT_SYM(TYP,NAM,FNC) {TYP,NAM,(double(*)(double))&FNC}
void InitArithFuncs(DataObj *d)
{
+ struct fdef {
+ int f_type;
+ char *name;
+ double (*fnct)(double);
+ };
+ fdef fncts[] = {
+ INIT_SYM(FUNC4, "classes", classes),
+ INIT_SYM(AFNCT, "rank", rank), INIT_SYM(YYFNC, "ltrim", ltrim),
+ INIT_SYM(YYFNC, "rtrim", rtrim), INIT_SYM(YYFNC, "trim", trim),
+ INIT_SYM(YYFNC, "asort", asort), INIT_SYM(YYFNC, "crank", _crank),
+ INIT_SYM(SRFUNC, "datestr", datestr), INIT_SYM(SFNCT, "dateval", dateval),
+ INIT_SYM(BFNCT, "leapyear", leapyear), INIT_SYM(YYFNC, "today", today),
+ INIT_SYM(YYFNC, "now", now), INIT_SYM(FNCT, "year", year),
+ INIT_SYM(FNCT, "month", month), INIT_SYM(FNCT, "dom", dom),
+ INIT_SYM(FNCT, "dow", dow), INIT_SYM(FNCT, "doy", doy),
+ INIT_SYM(FNCT, "hours", hours), INIT_SYM(FNCT, "minutes", minutes),
+ INIT_SYM(FNCT, "seconds", seconds), INIT_SYM(YYFNC, "date", fdate),
+ INIT_SYM(FNCT, "datetime", fdatetime), INIT_SYM(YYFNC, "time", ftime),
+ INIT_SYM(FUNC1, "fill", fill), INIT_SYM(FUNC2, "pearson", pearson),
+ INIT_SYM(FUNC2, "spearman", spearman), INIT_SYM(FUNC2, "kendall", kendall),
+ INIT_SYM(FUNC2, "correl", pearson), INIT_SYM(FUNC2, "regression", regression),
+ INIT_SYM(FUNC2, "covar", covar),
+ INIT_SYM(FUNC3, "utest", utest), INIT_SYM(FUNC2, "ttest2", ttest2),
+ INIT_SYM(FUNC3, "ttest", ttest), INIT_SYM(FUNC3, "ftest", ftest),
+ INIT_SYM(AFNCT, "variance", variance), INIT_SYM(AFNCT, "stdev", stdev),
+ INIT_SYM(AFNCT, "sterr", sterr), INIT_SYM(AFNCT, "min", min),
+ INIT_SYM(AFNCT, "max", max), INIT_SYM(AFNCT, "count", count),
+ INIT_SYM(AFNCT, "sum", sum), INIT_SYM(AFNCT, "mean", mean),
+ INIT_SYM(AFNCT, "kurt", kurt), INIT_SYM(AFNCT, "skew", skew),
+ INIT_SYM(AFNCT, "median", quartile2), INIT_SYM(AFNCT, "quartile1", quartile1),
+ INIT_SYM(AFNCT, "quartile2",quartile2), INIT_SYM(AFNCT, "quartile3", quartile3),
+ INIT_SYM(AFNCT, "gmean", gmean), INIT_SYM(AFNCT, "hmean", hmean),
+ INIT_SYM(AFNCT, "tdist", tdist), INIT_SYM(AFNCT, "tinv", tinv),
+ INIT_SYM(AFNCT, "poisdist", poisdist), INIT_SYM(AFNCT, "poisfreq", poisfreq),
+ INIT_SYM(AFNCT, "fdist", fdist),
+ INIT_SYM(AFNCT, "finv", finv), INIT_SYM(AFNCT, "gammp", _gammp),
+ INIT_SYM(AFNCT, "gammq", _gammq), INIT_SYM(AFNCT, "beta", beta),
+ INIT_SYM(AFNCT, "betai", _betai), INIT_SYM(AFNCT, "bincof", _bincof),
+ INIT_SYM(AFNCT, "binomdist",binomdist),
+ INIT_SYM(AFNCT, "binomfreq",binomfreq),
+ INIT_SYM(AFNCT, "normdist", normdist),
+ INIT_SYM(AFNCT, "norminv", norminv),
+ INIT_SYM(AFNCT, "normfreq", normfreq),
+ INIT_SYM(AFNCT, "lognormdist", lognormdist),
+ INIT_SYM(AFNCT, "lognorminv",lognorminv), INIT_SYM(AFNCT, "chidist", chidist),
+ INIT_SYM(AFNCT, "chiinv", chiinv), INIT_SYM(SFNCT, "strlen", _strlen),
+ INIT_SYM(SFNCT, "eval", eval), INIT_SYM(FNCT, "erf", errf),
+ INIT_SYM(FNCT, "erfc", errfc), INIT_SYM(FNCT, "sign", sign),
+ INIT_SYM(FNCT, "gammaln", gammln), INIT_SYM(FNCT, "factorial", factorial),
+ INIT_SYM(YYFNC, "rand", rand1), INIT_SYM(FNCT, "srand", srand),
+ INIT_SYM(FNCT, "floor", floor), INIT_SYM(FNCT, "abs", fabs),
+ INIT_SYM(FNCT, "asin", asin), INIT_SYM(FNCT, "acos", acos),
+ INIT_SYM(FNCT, "atan", atan), INIT_SYM(FNCT, "sinh", sinh),
+ INIT_SYM(FNCT, "cosh", cosh), INIT_SYM(FNCT, "tanh", tanh),
+ INIT_SYM(FNCT, "sin", sin), INIT_SYM(FNCT, "cos", cos),
+ INIT_SYM(FNCT, "tan", tan), INIT_SYM(FNCT, "log10", log10),
+ INIT_SYM(FNCT, "ln", log), INIT_SYM(FNCT, "log", log),
+ INIT_SYM(FNCT, "exp", exp), INIT_SYM(FNCT, "sqrt", sqrt),
+ INIT_SYM(0, 0L, nop)};
int i;
symrec *ptr, *next;
@@ -1037,17 +1452,19 @@ void InitArithFuncs(DataObj *d)
}
sym_table = sym_tab_first = (symrec *) 0;
}
- for (i = 0; arith_fncts[i].h_name; i++) {
- ptr = putsym (arith_fncts[i].h_name, arith_fncts[i].f_type);
- ptr->fnctptr = (double (*)(...))arith_fncts[i].fnct;
+ for (i = 0; fncts[i].name; i++) {
+ ptr = putsym (HashValue((unsigned char*) fncts[i].name), Hash2((unsigned char*) fncts[i].name), fncts[i].f_type);
+ ptr->fnctptr = (double (*)(...))fncts[i].fnct;
}
- ptr = putsym(HashValue((unsigned char*)"zdiv"), VAR); ptr->SetValue(1.0);
+ ptr = putsym(HashValue((unsigned char*)"zdiv"), Hash2((unsigned char*)"zdiv"), VAR); ptr->SetValue(1.0);
sym_tab_first = sym_table;
}
+#undef INIT_SYM
static void init_table (void)
{
str_list = 0L; n_str = 0;
+ arr_list = 0L; n_arr = 0;
push_syntax();
}
@@ -1059,33 +1476,37 @@ static void clear_table()
for(i = 0; i < n_str; i++) if(str_list[i]) free(str_list[i]);
free(str_list); str_list = 0L; n_str = 0;
}
+ if(arr_list) {
+ for(i = 0; i < n_arr; i++) if(arr_list[i]) free(arr_list[i]);
+ free(arr_list); arr_list = 0L; n_arr = 0;
+ }
pop_syntax();
}
static symrec *
-putsym (unsigned int h_name, int sym_type)
+putsym (unsigned int h_name, unsigned int h2_name, int sym_type)
{
- sym_table = new symrec(h_name, sym_type, sym_table);
+ sym_table = new symrec(h_name, h2_name, sym_type, sym_table);
return sym_table;
}
static symrec *
-getsym (unsigned int h_name, char *sym_name)
+getsym (unsigned int h_name, unsigned int h2_name, char *sym_name)
{
symrec *ptr;
if(!h_name) return 0;
for (ptr = sym_table; ptr != (symrec *) 0; ptr = (symrec *)ptr->next) {
- if (ptr->h_name == h_name){
+ if (ptr->h_name == h_name && ptr->h2_name == h2_name){
if(sym_name && !ptr->name) {
ptr->SetName(sym_name);
bRecent = true;
}
return ptr;
}
- //predefined variables never end on a digit
+ //predefined variables rarely end on a digit
else if(ptr == sym_tab_first) {
- if(sym_name && isdigit(sym_name[strlen(sym_name)-1])) return 0;
+ if(sym_name && isdigit(sym_name[strlen(sym_name)-1]) && strlen(sym_name) < 5) return 0;
}
}
return 0;
@@ -1096,28 +1517,28 @@ push(YYSTYPE *res, YYSTYPE *val)
{
if(val->a_data) {
if(!(res->a_data)) {
- if(!(val->a_data=(double*)realloc(val->a_data, (val->a_count+2)*sizeof(double))))return 0;
+ if(!(val->a_data=ReallocArray(val->a_data, (val->a_count+2)*sizeof(double))))return 0;
val->a_data[val->a_count++] = res->val;
res->a_data = val->a_data; res->a_count = val->a_count;
val->a_data = 0L; val->a_count = 0;
val->val = res->val; return 1;
}
else {
- if(!(res->a_data=(double*)realloc(res->a_data, (val->a_count+res->a_count)*sizeof(double))))return 0;
+ if(!(res->a_data=ReallocArray(res->a_data, (val->a_count+res->a_count)*sizeof(double))))return 0;
memcpy(&res->a_data[res->a_count], val->a_data, val->a_count*sizeof(double));
- res->a_count += val->a_count; free(val->a_data);
+ res->a_count += val->a_count;
val->a_data = 0L; val->a_count = 0;
return 1;
}
}
if(!(res->a_data )){
- if(!(res->a_data = (double*)malloc(2*sizeof(double))))return 0;
+ if(!(res->a_data = PushArray((double*)malloc(2*sizeof(double)))))return 0;
res->a_data[0] = res->val; res->a_data[1] = val->val;
res->a_count = 2;
return 1;
}
else {
- if(!(res->a_data = (double*)realloc(res->a_data, (res->a_count+2)*sizeof(double))))return 0;
+ if(!(res->a_data = ReallocArray(res->a_data, (res->a_count+2)*sizeof(double))))return 0;
res->a_data[res->a_count] = val->val; res->a_count++;
return 1;
}
@@ -1132,7 +1553,7 @@ range_array(YYSTYPE * res, char *range)
anyResult ares;
if(!range || !range[0] || !(r = new AccRange(range))) return 0;
- if(!r->GetFirst(&col, &row) || !(res->a_data = (double*)malloc(r->CountItems() * sizeof(double)))) {
+ if(!r->GetFirst(&col, &row) || !(res->a_data = PushArray((double*)malloc(r->CountItems() * sizeof(double))))) {
delete(r);
return 0;
}
@@ -1140,15 +1561,9 @@ range_array(YYSTYPE * res, char *range)
for(res->a_count = 0; r->GetNext(&col, &row); ) {
if(curr_data->GetResult(&ares, row, col, parse_level > MAX_PARSE)) {
switch(ares.type) {
- case ET_VALUE:
+ case ET_VALUE: case ET_TIME: case ET_DATE: case ET_DATETIME: case ET_BOOL:
res->a_data[res->a_count++] = ares.value;
break;
- case ET_TEXT:
- if(ares.text && ares.text[0]) last_err_desc = "#ARGS";
- break;
- case ET_ERROR:
- last_err_desc = "#ARGS";
- break;
}
}
}
@@ -1157,6 +1572,40 @@ range_array(YYSTYPE * res, char *range)
return 1;
}
+static int
+range_array2(YYSTYPE *res1, YYSTYPE *res2)
+{
+ AccRange *r1, *r2;
+ int row1, col1, row2, col2;
+ anyResult ares1, ares2;
+ char *range1, *range2;
+
+ range1 = res1->text; range2 = res2->text;
+ if(!range1 || !range1[0] || !range2 || !range2[0] || !(r1 = new AccRange(range1))
+ || !(r2 = new AccRange(range2))) return 0;
+ if(!r1->GetFirst(&col1, &row1) || !(res1->a_data = PushArray((double*)malloc(r1->CountItems() * sizeof(double))))) {
+ delete(r1); delete(r2);
+ return 0;
+ }
+ if(!r2->GetFirst(&col2, &row2) || !(res2->a_data = PushArray((double*)malloc(r2->CountItems() * sizeof(double))))) {
+ delete(r1); delete(r2);
+ return 0;
+ }
+ parse_level++;
+ for(res1->a_count = res2->a_count = 0; r1->GetNext(&col1, &row1) && r2->GetNext(&col2, &row2); ) {
+ if(curr_data->GetResult(&ares1, row1, col1, parse_level > MAX_PARSE)
+ && curr_data->GetResult(&ares2, row2, col2, parse_level > MAX_PARSE)
+ && (ares1.type==ET_VALUE || ares1.type==ET_TIME || ares1.type==ET_DATE || ares1.type==ET_DATETIME || ares1.type==ET_BOOL)
+ && (ares2.type==ET_VALUE || ares2.type==ET_TIME || ares2.type==ET_DATE || ares2.type==ET_DATETIME || ares2.type==ET_BOOL)){
+ res1->a_data[res1->a_count++] = ares1.value;
+ res2->a_data[res2->a_count++] = ares2.value;
+ }
+ }
+ parse_level--;
+ delete(r1); delete(r2);
+ return 1;
+}
+
static YYSTYPE *proc_clause(YYSTYPE *res)
{
int i, n, o_pos;
@@ -1165,12 +1614,12 @@ static YYSTYPE *proc_clause(YYSTYPE *res)
if(!(syntax_level) || !syntax_level->cl1 || syntax_level->cl2 <= syntax_level->cl1) return res;
if(!res->text) return res;
- if(!res->a_data && (res->a_data = (double*)malloc(sizeof(double)))) {
+ if(!res->a_data && (res->a_data = PushArray((double*)malloc(sizeof(double))))) {
res->a_data[0] = res->type == VAR && res->tptr ? res->tptr->GetValue() : res->val;
res->a_count = 1;
}
else if(!res->a_data) return res;
- if(!(n_data = (double*)malloc(res->a_count * sizeof(double)))) return res;
+ if(!(n_data = PushArray((double*)malloc(res->a_count * sizeof(double))))) return res;
o_pos = buff_pos; o_cmd = buffer;
for(i = n = 0; i < res->a_count; i++) {
buffer = res->text; buff_pos = 0;
@@ -1179,8 +1628,8 @@ static YYSTYPE *proc_clause(YYSTYPE *res)
yyparse();
if(line_res.type == ET_VALUE && line_res.value != 0.0) n_data[n++] = res->a_data[i];
}
- free(res->a_data); res->a_data = n_data; res->a_count = n;
- free(res->text); res->text=0L;
+ res->a_data = n_data; res->a_count = n;
+ res->text=0L;
syntax_level->cl1 = syntax_level->cl2 = 0;
buffer = o_cmd; buff_pos = o_pos;
return res;
@@ -1191,6 +1640,13 @@ static void exec_clause(YYSTYPE *res)
int i, j;
char *cmd;
+ if((!res->a_data || res->a_count <2) && res->text && res->text[0]) range_array(res, res->text);
+ if(!res->a_data) {
+ if(res->a_data = PushArray((double*)malloc(2*sizeof(double)))) {
+ res->a_data[0] = res->val; res->a_count = 1;
+ InfoBox("fixed data");
+ }
+ }
if(!(syntax_level) || !syntax_level->cl1 || syntax_level->cl2 <= syntax_level->cl1) return;
if(!(cmd = (char*)malloc(syntax_level->cl2 - syntax_level->cl1 +2)))return;
while(buffer[syntax_level->cl1] <= ' ' && syntax_level->cl1 < syntax_level->cl2) syntax_level->cl1++;
@@ -1198,7 +1654,8 @@ static void exec_clause(YYSTYPE *res)
cmd[j++] = buffer[i];
}
cmd[j++] = ';'; cmd[j++] = 0;
- res->text = cmd;
+ res->text = PushString(cmd);
+ free(cmd);
}
struct parse_info {
@@ -1209,8 +1666,9 @@ struct parse_info {
YYSTYPE yylval;
struct parse_info *next;
char **str_list;
+ double **arr_list;
char *last_err_desc;
- int n_str, yychar, yynerrs;
+ int n_str, n_arr, yychar, yynerrs;
};
static parse_info *parse_stack = 0L;
@@ -1228,6 +1686,8 @@ static void push_parser()
ptr->next = parse_stack;
ptr->str_list = str_list; str_list = 0L;
ptr->n_str = n_str; n_str = 0;
+ ptr->arr_list = arr_list; arr_list = 0L;
+ ptr->n_arr = n_arr; n_arr = 0;
ptr->yychar = yychar; ptr->yynerrs = yynerrs;
parse_stack = ptr; last_err_desc = 0L;
parse_level++; //reenter ?
@@ -1251,6 +1711,7 @@ static void pop_parser()
curr_data = ptr->curr_data; last_err_desc = ptr->last_err_desc;
memcpy(&yylval, &ptr->yylval, sizeof(YYSTYPE));
str_list = ptr->str_list; n_str = ptr->n_str;
+ arr_list = ptr->arr_list; n_arr = ptr->n_arr;
yychar = ptr->yychar; yynerrs = ptr->yynerrs;
free(ptr);
parse_level--;
@@ -1258,17 +1719,39 @@ static void pop_parser()
pop_syntax();
}
-static int is_ttoken(int h_nam)
+static int is_ttoken(unsigned int h_nam, unsigned int h2_nam)
{
switch(h_nam) {
- case 101: return E;
- case 26992: return PI;
+ case 69:
+ if(h2_nam == 101) return E;
+ break;
+ case 393:
+ if(h2_nam == 47081) return PI;
+ break;
case 28381:
- if(syntax_level) syntax_level->cl1 = buff_pos;
- return CLAUSE;
- case 9252: return CLVAL;
- case 26217: return IF;
- case 6033: return ELSE;
+ if((h2_nam & 0x7fffffff) == 0x7c2706ed) {
+ if(syntax_level) syntax_level->cl1 = buff_pos;
+ return CLAUSE;
+ }
+ break;
+ case 20:
+ if(h2_nam == 5220) return CLVAL;
+ break;
+ case 362:
+ if(h2_nam == 42878) return IF;
+ break;
+ case 1457:
+ if(h2_nam == 18357885) return DIM;
+ break;
+ case 6033:
+ if((h2_nam & 0x7fffffff) == 0x6371377d) return ELSE;
+ break;
+ case 7097:
+ if((h2_nam & 0x7fffffff) == 0x550a2d65) return BTRUE;
+ break;
+ case 23697:
+ if((h2_nam & 0x7fffffff) == 0x155f977d) return BFALSE;
+ break;
}
return 0;
}
@@ -1277,7 +1760,7 @@ static symrec *curr_sym;
static int yylex (void)
{
int i, c, tok;
- unsigned int h_nam;
+ unsigned int h_nam, h2_nam;
char tmp_txt[80];
symrec *s;
@@ -1322,10 +1805,10 @@ static int yylex (void)
}
tmp_txt[i] = 0;
h_nam = HashValue((unsigned char*)tmp_txt);
- if(tok = is_ttoken(h_nam))
- return tok;
- if(!(s = getsym(h_nam, tmp_txt))){
- s = putsym(h_nam, VAR);
+ h2_nam = Hash2((unsigned char*)tmp_txt);
+ if(tok = is_ttoken(h_nam, h2_nam)) return tok;
+ if(!(s = getsym(h_nam, h2_nam, tmp_txt))){
+ s = putsym(h_nam, h2_nam, VAR);
s->SetName(tmp_txt);
}
@@ -1403,6 +1886,13 @@ static int yylex (void)
return c;
}
+static unsigned int hn_x = HashValue((unsigned char *)"x");
+static unsigned int hn_y = HashValue((unsigned char *)"y");
+static unsigned int hn_z = HashValue((unsigned char *)"z");
+static unsigned int h2_x = Hash2((unsigned char *)"x");
+static unsigned int h2_y = Hash2((unsigned char *)"y");
+static unsigned int h2_z = Hash2((unsigned char *)"z");
+
bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOINT **pts, long *npts, char *param)
{
double x, y;
@@ -1410,8 +1900,6 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
lfPOINT *new_points;
long npoints = 0;
int length, res_mode = 0;
- unsigned int hn_x = HashValue((unsigned char *)"x");
- unsigned int hn_y = HashValue((unsigned char *)"y");
if(x1 < x2) step = fabs(step);
else step = -fabs(step);
@@ -1434,7 +1922,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
free(buffer); buffer = 0L;
}
length = strlen(expr);
- buffer = expr; sx = putsym(hn_x, VAR);
+ buffer = expr; sx = putsym(hn_x, h2_x, VAR);
for(x = x1; step > 0.0 ? x <= x2 : x >= x2; x += step) {
if(sx){
sx->SetValue(x); buff_pos = 0;
@@ -1447,7 +1935,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
case 2:
y = line_res.value; break;
default:
- if(sy = getsym(hn_y)) {
+ if(sy = getsym(hn_y, h2_y)) {
y = sy->GetValue(); res_mode = 1;
}
else {
@@ -1455,7 +1943,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
}
break;
}
- new_points[npoints].fx = (getsym(hn_x))->GetValue();
+ new_points[npoints].fx = (getsym(hn_x, h2_x))->GetValue();
new_points[npoints++].fy = y;
}
}
@@ -1475,9 +1963,6 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
int length, nr, nc, r, c, res_mode=0;
symrec *sx, *sz, *sy;
double x, y, z;
- unsigned int hn_x = HashValue((unsigned char *)"x");
- unsigned int hn_y = HashValue((unsigned char *)"y");
- unsigned int hn_z = HashValue((unsigned char *)"z");
if(!d || x2 <= x1 || z2 <= z1 || xstep <= 0.0 || zstep <= 0.0) return false;
push_parser();
@@ -1496,7 +1981,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
free(buffer); buffer = 0L;
}
length = strlen(expr); buffer = expr;
- sx = putsym(hn_x, VAR); sz = putsym(hn_z, VAR);
+ sx = putsym(hn_x, h2_x, VAR); sz = putsym(hn_z, h2_z, VAR);
nr = iround((z2-z1)/zstep)+1; nc = iround((x2-x1)/xstep)+1;
d->Init(nr, nc);
for(r = 0, x = x1; r < nr; r++, x += xstep) {
@@ -1511,7 +1996,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
case 2:
y = line_res.value; break;
default:
- if(sy = getsym(hn_y)) {
+ if(sy = getsym(hn_y, h2_y)) {
y = sy->GetValue(); res_mode = 1;
}
else {
@@ -1534,7 +2019,10 @@ anyResult *do_formula(DataObj *d, char *expr)
if(d) curr_data = d;
ret.type = ET_ERROR; ret.text = 0L;
- if(!expr || !expr[0]) return &ret;
+ if(!expr || !expr[0]) {
+ if(!sym_table) InitArithFuncs(0L);
+ return &ret;
+ }
push_parser(); //make code reentrant
init_table(); length = strlen(expr);
if(!(buffer = (char*)malloc(length+2))){
@@ -1586,7 +2074,8 @@ bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
case NUM:
pos += sprintf(res+pos, "%g", yylval.val);
break;
- case FNCT: case FUNC2: case AFNCT: case SFNCT:
+ case FNCT: case FUNC1: case FUNC2: case FUNC3: case AFNCT:
+ case SFNCT: case SRFUNC: case BFNCT: case YYFNC: case FUNC4:
pos += sprintf(res+pos, "%s", curr_sym->name);
break;
case COLR: case COLC:
@@ -1634,6 +2123,12 @@ bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
case E:
pos += sprintf(res+pos, "e");
break;
+ case BTRUE:
+ pos += sprintf(res+pos, "true");
+ break;
+ case BFALSE:
+ pos += sprintf(res+pos, "false");
+ break;
case AND:
pos += sprintf(res+pos, " && ");
break;
@@ -1683,20 +2178,20 @@ static void fcurve(double x, double z, double **a, double *y, double dyda[], int
{
int i, length;
double tmp, y1, y2;
- symrec *symx, *sy=0L;
- unsigned int hn_x = HashValue((unsigned char *)"x");
- unsigned int hn_y = HashValue((unsigned char *)"y");
+ symrec *symx, *symz, *sy=0L;
- if(!(symx = getsym(hn_x))) symx = putsym(hn_x, VAR);
+ if(!(symx = getsym(hn_x, h2_x))) symx = putsym(hn_x, h2_x, VAR);
+ if(!(symz = getsym(hn_z, h2_z))) symz = putsym(hn_z, h2_z, VAR);
//swap parameters to requested set
if(a != parval) for(i = 0; i < ma; i++) {
tmp = *parval[i]; *parval[i] = *a[i]; *a[i] = tmp;
}
//calc result
- symx->SetValue(x); buffer = txt_formula;
+ symx->SetValue(x); symz->SetValue(z);
+ buffer = txt_formula;
buff_pos = 0; length = strlen(txt_formula);
do { yyparse(); }while(buff_pos < length);
- if(sy = getsym(hn_y)) *y = sy->GetValue();
+ if(sy = getsym(hn_y, h2_y)) *y = sy->GetValue();
else *y = line_res.value;
if(*y == HUGE_VAL || *y == -HUGE_VAL) {
for(i = 0, *y = 0.0; i < ma; dyda[i++] = 0.0);
@@ -1756,7 +2251,7 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
if(arz) delete arz;
free(x); delete arx; delete ary; return 0;
}
- if(rz && !(y = (double*)malloc(i * sizeof(double)))){
+ if(rz && !(z = (double*)malloc(i * sizeof(double)))){
if(arz) delete arz;
free(y); free(x); delete arx; delete ary; return 0;
}
@@ -1850,29 +2345,3 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
return itst < maxiter ? itst+1 : maxiter;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resource.h b/resource.h
deleted file mode 100755
index 2e03463..0000000
--- a/resource.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by RLPLOT.RC
-//
-#define ACCELERATORS_1 1
-#define IDI_EVAL 50
-#define MENU_1 400
-#define MENU_2 401
-#define MENU_3 402
-#define CM_OPEN 500
-#define CM_SAVEDATAAS 501
-#define CM_EXIT 502
-#define CM_NEWGRAPH 503
-#define CM_NEWPAGE 504
-#define CM_DELGRAPH 505
-#define CM_ADDPLOT 506
-#define CM_ABOUT 507
-#define CM_ADDROWCOL 508
-#define CM_COPYGRAPH 509
-#define CM_SAVEGRAPHAS 510
-#define CM_REDRAW 511
-#define CM_ZOOM25 512
-#define CM_ZOOM50 513
-#define CM_ZOOM100 514
-#define CM_ZOOM200 515
-#define CM_ZOOM400 516
-#define CM_PRINT 517
-#define CM_EXPORT 518
-#define CM_DELOBJ 519
-#define CM_REBOOT 520
-#define CM_SHUTDOWN 521
-#define CM_DEFAULTS 522
-#define CM_COPY 523
-#define CM_PASTE 524
-#define CM_UPDATE 525
-#define CM_ADDAXIS 526
-#define CM_UNDO 527
-#define CM_ZOOMIN 528
-#define CM_ZOOMOUT 529
-#define CM_ZOOMFIT 530
-#define CM_FILE1 531
-#define CM_FILE2 532
-#define CM_FILE3 533
-#define CM_FILE4 534
-#define CM_FILE5 535
-#define CM_FILE6 536
-#define CM_FILLRANGE 537
-#define CM_CUT 538
-#define CM_LEGEND 539
-#define CM_LAYERS 540
-#define CM_T_STANDARD 550
-#define CM_T_DRAW 551
-#define CM_T_POLYLINE 552
-#define CM_T_POLYGON 553
-#define CM_T_RECTANGLE 554
-#define CM_T_ROUNDREC 555
-#define CM_T_ELLIPSE 556
-#define CM_T_ARROW 557
-#define CM_T_TEXT 558
-#define CM_DELKEY 600
-#define CM_LEFTARRKEY 601
-#define CM_RIGHTARRKEY 602
-#define CM_UPARRKEY 603
-#define CM_DOWNARRKEY 604
-#define CM_TAB 605
-#define CM_SHTAB 606
-#define CM_PGUP 607
-#define CM_PGDOWN 608
-#define CM_POS_FIRST 609
-#define CM_POS_LAST 610
-#define CM_SHLEFT 611
-#define CM_SHRIGHT 612
-#define CM_SHUP 613
-#define CM_SHDOWN 614
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NO_MFC 1
-#define _APS_NEXT_RESOURCE_VALUE 103
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1000
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/rlp_math.cpp b/rlp_math.cpp
index 7428003..9c16f60 100755
--- a/rlp_math.cpp
+++ b/rlp_math.cpp
@@ -1,4 +1,4 @@
-//rlp_math.cpp, Copyright (c) 2004, 2005 R.Lackner
+//rlp_math.cpp, Copyright (c) 2004-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -19,11 +19,17 @@
#include "rlplot.h"
#include <math.h>
#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
#define SWAP(a,b) {double temp=(a);(a)=(b);(b)=temp;}
#define _PREC 1.0e-12
+extern Default defs;
+
static char *MRQ_error = 0L;
+static double sqrt2pi = sqrt(_PI*2.0);
//---------------------------------------------------------------------------
//utilitity functions for memory allocation
@@ -347,27 +353,64 @@ void spline(lfPOINT *v, int n, double *y2)
}
//---------------------------------------------------------------------------
-// Special Functions
-// Ref.: W.H. Press, B.P. Flannery, S.A. Teukolsky, W.T. Vetterling (1989),
-// Numerical Rcipies in C. The Art of Scientific Computing,
-// Cambridge University Press, ISBN 0-521-35465, pp. 166 ff.
-
// The Gamma Function: return the ln(G(xx)) for xx > 0
-double gammln(double xx)
+// Ref: B.W. Brown, J. Lovato, K. Russel (1994)
+// DCDFLIB.C, Library of C Routinesfor Cumulative Distribution Functions,
+// Inverses, and other Parameters.
+
+double devlpl(double a[], int n, double x)
{
- double x, tmp, ser;
- static double cof[6] = {76.18009173, -86.50532033, 24.01409822,
- -1.231739516, 0.120858003e-2, -0.536382e-5};
- int j;
-
- if(xx < 0.0) return 0.0;
- x = xx-1; tmp = x + 5.5; tmp -= (x + 0.5)*log(tmp);
- for (j = 0, ser = 1.0; j <= 5; j++) {
- x += 1.0; ser += cof[j]/x;
+ double term;
+ int i;
+
+ for(term = a[n-1], i= n-2; i>=0; i--) term = a[i] + term * x;
+ return term;
+}
+
+
+double gammln(double x)
+{
+ static double coef[] = {0.83333333333333023564e-1,-0.27777777768818808e-2,
+ 0.79365006754279e-3, -0.594997310889e-3, 0.8065880899e-3};
+static double scoefd[] = {0.62003838007126989331e2, 0.9822521104713994894e1,
+ -0.8906016659497461257e1, 0.1000000000000000000e1};
+static double scoefn[] = {0.62003838007127258804e2, 0.36036772530024836321e2,
+ 0.20782472531792126786e2, 0.6338067999387272343e1,0.215994312846059073e1,
+ 0.3980671310203570498e0, 0.1093115956710439502e0,0.92381945590275995e-2,
+ 0.29737866448101651e-2};
+ double offset, prod, xx;
+ int i,n;
+
+ if(x < 6.0) {
+ prod = 1.0e0; xx = x;
+ while(xx > 3.0) {
+ xx -= 1.0; prod *= xx;
+ }
+ if(x <= 2.0) while(xx < 2.0) {
+ prod /= xx; xx += 1.0;
+ }
+ // compute rational approximation to gamma(x)
+ return log(devlpl(scoefn, 9, xx-2.0) / devlpl(scoefd, 4, xx-2.0) * prod);
+ }
+ else {
+ offset = 0.91893853320467274178; // hln2pi
+ // if necessary make x at least 12 and carry correction in offset
+ if(n = 13.0 >= x ? (int)(12.0 - x) : 0) xx = x;
+ else {
+ for(i=1, prod = 1.0; i<= n; i++) prod *= (x+(double)(i-1));
+ offset -= log(prod); xx = x+(double)n;
+ }
+ // compute power series
+ return devlpl(coef, 5, 1.0/(xx*xx)) / xx + (offset+(xx-0.5)*log(xx)-xx);
}
- return -tmp + log(2.50662827465*ser);
}
+//---------------------------------------------------------------------------
+// Special Functions
+// Ref.: W.H. Press, B.P. Flannery, S.A. Teukolsky, W.T. Vetterling (1989),
+// Numerical Rcipies in C. The Art of Scientific Computing,
+// Cambridge University Press, ISBN 0-521-35465, pp. 166 ff.
+
//The Factorial Function: return n!
double factrl(int n)
{
@@ -496,6 +539,11 @@ double betai(double a, double b, double x)
else return 1.0 - bt * betacf(b, a, 1.0 - x)/b;
}
+//The following relations are obviously based on:
+// Abramowitz, M. & Stegun I.A. (1964): Hanbook of Mathematical Functions.
+// Applied Mathematics Series, vol. 55 (Washington: National Bureau
+// of Standards).
+
//the binomial coefficient
double bincof(double n, double k)
{
@@ -525,14 +573,8 @@ double errf(double x)
//the complementary error function
double errfc(double x)
{
- double t, z, ans;
-
- z = fabs(x);
- t = 1.0/(1.0+0.5*z);
- ans = t * exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
- t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
- t*(-0.82215223+t*0.17087277)))))))));
- return x >= 0.0 ? ans : 2.0-ans;
+// return x < 0.0 ? 2.0 - gammq(0.5, x*x) : gammq(0.5, x*x);
+ return x < 0.0 ? 1.0 + gammp(0.5, x*x) : gammq(0.5, x*x);
}
//cumulative normal distribution
@@ -541,6 +583,21 @@ double norm_dist(double x, double m, double s)
return 0.5 + errf((x - m)/(s * _SQRT2))/2.0;
}
+//normal ditribution
+double norm_freq(double x, double m, double s)
+{
+ double ex;
+
+ ex = (x-m)/s; ex = exp(-0.5*ex*ex);
+ return ex/(s*sqrt2pi);
+}
+
+//cumulative lognormal distribution
+double lognorm_dist(double x, double m, double s)
+{
+ return 0.5 + errf((log(x) - m)/(s * _SQRT2))/2.0;
+}
+
//chi square distribution
double chi_dist(double x, double df, double)
{
@@ -673,16 +730,36 @@ void d_quartile(int n, double *v, double *q1, double *q2, double *q3)
}
}
+// statistical basics partly based on
+// Davies, J. and Gogh, B. (2000), GSL-1.7 - The GNU scientific library
+//
+//do variance
+double d_variance(int n, double *v, double *mean, double *ss)
+{
+ int i;
+ double d, m, va, e;
+
+ for(i = 0, m = 0.0, d = 1.0; i < n; i++, d += 1.0) {
+ m += (v[i] - m)/d;
+ }
+ if (mean) *mean = m;
+ for(i = 0, va = 0.0, d = 1.0; i < n; i++, d += 1.0) {
+ e = v[i] - m; va += (e * e - va)/d;
+ }
+ if (ss) *ss = va * (double)n;
+ return va * ((double)n/((double)(n-1)));
+}
+
//do arithmethic mean
double d_amean(int n, double *v)
{
int i;
- double sum;
+ double d, mean;
- for(i = 0, sum = 0.0; i < n; i++) {
- sum += (v[i]);
+ for(i = 0, mean = 0.0, d = 1.0; i < n; i++, d += 1.0) {
+ mean += (v[i] - mean)/d;
}
- return (sum/n);
+ return mean;
}
@@ -713,36 +790,88 @@ double d_hmean(int n, double *v)
return (n/sum);
}
+//kurtosis
+double d_kurt(int n, double *v)
+{
+ double sum, avg, sd, tmp, dn = n;
+ int i;
+
+ for(i = 0, sum = 0.0; i < n; i++) sum += v[i];
+ for(i = 0, avg = sum/dn, sum = 0.0; i < n; i++) sum += (tmp = v[i]-avg) * tmp;
+ for(i = 0, sd = sqrt(sum/(dn-1.0)), sum=0.0; i < n; i++) sum += ((tmp = (v[i]-avg)/sd)*tmp*tmp*tmp);
+ sum *= ((dn*(dn+1.0))/((dn-1.0)*(dn-2.0)*(dn-3.0)));
+ tmp = (3.0 * (dn-1.0) * (dn-1.0))/((dn-2.0)*(dn-3.0));
+ return sum - tmp;
+}
+
+//skewness
+double d_skew(int n, double *v)
+{
+ double sum, avg, sd, tmp, dn = n;
+ int i;
+
+ for(i = 0, sum = 0.0; i < n; i++) sum += v[i];
+ for(i = 0, avg = sum/dn, sum = 0.0; i < n; i++) sum += (tmp = v[i]-avg) * tmp;
+ for(i = 0, sd = sqrt(sum/(dn-1.0)), sum=0.0; i < n; i++) sum += ((tmp = (v[i]-avg)/sd)*tmp*tmp);
+ return sum * dn/((dn-1.0)*(dn-2.0));
+}
+
+//---------------------------------------------------------------------------
+// Create a frequency distribution by counting the elements which may be
+// assigned to a bin
+double d_classes(DataObj *d, double start, double step, double *v, int nv, char *range)
+{
+ int i, j, r, c, nc, *f;
+ AccRange *ar;
+
+ if(!range || !nv || !v || step <= 0.0 || !(ar = new AccRange(range))) return 0.0;
+ if(!(nc = ar->CountItems()) || !ar->GetFirst(&c, &r) || !(f=(int*)calloc(nc, sizeof(int)))) {
+ delete ar; return 0.0;
+ }
+ for(i = 0; i < nv; i++) {
+ j = (int)(floor((v[i] - start)/step));
+ if(j < 0) j = 0; if(j >= nc) j = (nc-1);
+ f[j]++;
+ }
+ for( ; nc > 0 && !(f[nc-1]); nc--);
+ for(i = 0; ar->GetNext(&c, &r) && i < nc; i++) {
+ d->SetValue(r, c, (double)f[i]);
+ }
+ free(f); return ((double)nv);
+}
+
//---------------------------------------------------------------------------
// Pearsons linear correlation
-// Ref.: W.H. Press, B.P. Flannery, S.A. Teukolsky, W.T. Vetterling (1989),
+// (1) W.H. Press, B.P. Flannery, S.A. Teukolsky, W.T. Vetterling (1989),
// Numerical Rcipies in C. The Art of Scientific Computing,
// Cambridge University Press, ISBN 0-521-35465, pp. 503 ff.
+// (2) B. Gough (2000), linear.c, gsl-1.7 the GNU scientific library
double d_pearson(double *x, double *y, int n, char *dest, DataObj *data)
{
int j, r, c;
- double yt, xt, t, df, res[3];
+ double yt, xt, t, df, res[4];
double syy=0.0, sxy=0.0, sxx=0.0, ay=0.0, ax=0.0;
AccRange *rD;
for(j = 0; j < n; j++) { // find means
- ax += x[j]; ay += y[j];
+ ax += (x[j] - ax) / (j+1); ay += (y[j] - ay) / (j+1);
}
- ax /= n; ay /= n;
for(j = 0; j < n; j++) { // correlation
- xt = x[j] - ax; yt = y[j] - ay;
- sxx += xt*xt; syy += yt*yt; sxy += xt * yt;
+ xt = x[j] - ax; yt = y[j] - ay;
+ sxx += (xt*xt-sxx) / (j+1); syy += (yt*yt-syy) / (j+1);
+ sxy += (xt*yt-sxy) / (j+1);
}
- res[0] = sxy/sqrt(sxx*syy); //pearsons r
+ res[0] = sxy/sqrt(sxx*syy); //pearsons r
if(dest) {
res[1] = 0.5 * log((1.0+res[0]+_PREC)/(1.0-res[0]+_PREC)); //Fishers z-transform
df = n-2;
t = res[0]*sqrt(df/((1.0-res[0]+_PREC)*(1.0+res[0]+_PREC))); //Student's t
res[2] = betai(0.5*df, 0.5, df/(df+t*t)); //probability
+ res[3] = n;
}
if((dest) && (data) && (rD = new AccRange(dest))) {
rD->GetFirst(&c, &r);
- for(j = 0; j < 3 && rD->GetNext(&c, &r); j++) {
+ for(j = 0; j < 4 && rD->GetNext(&c, &r); j++) {
data->SetValue(r, c, res[j]);
}
data->Command(CMD_UPDATE, 0L, 0L);
@@ -752,6 +881,26 @@ double d_pearson(double *x, double *y, int n, char *dest, DataObj *data)
}
//---------------------------------------------------------------------------
+// Given an array w, rank returns the rank of v1 in v
+// if v1 is not found in v 0 is returned
+double d_rank(int n, double *v, double v1)
+{
+ double *sv;
+ int i, j;
+
+ if(!n || !v) return 0.0; if(n < 2) return 1.0;
+ if(!(sv = (double*)memdup(v, n * sizeof(double), 0))) return 0.0;
+ SortArray(n, sv);
+ for(i = j = 0; i < n; i++) {
+ if(v1 == sv[i]) {
+ for( ;(i+j)<n; j++) if(sv[i+j] > v1) break;
+ free(sv); return (double)i + 1.0 + (((double)j-1.0)/2.0);
+ }
+ }
+ free(sv); return 0.0;
+}
+
+//---------------------------------------------------------------------------
// Spearman rank-order correlation
// Ref.: W.H. Press, B.P. Flannery, S.A. Teukolsky, W.T. Vetterling (1989),
// Numerical Recipies in C. The Art of Scientific Computing,
@@ -786,7 +935,7 @@ double d_spearman(double *x, double *y, int n, char *dest, DataObj *data)
{
int j, r, c;
double vard, t, sg, sf, fac, en3n, en, df, aved, tmp;
- double res[5];
+ double res[6];
AccRange *rD;
SortArray2(n, x, y); crank(n, x, &sf);
@@ -804,8 +953,8 @@ double d_spearman(double *x, double *y, int n, char *dest, DataObj *data)
df = en-2.0;
res[4] = betai(0.5*df, 0.5, df/(df+t*t));
if((dest) && (data) && (rD = new AccRange(dest))) {
- rD->GetFirst(&c, &r);
- for(j = 0; j < 5 && rD->GetNext(&c, &r); j++) {
+ rD->GetFirst(&c, &r); res[5] = n;
+ for(j = 0; j < 6 && rD->GetNext(&c, &r); j++) {
data->SetValue(r, c, res[j]);
}
data->Command(CMD_UPDATE, 0L, 0L);
@@ -814,12 +963,52 @@ double d_spearman(double *x, double *y, int n, char *dest, DataObj *data)
return res[3];
}
+//---------------------------------------------------------------------------
+// Kendal's non-parametric correlation
+// Ref.: W.H. Press, B.P. Flannery, S.A. Teukolsky, W.T. Vetterling (1989),
+// Numerical Recipies in C. The Art of Scientific Computing,
+// Cambridge University Press, ISBN 0-521-35465, pp. 510 ff.
+
+double d_kendall(double *x, double *y, int n, char *dest, DataObj *data)
+{
+ int j, k, n1, n2, is, r, c;
+ double aa, a1, a2, sv, res[4];
+ AccRange *rD;
+
+ for (j = n1 = n2 = is = 0; j < (n-1); j++) {
+ for(k = j+1; k < n; k++) {
+ a1 = x[j] - x[k]; a2 = y[j] - y[k]; aa = a1*a2;
+ if(aa != 0.0) {
+ n1++; n2++;
+ if (aa > 0.0) is++;
+ else is--;
+ }
+ else {
+ if(a1 != 0.0) n1++; if(a2 != 0.0) n2++;
+ }
+ }
+ }
+ res[0] = ((double)is)/(sqrt((double)n1) * sqrt((double)n2));
+ if((dest) && (data) && (rD = new AccRange(dest))) {
+ sv = (4.0 * ((double)n) + 10.0)/(9.0*((double)n)*((double)(n-1)));
+ res[1] = res[0]/sqrt(sv); res[2] = errfc(fabs(res[1])/_SQRT2);
+ res[3] = n; rD->GetFirst(&c, &r);
+ for(j = 0; j < 4 && rD->GetNext(&c, &r); j++) {
+ data->SetValue(r, c, res[j]);
+ }
+ data->Command(CMD_UPDATE, 0L, 0L);
+ delete rD;
+ }
+ return res[0];
+}
+
+
//linear regression
double d_regression(double *x, double *y, int n, char *dest, DataObj *data)
{
- double sx, sy, dx, dy, sxy, sxx, syy, sdy;
+ double sx, sy, dx, dy, sxy, sxx, syy, sdy, df;
double res[10]; // slope, intercept, mean x, mean y, SE of slope,
- // variance(x), variance(y), variance(fit), F of regression
+ // variance(x), variance(y), variance(fit), F of regression, significance
int i, j, r, c;
AccRange *rD;
@@ -838,12 +1027,13 @@ double d_regression(double *x, double *y, int n, char *dest, DataObj *data)
dy = y[i] - (res[1] + x[i] *res[0]);
sdy += (dy * dy);
}
- sdy = sdy/(n-2); res[4] = sqrt(sdy/sxx);
+ sdy = sdy/(n-2); res[4] = sqrt(sdy/sxx); df = (n-2);
res[5] = sxx/(n-1); res[6] = syy/(n-1); res[7] = sdy;
res[8] = sxy/sdy*sxy/sxx;
+ res[9] = betai(df/2.0, 0.5, df/(df+res[8]));
if((dest) && (data) && (rD = new AccRange(dest))) {
rD->GetFirst(&c, &r);
- for(j = 0; j < 9 && rD->GetNext(&c, &r); j++) {
+ for(j = 0; j < 10 && rD->GetNext(&c, &r); j++) {
data->SetValue(r, c, res[j]);
}
data->Command(CMD_UPDATE, 0L, 0L);
@@ -852,6 +1042,65 @@ double d_regression(double *x, double *y, int n, char *dest, DataObj *data)
return n;
}
+//covariance
+double d_covar(double *x, double *y, int n, char *dest, DataObj *data)
+{
+ int i;
+ double sx, sy, dx, dy, sxy;
+
+ if(n < 2) return 0.0;
+ for(i = 0, sx = sy = 0.0; i < n; i++) {
+ sx += x[i]; sy += y[i];
+ }
+ sx /= n; sy /= n; sxy = 0.0;
+ for(i = 0; i < n; i++) {
+ dx = x[i]-sx; dy = y[i]-sy;
+ sxy += (dx*dy - sxy) / (i+1);
+ }
+ return sxy;
+}
+
+//Mann-Whitney U Test
+double d_utest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
+{
+ double *da, *ta, u1, u2, su, tmp;
+ double res[7];
+ AccRange *rD;
+ int i, j, n, r, c;
+
+ if(!x || !y || n1 < 2 || n2 < 2) return 0.0;
+ da = (double*)malloc((n = (n1+n2)) * sizeof(double));
+ ta = (double*)malloc(n * sizeof(double));
+ if(!da || !ta) {
+ if(da) free(da); if(ta) free(ta); return 0.0;
+ }
+ for(i = 0; i < n1; i++) {
+ da[i] = x[i]; ta[i] = 1.0;
+ }
+ for(j = 0; j < n2; j++) {
+ da[i] = y[j]; ta[i++] = 2.0;
+ }
+ SortArray2(n, da, ta); crank(n, da, &tmp);
+ for(i = 0, res[0] = res[1] = 0.0; i < n; i++) {
+ if(ta[i] == 1.0) res[0] += da[i];
+ else res[1] += da[i];
+ }
+ free(da); free(ta);
+ u1 = (n1*n2 + (n1*(n1+1))/2.0) - res[0]; u2 = (n1*n2 + ((n2+1)*n2)/2.0) - res[1];
+ su = sqrt((n1*n2*(n1+n2+1))/12.0); res[2] = u2 > u1 ? u2 : u1;
+ res[3] = (res[2] - (n1*n2)/2.0)/su; res[6] = errfc(res[3]/_SQRT2);
+ if((dest) && (data) && (rD = new AccRange(dest))) {
+ res[4] = n1; res[5] = n2;
+ rD->GetFirst(&c, &r);
+ for(i = 0; i < 7 && rD->GetNext(&c, &r); i++) {
+ data->SetValue(r, c, res[i]);
+ }
+ data->Command(CMD_UPDATE, 0L, 0L);
+ delete rD;
+ }
+ return res[6];
+}
+
//t-test
double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
{
@@ -860,17 +1109,19 @@ double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
double res[9]; // mean1, SD1, n1, mean2, SD2, n2, p if variances equal,
AccRange *rD; // corrected df, corrected p
- for(i=0, sx = 0.0; i < n1; sx += x[i], i++); mx = sx/n1;
- for(i=0, sy = 0.0; i < n2; sy += y[i], i++); my = sy/n2;
- for(i=0, sx = 0.0; i < n1; sx += ((d=(x[i]-mx))*d), i++);
- for(i=0, sy = 0.0; i < n2; sy += ((d=(y[i]-my))*d), i++);
- d = ((sx+sy)/(n1+n2-2)) * ((double)(n1+n2)/(double)(n1*n2));
- d = (mx-my)/sqrt(d); //Student's t
+ d_variance(n1, x, &mx, &sx); d_variance(n2, y, &my, &sy);
+ d = ((sx+sy)/(n1+n2-2)) * ((double)(n1+n2)/(double)(n1*n2));
+ d = (mx-my)/sqrt(d); //Student's t
//Welch's correction for differences in variance
df = (sx/(double)n1)*(sx/(double)n1)/(double)(n1+1)+(sy/(double)n2)*(sy/(double)n2)/(double)(n2+1);
df = (sx/(double)n1+sy/(double)n2)*(sx/(double)n1+sy/(double)n2)/df;
df -= 2.0;
+
+// an alternative formula for correction
+// p = (sx/(double)n1)*(sx/(double)n1)/(double)(n1-1) + (sy/(double)n2)*(sy/(double)n2)/(double)(n2-1);
+// df = (sx/(double)n1 + sy/(double)n2) * (sx/(double)n1 + sy/(double)n2) / p;
+
p = betai(df/2.0, 0.5, (df/(df+d*d)));
if((dest) && (data) && (rD = new AccRange(dest))) {
res[0] = mx; res[1] = sqrt(sx/(double)(n1-1)); res[2] = n1;
@@ -887,6 +1138,33 @@ double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
return p;
}
+//t-test for paired samples
+double d_ttest2(double *x, double *y, int n, char *dest, DataObj *data)
+{
+ double sx, sy, mx, my, df, cov, sd, t, p;
+ int i, r, c;
+ double res[6]; // mean1, SD1, mean2, SD2, n, p
+ AccRange *rD;
+
+ d_variance(n, x, &mx, &sx); d_variance(n, y, &my, &sy);
+ sx = d_variance(n, x, &mx); sy = d_variance(n, y, &my);
+ cov = d_covar(x, y, n, 0L, 0L) * ((double)n/(double)(n-1));
+ sd = sqrt((sx+sy-2*cov)/n);
+ t = (mx-my)/sd; df = (n-1);
+ p = betai(0.5*df, 0.5, df/(df+t*t));
+ if((dest) && (data) && (rD = new AccRange(dest))) {
+ res[0] = mx; res[1] = sqrt(sx); res[5] = p;
+ res[2] = my; res[3] = sqrt(sy); res[4] = n;
+ rD->GetFirst(&c, &r);
+ for(i = 0; i < 6 && rD->GetNext(&c, &r); i++) {
+ data->SetValue(r, c, res[i]);
+ }
+ data->Command(CMD_UPDATE, 0L, 0L);
+ delete rD;
+ }
+ return p;
+}
+
//f-test
double d_ftest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
{
@@ -899,8 +1177,14 @@ double d_ftest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
for(i=0, sy = 0.0; i < n2; sy += y[i], i++); my = sy/n2;
for(i=0, sx = 0.0; i < n1; sx += ((d=(x[i]-mx))*d), i++); sx /= (n1-1);
for(i=0, sy = 0.0; i < n2; sy += ((d=(y[i]-my))*d), i++); sy /= (n2-1);
- d = sx/sy; df1 = n1-1; df2 = n2-1;
- p= 2.0 * betai(df2/2.0, df1/2.0, df2/(df2+df1*d));
+ if(sx > sy) {
+ d = sx/sy; df1 = n1-1; df2 = n2-1;
+ }
+ else {
+ d = sy/sx; df1 = n2-1; df2 = n1-1;
+ }
+ p = 2.0 * betai(df2/2.0, df1/2.0, df2/(df2+df1*d));
+ if(p > 1.0) p = 2.0-p;
if((dest) && (data) && (rD = new AccRange(dest))) {
res[0] = mx; res[1] = sqrt(sx); res[2] = n1;
res[3] = my; res[4] = sqrt(sy); res[5] = n2;
@@ -913,3 +1197,344 @@ double d_ftest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
}
return p;
}
+
+//---------------------------------------------------------------------------
+// Calendar, Date- and time functions
+// The following characters are used as format specifiers in a format string,
+// all other characters are either ignored or copyied to the output
+//
+// Y four digits year y two digits year
+// X month's full name x three character month name
+// Z two digits day of month z same as Z but no leading zero
+// V two digit month number v number of month
+// W single letter month
+// D full name of day d three characters for day name
+// E two digits weekday e one or two digits weekday
+// F single character day name
+// H two digits for hours h hours with no leading zero
+// M two digits for minutes m minutes with no leading zero
+// S two digits for seconds s seconds with no leading zero
+// T two digits seconds, two dec. t same as T but no leading zero
+// U full precision seconds
+
+static char *dt_month[] = {"January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"};
+
+static char *dt_months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
+ "Sep", "Oct", "Nov", "Dec"};
+
+static int dt_monthl[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static char *dt_day[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday"};
+
+static char *dt_days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+
+typedef struct rlp_datetime {
+ int aday, year, doy, month, dom, dow, hours, minutes;
+ double seconds;
+}rlp_datetime;
+
+static bool leapyear(int year) {
+ return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
+}
+
+static int year2aday(int y)
+{
+ int aday, y1;
+
+ y1 = y - 1900;
+ aday = y1 * 365;
+ aday += ((y1-1) >> 2 );
+ aday -= (y1 / 100);
+ aday += ((y/400)-4);
+ return aday;
+}
+
+static void set_dow(rlp_datetime *dt)
+{
+ dt->dow = (dt->aday %7)+1;
+}
+
+static int parse_date (rlp_datetime *dt, char *src, char *fmt)
+{
+ int i, j, k;
+ char tmp_str[10];
+
+ if(!src || !src[0] || !fmt || !fmt[0]) return 0;
+ if(*src == '\'') src++;
+ for(i = j = 0; fmt[i] && src[j]; i++) {
+ switch (fmt[i]) {
+ case 'Y': case 'y': // year is numeric
+ if(j && src[j] == '-' || src[j] == '/' || src[j] == '.') j++;
+ if(sscanf(src+j, "%d", &dt->year)) {
+ if(dt->year < 0) return 0;
+ while(isdigit(src[j])) j++;
+ if(dt->year<60) dt->year += 2000;
+ else if(dt->year <99) dt->year += 1900;
+ }
+ else return 0;
+ break;
+ case 'X': case 'x': // month can be text
+ if(j && src[j] == '-' || src[j] == '/' || src[j] == '.') j++;
+ tmp_str[0] = toupper(src[j]);
+ tmp_str[1] = tolower(src[j+1]);
+ tmp_str[2] = tolower(src[j+2]);
+ tmp_str[3] = 0;
+ for(k = dt->month = 0; k < 12; k++) {
+ if(0 == strcmp(tmp_str,dt_months[k])) {
+ dt->month = k+1; break;
+ }
+ }
+ if(dt->month) while(isalpha(src[j])) j++;
+ else return 0;
+ break;
+ case 'V': case 'v': // or numeric
+ if(j && src[j] == '-' || src[j] == '/' || src[j] == '.') j++;
+ if(sscanf(src+j, "%d", &dt->month)) {
+ if(dt->month <= 0 || dt->month > 12) return 0;
+ j++; if(isdigit(src[j])) j++;
+ }
+ else return 0;
+ break;
+ case 'Z': case 'z': // day of month is numeric
+ if(j && src[j] == '-' || src[j] == '/' || src[j] == '.') j++;
+ if(sscanf(src+j, "%d", &dt->dom)) {
+ if(dt->dom <= 0 || dt->dom > 31) return 0;
+ j++; if(isdigit(src[j])) j++;
+ }
+ else return 0;
+ break;
+ case 'H': case 'h': // hours are numeric
+ if(sscanf(src+j, "%2d", &dt->hours)) {
+ if(dt->hours < 0 || dt->hours > 23) return 0;
+ j++; if(isdigit(src[j])) j++;
+ }
+ else return 0;
+ break;
+ case 'M': case 'm': // minutes are numeric
+ if(j && src[j] == ' ' || src[j] == ':') j++;
+ if(sscanf(src+j, "%2d", &dt->minutes)) {
+ if(dt->minutes < 0 || dt->minutes >= 60) return 0;
+ j++; if(isdigit(src[j])) j++;
+ }
+ else return 0;
+ break;
+ case 'S': case 's': // seconds are numeric
+ case 'T': case 't':
+ if(j && src[j] == ' ' || src[j] == ':') j++;
+ if(sscanf(src+j, "%lf", &dt->seconds)) {
+ if(dt->seconds < 0.0 || dt->seconds >= 60.0) return 0;
+ while(isdigit(src[j]) || src[j] == '.') j++;
+ }
+ else return 0;
+ dt->seconds += 1.0e-12;
+ break;
+ default:
+ if(fmt[i] && fmt[i] == src[j]) j++;
+ }
+ }
+ if(dt->year && dt->month && dt->dom) {
+ for(dt->doy = 0, i = dt->month-2; i >= 0; i--) {
+ if(i == 1) dt->doy += leapyear(dt->year) ? 29 : 28;
+ else dt->doy += dt_monthl[i];
+ }
+ dt->doy += dt->dom;
+ if(dt->year >= 1900) dt->aday = year2aday(dt->year);
+ dt->aday += dt->doy;
+ }
+ return j;
+}
+
+static char *date2text(rlp_datetime *dt, char *fmt)
+{
+ static char res[80];
+ int i, pos;
+ double secs;
+
+ res[0] = 0;
+ if(!fmt || !fmt[0] || !dt) return res;
+ set_dow(dt);
+ secs = dt->seconds;
+ if (secs > 59.4999) secs = 59.4999;
+ for(pos = i = 0; fmt[i] && pos < 70; i++) {
+ switch(fmt[i]) {
+ case 'Y':
+ if(dt->year) pos+=sprintf(res+pos, "%4d", dt->year);
+ else pos += sprintf(res+pos, "####"); break;
+ case 'y':
+ if(dt->year) pos+=sprintf(res+pos, "%02d", (dt->year %100));
+ else pos += sprintf(res+pos, "##"); break;
+ case 'Z':
+ if(dt->dom) pos+=sprintf(res+pos, "%02d", dt->dom);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'z':
+ if(dt->dom) pos+=sprintf(res+pos, "%d", dt->dom);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'X':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf(res+pos, "%s", dt_month[dt->month-1]);
+ else pos += sprintf(res+pos, "###"); break;
+ case 'x':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf(res+pos, "%s", dt_months[dt->month-1]);
+ else pos += sprintf(res+pos, "###"); break;
+ case 'V':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf(res+pos, "%02d", dt->month);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'v':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf(res+pos, "%d", dt->month);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'W':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf(res+pos, "%c", dt_month[dt->month-1][0]);
+ else pos += sprintf(res+pos, "#"); break;
+ case 'D':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf(res+pos, "%s", dt_day[dt->dow-1]);
+ else pos += sprintf(res+pos, "###"); break;
+ case 'd':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf(res+pos, "%s", dt_days[dt->dow-1]);
+ else pos += sprintf(res+pos, "###"); break;
+ case 'E':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf(res+pos, "%02d", dt->dow);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'e':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf(res+pos, "%d", dt->dow);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'F':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf(res+pos, "%c", dt_day[dt->dow-1][0]);
+ else pos += sprintf(res+pos, "#"); break;
+ case 'H':
+ if(dt->hours >=0 && dt->hours < 24) pos+=sprintf(res+pos, "%02d", dt->hours);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'h':
+ if(dt->hours >=0 && dt->hours < 24) pos+=sprintf(res+pos, "%d", dt->hours);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'M':
+ if(dt->minutes >=0 && dt->minutes < 60) pos+=sprintf(res+pos, "%02d", dt->minutes);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'm':
+ if(dt->minutes >=0 && dt->minutes < 60) pos+=sprintf(res+pos, "%d", dt->minutes);
+ else pos += sprintf(res+pos, "##"); break;
+ case 'S':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf(res+pos, "%02d", iround(secs));
+ else pos += sprintf(res+pos, "##"); break;
+ case 's':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf(res+pos, "%d", iround(secs));
+ else pos += sprintf(res+pos, "##"); break;
+ case 'T':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf(res+pos, "%02.2lf", dt->seconds);
+ else pos += sprintf(res+pos, "##.##"); break;
+ case 't':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf(res+pos, "%.2lf", dt->seconds);
+ else pos += sprintf(res+pos, "##.##"); break;
+ default:
+ pos += sprintf(res+pos, "%c", fmt[i]); break;
+ }
+ }
+ res[pos] = 0;
+ return res;
+}
+
+static double date2value(rlp_datetime *dt)
+{
+ double res;
+
+ if(!dt) return 0.0;
+
+ res = dt->seconds/60.0 + (double)dt->minutes;
+ res = res/60.0 + (double)dt->hours;
+ res = res/24.0 + (double)dt->aday;
+ return res;
+}
+
+static void parse_datevalue(rlp_datetime *dt, double dv)
+{
+ int i, j, d;
+
+ if(!dt || dv < 0.0) return;
+ if(dv > 1.0) {
+ dt->aday = (int)floor(dv);
+ dt->year = (int)(dv/365.2425);
+ d = (int)floor(dv);
+ do {
+ dt->doy = d - 365*dt->year;
+ dt->doy -= ((dt->year-1)>>2);
+ dt->doy += ((dt->year)/100);
+ dt->doy -= ((dt->year+300)/400);
+ if(dt->doy < 1) dt->year--;
+ }while(dt->doy < 1);
+ dt->year += 1900;
+ for(i = dt->month = 0, d = dt->doy; i < 12 && d > 0; i++) {
+ if(i == 1 && d > (j = (leapyear(dt->year)) ? 29 : 28)) d -= j;
+ else if(i != 1 && d > dt_monthl[i]) d -= dt_monthl[i];
+ else break;
+ }
+ dt->month = i+1; dt->dom = d;
+ }
+ dv -= floor(dv); dv *= 24.0;
+ dt->hours = (int)floor(dv); dv -= floor(dv);
+ dv *= 60.0; dt->minutes = (int)floor(dv);
+ dv -= floor(dv); dt->seconds = dv *60.0 + 1.0e-12;
+ if(dt->seconds > 59.9999) {
+ dt->seconds = 0.0; dt->minutes++;
+ if(dt->minutes == 60) {
+ dt->hours++; dt->minutes = 0;
+ }
+ }
+}
+
+static char *dt_popfmt[] = {"Z.V.Y H:M:S", "Z/V/Y H:M:S", "Z-V-Y H:M:S", "Z.X.Y H:M:S",
+ "Y.V.Z H:M:S", "Y-X-Z H:M:S", "H:M:S", 0L};
+
+bool date_value(char *desc, char *fmt, double *value)
+{
+ int i;
+ rlp_datetime dt;
+
+ dt.year = dt.aday = dt.doy = dt.month = dt.dom = dt.dow = dt.hours = dt.minutes = 0;
+ dt.seconds = 0.0;
+ if(!value || !desc || !desc[0]) return false;
+ if(fmt && fmt[0]) {
+ if(parse_date(&dt, desc, fmt)) {
+ *value = date2value(&dt); return true;
+ }
+ }
+ else {
+ if(parse_date(&dt, desc, defs.fmt_datetime)) {
+ *value = date2value(&dt); return true;
+ }
+ }
+ for(i=0; dt_popfmt[i]; i++) {
+ if(parse_date(&dt, desc, dt_popfmt[i])) {
+ *value = date2value(&dt); return true;
+ }
+ }
+ return false;
+}
+
+char *value_date(double dv, char *fmt)
+{
+ rlp_datetime dt;
+
+ parse_datevalue(&dt, dv);
+ return date2text(&dt, fmt ? fmt : defs.fmt_date);
+}
+
+double now_today()
+{
+ double res = 0.0;
+ time_t ti = time(0L);
+
+ date_value(ctime(&ti)+4, "x z H:M:S Y", &res);
+ return res;
+}
+
+void split_date(double dv, int *y, int *mo, int *dom, int *dow, int *doy, int *h, int *m, double *s)
+{
+ rlp_datetime dt;
+
+ parse_datevalue(&dt, dv);
+ set_dow(&dt);
+ if(y) *y = dt.year; if(mo) *mo = dt.month;
+ if(dom) *dom = dt.dom; if(dow) *dow = dt.dow;
+ if(doy) *doy = dt.doy; if(h) *h = dt.hours;
+ if(m) *m = dt.minutes; if(s) *s = dt.seconds;
+}
diff --git a/rlplot.cpp b/rlplot.cpp
index 0c1fdd5..6856d42 100755
--- a/rlplot.cpp
+++ b/rlplot.cpp
@@ -1,4 +1,4 @@
-//RLPlot.cpp, Copyright 2000, 2001, 2002, 2003, 2004, 2005 R.Lackner
+//RLPlot.cpp, Copyright 2000-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -91,7 +91,7 @@ GraphObj::Track(POINT *p, anyOutput *o)
// Spread sheet buttons used for rows and columns
ssButton::ssButton(GraphObj *par, int x, int y, int w, int h):GraphObj(par, 0L)
{
- bLBdown = false;
+ bLBdown = bSelected = bMarked = false;
SetMinMaxRect(&rDims, x, y, x+w, y+h);
Line.width = 0.0f; Line.patlength = 1.0f;
Line.color = 0x00000000L; Line.pattern = 0x00000000L;
@@ -102,7 +102,6 @@ ssButton::ssButton(GraphObj *par, int x, int y, int w, int h):GraphObj(par, 0L)
TextDef.iSize = 0; TextDef.Align = TXA_HLEFT | TXA_VTOP;
TextDef.Mode = TXM_TRANSPARENT; TextDef.Style = TXS_NORMAL;
TextDef.Font = FONT_HELVETICA; TextDef.text = 0L;
- bSelected = false;
}
ssButton::~ssButton()
@@ -115,7 +114,13 @@ ssButton::DoPlot(anyOutput *o)
{
POINT pts[3];
- Line.color = 0x00000000L; Fill.color = bSelected ? 0x00ffffff : 0x00e8e8e8L;
+ Line.color = 0x00000000L;
+ if(bSelected) {
+ Fill.color = bMarked ? 0x00ffffe0L : 0x00ffffffL;
+ }
+ else {
+ Fill.color = bMarked ? 0x00ffe0e0L : 0x00e8e8e8L;
+ }
o->SetLine(&Line); o->SetFill(&Fill);
if(bLBdown){
o->oRectangle(rDims.left, rDims.top, rDims.right, rDims.bottom);
@@ -167,7 +172,17 @@ ssButton::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_SELECT:
if(tmpl && *((int*)tmpl)) bSelected = true;
else bSelected = false;
- if(o) DoPlot(o);
+ if(o) {
+ DoPlot(o);
+ o->UpdateRect(&rDims, false);
+ }
+ return true;
+ case CMD_SETSTYLE:
+ if(tmpl && *((int*)tmpl)) bMarked = true;
+ else bMarked = false;
+ if(o) {
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ }
return true;
case CMD_SETTEXT:
if(TextDef.text) free(TextDef.text);
@@ -204,350 +219,399 @@ ssButton::Command(int cmd, void *tmpl, anyOutput *o)
}
return false;
}
-
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// drag handles are graphic objects which allow the user to interactively
// change the size of an object
-dragHandle::dragHandle(GraphObj *par, int which):GraphObj(par, 0L)
-{
- type = which;
- Id = GO_DRAGHANDLE;
- LineDef.width = LineDef.patlength = 0.0;
- LineDef.color = LineDef.pattern = 0L;
- FillDef.type = FILL_NONE;
- FillDef.color = 0x00ffffffL;
- FillDef.scale = 1.0;
- FillDef.hatch = 0L;
- minRC = maxRC = 0L;
-}
-
-dragHandle::~dragHandle()
-{
- if(minRC) free(minRC);
- if(maxRC) free(maxRC);
- if(CurrHandle == this) CurrHandle = 0L;
-}
-
-void
-dragHandle::DoPlot(anyOutput *o)
-{
- double fx, fy, dx, dy;
- int ix, iy;
- fPOINT3D fp3d, ifp3d;
- bool is3D = false;
-
- if(!o || !parent) return;
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- SetMinMaxRect(&drec, o->co2ix(parent->GetSize(SIZE_XPOS)+dx),
- o->co2iy(parent->GetSize(SIZE_YPOS)+dy), o->co2ix(parent->GetSize(SIZE_XPOS+1)+dx),
- o->co2iy(parent->GetSize(SIZE_YPOS+1)+dy));
- switch(type) {
- case DH_19: case DH_12:
- fx = parent->GetSize(SIZE_XPOS); fy = parent->GetSize(SIZE_YPOS);
- break;
- case DH_99: case DH_22:
- fx = parent->GetSize(SIZE_XPOS+1); fy = parent->GetSize(SIZE_YPOS+1);
- break;
- case DH_29:
- fx = (parent->GetSize(SIZE_XPOS) + parent->GetSize(SIZE_XPOS+1))/2.0;
- fy = parent->GetSize(SIZE_YPOS);
- break;
- case DH_39:
- fx = parent->GetSize(SIZE_XPOS+1); fy = parent->GetSize(SIZE_YPOS);
- break;
- case DH_49:
- fx = parent->GetSize(SIZE_XPOS);
- fy = (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
- break;
- case DH_59:
- fx = (parent->GetSize(SIZE_XPOS) + parent->GetSize(SIZE_XPOS+1))/2.0;
- fy = (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
- break;
- case DH_69:
- fx = parent->GetSize(SIZE_XPOS+1);
- fy = (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
- break;
- case DH_79:
- fx = parent->GetSize(SIZE_XPOS);
- fy = parent->GetSize(SIZE_YPOS+1);
- break;
- case DH_89:
- fx = (parent->GetSize(SIZE_XPOS) + parent->GetSize(SIZE_XPOS+1))/2.0;
- fy = parent->GetSize(SIZE_YPOS+1);
- break;
- case DH_18: case DH_28: case DH_38: case DH_48:
- case DH_58: case DH_68: case DH_78: case DH_88:
- fp3d.fx = parent->GetSize(SIZE_XPOS + type - DH_18);
- fp3d.fy = parent->GetSize(SIZE_YPOS + type - DH_18);
- fp3d.fz = parent->GetSize(SIZE_ZPOS + type - DH_18);
- is3D = true;
- break;
- default:
- if(type >= DH_DATA) {
- fx = parent->GetSize(SIZE_XPOS + type - DH_DATA);
- fy = parent->GetSize(SIZE_YPOS + type - DH_DATA);
- FillDef.color = (this == CurrHandle) ? 0x0L : 0x00ffffffL;
- }
- else return;
- }
- if(is3D) {
- o->cvec2ivec(&fp3d, &ifp3d);
- ix = iround(ifp3d.fx); iy = iround(ifp3d.fy);
- }
- else {
- ix = o->co2ix(fx+dx); iy = o->co2iy(fy+dy);
- }
- SetMinMaxRect(&rDims, ix-4, iy-4, ix+4, iy+4);
- memcpy(&upd, &rDims, sizeof(RECT));
- switch(type) {
- case DH_12: case DH_22: case DH_19: case DH_29: case DH_39:
- case DH_49: case DH_69: case DH_79: case DH_89: case DH_99:
- o->SetLine(&LineDef); o->SetFill(&FillDef);
- o->oRectangle(rDims.left, rDims.top, rDims.right, rDims.bottom);
- o->UpdateRect(&rDims, false);
- break;
- case DH_59:
- o->SetLine(&LineDef); o->SetFill(&FillDef);
- IncrementMinMaxRect(&rDims, 2);
- o->oCircle(rDims.left, rDims.top, rDims.right, rDims.bottom);
- IncrementMinMaxRect(&rDims, 1);
- o->UpdateRect(&rDims, false);
- break;
- default:
- if(type >= DH_DATA) {
- o->SetLine(&LineDef); o->SetFill(&FillDef);
- o->oRectangle(rDims.left, rDims.top, rDims.right, rDims.bottom);
- o->UpdateRect(&rDims, false);
- }
- else {
- IncrementMinMaxRect(&rDims, -1);
- o->UpdateRect(&rDims, true);
- }
- break;
- }
-}
-
-bool
-dragHandle::Command(int cmd, void *tmpl, anyOutput *o)
-{
- lfPOINT pos;
- int idx;
-
- if(!parent) return false;
- switch (cmd) {
- case CMD_MOUSECURSOR:
- if(o) switch(type) {
- case DH_19: case DH_99:
- o->MouseCursor(MC_SE, false); break;
- case DH_29: case DH_89:
- o->MouseCursor(MC_NORTH, false); break;
- case DH_39: case DH_79:
- o->MouseCursor(MC_NE, false); break;
- case DH_49: case DH_69:
- o->MouseCursor(MC_EAST, false); break;
- default:
- if(type >= DH_DATA) o->MouseCursor(MC_SALL, false);
- else o->MouseCursor(MC_MOVE, false); break;
- }
- return true;
- case CMD_MINRC:
- if(!(minRC)) minRC = (RECT*)calloc(1, sizeof(RECT));
- if(tmpl && minRC) SetMinMaxRect(minRC, ((RECT*)tmpl)->left, ((RECT*)tmpl)->top,
- ((RECT*)tmpl)->right, ((RECT*)tmpl)->bottom);
- return true;
- case CMD_MAXRC:
- if(!(maxRC)) maxRC = (RECT*)calloc(1, sizeof(RECT));
- if(tmpl && maxRC) SetMinMaxRect(maxRC, ((RECT*)tmpl)->left, ((RECT*)tmpl)->top,
- ((RECT*)tmpl)->right, ((RECT*)tmpl)->bottom);
- return true;
- case CMD_MOVE:
- idx = type >= DH_DATA ? type - DH_DATA : 0;
- pos.fx = NiceValue(((lfPOINT*)tmpl)[0].fx);
- pos.fy = NiceValue(((lfPOINT*)tmpl)[0].fy);
- if(pos.fx == 0.0 && pos.fy == 0.0) return false;
- parent->Command(CMD_SAVEPOS, &idx, o);
- switch(type) {
- case DH_12:
- parent->SetSize(SIZE_XPOS, pos.fx + parent->GetSize(SIZE_XPOS));
- parent->SetSize(SIZE_YPOS, pos.fy + parent->GetSize(SIZE_YPOS));
- break;
- case DH_22:
- parent->SetSize(SIZE_XPOS+1, pos.fx + parent->GetSize(SIZE_XPOS+1));
- parent->SetSize(SIZE_YPOS+1, pos.fy + parent->GetSize(SIZE_YPOS+1));
- break;
- case DH_19: parent->parent->SetSize(SIZE_XPOS,
- pos.fx + parent->GetSize(SIZE_XPOS));
- case DH_29: parent->parent->SetSize(SIZE_YPOS,
- pos.fy + parent->GetSize(SIZE_YPOS));
- break;
- case DH_39: parent->parent->SetSize(SIZE_YPOS,
- pos.fy + parent->GetSize(SIZE_YPOS));
- case DH_69: parent->parent->SetSize(SIZE_XPOS+1,
- pos.fx + parent->GetSize(SIZE_XPOS+1));
- break;
- case DH_99: parent->parent->SetSize(SIZE_XPOS+1,
- pos.fx + parent->GetSize(SIZE_XPOS+1));
- case DH_89: parent->parent->SetSize(SIZE_YPOS+1,
- pos.fy + parent->GetSize(SIZE_YPOS+1));
- break;
- case DH_79: parent->parent->SetSize(SIZE_YPOS+1,
- pos.fy + parent->GetSize(SIZE_YPOS+1));
- case DH_49:
- parent->parent->SetSize(SIZE_XPOS,
- pos.fx + parent->GetSize(SIZE_XPOS));
- break;
- case DH_18: case DH_28: case DH_38: case DH_48:
- case DH_58: case DH_68: case DH_78: case DH_88:
- case DH_59:
- return parent->parent->Command(cmd, tmpl, o);
- default:
- if (type >= DH_DATA) {
- parent->SetSize(SIZE_XPOS + idx, pos.fx + parent->GetSize(SIZE_XPOS + idx));
- parent->SetSize(SIZE_YPOS + idx, pos.fy + parent->GetSize(SIZE_YPOS + idx));
- CurrGO = parent;
- }
- break;
- }
- return parent->Command(CMD_REDRAW, 0L, o);
- break;
- }
- return false;
-}
-
-void *
-dragHandle::ObjThere(int x, int y)
-{
- if(IsInRect(&rDims, x, y)) return (CurrHandle = this);
- else return 0L;
-}
-
-
-void
-dragHandle::Track(POINT *p, anyOutput *o)
-{
- POINT p1, p2, pts[5];
- double dx, dy;
- int npts=0, idx;
- DWORD color;
-
- if(!parent || !o) return;
- Command(CMD_MOUSECURSOR, 0L, o);
- if(upd.right < upd.left) Swap(upd.right, upd.left);
- if(upd.bottom < upd.top) Swap(upd.bottom, upd.top);
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- IncrementMinMaxRect(&upd, 2);
- o->UpdateRect(&upd, false);
- if(type >= DH_19 && type <= DH_99) memcpy(&upd, &drec, sizeof(RECT));
- color = parent->GetColor(COL_DATA_LINE);
- switch(type) {
- case DH_12:
- case DH_22:
- pts[0].x = o->co2ix(parent->GetSize(SIZE_XPOS)+dx);
- pts[0].y = o->co2iy(parent->GetSize(SIZE_YPOS)+dy);
- pts[1].x = o->co2ix(parent->GetSize(SIZE_XPOS+1)+dx);
- pts[1].y = o->co2iy(parent->GetSize(SIZE_YPOS+1)+dy);
- if(type == DH_12) {
- pts[0].x += p->x; pts[0].y += p->y;
- }
- else if(type == DH_22) {
- pts[1].x += p->x; pts[1].y += p->y;
- }
- UpdateMinMaxRect(&upd, pts[0].x, pts[0].y);
- UpdateMinMaxRect(&upd, pts[1].x, pts[1].y);
- npts = 2;
- break;
- case DH_19:
- if(minRC && IsInRect(minRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
- upd.left = minRC->left;
- else if(maxRC && !IsInRect(maxRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
- upd.left = upd.left+p->x >= maxRC->right ? maxRC->right : maxRC->left;
- else upd.left += p->x;
- case DH_29:
- if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.top+p->y))
- upd.top = minRC->top;
- else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.top+p->y))
- upd.top = upd.top +p->y >= maxRC->bottom? maxRC->bottom : maxRC->top;
- else upd.top += p->y;
- break;
- case DH_39:
- if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.top+p->y))
- upd.top = minRC->top;
- else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.top+p->y))
- upd.top = upd.top+p->y >= maxRC->bottom ? maxRC->bottom : maxRC->top;
- else upd.top += p->y;
- case DH_69:
- if(minRC && IsInRect(minRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
- upd.right = minRC->right;
- else if(maxRC && !IsInRect(maxRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
- upd.right = upd.right+p->x <= maxRC->left ? maxRC->left : maxRC->right;
- else upd.right += p->x;
- break;
- case DH_99:
- if(minRC && IsInRect(minRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
- upd.right = minRC->right;
- else if(maxRC && !IsInRect(maxRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
- upd.right = upd.right+p->x <= maxRC->left ? maxRC->left : maxRC->right;
- else upd.right += p->x;
- case DH_89:
- if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
- upd.bottom = minRC->bottom;
- else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
- upd.bottom = upd.bottom+p->y <= maxRC->top? maxRC->top : maxRC->bottom;
- else upd.bottom += p->y;
- break;
- case DH_79:
- if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
- upd.bottom = minRC->bottom;
- else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
- upd.bottom = upd.bottom+p->y <= maxRC->top? maxRC->top : maxRC->bottom;
- else upd.bottom += p->y;
- case DH_49:
- if(minRC && IsInRect(minRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
- upd.left = minRC->left;
- else if(maxRC && !IsInRect(maxRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
- upd.left = upd.left+p->x >= maxRC->right ? maxRC->right : maxRC->left;
- else upd.left += p->x;
- break;
- case DH_18: case DH_28: case DH_38: case DH_48:
- case DH_58: case DH_68: case DH_78: case DH_88:
- CurrGO = this;
- case DH_59:
- parent->parent->Track(p, o);
- return;
- default:
- if(type >= DH_DATA) {
- idx = type - DH_DATA;
- pts[1].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx)+dx);
- pts[1].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx)+dy);
- pts[1].x += p->x; pts[1].y += p->y;
- if(type > DH_DATA) {
- pts[0].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx -1)+dx);
- pts[0].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx -1)+dy);
- }
- else {
- pts[0].x = pts[1].x; pts[0].y = pts[1].y;
- }
- pts[2].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx +1)+dx);
- pts[2].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx +1)+dy);
- UpdateMinMaxRect(&upd, pts[0].x, pts[0].y);
- UpdateMinMaxRect(&upd, pts[1].x, pts[1].y);
- UpdateMinMaxRect(&upd, pts[2].x, pts[2].y);
- npts = 3;
- if(color == 0x0L || color == 0x00ffffffL) color = 0x00c0c0c0L;
- }
- else return;
- }
- if(type >= DH_19 && type <= DH_99) {
- pts[0].x = pts[4].x = pts[3].x = p1.x = upd.left;
- pts[0].y = pts[1].y = pts[4].y = p1.y = upd.top;
- pts[1].x = pts[2].x = p2.x = upd.right;
- pts[2].y = pts[3].y = p2.y = upd.bottom;
- npts = 5;
- if(parent->parent->Id == GO_ELLIPSE) o->ShowEllipse(p1, p2, color);
- }
- o->ShowLine(pts, npts, color);
-}
-
+dragHandle::dragHandle(GraphObj *par, int which):GraphObj(par, 0L)
+{
+ type = which;
+ Id = GO_DRAGHANDLE;
+ LineDef.width = LineDef.patlength = 0.0;
+ LineDef.color = LineDef.pattern = 0L;
+ FillDef.type = FILL_NONE;
+ FillDef.color = 0x00ffffffL;
+ FillDef.scale = 1.0;
+ FillDef.hatch = 0L;
+ minRC = maxRC = 0L;
+}
+
+dragHandle::~dragHandle()
+{
+ if(minRC) free(minRC);
+ if(maxRC) free(maxRC);
+ if(CurrHandle == this) CurrHandle = 0L;
+}
+
+void
+dragHandle::DoPlot(anyOutput *o)
+{
+ double fx, fy, dx, dy;
+ int ix, iy, idx;
+ fPOINT3D fp3d, ifp3d;
+ bool is3D = false;
+
+ if(!o || !parent) return;
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ SetMinMaxRect(&drec, o->co2ix(parent->GetSize(SIZE_XPOS)+dx),
+ o->co2iy(parent->GetSize(SIZE_YPOS)+dy), o->co2ix(parent->GetSize(SIZE_XPOS+1)+dx),
+ o->co2iy(parent->GetSize(SIZE_YPOS+1)+dy));
+ switch(type) {
+ case DH_19: case DH_12:
+ fx = parent->GetSize(SIZE_XPOS); fy = parent->GetSize(SIZE_YPOS);
+ break;
+ case DH_99: case DH_22:
+ fx = parent->GetSize(SIZE_XPOS+1); fy = parent->GetSize(SIZE_YPOS+1);
+ break;
+ case DH_29:
+ fx = (parent->GetSize(SIZE_XPOS) + parent->GetSize(SIZE_XPOS+1))/2.0;
+ fy = parent->GetSize(SIZE_YPOS);
+ break;
+ case DH_39:
+ fx = parent->GetSize(SIZE_XPOS+1); fy = parent->GetSize(SIZE_YPOS);
+ break;
+ case DH_49:
+ fx = parent->GetSize(SIZE_XPOS);
+ fy = (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
+ break;
+ case DH_59:
+ fx = (parent->GetSize(SIZE_XPOS) + parent->GetSize(SIZE_XPOS+1))/2.0;
+ fy = (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
+ break;
+ case DH_69:
+ fx = parent->GetSize(SIZE_XPOS+1);
+ fy = (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
+ break;
+ case DH_79:
+ fx = parent->GetSize(SIZE_XPOS);
+ fy = parent->GetSize(SIZE_YPOS+1);
+ break;
+ case DH_89:
+ fx = (parent->GetSize(SIZE_XPOS) + parent->GetSize(SIZE_XPOS+1))/2.0;
+ fy = parent->GetSize(SIZE_YPOS+1);
+ break;
+ case DH_18: case DH_28: case DH_38: case DH_48:
+ case DH_58: case DH_68: case DH_78: case DH_88:
+ fp3d.fx = parent->GetSize(SIZE_XPOS + type - DH_18);
+ fp3d.fy = parent->GetSize(SIZE_YPOS + type - DH_18);
+ fp3d.fz = parent->GetSize(SIZE_ZPOS + type - DH_18);
+ is3D = true;
+ break;
+ default:
+ if(type >= DH_DATA) {
+ fx = parent->GetSize(SIZE_XPOS + type - DH_DATA);
+ fy = parent->GetSize(SIZE_YPOS + type - DH_DATA);
+ FillDef.color = (this == CurrHandle) ? 0x0L : 0x00ffffffL;
+ }
+ else return;
+ }
+ if(is3D) {
+ o->cvec2ivec(&fp3d, &ifp3d);
+ ix = iround(ifp3d.fx); iy = iround(ifp3d.fy);
+ }
+ else {
+ ix = o->co2ix(fx+dx); iy = o->co2iy(fy+dy);
+ }
+ SetMinMaxRect(&rDims, ix-4, iy-4, ix+4, iy+4);
+ memcpy(&upd, &rDims, sizeof(RECT));
+ switch(type) {
+ case DH_12: case DH_22: case DH_19: case DH_29: case DH_39:
+ case DH_49: case DH_69: case DH_79: case DH_89: case DH_99:
+ o->SetLine(&LineDef); o->SetFill(&FillDef);
+ o->oRectangle(rDims.left, rDims.top, rDims.right, rDims.bottom);
+ o->UpdateRect(&rDims, false);
+ break;
+ case DH_59:
+ o->SetLine(&LineDef); o->SetFill(&FillDef);
+ IncrementMinMaxRect(&rDims, 2);
+ o->oCircle(rDims.left, rDims.top, rDims.right, rDims.bottom);
+ IncrementMinMaxRect(&rDims, 1);
+ o->UpdateRect(&rDims, false);
+ break;
+ default:
+ if(type >= DH_DATA) {
+ idx = (type - DH_DATA);
+ o->SetLine(&LineDef); o->SetFill(&FillDef);
+ if(parent->Id == GO_BEZIER && (idx %3)) {
+ IncrementMinMaxRect(&rDims, -1);
+ o->oRectangle(rDims.left, rDims.top, rDims.right, rDims.bottom);
+ }
+ else if(parent->Id == GO_POLYLINE || parent->Id == GO_BEZIER) {
+ o->oCircle(rDims.left, rDims.top, rDims.right, rDims.bottom);
+ }
+ else {
+ o->oRectangle(rDims.left, rDims.top, rDims.right, rDims.bottom);
+ }
+ o->UpdateRect(&rDims, false);
+ }
+ else {
+ IncrementMinMaxRect(&rDims, -1);
+ o->UpdateRect(&rDims, true);
+ }
+ break;
+ }
+}
+
+bool
+dragHandle::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ lfPOINT pos;
+ int idx;
+
+ if(!parent) return false;
+ switch (cmd) {
+ case CMD_MOUSECURSOR:
+ if(o) switch(type) {
+ case DH_19: case DH_99:
+ o->MouseCursor(MC_SE, false); break;
+ case DH_29: case DH_89:
+ o->MouseCursor(MC_NORTH, false); break;
+ case DH_39: case DH_79:
+ o->MouseCursor(MC_NE, false); break;
+ case DH_49: case DH_69:
+ o->MouseCursor(MC_EAST, false); break;
+ default:
+ if(type >= DH_DATA) o->MouseCursor(MC_SALL, false);
+ else o->MouseCursor(MC_MOVE, false); break;
+ }
+ return true;
+ case CMD_MINRC:
+ if(!(minRC)) minRC = (RECT*)calloc(1, sizeof(RECT));
+ if(tmpl && minRC) SetMinMaxRect(minRC, ((RECT*)tmpl)->left, ((RECT*)tmpl)->top,
+ ((RECT*)tmpl)->right, ((RECT*)tmpl)->bottom);
+ return true;
+ case CMD_MAXRC:
+ if(!(maxRC)) maxRC = (RECT*)calloc(1, sizeof(RECT));
+ if(tmpl && maxRC) SetMinMaxRect(maxRC, ((RECT*)tmpl)->left, ((RECT*)tmpl)->top,
+ ((RECT*)tmpl)->right, ((RECT*)tmpl)->bottom);
+ return true;
+ case CMD_MOVE:
+ idx = type >= DH_DATA ? type - DH_DATA : 0;
+ pos.fx = NiceValue(((lfPOINT*)tmpl)[0].fx);
+ pos.fy = NiceValue(((lfPOINT*)tmpl)[0].fy);
+ if(pos.fx == 0.0 && pos.fy == 0.0) return false;
+ parent->Command(CMD_SAVEPOS, &idx, o);
+ switch(type) {
+ case DH_12:
+ parent->SetSize(SIZE_XPOS, pos.fx + parent->GetSize(SIZE_XPOS));
+ parent->SetSize(SIZE_YPOS, pos.fy + parent->GetSize(SIZE_YPOS));
+ break;
+ case DH_22:
+ parent->SetSize(SIZE_XPOS+1, pos.fx + parent->GetSize(SIZE_XPOS+1));
+ parent->SetSize(SIZE_YPOS+1, pos.fy + parent->GetSize(SIZE_YPOS+1));
+ break;
+ case DH_19: parent->parent->SetSize(SIZE_XPOS,
+ pos.fx + parent->GetSize(SIZE_XPOS));
+ case DH_29: parent->parent->SetSize(SIZE_YPOS,
+ pos.fy + parent->GetSize(SIZE_YPOS));
+ break;
+ case DH_39: parent->parent->SetSize(SIZE_YPOS,
+ pos.fy + parent->GetSize(SIZE_YPOS));
+ case DH_69: parent->parent->SetSize(SIZE_XPOS+1,
+ pos.fx + parent->GetSize(SIZE_XPOS+1));
+ break;
+ case DH_99: parent->parent->SetSize(SIZE_XPOS+1,
+ pos.fx + parent->GetSize(SIZE_XPOS+1));
+ case DH_89: parent->parent->SetSize(SIZE_YPOS+1,
+ pos.fy + parent->GetSize(SIZE_YPOS+1));
+ break;
+ case DH_79: parent->parent->SetSize(SIZE_YPOS+1,
+ pos.fy + parent->GetSize(SIZE_YPOS+1));
+ case DH_49:
+ parent->parent->SetSize(SIZE_XPOS,
+ pos.fx + parent->GetSize(SIZE_XPOS));
+ break;
+ case DH_18: case DH_28: case DH_38: case DH_48:
+ case DH_58: case DH_68: case DH_78: case DH_88:
+ case DH_59:
+ return parent->parent->Command(cmd, tmpl, o);
+ default:
+ if (type >= DH_DATA) {
+ parent->SetSize(SIZE_XPOS + idx, pos.fx + parent->GetSize(SIZE_XPOS + idx));
+ parent->SetSize(SIZE_YPOS + idx, pos.fy + parent->GetSize(SIZE_YPOS + idx));
+ CurrGO = parent;
+ }
+ break;
+ }
+ return parent->Command(CMD_REDRAW, 0L, o);
+ break;
+ }
+ return false;
+}
+
+void *
+dragHandle::ObjThere(int x, int y)
+{
+ if(IsInRect(&rDims, x, y)) return (CurrHandle = this);
+ else return 0L;
+}
+
+
+void
+dragHandle::Track(POINT *p, anyOutput *o)
+{
+ POINT p1, p2, pts[5], bez[256];
+ double dx, dy;
+ int i, first=0, last = 0, idx;
+ long nbez;
+ DWORD color;
+
+ if(!parent || !o) return;
+ Command(CMD_MOUSECURSOR, 0L, o);
+ if(upd.right < upd.left) Swap(upd.right, upd.left);
+ if(upd.bottom < upd.top) Swap(upd.bottom, upd.top);
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ IncrementMinMaxRect(&upd, 2);
+ o->UpdateRect(&upd, false);
+ if(type >= DH_19 && type <= DH_99) memcpy(&upd, &drec, sizeof(RECT));
+ color = parent->GetColor(COL_DATA_LINE);
+ switch(type) {
+ case DH_12:
+ case DH_22:
+ pts[0].x = o->co2ix(parent->GetSize(SIZE_XPOS)+dx);
+ pts[0].y = o->co2iy(parent->GetSize(SIZE_YPOS)+dy);
+ pts[1].x = o->co2ix(parent->GetSize(SIZE_XPOS+1)+dx);
+ pts[1].y = o->co2iy(parent->GetSize(SIZE_YPOS+1)+dy);
+ if(type == DH_12) {
+ pts[0].x += p->x; pts[0].y += p->y;
+ }
+ else if(type == DH_22) {
+ pts[1].x += p->x; pts[1].y += p->y;
+ }
+ UpdateMinMaxRect(&upd, pts[0].x, pts[0].y);
+ UpdateMinMaxRect(&upd, pts[1].x, pts[1].y);
+ last = 2;
+ break;
+ case DH_19:
+ if(minRC && IsInRect(minRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
+ upd.left = minRC->left;
+ else if(maxRC && !IsInRect(maxRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
+ upd.left = upd.left+p->x >= maxRC->right ? maxRC->right : maxRC->left;
+ else upd.left += p->x;
+ case DH_29:
+ if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.top+p->y))
+ upd.top = minRC->top;
+ else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.top+p->y))
+ upd.top = upd.top +p->y >= maxRC->bottom? maxRC->bottom : maxRC->top;
+ else upd.top += p->y;
+ break;
+ case DH_39:
+ if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.top+p->y))
+ upd.top = minRC->top;
+ else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.top+p->y))
+ upd.top = upd.top+p->y >= maxRC->bottom ? maxRC->bottom : maxRC->top;
+ else upd.top += p->y;
+ case DH_69:
+ if(minRC && IsInRect(minRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
+ upd.right = minRC->right;
+ else if(maxRC && !IsInRect(maxRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
+ upd.right = upd.right+p->x <= maxRC->left ? maxRC->left : maxRC->right;
+ else upd.right += p->x;
+ break;
+ case DH_99:
+ if(minRC && IsInRect(minRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
+ upd.right = minRC->right;
+ else if(maxRC && !IsInRect(maxRC, upd.right+p->x, (upd.top+upd.bottom)>>1))
+ upd.right = upd.right+p->x <= maxRC->left ? maxRC->left : maxRC->right;
+ else upd.right += p->x;
+ case DH_89:
+ if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
+ upd.bottom = minRC->bottom;
+ else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
+ upd.bottom = upd.bottom+p->y <= maxRC->top? maxRC->top : maxRC->bottom;
+ else upd.bottom += p->y;
+ break;
+ case DH_79:
+ if(minRC && IsInRect(minRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
+ upd.bottom = minRC->bottom;
+ else if(maxRC && !IsInRect(maxRC, (upd.left + upd.right)>>1, upd.bottom+p->y))
+ upd.bottom = upd.bottom+p->y <= maxRC->top? maxRC->top : maxRC->bottom;
+ else upd.bottom += p->y;
+ case DH_49:
+ if(minRC && IsInRect(minRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
+ upd.left = minRC->left;
+ else if(maxRC && !IsInRect(maxRC, upd.left+p->x, (upd.top+upd.bottom)>>1))
+ upd.left = upd.left+p->x >= maxRC->right ? maxRC->right : maxRC->left;
+ else upd.left += p->x;
+ break;
+ case DH_18: case DH_28: case DH_38: case DH_48:
+ case DH_58: case DH_68: case DH_78: case DH_88:
+ CurrGO = this;
+ case DH_59:
+ parent->parent->Track(p, o);
+ return;
+ default:
+ if(type >= DH_DATA) {
+ idx = type - DH_DATA;
+ pts[1].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx)+dx);
+ pts[1].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx)+dy);
+ pts[1].x += p->x; pts[1].y += p->y;
+ if(type > DH_DATA) {
+ pts[0].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx -1)+dx);
+ pts[0].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx -1)+dy);
+ }
+ else {
+ pts[0].x = pts[1].x; pts[0].y = pts[1].y;
+ }
+ pts[3].x = pts[2].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx +1)+dx);
+ pts[3].y = pts[2].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx +1)+dy);
+ UpdateMinMaxRect(&upd, pts[0].x, pts[0].y);
+ UpdateMinMaxRect(&upd, pts[1].x, pts[1].y);
+ UpdateMinMaxRect(&upd, pts[2].x, pts[2].y);
+ if(parent ->Id == GO_BEZIER) {
+ switch(idx % 3) {
+ case 0:
+ o->ShowLine(pts, 3, 0x00c0c0c0L);
+ pts[0].x = pts[1].x; pts[0].y = pts[1].y;
+ for(nbez = 0, i = 1; i < 4; i++) {
+ pts[i].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx +i)+dx);
+ pts[i].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx +i)+dy);
+ }
+ DrawBezier(&nbez, bez, pts[0], pts[1], pts[2], pts[3], 0);
+ o->ShowLine(bez, nbez, color);
+ if(idx < 3) return;
+ pts[3].x = pts[0].x; pts[3].y = pts[0].y;
+ for(i = nbez = 0, idx -= 3; i < 3; i++) {
+ pts[i].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx +i)+dx);
+ pts[i].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx +i)+dy);
+ }
+ DrawBezier(&nbez, bez, pts[0], pts[1], pts[2], pts[3], 0);
+ o->ShowLine(bez, nbez, color);
+ return;
+ case 1:
+ pts[3].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx +2)+dx);
+ pts[3].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx +2)+dy);
+ last = 2; break;
+ case 2:
+ pts[2].x = pts[1].x; pts[2].y = pts[1].y;
+ pts[1].x = pts[0].x; pts[1].y = pts[0].y;
+ pts[0].x = o->co2ix(parent->GetSize(SIZE_XPOS + idx -2)+dx);
+ pts[0].y = o->co2iy(parent->GetSize(SIZE_YPOS + idx -2)+dy);
+ first = 2; last = 4; break;
+ }
+ if(idx %3) {
+ nbez = 0;
+ DrawBezier(&nbez, bez, pts[0], pts[1], pts[2], pts[3], 0);
+ o->ShowLine(bez, nbez, color);
+ }
+ color = 0x00c0c0c0L;
+ }
+ else last = 3;
+ if(color == 0x0L || color == 0x00ffffffL) color = 0x00c0c0c0L;
+ }
+ else return;
+ }
+ if(type >= DH_19 && type <= DH_99) {
+ pts[0].x = pts[4].x = pts[3].x = p1.x = upd.left;
+ pts[0].y = pts[1].y = pts[4].y = p1.y = upd.top;
+ pts[1].x = pts[2].x = p2.x = upd.right;
+ pts[2].y = pts[3].y = p2.y = upd.bottom;
+ last = 5;
+ if(parent->parent->Id == GO_ELLIPSE) o->ShowEllipse(p1, p2, color);
+ }
+ o->ShowLine(pts+first, last-first, color);
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// the dragRect object uses nine dragHandles to create a user interface
// for modification of rectangular shapes
@@ -1618,9 +1682,12 @@ Bar::DoPlot(anyOutput *target)
void
Bar::DoMark(anyOutput *o, bool mark)
{
+ int i;
+
if(mark){
memcpy(&mrc, &rDims, sizeof(RECT));
- IncrementMinMaxRect(&mrc, 3);
+ i = 2*o->un2ix(BarLine.width); //increase size of rectangle for marks
+ IncrementMinMaxRect(&mrc, i);
mo = GetRectBitmap(&mrc, o);
o->CopyBitmap(mrc.left, mrc.top, mo, 0, 0, mrc.right-mrc.left, mrc.bottom - mrc.top, true);
o->UpdateRect(&mrc, false);
@@ -1885,8 +1952,7 @@ DataLine::DoPlot(anyOutput *target)
AddToPolygon(&cp, pts, pts);
}
else{
- target->SetLine(&LineDef);
- target->oPolyline(pts, cp);
+ target->SetLine(&LineDef); target->oPolyline(pts, cp);
}
if(tmppts = (POINT*)realloc(pts, cp *sizeof(POINT))) pts = tmppts;
SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
@@ -2640,7 +2706,9 @@ ErrorBar::ErrorBar(int src):GraphObj(0L, 0L)
ErrorBar::~ErrorBar()
{
- if(ssRef) free(ssRef); ssRef = 0L;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
}
bool
@@ -2677,10 +2745,10 @@ ErrorBar::DoPlot(anyOutput *target)
case ERRBAR_VSYM:
case ERRBAR_VUP:
case ERRBAR_VDOWN:
- ie = target->un2ix(SizeBar/2.0f);
+ ie = target->un2ix(SizeBar/2.0);
break;
default:
- ie = target->un2iy(SizeBar/2.0f);
+ ie = target->un2iy(SizeBar/2.0);
break;
}
target->SetLine(&ErrLine);
@@ -2743,33 +2811,26 @@ ErrorBar::DoPlot(anyOutput *target)
}
if(rDims.left > rDims.right) Swap(rDims.left, rDims.right);
if(rDims.top > rDims.bottom) Swap(rDims.top, rDims.bottom);
- IncrementMinMaxRect(&rDims, 3);
+ IncrementMinMaxRect(&rDims, 2);
}
void
ErrorBar::DoMark(anyOutput *o, bool mark)
{
- LineDEF OldLine;
-
- memcpy(&OldLine, &ErrLine, sizeof(LineDEF));
- if(mark) {
- ErrLine.color = 0x00000000L;
- ErrLine.width = 1.2f;
- DoPlot(o);
- ErrLine.width = 0.4f;
- ErrLine.color = OldLine.color ^ 0x00ffffffL;
- DoPlot(o);
- }
- else {
- ErrLine.color = 0x00ffffffL; //DEBUG: assume white background
- ErrLine.width = 1.2f;
- DoPlot(o);
- ErrLine.width = OldLine.width;
- ErrLine.color = OldLine.color;
- DoPlot(o);
- }
- memcpy(&ErrLine, &OldLine, sizeof(LineDEF));
- o->UpdateRect(&rDims, false);
+ int i;
+ LineDEF OldLine;
+
+ if(mark){
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ memcpy(&OldLine, &ErrLine, sizeof(LineDEF));
+ i = 3*o->un2ix(ErrLine.width); //increase size of rectangle for marks
+ IncrementMinMaxRect(&mrc, i); mo = GetRectBitmap(&mrc, o);
+ ErrLine.width *= 5.0; DoPlot(o);
+ ErrLine.width = OldLine.width; ErrLine.color = OldLine.color ^ 0x00ffffffL;
+ DoPlot(o); o->UpdateRect(&mrc, false);
+ memcpy(&ErrLine, &OldLine, sizeof(LineDEF));
+ }
+ else RestoreRectBitmap(&mo, &mrc, o);
}
bool
@@ -2786,17 +2847,13 @@ ErrorBar::Command(int cmd, void *tmpl, anyOutput *o)
case MOUSE_LBUP:
if(!IsInRect(&rDims, mev->x, mev->y) || CurrGO) return false;
switch (type) {
- case ERRBAR_HSYM:
- case ERRBAR_HLEFT:
- case ERRBAR_HRIGHT:
+ case ERRBAR_HSYM: case ERRBAR_HLEFT: case ERRBAR_HRIGHT:
if(mev->y >= (ebpts[0].y-2) && mev->y <= (ebpts[1].y+2)) bFound = true;
else if(mev->x >= (ebpts[2].x-2) && mev->x <= (ebpts[2].x+2)) bFound = true;
else if(type == ERRBAR_HSYM && mev->x >= (ebpts[4].x-2) &&
mev->x <= (ebpts[4].x + 2)) bFound = true;
break;
- case ERRBAR_VSYM:
- case ERRBAR_VUP:
- case ERRBAR_VDOWN:
+ case ERRBAR_VSYM: case ERRBAR_VUP: case ERRBAR_VDOWN:
if(mev->x >= (ebpts[0].x-2) && mev->x <= (ebpts[1].x+2)) bFound = true;
else if(mev->y >= (ebpts[2].y-2) && mev->y <= (ebpts[2].y+2)) bFound = true;
else if(type == ERRBAR_VSYM && mev->y >= (ebpts[4].y-2) &&
@@ -2816,7 +2873,21 @@ ErrorBar::Command(int cmd, void *tmpl, anyOutput *o)
data->GetValue(ssRef[2].y, ssRef[2].x, &ferr);
return true;
}
- return false;
+ return false;
+ case CMD_LEGEND:
+ if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
+ switch(type) {
+ case ERRBAR_VSYM: case ERRBAR_VUP: case ERRBAR_VDOWN:
+ ((Legend*)tmpl)->HasErr(&ErrLine, 1, name);
+ break;
+ case ERRBAR_HSYM: case ERRBAR_HLEFT: case ERRBAR_HRIGHT:
+ ((Legend*)tmpl)->HasErr(&ErrLine, 2, name);
+ break;
+ }
+ break;
+ case CMD_ERRDESC:
+ if(name = (char*)realloc(name, strlen((char*)tmpl)+2)) strcpy(name, (char*)tmpl);
+ return true;
case CMD_ERR_TYPE:
if(tmpl) type = *((int*)tmpl);
return true;
@@ -3326,14 +3397,13 @@ Box::Command(int cmd, void *tmpl, anyOutput *o)
case MOUSE_LBUP:
if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
if(pts[0].x == pts[1].x || pts[0].y == pts[1].y) {
- o->ShowMark(&rDims, MRK_INVERT);
- CurrGO = this;
+ o->ShowMark(CurrGO = this, MRK_GODRAW);
return true;
}
else {
p.x = mev->x; p.y = mev->y;
if(IsInPolygon(&p, pts, 5)) {
- o->ShowMark(this, MRK_GODRAW);
+ o->ShowMark(CurrGO = this, MRK_GODRAW);
return true;
}
}
@@ -3380,6 +3450,16 @@ Box::Command(int cmd, void *tmpl, anyOutput *o)
else {
((Plot*)parent)->CheckBounds(pos1.fx, pos1.fy);
((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy);
+ if(parent && (type & BAR_RELWIDTH)) {
+ if(pos1.fy == pos2.fy) {
+ ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy + parent->GetSize(SIZE_BOXMINY));
+ ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy - parent->GetSize(SIZE_BOXMINY));
+ }
+ else if(pos1.fx == pos2.fx) {
+ ((Plot*)parent)->CheckBounds(pos2.fx + parent->GetSize(SIZE_BOXMINX), pos2.fy);
+ ((Plot*)parent)->CheckBounds(pos2.fx - parent->GetSize(SIZE_BOXMINX), pos2.fy);
+ }
+ }
}
return true;
}
@@ -3409,6 +3489,7 @@ Whisker::Whisker(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
cssRef = 4;
}
}
+ Command(CMD_AUTOSCALE, 0L, 0L);
}
Whisker::Whisker(int src):GraphObj(0L, 0L)
@@ -3417,6 +3498,13 @@ Whisker::Whisker(int src):GraphObj(0L, 0L)
if(src == FILE_READ) {
FileIO(FILE_READ);
}
+}
+
+Whisker::~Whisker()
+{
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
}
bool
@@ -3498,32 +3586,20 @@ Whisker::DoPlot(anyOutput *o)
void
Whisker::DoMark(anyOutput *o, bool mark)
{
- LineDEF OldLine;
- int i;
-
- memcpy(&OldLine, &LineDef, sizeof(LineDEF));
- if(mark) {
- LineDef.color = 0x00000000L;
- LineDef.width = 1.2f;
- o->SetLine(&LineDef);
- for(i = 0; i < 5; i+=2) o->oSolidLine(pts+i);
- LineDef.width = 0.4f;
- LineDef.color = OldLine.color ^ 0x00ffffffL;
- o->SetLine(&LineDef);
- for(i = 0; i < 5; i+=2) o->oSolidLine(pts+i);
- }
- else {
- LineDef.color = 0x00ffffffL; //DEBUG: assume white background
- LineDef.width = 1.2f;
- o->SetLine(&LineDef);
- for(i = 0; i < 5; i+=2) o->oSolidLine(pts+i);
- LineDef.width = OldLine.width;
- LineDef.color = OldLine.color;
- o->SetLine(&LineDef);
- for(i = 0; i < 5; i+=2) o->oSolidLine(pts+i);
- }
- memcpy(&LineDef, &OldLine, sizeof(LineDEF));
- o->UpdateRect(&rDims, false);
+ int i;
+ LineDEF OldLine;
+
+ if(mark){
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ memcpy(&OldLine, &LineDef, sizeof(LineDEF));
+ i = 3*o->un2ix(LineDef.width); //increase size of rectangle for marks
+ IncrementMinMaxRect(&mrc, i); mo = GetRectBitmap(&mrc, o);
+ LineDef.width *= 5.0; DoPlot(o);
+ LineDef.width = OldLine.width; LineDef.color = OldLine.color ^ 0x00ffffffL;
+ DoPlot(o); o->UpdateRect(&mrc, false);
+ memcpy(&LineDef, &OldLine, sizeof(LineDEF));
+ }
+ else RestoreRectBitmap(&mo, &mrc, o);
}
bool
@@ -3547,9 +3623,24 @@ Whisker::Command(int cmd, void *tmpl, anyOutput *o)
break;
}
return false;
+ case CMD_ERRDESC:
+ if(name = (char*)realloc(name, strlen((char*)tmpl)+2)) strcpy(name, (char*)tmpl);
+ return true;
+ case CMD_LEGEND:
+ if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
+ switch(type & 0x0f) {
+ case 1: ((Legend*)tmpl)->HasErr(&LineDef, 5, name); break;
+ case 2: ((Legend*)tmpl)->HasErr(&LineDef, 4, name); break;
+ case 3: ((Legend*)tmpl)->HasErr(&LineDef, 3, name); break;
+ default:
+ if((rDims.right - rDims.left) < (rDims.bottom - rDims.top))
+ ((Legend*)tmpl)->HasErr(&LineDef, 1, name);
+ else ((Legend*)tmpl)->HasErr(&LineDef, 2, name);
+ break;
+ }
+ break;
case CMD_SET_DATAOBJ:
- Id = GO_WHISKER;
- data = (DataObj *)tmpl;
+ Id = GO_WHISKER; data = (DataObj *)tmpl;
return true;
case CMD_UPDATE:
if(ssRef && cssRef >3 && data) {
@@ -6946,7 +7037,7 @@ polyline::polyline(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts):
if(parent){
dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
}
- if(Values = (lfPOINT*)malloc((nPoints = cpts)* sizeof(lfPOINT))){
+ if(cpts && (Values = (lfPOINT*)malloc((nPoints = cpts)* sizeof(lfPOINT)))){
memcpy(Values, fpts, cpts*sizeof(lfPOINT));
for(i = 0; i < cpts; i++) {
Values[i].fx -= dx; Values[i].fy -= dy;
@@ -7035,15 +7126,13 @@ polyline::DoPlot(anyOutput *o)
for(i = 2; i < nPts; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
i = 3*o->un2ix(pgLine.width)+3; //increase size of rectangle for marks
IncrementMinMaxRect(&rDims, i);
- o->SetLine(&pgLine);
if(this == CurrGO) o->ShowMark(this, MRK_GODRAW);
else switch(type) {
case 0: //line
- o->oPolyline(pts, nPts);
+ o->SetLine(&pgLine); o->oPolyline(pts, nPts);
break;
case 1: //polygon
- o->SetFill(&pgFill);
- o->oPolygon(pts, nPts);
+ o->SetLine(&pgLine); o->SetFill(&pgFill); o->oPolygon(pts, nPts);
break;
}
}
@@ -7051,7 +7140,7 @@ polyline::DoPlot(anyOutput *o)
void
polyline::DoMark(anyOutput *o, bool mark)
{
- RECT upd;
+ RECT upd;
memcpy(&upd, &rDims, sizeof(RECT));
IncrementMinMaxRect(&upd, 6 + o->un2ix(pgLine.width)*4);
@@ -7059,20 +7148,21 @@ polyline::DoMark(anyOutput *o, bool mark)
o->SetLine(&pgLine);
if(nPoints < 200){
switch(type) {
- case 0: //line
+ case 0: //line
o->oPolyline(pts, nPts);
break;
case 1: //polygon
- o->SetFill(&pgFill);
- o->oPolygon(pts, nPts);
+ o->SetFill(&pgFill); o->oPolygon(pts, nPts);
break;
}
ShowPoints(o);
}
else InvertLine(pts, nPts, &pgLine, &upd, o, true);;
+ o->UpdateRect(&upd, false);
}
- else if(parent) parent->DoPlot(o);
- o->UpdateRect(&upd, false);
+ else {
+ if(parent) parent->DoPlot(o);
+ }
}
bool
@@ -7132,8 +7222,7 @@ polyline::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_SET_DATAOBJ:
Id = type == 1 ? GO_POLYGON : GO_POLYLINE;
return true;
- case CMD_SETSCROLL:
- case CMD_REDRAW:
+ case CMD_SETSCROLL: case CMD_REDRAW:
if(parent) return parent->Command(cmd, tmpl, o);
return false;
case CMD_MOVE:
@@ -7161,9 +7250,8 @@ polyline::ObjThere(int x, int y)
void *ret;
if(IsInRect(&rDims, p1.x = x, p1.y = y)) {
- if(CurrGO == this && pHandles)
- for(i = nPoints-1; i >= 0; i--)
- if((pHandles[i]) && (ret = pHandles[i]->ObjThere(x, y))) return ret;
+ if(CurrGO == this && pHandles) for(i = nPoints-1; i >= 0; i--)
+ if((pHandles[i]) && (ret = pHandles[i]->ObjThere(x, y))) return ret;
if(type == 1) bFound = IsInPolygon(&p1, pts, nPts);
if(bFound || IsCloseToPL(p1,pts,nPts)) return this;
}
@@ -7195,17 +7283,422 @@ polyline::Track(POINT *p, anyOutput *o)
void
polyline::ShowPoints(anyOutput *o)
{
- int i;
+ int i;
+ double dx, dy;
+ POINT hpts[3];
+ LineDEF gl = {0.0, 1.0, 0x00c0c0c0, 0};
- if(nPoints >= 200) return;
- if(!pHandles) if(pHandles = (dragHandle**)calloc(nPoints+1, sizeof(dragHandle*))){
+ if(nPoints >= 200 || !o) return;
+ if(!pHandles && (pHandles = (dragHandle**)calloc(nPoints+4, sizeof(dragHandle*)))){
for(i = 0; i < nPoints; i++) pHandles[i] = new dragHandle(this, DH_DATA+i);
}
- else return;
- for(i = 0; i < nPoints; i++) if(pHandles[i]) pHandles[i]->DoPlot(o);
+ if(!pHandles) return;
+ if(Id == GO_BEZIER && parent && nPoints > 3) {
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ o->SetLine(&gl);
+ hpts[0].x = o->co2ix(Values[0].fx+dx); hpts[0].y = o->co2iy(Values[0].fy+dy);
+ hpts[1].x = o->co2ix(Values[1].fx+dx); hpts[1].y = o->co2iy(Values[1].fy+dy);
+ o->oPolyline(hpts, 2);
+ for(i = 3; i < (nPoints-2); i += 3) {
+ hpts[0].x = o->co2ix(Values[i-1].fx+dx); hpts[0].y = o->co2iy(Values[i-1].fy+dy);
+ hpts[1].x = o->co2ix(Values[i].fx+dx); hpts[1].y = o->co2iy(Values[i].fy+dy);
+ hpts[2].x = o->co2ix(Values[i+1].fx+dx); hpts[2].y = o->co2iy(Values[i+1].fy+dy);
+ o->oPolyline(hpts, 3);
+ }
+ hpts[0].x = o->co2ix(Values[i-1].fx+dx); hpts[0].y = o->co2iy(Values[i-1].fy+dy);
+ hpts[1].x = o->co2ix(Values[i].fx+dx); hpts[1].y = o->co2iy(Values[i].fy+dy);
+ o->oPolyline(hpts, 2);
+ }
+ for(i = 0; i < nPoints; i++) if(pHandles[i]) pHandles[i]->DoPlot(o);
}
-
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Beziers are based on the polyline object
+Bezier::Bezier(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts, int mode, double res):
+ polyline(par, d, 0L, 0)
+{
+ double dx, dy, merr;
+ int i;
+
+ type = mode;
+ Id = GO_BEZIER;
+
+ if(!parent) return;
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ if(type == 0 && (Values = (lfPOINT*)malloc(4 * cpts * sizeof(lfPOINT)))) {
+ merr = 0.01 * Units[defs.cUnits].convert * res;
+ FitCurve(fpts, cpts, merr);
+ Values[nPoints].fx = fpts[cpts-1].fx; Values[nPoints].fy = fpts[cpts-1].fy;
+ for(i = 0; i < nPoints; i++) {
+ Values[i].fx -= dx; Values[i].fy -= dy;
+ }
+ nPoints ++;
+ }
+ return;
+}
+
+Bezier::Bezier(int src):polyline(0L, 0L, 0L, 0)
+{
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+void
+Bezier::DoPlot(anyOutput *o)
+{
+ POINT *tmppts;
+ double dx, dy;
+ int i;
+
+ if(!Values || !nPoints || !o || !parent) return;
+ if(pts) free(pts); pts = 0L;
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ if(!(tmppts = (POINT*)malloc((nPoints+2)*sizeof(POINT))))return;
+ for(i = 0; i < nPoints; i++){
+ tmppts[i].x = o->co2ix(Values[i].fx + dx); tmppts[i].y = o->co2iy(Values[i].fy + dy);
+ }
+ rDims.left = rDims.right = tmppts[0].x; rDims.top = rDims.bottom = tmppts[0].y;
+ for(i = 1; i < nPoints; i++) {
+ if(tmppts[i].x < rDims.left) rDims.left = tmppts[i].x;
+ else if(tmppts[i].x > rDims.right) rDims.right = tmppts[i].x;
+ if(tmppts[i].y < rDims.top) rDims.top = tmppts[i].y;
+ else if(tmppts[i].y > rDims.bottom) rDims.bottom = tmppts[i].y;
+ }
+ //DrawBezier returns not more than 2^MAXDEPTH points
+ pts = (POINT*)malloc(nPoints * 64 * sizeof(POINT));
+ for(i= nPts = 0; i< (nPoints-2); i += 3) {
+ DrawBezier(&nPts, pts, tmppts[i], tmppts[i+1], tmppts[i+2], tmppts[i+3], 0);
+ }
+ IncrementMinMaxRect(&rDims, 3);
+ o->ShowLine(pts, nPts, 0x00c0c0c0L);
+ if(this == CurrGO) o->ShowMark(this, MRK_GODRAW);
+ else {
+ o->SetLine(&pgLine); o->oPolyline(pts, nPts);
+ }
+}
+
+bool
+Bezier::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ int i, i1, i2;
+
+ switch (cmd) {
+ case CMD_MRK_DIRTY: //issued by Undo
+ CurrGO = this;
+ bModified = true;
+ case CMD_FLUSH:
+ if(pHandles) {
+ for(i = 0; i < nPoints; i++) if(pHandles[i]) delete(pHandles[i]);
+ free(pHandles); pHandles = 0L;
+ }
+ if(cmd == CMD_FLUSH && Values && nPoints){
+ free(Values);
+ Values = 0L; nPoints = 0;
+ }
+ if(pts && nPts) free(pts); pts = 0L; nPts = 0;
+ return true;
+ case CMD_DELOBJ:
+ if(pHandles && tmpl && tmpl == (void*)CurrHandle) {
+ i = CurrHandle->type - DH_DATA;
+ if (i >= 0 && i < nPoints) {
+ i = CurrHandle->type - DH_DATA;
+ Undo.DataMem(this, (void**)&Values, nPoints * sizeof(lfPOINT), &nPoints, 0L);
+ if (i < 2) {
+ i1 = 0; i2 = 3;
+ }
+ else if (i > (nPoints-3)) {
+ i1 = nPoints -3; i2 = nPoints;
+ }
+ else {
+ i -= (((i-2) % 3)-1); i1 = i -1; i2 = i +2;
+ RemovePoint(Values, i1+1);
+ Values[i2].fx = Values[i1].fx; Values[i2].fy = Values[i1].fy;
+ }
+ for(i = 0; i < nPoints; i++) if(pHandles[i]) delete(pHandles[i]);
+ free(pHandles); pHandles = 0L; CurrHandle = 0L;
+ i = i2 - i1;
+ for( ; i2 < nPoints; i1++, i2++) {
+ Values[i1].fx = Values[i2].fx; Values[i1].fy = Values[i2].fy;
+ }
+ nPoints -= i; CurrGO = this; bModified = true;
+ return true;
+ }
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_BEZIER;
+ return true;
+ }
+ return polyline::Command(cmd, tmpl, o);
+}
+
+void
+Bezier::AddPoints(int n, lfPOINT *p)
+{
+ int i;
+
+ for(i = 0; i< n; i++) {
+ Values[nPoints].fx = p[i].fx; Values[nPoints].fy = p[i].fy;
+ nPoints ++;
+ }
+}
+
+//Fitting of a Bezier curve to digitized points is based on:
+// P.J. Schneider (1990) An Algorithm for Automatically Fitting Digitized
+// Curves. In: Graphics Gems (Ed. A. Glassner, Academic Press Inc.,
+// ISBN 0-12-286165-5) pp. 612ff
+void
+Bezier::FitCurve(lfPOINT *d, int npt, double error)
+{
+ double len;
+ lfPOINT tHat1, tHat2;
+
+ tHat1.fx = d[1].fx - d[0].fx; tHat1.fy = d[1].fy - d[0].fy;
+ if(0.0 != (len = sqrt((tHat1.fx * tHat1.fx) + (tHat1.fy * tHat1.fy)))) {
+ tHat1.fx /= len; tHat1.fy /= len;
+ }
+ tHat2.fx = d[npt-2].fx - d[npt-1].fx; tHat2.fy = d[npt-2].fy - d[npt-1].fy;
+ if(0.0 != (len = sqrt((tHat2.fx * tHat2.fx) + (tHat2.fy * tHat2.fy)))) {
+ tHat2.fx /= len; tHat2.fy /= len;
+ }
+ FitCubic(d, 0, npt -1, tHat1, tHat2, error);
+}
+
+void
+Bezier::RemovePoint(lfPOINT *d, int sel)
+{
+ long o_nPoints;
+ double len;
+ lfPOINT ndata[3], tHat1, tHat2;
+
+ o_nPoints = nPoints; nPoints = sel-3;
+ ndata[0].fx = d[sel-3].fx; ndata[0].fy = d[sel-3].fy;
+ ndata[1].fx = d[sel].fx; ndata[1].fy = d[sel].fy;
+ ndata[2].fx = d[sel+3].fx; ndata[2].fy = d[sel+3].fy;
+ tHat1.fx = d[sel-2].fx - d[sel-3].fx; tHat1.fy = d[sel-2].fy - d[sel-3].fy;
+ if(0.0 != (len = sqrt((tHat1.fx * tHat1.fx) + (tHat1.fy * tHat1.fy)))) {
+ tHat1.fx /= len; tHat1.fy /= len;
+ }
+ tHat2.fx = d[sel+2].fx - d[sel+3].fx; tHat2.fy = d[sel+2].fy - d[sel+3].fy;
+ if(0.0 != (len = sqrt((tHat2.fx * tHat2.fx) + (tHat2.fy * tHat2.fy)))) {
+ tHat2.fx /= len; tHat2.fy /= len;
+ }
+ FitCubic(ndata, 0, 2, tHat1, tHat2, 1.0e-13);
+ nPoints = o_nPoints;
+}
+
+//Fit a Bezier curve to a (sub)set of digitized points
+void
+Bezier::FitCubic(lfPOINT *d, int first, int last, lfPOINT tHat1, lfPOINT tHat2, double error)
+{
+ lfPOINT bezCurve[4];
+ double *u, *uPrime, maxError, iterationError;
+ int i, splitPoint, npt;
+ lfPOINT tHatCenter;
+ int maxIterations = 8;
+ double len, b0, b1, b2; //temp variables
+
+ iterationError = error * error;
+ npt = last - first +1;
+ if(npt == 2) {
+ b1 = d[last].fx - d[first].fx; b2 = d[last].fy - d[first].fy;
+ b0 = sqrt(b1 * b1 + b2 * b2)/3.0;
+ b1 = b0/sqrt(tHat1.fx * tHat1.fx + tHat1.fy * tHat1.fy);
+ b2 = b0/sqrt(tHat2.fx * tHat2.fx + tHat2.fy * tHat2.fy);
+ bezCurve[0] = d[first]; bezCurve[3] = d[last];
+ bezCurve[1].fx = bezCurve[0].fx + tHat1.fx * b1;
+ bezCurve[1].fy = bezCurve[0].fy + tHat1.fy * b1;
+ bezCurve[2].fx = bezCurve[3].fx + tHat2.fx * b2;
+ bezCurve[2].fy = bezCurve[3].fy + tHat2.fy * b2;
+ AddPoints(3, bezCurve);
+ return;
+ }
+ u = ChordLengthParameterize(d, first, last);
+ GenerateBezier(d, first, last, u, tHat1, tHat2, bezCurve);
+ maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
+ if(maxError < error) {
+ AddPoints(3, bezCurve); return;
+ }
+ if(maxError < iterationError) {
+ for (i = 0; i < maxIterations; i++) {
+ uPrime = Reparameterize(d, first, last, u, bezCurve);
+ GenerateBezier(d, first, last, uPrime, tHat1, tHat2, bezCurve);
+ maxError = ComputeMaxError(d, first, last, bezCurve, uPrime, &splitPoint);
+ if (maxError < error) {
+ AddPoints(3, bezCurve); return;
+ }
+ free(u); u = uPrime;
+ }
+ }
+ //Fitting failed: split at max error point and recurse
+ tHatCenter.fx = d[splitPoint-1].fx - d[splitPoint+1].fx;
+ tHatCenter.fy = d[splitPoint-1].fy - d[splitPoint+1].fy;
+ if(0.0 != (len = sqrt((tHatCenter.fx * tHatCenter.fx) + (tHatCenter.fy * tHatCenter.fy)))) {
+ tHatCenter.fx /= len; tHatCenter.fy /= len;
+ }
+ FitCubic(d, first, splitPoint, tHat1, tHatCenter, error * _SQRT2);
+ tHatCenter.fx = -tHatCenter.fx; tHatCenter.fy = -tHatCenter.fy;
+ FitCubic(d, splitPoint, last, tHatCenter, tHat2, error * _SQRT2);
+}
+
+//Use least-squares method to find Bezier control points for region.
+void
+Bezier::GenerateBezier(lfPOINT *d, int first, int last, double *uPrime,
+ lfPOINT tHat1, lfPOINT tHat2, lfPOINT *bezCurve)
+{
+ int i, npt;
+ lfPOINT *A0, *A1, tmp, v1, v2;
+ double C[2][2], X[2];
+ double det_C0_C1, det_C0_X, det_X_C1, alpha_l, alpha_r;
+ double b0, b1, b2, b3; //temp variables
+
+ npt = last - first +1;
+ A0 = (lfPOINT*) malloc(npt * sizeof(lfPOINT));
+ A1 = (lfPOINT*) malloc(npt * sizeof(lfPOINT));
+ for (i = 0; i < npt; i++) {
+ v1 = tHat1; v2 = tHat2;
+ b2 = 1.0 - uPrime[i];
+ b1 = 3.0 * uPrime[i] * b2 * b2; b2 = 3.0 * uPrime[i] * uPrime[i] * b2;
+ if(0.0 != (b0 = sqrt((v1.fx * v1.fx) + (v1.fy * v1.fy)))) {
+ v1.fx *= b1/b0; v1.fy *= b1/b0;
+ }
+ if(0.0 != (b0 = sqrt((v2.fx * v2.fx) + (v2.fy * v2.fy)))) {
+ v2.fx *= b2/b0; v2.fy *= b2/b0;
+ }
+ A0[i] = v1; A1[i] = v2;
+ }
+ C[0][0] = C[0][1] = C[1][0] = C[1][1] = X[0] = X[1] = 0.0;
+ for (i = 0; i < npt; i++) {
+ C[0][0] += ((A0[i].fx * A0[i].fx) + (A0[i].fy * A0[i].fy));
+ C[0][1] += ((A0[i].fx * A1[i].fx) + (A0[i].fy * A1[i].fy));
+ C[1][0] = C[0][1];
+ C[1][1] += ((A1[i].fx * A1[i].fx) + (A1[i].fy * A1[i].fy));
+ b2 = 1.0 - uPrime[i]; b0 = b2 * b2 * b2;
+ b1 = 3.0 * uPrime[i] * b2 * b2; b2 = 3.0 * uPrime[i] * uPrime[i] * b2;
+ b3 = uPrime[i] * uPrime[i] * uPrime[i];
+ tmp.fx = d[last].fx * b2 + d[last].fx * b3;
+ tmp.fy = d[last].fy * b2 + d[last].fy * b3;
+ tmp.fx += d[first].fx * b1; tmp.fy += d[first].fy * b1;
+ tmp.fx += d[first].fx * b0; tmp.fy += d[first].fy * b0;
+ tmp.fx = d[first+i].fx - tmp.fx; tmp.fy = d[first+i].fy - tmp.fy;
+ X[0] += (A0[i].fx * tmp.fx + A0[i].fy * tmp.fy);
+ X[1] += (A1[i].fx * tmp.fx + A1[i].fy * tmp.fy);
+ }
+ det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1];
+ det_C0_X = C[0][0] * X[1] - C[0][1] * X[0];
+ det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1];
+ if(det_C0_C1 == 0.0) det_C0_C1 = (C[0][0] * C[1][1]) * 10e-12;
+ alpha_l = det_X_C1 / det_C0_C1; alpha_r = det_C0_X / det_C0_C1;
+ bezCurve[0] = d[first]; bezCurve[3] = d[last];
+ if(alpha_l < 0.0 || alpha_r < 0.0) {
+ //use Wu/Barsky heuristic
+ b1 = d[last].fx - d[first].fx; b2 = d[last].fy - d[first].fy;
+ b0 = sqrt(b1 * b1 + b2 * b2)/3.0;
+ b1 = b0/sqrt(tHat1.fx * tHat1.fx + tHat1.fy * tHat1.fy);
+ b2 = b0/sqrt(tHat2.fx * tHat2.fx + tHat2.fy * tHat2.fy);
+ }
+ else {
+ b1 = alpha_l/sqrt(tHat1.fx * tHat1.fx + tHat1.fy * tHat1.fy);
+ b2 = alpha_r/sqrt(tHat2.fx * tHat2.fx + tHat2.fy * tHat2.fy);
+ }
+ bezCurve[1].fx = bezCurve[0].fx + tHat1.fx * b1;
+ bezCurve[1].fy = bezCurve[0].fy + tHat1.fy * b1;
+ bezCurve[2].fx = bezCurve[3].fx + tHat2.fx * b2;
+ bezCurve[2].fy = bezCurve[3].fy + tHat2.fy * b2;
+ free(A0); free(A1);
+}
+
+//Given set of points and their parameterization, try to find
+// a better parameterization.
+double *
+Bezier::Reparameterize(lfPOINT *d, int first, int last, double *u, lfPOINT *bezCurve)
+{
+ int i, j, k, npt = last-first+1;
+ double *uPrime, num, den, *pl, *ph, *pq;
+ lfPOINT Q1[3], Q2[2], Q_u, Q1_u, Q2_u;
+
+ uPrime = (double*)malloc(npt * sizeof(double));
+ //Use Newton-Raphson iteration to find better root
+ for (i = first, j = 0; i <= last; i++, j++) {
+ for(pl=(double*)bezCurve, ph=pl+2, pq=(double*)Q1, k=0; k <= 4; pl++, ph++, pq++, k++) {
+ *pq = (*ph - *pl ) * 3.0;
+ }
+ for(pl=(double*)Q1, ph=pl+2, pq=(double*)Q2, k=0; k <= 2; pl++, ph++, pq++, k++) {
+ *pq = (*ph - *pl ) * 2.0;
+ }
+ Q_u = fBezier(3, bezCurve, u[j]);
+ Q1_u = fBezier(2, Q1, u[j]);
+ Q2_u = fBezier(1, Q2, u[j]);
+ num = (Q_u.fx - d[i].fx) * (Q1_u.fx) + (Q_u.fy - d[i].fy) * (Q1_u.fy);
+ den = (Q1_u.fx) * (Q1_u.fx) + (Q1_u.fy) * (Q1_u.fy) +
+ (Q_u.fx - d[i].fx) * (Q2_u.fx) + (Q_u.fy - d[i].fy) * (Q2_u.fy);
+ uPrime[j] = u[j] - (num/den);
+ }
+ return uPrime;
+}
+
+//evaluate a Bezier curve at a particular parameter value
+lfPOINT
+Bezier::fBezier(int degree, lfPOINT *V, double t)
+{
+ int i, j;
+ lfPOINT Q;
+ lfPOINT *Vtemp;
+
+ Vtemp = (lfPOINT *)malloc((degree+1) * sizeof(lfPOINT));
+ for (i = 0; i <= degree; i++) {
+ Vtemp[i] = V[i];
+ }
+ for (i = 1; i <= degree; i++) {
+ for (j = 0; j <= degree-i; j++) {
+ Vtemp[j].fx = (1.0 -t) * Vtemp[j].fx + t * Vtemp[j+1].fx;
+ Vtemp[j].fy = (1.0 -t) * Vtemp[j].fy + t * Vtemp[j+1].fy;
+ }
+ }
+ Q = Vtemp[0];
+ free(Vtemp);
+ return Q;
+}
+
+double *
+Bezier::ChordLengthParameterize(lfPOINT *d, int first, int last)
+{
+ int i;
+ double tmp, *u;
+
+ u = (double*)malloc((last-first+1) * sizeof(double));
+ u[0] = 0.0;
+ for(i = first+1; i <= last; i++) {
+ u[i-first] = u[i-first-1] +
+ sqrt(((tmp=(d[i].fx - d[i-1].fx))*tmp) + ((tmp=(d[i].fy - d[i-1].fy))*tmp));
+ }
+ for(i = first +1; i <= last; i++) {
+ u[i-first] = u[i-first] / u[last-first];
+ }
+ return u;
+}
+
+double
+Bezier::ComputeMaxError(lfPOINT *d, int first, int last, lfPOINT *bezCurve, double *u, int *splitPoint)
+{
+ int i;
+ double maxDist, dist;
+ lfPOINT P, v;
+
+ *splitPoint = (last - first + 1)>>1;
+ maxDist = 0.0;
+ for(i = first +1; i < last; i++) {
+ P = fBezier(3, bezCurve, u[i-first]);
+ v.fx = P.fx - d[i].fx; v.fy = P.fy - d[i].fy;
+ dist = v.fx * v.fx + v.fy * v.fy;
+ if(dist >= maxDist) {
+ maxDist = dist; *splitPoint = i;
+ }
+ }
+ return maxDist;
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// polygons are based on the polyline object
polygon::polygon(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts):
@@ -7541,6 +8034,16 @@ LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, Symbol *sy)
DefDesc(0L); Id = GO_LEGITEM; moveable = true;
}
+LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, int err, char *desc)
+ :GraphObj(par, d)
+{
+ FileIO(INIT_VARS); flags |= (0x80 | (err & 0x7f));
+ if(ld) {
+ memcpy(&OutLine, ld, sizeof(LineDEF));
+ }
+ DefDesc(desc); Id = GO_LEGITEM; moveable = true;
+}
+
LegItem::LegItem(int src):GraphObj(0L, 0L)
{
FileIO(INIT_VARS);
@@ -7577,34 +8080,81 @@ LegItem::GetSize(int select)
void
LegItem::DoPlot(anyOutput *o)
{
- POINT pts[2];
-
- if(!parent || !o) return;
- hcr.left = iround(parent->GetSize((flags & 0x01) ? SIZE_XPOS+2 : SIZE_XPOS));
- hcr.right = iround(parent->GetSize((flags & 0x01) ? SIZE_XPOS+3 :SIZE_XPOS+1));
- hcr.top = iround(parent->GetSize(SIZE_YPOS));
- hcr.bottom = iround(parent->GetSize(SIZE_YPOS+1));
- SetMinMaxRect(&rDims, hcr.left, hcr.top, hcr.right, hcr.bottom);
- if(flags & 0x02){
- o->SetLine(&OutLine); o->SetFill(&Fill);
- o->oRectangle(hcr.left, hcr.top, hcr.right, hcr.bottom, name);
- }
- if(flags & 0x01){
- pts[0].x = hcr.left; pts[1].x = hcr.right;
- pts[0].y = pts[1].y = iround(GetSize(SIZE_YCENTER))+1;
- o->SetLine(&DataLine); o->oPolyline(pts, 2, 0L);
- }
- if(flags & 0x04){
- if(Sym) Sym->DoPlot(o);
- }
- if(Desc) {
- Desc->moveable = false; Desc->DoPlot(o);
- if(Desc->rDims.bottom > rDims.bottom){
- parent->SetSize(SIZE_YPOS+1, (double)Desc->rDims.bottom);
- }
- UpdateMinMaxRect(&rDims, Desc->rDims.left, Desc->rDims.top);
- UpdateMinMaxRect(&rDims, Desc->rDims.right, Desc->rDims.bottom);
- }
+ POINT pts[3];
+ int ie, cy;
+
+ if(!parent || !o) return;
+ hcr.top = iround(parent->GetSize(SIZE_YPOS));
+ hcr.bottom = iround(parent->GetSize(SIZE_YPOS+1));
+ SetMinMaxRect(&rDims, hcr.left, hcr.top, hcr.right, hcr.bottom);
+ if(flags & 0x80) {
+ hcr.left = iround(parent->GetSize((flags & 0x40) ? SIZE_XPOS+2 : SIZE_XPOS));
+ hcr.right = iround(parent->GetSize((flags & 0x40) ? SIZE_XPOS+3 :SIZE_XPOS+1));
+ ie = o->un2ix(defs.GetSize(SIZE_ERRBAR)/2.0);
+ o->SetLine(&OutLine); cy = (hcr.top + hcr.bottom)>>1;
+ if((flags & 0x3f) == 0x01) {
+ pts[0].x = pts[1].x = (hcr.right + hcr.left)>>1;
+ pts[0].y = hcr.top; pts[1].y = hcr.bottom;
+ o->oPolyline(pts, 2, 0L);
+ pts[0].x -= (ie-1); pts[1].x += ie; pts[0].y = pts[1].y = hcr.top;
+ o->oPolyline(pts, 2, 0L); pts[0].y = pts[1].y = hcr.bottom;
+ o->oPolyline(pts, 2, 0L);
+ }
+ else if((flags & 0x3f) == 0x02) {
+ pts[0].x = pts[1].x = ((hcr.right + hcr.left)>>1);
+ pts[0].y = pts[1].y = cy; cy = ((hcr.bottom - hcr.top)>>1);
+ pts[0].x -= cy; pts[2].x = (pts[1].x += cy);
+ o->oPolyline(pts, 2, 0L); pts[1].x = pts[0].x;
+ pts[0].y -= ie; pts[1].y += ie;
+ o->oPolyline(pts, 2, 0L);
+ pts[0].x = pts[1].x = pts[2].x; o->oPolyline(pts, 2, 0L);
+ }
+ else if((flags & 0x3f) == 0x03) {
+ pts[0].x = pts[1].x = (hcr.right + hcr.left)>>1;
+ pts[0].y = hcr.top; pts[1].y = hcr.bottom;
+ o->oPolyline(pts, 2, 0L); pts[0].x -= (ie-1);
+ pts[0].y = pts[1].y = hcr.top; o->oPolyline(pts, 2, 0L);
+ pts[0].y = pts[1].y = hcr.bottom; pts[0].x += (ie + ie -1);
+ o->oPolyline(pts, 2, 0L);
+ }
+ else if((flags & 0x3f) == 0x04) {
+ pts[0].x = pts[1].x = (hcr.right + hcr.left)>>1;
+ pts[0].y = hcr.top; pts[1].y = hcr.bottom;
+ o->oPolyline(pts, 2, 0L); pts[0].x += ie;
+ pts[0].y = pts[1].y = hcr.top; o->oPolyline(pts, 2, 0L);
+ pts[0].y = pts[1].y = hcr.bottom; pts[0].x -= (ie + ie -1);
+ o->oPolyline(pts, 2, 0L);
+ }
+ else if((flags & 0x3f) == 0x05) {
+ pts[0].x = pts[1].x = (hcr.right + hcr.left)>>1;
+ pts[0].y = hcr.top; pts[1].y = hcr.bottom;
+ o->oPolyline(pts, 2, 0L);
+ }
+ }
+ else {
+ hcr.left = iround(parent->GetSize((flags & 0x01) ? SIZE_XPOS+2 : SIZE_XPOS));
+ hcr.right = iround(parent->GetSize((flags & 0x01) ? SIZE_XPOS+3 :SIZE_XPOS+1));
+ if(flags & 0x02){
+ o->SetLine(&OutLine); o->SetFill(&Fill);
+ o->oRectangle(hcr.left, hcr.top, hcr.right, hcr.bottom, name);
+ }
+ if(flags & 0x01){
+ pts[0].x = hcr.left; pts[1].x = hcr.right;
+ pts[0].y = pts[1].y = iround(GetSize(SIZE_YCENTER))+1;
+ o->SetLine(&DataLine); o->oPolyline(pts, 2, 0L);
+ }
+ if(flags & 0x04){
+ if(Sym) Sym->DoPlot(o);
+ }
+ }
+ if(Desc) {
+ Desc->moveable = false; Desc->DoPlot(o);
+ if(Desc->rDims.bottom > rDims.bottom){
+ parent->SetSize(SIZE_YPOS+1, (double)Desc->rDims.bottom);
+ }
+ UpdateMinMaxRect(&rDims, Desc->rDims.left, Desc->rDims.top);
+ UpdateMinMaxRect(&rDims, Desc->rDims.right, Desc->rDims.bottom);
+ }
}
void
@@ -7690,7 +8240,15 @@ LegItem::HasSym(LineDEF *ld, GraphObj *sy)
}
if(ld && cmpLineDEF(ld, &DataLine)) return false;
return true;
-}
+}
+
+bool
+LegItem::HasErr(LineDEF *ld, int err)
+{
+ if((((DWORD)err & 0x1f) | 0x80) != (flags & 0x9f)) return false;
+ if(ld && cmpLineDEF(ld, &OutLine)) return false;
+ return true;
+}
void
LegItem::DefDesc(char *txt)
@@ -7786,6 +8344,7 @@ Legend::DoPlot(anyOutput *o)
//draw all items
for(i = 0; i < nItems; i++) {
if(Items[i]){
+ if((Items[i]->flags & 0x11) == 0x01) hasLine = true;
Items[i]->DoPlot(o);
if(rDims.left == rDims.right || rDims.top == rDims.bottom){
rDims.left = Items[i]->rDims.left; rDims.right = Items[i]->rDims.right;
@@ -7924,6 +8483,7 @@ Legend::HasSym(LineDEF *ld, GraphObj *sy)
LegItem *li;
if(!parent || !sy) return true;
+ if(ld) hasLine = true;
if(Items) for(i = 0; i < nItems; i++) {
if(Items[i] && Items[i]->HasSym(ld, sy)) return true;
}
@@ -7938,6 +8498,21 @@ Legend::HasSym(LineDEF *ld, GraphObj *sy)
}
return false;
}
+
+bool
+Legend::HasErr(LineDEF *ld, int err, char *desc)
+{
+ int i;
+ LegItem *li;
+
+ if(Items) for(i = 0; i < nItems; i++) {
+ if(Items[i] && Items[i]->HasErr(ld, err)) return true;
+ }
+ if(li = new LegItem(this, data, ld, err | (hasLine ? 0x40 : 0), desc)){
+ if(!(Command(CMD_DROP_OBJECT, li, 0L))) DeleteGO(li);
+ }
+ return false;
+}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Graphs are graphic objects containing plots, axes, and drawn objects
@@ -7972,16 +8547,15 @@ Graph::~Graph()
int i;
if(!parent) return; parent = 0L;
- Undo.InvalidGO(this);
- DoZoom("reset");
+ Undo.InvalidGO(this); DoZoom("reset");
if(CurrGraph == this) CurrGraph = 0L;
if(Plots) {
for(i = 0; i< NumPlots; i++) if(Plots[i]) DeleteGO(Plots[i]);
- free(Plots);
+ free(Plots); Plots = 0L; NumPlots = 0;
}
if(Axes) {
- for(i = 0; i< NumAxes; i++) if(Axes[i]) delete Axes[i];
- free(Axes);
+ for(i = 0; i< NumAxes; i++) if(Axes[i]) DeleteGO(Axes[i]);
+ free(Axes); Axes = 0L; NumAxes = 0;
}
if(OwnDisp && Disp) DelDispClass(Disp); OwnDisp = false; Disp = 0L;
if(frm_g) DeleteGO(frm_g); if(frm_d) DeleteGO(frm_d);
@@ -8127,7 +8701,8 @@ Graph::DoPlot(anyOutput *target)
else {
Plots[i]->DoPlot(CurrDisp);
}
- }
+ }
+ if(bModified) data->Command(CMD_MRK_DIRTY, 0L, 0L);
if(target && ToolMode == TM_STANDARD) target->MouseCursor(MC_ARROW, false);
}
@@ -8141,7 +8716,7 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
int i, j;
DWORD delflg = 0L;
- if(!o) o = CurrDisp;
+ if(!o) o = Disp ? Disp : CurrDisp;
switch (cmd){
case CMD_CAN_CLOSE:
HideTextCursor();
@@ -8152,7 +8727,7 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
if(i == 2) return false;
else if(i == 1) if(! SaveGraphAs(this)) return false;
}
- //fall through
+ return true;
case CMD_CAN_DELETE:
HideTextCursor();
if(bModified) {
@@ -8160,13 +8735,11 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
if(YesNoBox(TmpTxt)) SaveGraphAs(this);
}
bModified = false;
- if(OwnDisp && Disp && parent){ //be careful not to reenter
- OwnDisp = false; DelDispClass(Disp); Disp = CurrDisp = 0L;
- if(Axes) for(i = 0; i< NumAxes; i++) if(Axes[i]) DeleteGO(Axes[i]);
- if(Plots) for(i = 0; i< NumPlots; i++) if(Plots[i]) DeleteGO(Plots[i]);
- Axes = 0L; Plots = 0L; NumPlots = 0; NumAxes = 0;
- if(parent) parent->Command(CMD_DELOBJ, this, 0L);
+ if(OwnDisp == true && Disp && CurrDisp){ //be careful not to reenter
+ OwnDisp = false; DelDispClass(Disp);
+ Disp = CurrDisp = 0L; parent = 0L;
}
+ if(parent) parent->Command(CMD_DELOBJ, this, 0L);
return true;
case CMD_LAYERS:
Undo.SetDisp(o ? o : CurrDisp);
@@ -8178,6 +8751,7 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
Undo.ValRect(this, &DRect, UNDO_CONTINUE);
return true;
case CMD_LEGEND:
+ Undo.SetDisp(o ? o : CurrDisp);
if(Id == GO_PAGE) {
if(CurrGraph && CurrGraph->parent == this) return CurrGraph->Command(cmd, tmpl, o);
if(!CurrGraph && NumPlots == 1 && Plots[0] && Plots[0]->Id == GO_GRAPH){
@@ -8289,7 +8863,7 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_ZOOM:
return DoZoom((char*)tmpl);
case CMD_MOUSECURSOR:
- if(Disp)Disp->MouseCursor(MC_ARROW, false);
+ if(o)o->MouseCursor(PasteObj ? MC_PASTE : MC_ARROW, false);
return true;
case CMD_AXIS: //one of the plots has changed scaling: reset
if(o)o->SetRect(CurrRect, units, &x_axis, &y_axis);
@@ -8325,7 +8899,7 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
if(CurrDisp) CurrDisp->MouseCursor(MC_ARROW, true);
return true;
case CMD_ADDAXIS:
- Command(CMD_TOOLMODE, 0L, o);
+ Undo.SetDisp(o ? o : CurrDisp); Command(CMD_TOOLMODE, 0L, o);
if(Id == GO_PAGE) {
if(CurrGraph && CurrGraph->parent == this) return CurrGraph->Command(cmd, tmpl, o);
if(!CurrGraph && NumPlots == 1 && Plots[0] && Plots[0]->Id == GO_GRAPH){
@@ -8339,7 +8913,8 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
else {
if(type == GT_3D && Plots){
for(i = 0; i < NumPlots; i++)
- if(Plots[i] && (Plots[i]->Id == GO_PLOT3D || Plots[i]->Id == GO_FUNC3D))
+ if(Plots[i] && (Plots[i]->Id == GO_PLOT3D || Plots[i]->Id == GO_FUNC3D
+ || Plots[i]->Id == GO_FITFUNC3D))
return Plots[i]->Command(cmd, tmpl, o);
}
else if(AddAxis()) {
@@ -8378,7 +8953,7 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
f_name = OpenGraphName(filename);
if(f_name && f_name[0]) {
if(data) data->Command(CMD_UPDHISTORY, 0L, 0L);
- return OpenGraph(Id == GO_PAGE ? this : parent, f_name, 0L);
+ return OpenGraph(Id == GO_PAGE ? this : parent, f_name, 0L, false);
}
return true;
case CMD_UPDHISTORY:
@@ -8426,7 +9001,7 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
return parent->Command(CMD_DELOBJ_CONT, (void*)this, o);
return false;
case CMD_TOOLMODE:
- if(o) {
+ if(o && tmpl) {
o->CheckMenu(ToolMode & 0x0f, false);
o->CheckMenu(ToolMode = tmpl ? (*((int*)tmpl)) & 0x0f : TM_STANDARD, true);
}
@@ -8437,13 +9012,16 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
case TM_TEXT: o->MouseCursor(MC_TEXT, false); break;
case TM_DRAW: case TM_POLYLINE: case TM_POLYGON:
case TM_RECTANGLE: case TM_ELLIPSE: case TM_ROUNDREC:
- case TM_ARROW:
+ case TM_ARROW:
o->MouseCursor(MC_CROSS, false);
break;
- default: o->MouseCursor(MC_ARROW, true); break;
- }
+ default:
+ o->MouseCursor(MC_ARROW, true);
+ break;
+ }
return Command(CMD_REDRAW, 0L, CurrDisp);
case CMD_ADDPLOT:
+ Undo.SetDisp(o ? o : CurrDisp);
if(Id == GO_PAGE) {
if(CurrGraph && CurrGraph->parent == this) return CurrGraph->Command(cmd, tmpl, o);
if(!CurrGraph && NumPlots == 1 && Plots[0] && Plots[0]->Id == GO_GRAPH){
@@ -8457,7 +9035,8 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
else if(Id == GO_GRAPH) {
if(type == GT_3D && Plots){
for(i = 0; i < NumPlots; i++) {
- if(Plots[i] && (Plots[i]->Id == GO_PLOT3D || Plots[i]->Id == GO_FUNC3D)) {
+ if(Plots[i] && (Plots[i]->Id == GO_PLOT3D || Plots[i]->Id == GO_FUNC3D
+ || Plots[i]->Id == GO_FITFUNC3D)) {
if(Plots[i]->Command(cmd, tmpl, CurrDisp)) return Command(CMD_REDRAW, 0L, o);
else return false;
}
@@ -8471,7 +9050,10 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
return (dirty = true);
case CMD_CURRLEFT: case CMD_CURRIGHT: case CMD_ADDCHAR:
case CMD_BACKSP: case CMD_POS_FIRST: case CMD_POS_LAST:
- defs.SetDisp(o);
+ defs.SetDisp(o);
+ if(tmpl && *((int*)tmpl) == 27) { //Escape
+ o->HideMark(); CurrLabel = 0L;
+ }
if(CurrLabel) return CurrLabel->Command(cmd, tmpl, o);
if(CurrGO && tmpl && *((int*)tmpl) == 13) {
CurrGO->PropertyDlg();
@@ -8490,7 +9072,8 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
else {
if(type == GT_3D && Plots) {
for(i = 0; i < NumPlots; i++) {
- if(Plots[i] && (Plots[i]->Id == GO_PLOT3D || Plots[i]->Id == GO_FUNC3D))
+ if(Plots[i] && (Plots[i]->Id == GO_PLOT3D || Plots[i]->Id == GO_FUNC3D
+ || Plots[i]->Id == GO_FITFUNC3D))
return Plots[i]->Command(cmd, tmpl, CurrDisp);
}
}
@@ -8508,8 +9091,11 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_DELETE:
if(!CurrGO) return false;
bModified = true;
- if(CurrGO == CurrLabel) return CurrLabel->Command(cmd, tmpl, o);
+ if(CurrGO == CurrLabel) return CurrLabel->Command(cmd, tmpl, o);
if(CurrGO->parent)return CurrGO->parent->Command(CMD_DELOBJ, (void*)CurrGO, o);
+ return false;
+ case CMD_DROP_GRAPH:
+ if(parent) return parent->Command(cmd, tmpl, o);
return false;
case CMD_DROP_PLOT:
if(!tmpl || ((GraphObj*)tmpl)->Id < GO_PLOT) return false;
@@ -8525,7 +9111,8 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
case GO_POLARPLOT:
type = GT_POLARPLOT;
break;
- case GO_SCATT3D: case GO_PLOT3D: case GO_FUNC3D:
+ case GO_SCATT3D: case GO_PLOT3D: case GO_FUNC3D:
+ case GO_FITFUNC3D:
type = GT_3D;
break;
default:
@@ -8597,7 +9184,11 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
CurrDisp->EndPage();
return true;
}
- break;
+ break;
+ case CMD_PASTE_OBJ:
+// ToolMode = TM_PASTE; o->MouseCursor(MC_PASTE, false);
+// PasteObj = (GraphObj*)tmpl;
+ return false;
case CMD_MOUSE_EVENT:
mev = (MouseEvent *)tmpl; defs.SetDisp(o);
if(CurrGO && CurrGO->moveable && mev->Action == MOUSE_LBDOWN &&
@@ -8682,7 +9273,8 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
((ObjTree*)tmpl)->Command(CMD_UPDATE, Plots[i], 0L);
if(Plots[i]->Id == GO_STACKBAR || Plots[i]->Id == GO_GRAPH ||
Plots[i]->Id == GO_PLOT3D || Plots[i]->Id == GO_POLARPLOT ||
- Plots[i]->Id == GO_FUNC3D) Plots[i]->Command(cmd, tmpl, o);
+ Plots[i]->Id == GO_FUNC3D || Plots[i]->Id == GO_FITFUNC3D)
+ Plots[i]->Command(cmd, tmpl, o);
}
return true;
}
@@ -8768,7 +9360,7 @@ Graph::CreateAxes(int templ)
{
AxisDEF tmp_axis;
TextDEF label_def, tlbdef;
- char label_text[20];
+ char label_text[500];
Label *label;
double ts, lb_ydist, lb_xdist, tlb_dist;
DWORD ptick, ntick, utick;
@@ -9067,10 +9659,8 @@ Graph::ExecTool(MouseEvent *mev)
if(ToolMode & TM_MOVE) switch (mev->Action) {
case MOUSE_LBDOWN:
pl.x = pc.x = mev->x; pl.y = pc.y = mev->y;
- CurrDisp->HideMark();
- if(TrackGO && TrackGO->Command(CMD_MOUSECURSOR, 0L, CurrDisp))
- return true;
- else CurrDisp->MouseCursor(MC_MOVE, false);
+ if(TrackGO && TrackGO->Command(CMD_MOUSECURSOR, 0L, CurrDisp)) return true;
+ CurrDisp->HideMark(); CurrDisp->MouseCursor(MC_MOVE, false);
return true;
case MOUSE_MOVE:
if(TrackGO) {
@@ -9113,8 +9703,9 @@ Graph::ExecTool(MouseEvent *mev)
case MOUSE_LBUP:
j = (i = rc_mrk.left - mev->x)*i;
j += ((i = rc_mrk.top - mev->y)*i);
- if(j < 20) { //glitch
- ToolMode = TM_STANDARD;
+ if(j < 20) { //glitch
+ rc_mrk.left = rc_mrk.right = rc_mrk.top = rc_mrk.bottom = 0;
+ ToolMode = TM_STANDARD; CurrDisp->MouseCursor(MC_ARROW, false);
return false;
}
if(ToolMode == TM_ZOOMIN) {
@@ -9140,6 +9731,14 @@ Graph::ExecTool(MouseEvent *mev)
}
return true;
}
+ }
+ if(ToolMode == TM_PASTE) {
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ ToolMode = TM_STANDARD; CurrDisp->MouseCursor(MC_ARROW, false);
+ break;
+ }
+ return true;
}
if(NumPlots && !Plots[NumPlots-1]) {
Undo.StoreListGO(this, &Plots, &NumPlots, UNDO_CONTINUE);
@@ -9181,7 +9780,9 @@ Graph::ExecTool(MouseEvent *mev)
}
if(Plots[NumPlots]) i = NumPlots+1;
else i = NumPlots;
- Undo.SetGO(this, &Plots[i], new polyline(this, data, lfp, (int)tl_nPts), 0L);
+// Undo.SetGO(this, &Plots[i], new polyline(this, data, lfp, (int)tl_nPts), 0L);
+ Undo.SetGO(this, &Plots[i], new Bezier(this, data, lfp, (int)tl_nPts, 0,
+ (CurrDisp->hres/CurrDisp->VPscale+CurrDisp->vres/CurrDisp->VPscale)/2.0), 0L);
if(Plots[i]){
NumPlots = i+1;
Plots[i]->moveable = 1;
@@ -9261,7 +9862,8 @@ Graph::ExecTool(MouseEvent *mev)
else i = NumPlots;
Undo.SetGO(this, &Plots[i], ToolMode == TM_POLYLINE ?
new polyline(this, data, lfp, (int)tl_nPts) :
- new polygon(this, data, lfp, (int)tl_nPts), 0L);
+// (GraphObj*) new Bezier(this, data, lfp, (int)tl_nPts) :
+ (GraphObj*) new polygon(this, data, lfp, (int)tl_nPts), 0L);
if(Plots[i]){
NumPlots = i+1;
Plots[i]->moveable = 1;
@@ -9277,10 +9879,7 @@ Graph::ExecTool(MouseEvent *mev)
}
if(mev->x == pc.x && mev->y == pc.y) return true; //rebounce
break;
- case TM_RECTANGLE:
- case TM_ELLIPSE:
- case TM_ROUNDREC:
- case TM_ARROW:
+ case TM_RECTANGLE: case TM_ELLIPSE: case TM_ROUNDREC: case TM_ARROW:
switch (mev->Action) {
case MOUSE_LBDOWN:
CurrGO = 0L;
@@ -9375,7 +9974,7 @@ Graph::ExecTool(MouseEvent *mev)
free(td);
return true;
}
- break;
+ break;
}
return false;
}
@@ -9616,8 +10215,10 @@ Page::DoPlot(anyOutput *o)
pts[1].x = pts[2].x = rDims.right; pts[2].y = rDims.top +3;
CurrDisp->oPolyline(pts, 3);
//do all plots
- if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i]) Plots[i]->DoPlot(CurrDisp);
-
+ if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i]) Plots[i]->DoPlot(CurrDisp);
+ if(PasteObj) {
+ ToolMode = TM_PASTE; CurrDisp->MouseCursor(MC_PASTE, false);
+ }
}
bool
diff --git a/rlplot.h b/rlplot.h
index b942817..875f2de 100755
--- a/rlplot.h
+++ b/rlplot.h
@@ -1,4 +1,4 @@
-//RLPlot.h, Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005 R.Lackner
+//RLPlot.h, Copyright (c) 2000-2006 R.Lackner
//
// This file is part of RLPlot.
//
@@ -40,6 +40,7 @@ inline int WriteFloatToBuff(char *buff, double val) {return sprintf(buff, " %g",
#define w_char unsigned short
#define _SBINC 8 //scrollbox extra space/line
#define _TXH 3.0 //graph text default size in mm
+#define RLP_PORT 4321 //clipboard server
typedef struct tagPOINT { // pt
long x;
@@ -114,7 +115,8 @@ enum {CMD_NONE, CMD_ADDCHAR, CMD_SETFOCUS, CMD_KILLFOCUS, CMD_DELETE,
CMD_FILLRANGE, CMD_BUSY, CMD_ERROR, CMD_CLEAR_ERROR, CMD_SETPARAM, CMD_SETFUNC,
CMD_HIDE_MARK, CMD_LEGEND, CMD_FILENAME, CMD_LAYERS, CMD_OBJTREE, CMD_TEXTDEF,
CMD_HASSTACK, CMD_WRITE_GRAPHS, CMD_SETFONT, CMD_SETSTYLE, CMD_COPY, CMD_PASTE,
- CMD_INSROW, CMD_INSCOL, CMD_DELROW, CMD_DELCOL, CMD_ADDTXT, CMD_ETRACC, CMD_SHPGUP, CMD_SHPGDOWN};
+ CMD_INSROW, CMD_INSCOL, CMD_DELROW, CMD_DELCOL, CMD_ADDTXT, CMD_ETRACC, CMD_SHPGUP,
+ CMD_SHPGDOWN, CMD_ERRDESC, CMD_SAVEDATA, CMD_GETMARK, CMD_PASTE_OBJ};
enum {SYM_CIRCLE, SYM_CIRCLEF, SYM_RECT, SYM_RECTF, SYM_TRIAU, SYM_TRIAUF,
SYM_TRIAD, SYM_TRIADF, SYM_DIAMOND, SYM_DIAMONDF, SYM_PLUS, SYM_CROSS,
SYM_STAR, SYM_HLINE, SYM_VLINE, SYM_TEXT, SYM_POS_PARENT = 0x1000};
@@ -127,27 +129,28 @@ enum {GO_UNKNOWN, GO_AXIS, GO_TICK, GO_GRIDLINE, GO_SYMBOL, GO_BUBBLE, GO_BAR,
GO_DRAGHANDLE, GO_DRAGRECT, GO_DRAG3D, GO_FRAMERECT, GO_SPHERE, GO_SVGOPTIONS,
GO_PLANE, GO_BRICK, GO_LINESEG, GO_LINE3D, GO_GRIDLINE3D, GO_GRIDRADIAL,
GO_SPHSCANL, GO_DROPL3D, GO_ARROW3D, GO_PLANE3D, GO_LEGITEM, GO_LEGEND,
- GO_OBJTREE,
+ GO_OBJTREE, GO_BEZIER,
GO_PLOT = 0x100, GO_PLOTSCATT, GO_REGRESSION, GO_BARCHART, GO_BUBBLEPLOT,
GO_BOXPLOT, GO_DENSDISP, GO_STACKBAR, GO_STACKPG, GO_WATERFALL, GO_POLARPLOT,
GO_PIECHART, GO_RINGCHART, GO_GROUP, GO_STARCHART, GO_SCATT3D, GO_PLOT3D,
GO_RIBBON, GO_LIMITS, GO_FUNCTION, GO_FITFUNC, GO_FREQDIST, GO_GRID3D, GO_FUNC3D,
- GO_XYSTAT,
+ GO_XYSTAT, GO_FITFUNC3D,
GO_GRAPH = 0x200, GO_PAGE, GO_SPREADDATA = 0x300, GO_DEFRW};
enum {FILL_NONE, FILL_HLINES, FILL_VLINES, FILL_HVCROSS, FILL_DLINEU, FILL_DLINED,
FILL_DCROSS, FILL_STIPPLE1, FILL_STIPPLE2, FILL_STIPPLE3, FILL_STIPPLE4,
FILL_STIPPLE5, FILL_ZIGZAG, FILL_COMBS, FILL_BRICKH, FILL_BRICKV, FILL_BRICKDU,
FILL_BRICKDD, FILL_TEXTURE1, FILL_TEXTURE2, FILL_WAVES1, FILL_SCALES, FILL_SHINGLES,
- FILL_WAVES2, FILL_HERRING, FILL_CIRCLES, FILL_GRASS, FILL_FOAM, FILL_RECS,
- NUM_FILLS, FILL_LIGHT3D = 0x100};
+ FILL_WAVES2, FILL_HERRING, FILL_CIRCLES, FILL_GRASS, FILL_FOAM, FILL_RECS,
+ FILL_HASH, FILL_WATER, NUM_FILLS, FILL_LIGHT3D = 0x100};
enum {ERRBAR_VSYM, ERRBAR_VUP, ERRBAR_VDOWN, ERRBAR_HSYM, ERRBAR_HLEFT,
ERRBAR_HRIGHT};
enum {BAR_NONE, BAR_VERTB, BAR_VERTT, BAR_VERTU, BAR_HORL, BAR_HORR, BAR_HORU,
BAR_RELWIDTH = 0x100, BAR_CENTERED = 0x200, BAR_WIDTHDATA = 0x400};
enum {TM_STANDARD, TM_DRAW, TM_POLYLINE, TM_POLYGON, TM_RECTANGLE, TM_ELLIPSE,
- TM_ROUNDREC, TM_ARROW, TM_TEXT, TM_MARK, TM_ZOOMIN, TM_MOVE = 0x100};
+ TM_ROUNDREC, TM_ARROW, TM_TEXT, TM_MARK, TM_ZOOMIN, TM_MOVE = 0x100,
+ TM_PASTE=0x200};
enum {MC_LAST, MC_ARROW, MC_CROSS, MC_TEXT, MC_WAIT, MC_MOVE, MC_NORTH,
- MC_NE, MC_EAST, MC_SE, MC_SALL, MC_ZOOM};
+ MC_NE, MC_EAST, MC_SE, MC_SALL, MC_ZOOM, MC_PASTE};
enum {FILE_ERROR, FILE_READ, FILE_WRITE, INIT_VARS, SAVE_VARS};
enum {ARROW_NOCAP, ARROW_LINE, ARROW_TRIANGLE, ARROW_UNITS = 0x100};
enum {MENU_NONE, MENU_SPREAD, MENU_GRAPH, MENU_PAGE};
@@ -435,8 +438,8 @@ public:
virtual bool oArc(int x1, int y1, int x2, int y2, int quads){return false;};
};
-enum {ET_UNKNOWN, ET_VALUE, ET_TEXT, ET_FORMULA, ET_ERROR, ET_BUSY=0x100,
- ET_CIRCULAR=0x200};
+enum {ET_UNKNOWN, ET_VALUE, ET_TEXT, ET_FORMULA, ET_ERROR, ET_BOOL,
+ ET_DATE, ET_TIME, ET_DATETIME, ET_BUSY=0x100, ET_CIRCULAR=0x200};
class EditText {
public:
@@ -454,11 +457,10 @@ public:
void Mark(anyOutput *Out, int mark);
bool Command(int cmd, anyOutput *Out, void *data_obj);
bool GetValue(double *v);
- bool GetText(char *t, int size);
+ bool GetText(char *t, int size, bool bTranslate);
bool GetResult(anyResult *r, bool use_last = false);
bool SetValue(double v);
bool SetText(char *t);
- bool GetItem(char *text, int size);
void SetRec(RECT *rc);
int GetX() {return loc.x;};
int GetY() {return loc.y;};
@@ -520,7 +522,7 @@ public:
virtual bool SetValue(int row, int col, double val);
virtual bool SetText(int row, int col, char *txt);
virtual bool GetValue(int row, int col, double *v);
- virtual bool GetText(int row, int col, char *txt, int len);
+ virtual bool GetText(int row, int col, char *txt, int len, bool bTranslate = true);
char ** GetTextPtr(int row, int col);
virtual bool GetResult(anyResult *r, int row, int col, bool use_last = false);
virtual bool GetSize(int *width, int *height);
@@ -532,6 +534,7 @@ public:
virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
virtual bool ReadData(char *, unsigned char *, int){return false;};
virtual void FlushData();
+ bool ValueRec(RECT *rc);
};
class StrData {
@@ -591,12 +594,13 @@ private:
void Texture1();
void Texture2();
void Arcs(int type);
- void Waves2();
+ void Waves2(int type);
void Herringbone();
void Circles();
void Grass();
void Foam();
- void Recs();
+ void Recs();
+ void Hash();
void CircGrad();
};
@@ -637,7 +641,7 @@ public:
bool Command(int cmd, void *tmpl, anyOutput *o);
private:
- bool bLBdown, bSelected;
+ bool bLBdown, bSelected, bMarked;
TextDEF TextDef;
LineDEF Line;
FillDEF Fill;
@@ -910,6 +914,8 @@ public:
bool FileIO(int rw);
private:
+ anyOutput *mo;
+ RECT mrc;
lfPOINT fPos;
double ferr, SizeBar;
POINT ebpts[6];
@@ -981,7 +987,8 @@ public:
Whisker(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
int xc1=-1, int xr1=-1, int yc1=-1, int yr1=-1, int xc2=-1, int xr2=-1,
int yc2=-1, int yr2=-1);
- Whisker(int src);
+ Whisker(int src);
+ ~Whisker();
bool SetSize(int select, double value);
bool SetColor(int select, DWORD col);
void DoPlot(anyOutput *o);
@@ -991,6 +998,8 @@ public:
bool FileIO(int rw);
private:
+ anyOutput *mo;
+ RECT mrc;
double size;
POINT pts[6];
lfPOINT pos1, pos2;
@@ -1350,6 +1359,7 @@ private:
class polyline:public GraphObj {
public:
+ dragHandle **pHandles;
lfPOINT *Values;
long nPoints, nPts;
POINT *pts;
@@ -1363,19 +1373,38 @@ public:
double GetSize(int select);
bool SetSize(int select, double value);
DWORD GetColor(int select);
- void DoPlot(anyOutput *o);
+ virtual void DoPlot(anyOutput *o);
void DoMark(anyOutput *o, bool mark);
bool Command(int cmd, void *tmpl, anyOutput *o);
virtual bool PropertyDlg();
- bool FileIO(int rw);
+ virtual bool FileIO(int rw);
void * ObjThere(int x, int y);
void Track(POINT *p, anyOutput *o);
private:
- dragHandle **pHandles;
-
void ShowPoints(anyOutput *o);
-};
+};
+
+class Bezier:public polyline {
+public:
+ Bezier(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts, int mode, double res);
+ Bezier(int src);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool FileIO(int rw);
+
+private:
+ void AddPoints(int n, lfPOINT *p);
+
+ void FitCurve(lfPOINT *d, int npt, double error);
+ void FitCubic(lfPOINT *d, int first, int last, lfPOINT tHat1, lfPOINT tHat2, double error);
+ void RemovePoint(lfPOINT *d, int sel);
+ void GenerateBezier(lfPOINT *d, int first, int last, double * uPrime, lfPOINT tHat1, lfPOINT tHat2, lfPOINT *bezCurve);
+ double *Reparameterize(lfPOINT *d, int first, int last, double *u, lfPOINT *bezCurve);
+ lfPOINT fBezier(int degree, lfPOINT *V, double t);
+ double * ChordLengthParameterize(lfPOINT *d, int first, int last);
+ double ComputeMaxError(lfPOINT *d, int first, int last, lfPOINT *bezCurve, double *u, int *splitPoint);
+};
class polygon:public polyline {
public:
@@ -1427,8 +1456,11 @@ public:
class LegItem:public GraphObj{
public:
+ DWORD flags;
+
LegItem(GraphObj *par, DataObj *d, LineDEF *ld, LineDEF *lf, FillDEF *fill);
LegItem(GraphObj *par, DataObj *d, LineDEF *ld, Symbol *sy);
+ LegItem(GraphObj *par, DataObj *d, LineDEF *ld, int err, char *desc);
LegItem(int src);
~LegItem();
double GetSize(int select);
@@ -1441,13 +1473,13 @@ public:
bool HasFill(LineDEF *ld, FillDEF *fd);
bool HasSym(LineDEF *ld, GraphObj *sy);
+ bool HasErr(LineDEF *ld, int err);
private:
LineDEF DataLine, OutLine, HatchLine;
FillDEF Fill;
Symbol *Sym;
Label *Desc;
- DWORD flags;
RECT hcr;
void DefDesc(char *txt);
@@ -1469,6 +1501,7 @@ public:
bool HasFill(LineDEF *ld, FillDEF *fd);
bool HasSym(LineDEF *ld, GraphObj *sy);
+ bool HasErr(LineDEF *ld, int err, char *desc);
private:
lfPOINT pos, lb_pos;
@@ -1476,6 +1509,7 @@ private:
anyOutput *to;
fRECT B_Rect, C_Rect, D_Rect, E_Rect, F_Rect;
long nItems;
+ bool hasLine;
LegItem **Items;
};
@@ -1846,10 +1880,11 @@ public:
bool SetColor(int select, DWORD col);
void DoPlot(anyOutput *o);
bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
void RegGO(void *n);
bool FileIO(int rw);
- void CreateObs();
+ void CreateObs(bool set_undo);
private:
long nLines, nPlanes;
@@ -1858,6 +1893,8 @@ private:
FillDEF Fill;
Line3D **lines;
Plane3D **planes;
+
+ bool Configure();
};
class Scatt3D:public Plot{
@@ -2154,7 +2191,29 @@ private:
bool Update();
double x1, x2, xstep, z1, z2, zstep;
- int g_idx;
+ LineDEF Line;
+ FillDEF Fill;
+ char *param, *cmdxy;
+ DataObj *gda;
+ Grid3D *gob;
+};
+
+class FitFunc3D:public Plot3D {
+public:
+ FitFunc3D(GraphObj *par, DataObj *d);
+ FitFunc3D(int src);
+ ~FitFunc3D();
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ void RegGO(void *n);
+ bool FileIO(int rw);
+
+private:
+ bool Update();
+
+ double x1, x2, xstep, z1, z2, zstep, conv, chi2;
+ char *ssXref, *ssYref, *ssZref;
+ int maxiter;
LineDEF Line;
FillDEF Fill;
char *param, *cmdxy;
@@ -2170,7 +2229,7 @@ public:
fRECT GRect, DRect, Bounds;
bool OwnDisp, bModified;
fRECT CurrRect;
- GraphObj **Plots;
+ GraphObj **Plots, *PasteObj;
DWORD ColBG, ColAX;
GraphObj **Sc_Plots;
Axis **Axes;
@@ -2266,7 +2325,8 @@ public:
int dUnits, cUnits;
char DecPoint[2], ColSep[2];
char *svgAttr, *svgScript, *currPath, *IniFile;
- char *File1, *File2, *File3, *File4, *File5, *File6;
+ char *File1, *File2, *File3, *File4, *File5, *File6;
+ char *fmt_date, *fmt_time, *fmt_datetime;
double min4log, ss_txt;
RECT clipRC;
@@ -2461,7 +2521,7 @@ bool DelBitmapClass(anyOutput *w);
bool SaveGraphAs(GraphObj *g);
char *GraphToMem(GraphObj *g, long *size);
void UpdGOfromMem(GraphObj *go, unsigned char *buff);
-bool OpenGraph(GraphObj *root, char *name, unsigned char *mem);
+bool OpenGraph(GraphObj *root, char *name, unsigned char *mem, bool bPaste);
void SavVarInit(long len);
void *SavVarFetch();
@@ -2492,7 +2552,11 @@ double base4log(AxisDEF *axis, int direc);
double TransformValue(AxisDEF *axis, double val, bool transform);
void SortAxisBreaks(AxisDEF *axis);
double GetAxisFac(AxisDEF *axis, double delta, int direc);
+char *str_ltrim(char *str);
+char *str_rtrim(char *str);
+char *str_trim(char *str);
void ReshapeFormula(char **text);
+void TranslateResult(anyResult *res);
void CleanTags(char *txt, int *i1, int *i2, int *i3);
void ChangeChar(char *text, char c1, char c2);
char *Int2Nat(char *Text);
@@ -2513,7 +2577,8 @@ bool IsCloseToLine(POINT *p1, POINT *p2, int x, int y);
bool IsCloseToPL(POINT p, POINT *pts, int cp);
bool IsInPolygon(POINT *p, POINT *pts, int cp);
bool OverlapRect(RECT *rc1, RECT *rc2);
-void AddToPolygon(long *cp, POINT *pts, POINT *np);
+void AddToPolygon(long *cp, POINT *pts, POINT *np);
+void DrawBezier(long *cp, POINT *pts, POINT p0, POINT p1, POINT p2, POINT p3, int depth=0);
POINT *MakeArc(int ix, int iy, int r, int qad, long *npts);
void InvertPolygon(POINT*, int, LineDEF*, FillDEF*, RECT*, anyOutput*, bool);
void InvertLine(POINT*, int, LineDEF*, RECT*, anyOutput*, bool);
@@ -2535,6 +2600,7 @@ double sininv(double val);
double trig2deg(double si, double csi);
bool ReplaceGO(GraphObj **oldobj, GraphObj **newobj);
unsigned int HashValue(unsigned char *str);
+unsigned int Hash2(unsigned char * str);
bool cmpLineDEF(LineDEF *l1, LineDEF *l2);
bool cmpFillDEF(FillDEF *f1, FillDEF *f2);
bool cmpAxisDEF(AxisDEF *a1, AxisDEF *a2);
@@ -2575,9 +2641,10 @@ void free_dmatrix(double **m, int nrl, int nrh, int ncl, int);
bool mrqmin(double *, double *, double *, int, double **, int, int *, int, double **, double **, double *,
void (*funcs)(double, double, double **, double *, double *, int), double *);
bool Check_MRQerror();
+void SortArray(int n, double *vals);
void SortFpArray(int n, lfPOINT *vals);
void spline(lfPOINT *v, int n, double *y2);
-double gammln(double xx);
+double gammln(double x);
double factrl(int n);
double gammp(double a, double x);
double gammq(double a, double x);
@@ -2588,18 +2655,33 @@ double betaf(double z, double w);
double errf(double x);
double errfc(double x);
double norm_dist(double x, double m, double s);
+double norm_freq(double x, double m, double s);
+double lognorm_dist(double x, double m, double s);
double chi_dist(double x, double df, double);
double t_dist(double t, double df, double);
double pois_dist(double x, double m, double);
double f_dist(double f, double df1, double df2);
double distinv(double (*sf)(double, double, double), double df1, double df2, double p, double x0);
void d_quartile(int n, double *v, double *q1, double *q2, double *q3);
+double d_variance(int n, double *v, double *mean = 0L, double *ss = 0L);
double d_amean(int n, double *v);
+double d_kurt(int n, double *v);
+double d_skew(int n, double *v);
double d_gmean(int n, double *v);
double d_hmean(int n, double *v);
+double d_classes(DataObj *d, double start, double step, double *v, int nv, char *range);
double d_pearson(double *x, double *y, int n, char *dest, DataObj *data);
+double d_rank(int n, double *v, double v1);
+void crank(int n, double *w0, double *s);
double d_spearman(double *x, double *y, int n, char *dest, DataObj *data);
+double d_kendall(double *x, double *y, int n, char *dest, DataObj *data);
double d_regression(double *x, double *y, int n, char *dest, DataObj *data);
+double d_covar(double *x, double *y, int n, char *dest, DataObj *data);
+double d_utest(double *x, double *y, int n1, int n2, char *dest, DataObj *data);
double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data);
+double d_ttest2(double *x, double *y, int n, char *dest, DataObj *data);
double d_ftest(double *x, double *y, int n1, int n2, char *dest, DataObj *data);
-
+bool date_value(char *desc, char *fmt, double *value);
+char *value_date(double dv, char *fmt);
+double now_today();
+void split_date(double dv, int *y, int *mo, int *dom, int *dow, int *doy, int *h, int *m, double *s);
diff --git a/rlplot.spec b/rlplot.spec
index 315c497..e280847 100755
--- a/rlplot.spec
+++ b/rlplot.spec
@@ -1,5 +1,5 @@
Name: rlplot
-Version: 1.0
+Version: 1.1
Release: 1
Summary: A plotting program to create high quality graphs from data.
License: GPL
@@ -41,6 +41,9 @@ rm -rf "$RPM_BUILD_ROOT"
%{_bindir}/exprlp
%changelog
+* Fri Feb 24 2006 Reinhard Lackner
+- release 1.1
+
* Wed Sep 07 2005 Reinhard Lackner
- release 1.0
@@ -56,11 +59,3 @@ rm -rf "$RPM_BUILD_ROOT"
* Mon Nov 25 2002 Guido Gonzato
- initial
-
-
-
-
-
-
-
-
diff --git a/spreadwi.cpp b/spreadwi.cpp
index 734c7b8..97b6824 100755
--- a/spreadwi.cpp
+++ b/spreadwi.cpp
@@ -1,4 +1,4 @@
-//spreadwin.cpp, (c)2000, 2001, 2002, 2003, 2004, 2005 by R. Lackner
+//spreadwin.cpp, (c)2000-2006 by R. Lackner
//
// This file is part of RLPlot.
//
@@ -20,7 +20,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
+#include <time.h>
+#include <math.h>
#include <fcntl.h> //file open flags
#include <sys/stat.h> //I/O flags
@@ -132,6 +133,7 @@ public:
bool Command(int cmd, void *tmpl, anyOutput *o);
bool ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cpos);
+ void MarkButtons(char *rng, POINT *cp = 0L);
bool PrintData(anyOutput *o);
void WriteGraphXML(unsigned char **ptr, long *cbd);
@@ -215,12 +217,13 @@ bool
SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
{
char *Name;
- Graph **g1, *g2;
+ Graph *g2;
int i, j, k;
MouseEvent *mev;
POINT p1;
- if(d) {
+ if(d) {
+ if(!o) o = w;
switch(cmd) {
case CMD_CURRPOS:
if(tmpl && cButtons && rButtons) {
@@ -246,19 +249,16 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
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) {
+ if(is_modified == true) {
is_modified=false;
- i = YesNoCancelBox("The spreadsheet has been modified!\n\nDo you want to save it now?");
+ i = YesNoCancelBox("The spreadsheet or a graph 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
+ return true;
case CMD_CAN_DELETE:
HideTextCursor();
- if(is_modified && YesNoBox("The spreadsheet has been modified!\n\nDo you want to save it now?")){
+ if(is_modified==true && YesNoBox("The spreadsheet or a graph has been modified!\n\nDo you want to save it now?")){
is_modified=false;
return Command(CMD_SAVEDATAAS, tmpl, o);
}
@@ -271,24 +271,26 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
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;
+ if(!tmpl) return false; if(o) o->FileHistory();
+ if(g && NumGraphs) {
+ if(g = (Graph**)realloc(g, (NumGraphs+2) * sizeof(Graph*)))
+ g[NumGraphs++] = (Graph *)tmpl;
+ else return false;
+ }
+ else {
+ if(g = (Graph **)calloc(2, sizeof(Graph*))){
+ g[0] = (Graph *)tmpl; NumGraphs = 1;
+ }
+ }
+ for(i = j = 0; i < NumGraphs; i++) {
+ if(g[i]) {
+ g[j] = g[i]; g[j]->parent = this;
+ g[j]->Command(CMD_SET_DATAOBJ, (void*)d, 0L);
+ j++;
+ }
+ }
+ NumGraphs = j; g[j-1]->DoPlot(0L);
+ 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);
@@ -309,28 +311,31 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
}
free (g);
}
- g = 0L;
- NumGraphs = 0;
- Undo.Flush();
+ 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;
- }
- }
+ case CMD_DELOBJ:
+ if(g && tmpl) for(i = j = 0; i < NumGraphs; i++) {
+ if(g[i] == (Graph*) tmpl) {
+ DeleteGO(g[i]);
+ }
+ else (g[j++] = g[i]);
+ }
+ if(j < i) g[j] = 0L; NumGraphs = j;
+ return true;
+ case CMD_SAVEDATA:
+ if(o) o->MouseCursor(MC_WAIT, false);
+ if(d->WriteData(0L)) {
+ is_modified=false;
+ if(o) o->MouseCursor(MC_ARROW, false);
+ return true;
}
- return false;
+ if(o) o->MouseCursor(MC_ARROW, true);
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);
+ if(filename) free(filename); filename = strdup(Name);
}
else return false;
}
@@ -338,10 +343,9 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
return true;
case CMD_DROPFILE:
if(!Command(CMD_CAN_CLOSE, 0L, o)) return false;
- if(IsRlpFile((char*)tmpl)) return OpenGraph(this, (char*)tmpl, 0L);
+ if(IsRlpFile((char*)tmpl)) return OpenGraph(this, (char*)tmpl, 0L, false);
else if(d->ReadData((char*)tmpl, 0L, FF_UNKNOWN)){
- if(filename) free(filename);
- filename = strdup((char*)tmpl);
+ if(filename) free(filename); filename = strdup((char*)tmpl);
return Command(CMD_SETSCROLL, 0L, w);
}
return false;
@@ -349,10 +353,9 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
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);
+ if(IsRlpFile(Name)) return OpenGraph(this, Name, 0L, false);
else if(d->ReadData(Name, 0L, FF_UNKNOWN)){
- if(filename) free(filename);
- filename = strdup(Name);
+ if(filename) free(filename); filename = strdup(Name);
return Command(CMD_SETSCROLL, 0L, w);
}
}
@@ -390,23 +393,20 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_SHPGUP: case CMD_SHPGDOWN:
return d->Command(cmd, tmpl, o);
case CMD_REDRAW:
- Undo.SetDisp(w);
- d->Command(cmd, tmpl, o);
+ Undo.SetDisp(w); d->Command(cmd, tmpl, o);
return true;
+ case CMD_MOUSECURSOR:
+ if(o)o->MouseCursor(MC_ARROW, false);
+ 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);
+ 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;
+ 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;
}
@@ -431,7 +431,8 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
if(tmpl)ssText.iSize = *((int*)tmpl);
return true;
case CMD_CONFIG:
- return defs.PropertyDlg();
+ if(defs.PropertyDlg()) return Command(CMD_REDRAW, 0L, o);
+ return false;
case CMD_NONE:
return true;
case CMD_PRINT:
@@ -446,10 +447,10 @@ SpreadWin::ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cp)
{
int i, c, nr, nc, ac = 1, na = 0;
RECT rc;
- char text[20];
+ char text[20];
POINT grid[2];
TextDEF ButtText;
- bool redim = false;
+ bool redim = false;
cpos.x = cp->x; cpos.y = cp->y;
if(ch != CellHeight || cw != CellWidth || fw != FirstWidth) redim = true;
@@ -512,23 +513,57 @@ SpreadWin::ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cp)
}
grid[0].x = grid[1].x = i*CellWidth+FirstWidth-1;
if(i <= (nc-ssOrg.x)) w->oSolidLine(grid);
- }
+ }
w->SetTextSpec(&ssText);
if(aButton) aButton->DoPlot(w);
return true;
+}
+
+void
+SpreadWin::MarkButtons(char *rng, POINT *cp)
+{
+ int i, r, c, ncb, nrb, *r_idx, *c_idx;
+ AccRange *mr;
+
+ if(!rButtons || !cButtons) return;
+ for(ncb = 0; cButtons[ncb]; ncb++); ncb--;
+ for(nrb = 0; rButtons[nrb]; nrb++); nrb--;
+ if(!nrb || !ncb || !(r_idx=(int*)calloc(nrb,sizeof(int))) || !(c_idx=(int*)calloc(ncb,sizeof(int)))) return;
+ if(rng && rng[0] && (mr = new AccRange(rng)) && mr->GetFirst(&c, &r)) {
+ mr->NextCol(&c);
+ do {
+ if((i = c - ssOrg.x) >= 0 && i < ncb) c_idx[i] = 1;
+ }while(mr->NextCol(&c));
+ mr->GetFirst(&c, &r); mr->NextRow(&r);
+ do {
+ if((i = r - ssOrg.y) >= 0 && i < nrb) r_idx[i] = 1;
+ }while(mr->NextRow(&r));
+ delete mr;
+ }
+ for(i = 0; i < ncb; i++) cButtons[i]->Command(CMD_SETSTYLE, &c_idx[i], w);
+ for(i = 0; i < nrb; i++) rButtons[i]->Command(CMD_SETSTYLE, &r_idx[i], w);
+ if(cp) {
+ c_idx[0] = r_idx[0] = 0; c_idx[1] = r_idx[1] = 1;
+ r = (cp->y - ssOrg.y); c = cp->x -ssOrg.x;
+ for(i = 0; i < ncb; i++) cButtons[i]->Command(CMD_SELECT, c == i ? &c_idx[1] : &c_idx[0], w);
+ for(i = 0; i < nrb; i++) rButtons[i]->Command(CMD_SELECT, r == i ? &r_idx[1] : &r_idx[0], w);
+ }
+ free(r_idx); free(c_idx);
}
bool
SpreadWin::PrintData(anyOutput *o)
{
- int i, j, k, l, pfw, pcw, pch, rpp, cpp, nc, nr, ix, iy, cpages;
+ int i, j, k, l, pfw, pcw, pch, rpp, cpp, nc, nr, ix, iy, cpages;
+ int row, col, width, height, ipad;
+ double scale;
RECT rc, margin, margin_first;
POINT pp_pos, ss_pos, grid[2];
LineDEF Line1, Line2;
TextDEF td, tdp;
bool bContinue;
time_t ti = time(0L);
- double val;
+ anyResult res;
Line1.patlength = Line2.patlength = 1.0;
Line1.color = Line2.color = 0x0; //black gridlines
@@ -538,12 +573,17 @@ SpreadWin::PrintData(anyOutput *o)
case 2: Line1.width = 0.003937; break;
default: Line1.width = 0.1; break;
}
+#ifdef _WINDOWS
+ scale = 1.0/_SQRT2;
+#else
+ scale = 0.9;
+#endif
Line2.width = Line1.width * 3.0;
d->GetSize(&nc, &nr);
if(!(o->StartPage())) return false;
- pfw = iround(o->hres * ((double)fw)/w->hres);
- pcw = iround(o->hres * ((double)cw)/w->hres);
- pch = iround(o->vres * ((double)ch)/w->vres + o->vres/20.0);
+ pfw = iround(o->hres * ((double)fw)/w->hres * scale);
+ pcw = iround(o->hres * ((double)cw)/w->hres * scale);
+ pch = iround((o->vres * ((double)ch)/w->vres) * scale + o->vres/20.0);
o->ActualSize(&rc);
tdp.ColTxt = 0x0; tdp.ColBg = 0x00ffffffL;
tdp.fSize = tdp.RotBL = tdp.RotCHAR = 0.0; tdp.Align = TXA_HRIGHT | TXA_VCENTER;
@@ -608,28 +648,43 @@ SpreadWin::PrintData(anyOutput *o)
o->oSolidLine(grid); iy = grid[0].y + (pch >>1);
sprintf(TmpTxt, "%d", i+1+ss_pos.y);
if(i < l) o->oTextOut(ix, iy, TmpTxt, 0);
- }
+ }
+ ipad = iround(o->hres/20.0);
for(i = 0; i < k; i++) { //spreadsheet data
- for (j = 0; j < l; j++) {
- if(d->GetText(j+ss_pos.y, i+ss_pos.x, TmpTxt, TMP_TXT_SIZE)){
- if(d->etRows[j+ss_pos.y][i+ss_pos.x]->isFormula()){
- td.Align = TXA_HRIGHT | TXA_VCENTER;
- ix = margin.left+pfw+pcw + i*pcw - iround(o->hres/20.0);
- d->etRows[j+ss_pos.y][i+ss_pos.x]->GetValue(&val);
- sprintf(TmpTxt,"%g", val);
- fit_num_rect(o, pcw - iround(o->hres/30.0), TmpTxt);
- }
- else if(d->etRows[j+ss_pos.y][i+ss_pos.x]->isValue()){
- td.Align = TXA_HRIGHT | TXA_VCENTER;
- ix = margin.left+pfw+pcw + i*pcw - iround(o->hres/20.0);
- }
- else {
- td.Align = TXA_HLEFT | TXA_VCENTER;
- ix = margin.left+pfw + i*pcw + iround(o->hres/20.0);
- }
- iy = pp_pos.y + pch + (pch>>1) + j * pch;
- o->SetTextSpec(&td);
- o->oTextOut(ix, iy, TmpTxt, 0);
+ for (j = 0; j < l; j++) {
+ row = j+ss_pos.y; col = i+ss_pos.x;
+ if(row >= 0 && row < d->cRows && col >= 0 && col < d->cCols && d->etRows[row][col]) {
+ d->etRows[row][col]->GetResult(&res, false);
+ TranslateResult(&res);
+ td.Align = TXA_HLEFT | TXA_VCENTER;
+ ix = margin.left+pfw + i*pcw + ipad;
+ switch (res.type) {
+ case ET_VALUE:
+ ix = margin.left+pfw+pcw + i*pcw - ipad;
+ td.Align = TXA_HRIGHT | TXA_VCENTER;
+ strcpy(TmpTxt, res.text);
+ fit_num_rect(o, pcw - ipad, TmpTxt);
+ Int2Nat(TmpTxt); break;
+ case ET_BOOL: case ET_DATE: case ET_TIME: case ET_DATETIME:
+ ix = margin.left+pfw+pcw + i*pcw - ipad;
+ td.Align = TXA_HRIGHT | TXA_VCENTER;
+ case ET_TEXT: case ET_UNKNOWN:
+ if(res.text && strlen(res.text) < 40)
+ strcpy(TmpTxt, res.text[0] != '\'' ? res.text : res.text +1);
+ else if(res.text) sprintf(TmpTxt,"#SIZE");
+ else TmpTxt[0] = 0;
+ do {
+ o->oGetTextExtent(TmpTxt, strlen(TmpTxt), &width, &height);
+ if(width > (pcw + iround(o->hres/20.0))) TmpTxt[strlen(TmpTxt)-1] = 0;
+ }while(width > (pcw + ipad));
+ break;
+ case ET_ERROR:
+ strcpy(TmpTxt, "#ERROR"); break;
+ default:
+ strcpy(TmpTxt, "#VALUE"); break;
+ }
+ iy = pp_pos.y + pch + (pch>>1) + j * pch;
+ o->SetTextSpec(&td); o->oTextOut(ix, iy, TmpTxt, 0);
}
}
}
@@ -680,20 +735,17 @@ void
SpreadWin::WriteGraphXML(unsigned char **ptr, long *cbd)
{
unsigned char *pg;
- long cb = 0, size = 0;
+ long cb = 0, size = 0, newsize;
int i;
- if(cbd) size = (*cbd / 10000)+ 10000;
for(i = 0; i < NumGraphs; i++) if(g[i]) {
- pg = (unsigned char*)GraphToMem(g[i], &cb);
- if(pg && cb) {
- while ((*cbd+cb+100) > size){
- *ptr = (unsigned char*)realloc(*ptr, size += 10000);
- }
+ if((pg = (unsigned char*)GraphToMem(g[i], &cb)) && cb) {
+ newsize = *cbd + cb + 100;
+ *ptr = (unsigned char*)realloc(*ptr, newsize);
*cbd += sprintf(((char*)*ptr)+*cbd, "<Graph><![CDATA[\n");
- memcpy(*ptr+*cbd, pg, cb); *cbd += cb;
+ *cbd += sprintf(((char*)*ptr)+*cbd, "%s", pg);
*cbd += sprintf(((char*)*ptr)+*cbd, "]]>\n</Graph>\n");
- if(pg) free(pg); pg = 0L; cb = 0;
+ if(pg) free(pg); pg = 0L; cb = 0;
}
}
}
@@ -712,7 +764,7 @@ public:
bool Init(int nRows, int nCols);
bool mpos2dpos(POINT *mp, POINT *dp);
bool Select(POINT *p);
- void MarkRange(char *range);
+ void MarkRange(char *range, POINT *cp = 0L);
void HideMark(bool cclp);
bool WriteData(char *FileName);
bool AddCols(int nCols);
@@ -736,7 +788,7 @@ public:
private:
int CellHeight, CellWidth, FirstWidth, r_disp, c_disp, mrk_offs;
- RECT rcCopy, cp_src_rec; //bounding rectangle for copy range
+ RECT cp_src_rec; //bounding rectangle for copy range
bool bActive, new_mark, bCopyCut, bUpdate, isRowMark, isColMark;
POINT currpos, currpos2;
anyOutput *w;
@@ -745,20 +797,20 @@ private:
EditText *et_racc;
char *m_range, *c_range; //mark and copy ranges
char *err_msg, *last_err; //error message
+ char *rlw_file; //use this name for save
_pos_info pos_info; //save position settings
};
SpreadData::SpreadData(GraphObj *par)
{
- Disp = 0L; m_range = 0L; c_range = 0L; w = 0L; err_msg=last_err = 0L;
+ Disp = 0L; m_range = 0L; c_range = 0L; w = 0L; err_msg=last_err=rlw_file = 0L;
g_parent = par; CellWidth = CellHeight = FirstWidth = 0;
et_racc = 0L;
currpos.x = currpos.y = r_disp = c_disp = mrk_offs = 0;
bActive = bCopyCut = bUpdate = isRowMark = isColMark = false;
- rcCopy.left = rcCopy.right = rcCopy.top = rcCopy.bottom = 0;
cp_src_rec.left = cp_src_rec.right = cp_src_rec.top = cp_src_rec.bottom = 0;
if(defs.IniFile && FileExist(defs.IniFile)) {
- OpenGraph(0L, defs.IniFile, 0L);
+ OpenGraph(0L, defs.IniFile, 0L, false);
}
pos_info.currpos.x = currpos.x; pos_info.currpos.y = currpos.y;
pos_info.CurrText = CurrText;
@@ -769,7 +821,8 @@ SpreadData::~SpreadData()
FlushData();
if(Disp) delete Disp; Disp = 0L;
if(m_range) free(m_range); m_range = 0L;
- if(c_range) free(c_range); c_range = 0L;
+ if(c_range) free(c_range); c_range = 0L;
+ if(rlw_file) free(rlw_file); rlw_file = 0L;
}
bool
@@ -778,8 +831,7 @@ SpreadData::Init(int nRows, int nCols)
int i, j;
RECT rc;
- rcCopy.left = rcCopy.top = 0; rcCopy.bottom = cRows = nRows;
- rcCopy.right = cCols = nCols; currpos.x = currpos.y = 0;
+ cRows = nRows; cCols = nCols; currpos.x = currpos.y = 0;
new_mark = bCopyCut = false;
if(!Disp) {
Disp = new SpreadWin(g_parent, this);
@@ -793,7 +845,6 @@ SpreadData::Init(int nRows, int nCols)
c_disp = (rc.right-rc.left)/CellWidth+1;
}
else return false;
- Disp->ShowGrid(CellWidth, CellHeight, FirstWidth, &currpos);
pos_info.ssOrg.x = Disp->ssOrg.x; pos_info.ssOrg.y = Disp->ssOrg.y;
pos_info.CurrText = CurrText;
}
@@ -885,7 +936,7 @@ SpreadData::Select(POINT *p)
}
void
-SpreadData::MarkRange(char *range)
+SpreadData::MarkRange(char *range, POINT *cp)
{
AccRange *nr, *oldr;
int r, c;
@@ -896,8 +947,8 @@ SpreadData::MarkRange(char *range)
if(range) nr = new AccRange(range);
if(oldr && nr && oldr->GetFirst(&c, &r)) {
for( ; oldr->GetNext(&c, &r); ) {
- if(r >= Disp->ssOrg.y && r < (r_disp +Disp->ssOrg.y) && c >= Disp->ssOrg.x
- && c < (c_disp + Disp->ssOrg.x) && !nr->IsInRange(c, r) && etRows[r] && etRows[r][c]){
+ if(r >= Disp->ssOrg.y && r < (r_disp +Disp->ssOrg.y) && r < cRows && c >= Disp->ssOrg.x
+ && c < (c_disp + Disp->ssOrg.x) && c < cCols && !nr->IsInRange(c, r) && etRows[r] && etRows[r][c]){
etRows[r][c]->Mark(w, etRows[r][c] != CurrText ? 0 : 1);
}
}
@@ -913,7 +964,7 @@ SpreadData::MarkRange(char *range)
strcpy(m_range, range);
else if (m_range) m_range[0] = 0;
if(oldr) delete(oldr); if(nr) delete(nr);
- new_mark = true;
+ new_mark = true; Disp->MarkButtons(m_range, cp);
}
void
@@ -921,15 +972,13 @@ SpreadData::HideMark(bool cclp)
{
if(cclp && c_range && c_range != m_range){
free(c_range); c_range = 0L;
- rcCopy.left = rcCopy.top = 0;
- rcCopy.bottom = cRows; rcCopy.right = cCols;
}
if(m_range){
free(m_range); m_range = 0L;
DoPlot(w);
}
- if(cclp) EmptyClip();
- new_mark = false;
+ if(cclp) EmptyClip(); new_mark = false;
+ Disp->MarkButtons(m_range, 0L);
}
bool
@@ -937,20 +986,25 @@ SpreadData::WriteData(char *FileName)
{
FILE *File;
int i, j;
- char tmp[800];
- unsigned char *buff = 0L;
+ unsigned char *buff = 0L;
+ anyResult res;
+ bool bErr = false;
- if(!cRows || !cCols || !etRows) return false;
- BackupFile(FileName);
- if(!(File = fopen(FileName, "w")))return false;
+ if(!cRows || !cCols || !etRows) return false;
+ if(!FileName) FileName = rlw_file;
+ if(FileName && FileName[0]) BackupFile(FileName);
+ else return false;
+ if(!(File = fopen(FileName, "w"))) {
+ ErrorBox("An error occured during write,\n\nplease try again!");
+ return false;
+ }
HideMark(true);
- rcCopy.left = rcCopy.top = 0; rcCopy.bottom = cRows; rcCopy.right = cCols;
i = strlen(FileName);
//test for xml extension
if(!strcmp(".xml", FileName+i-4) || !strcmp(".XML", FileName+i-4)) {
MemList(&buff, FF_XML);
if(buff){
- fprintf(File, "%s", buff);
+ if(fprintf(File, "%s", buff) <= 0) bErr = true;
free(buff); fclose(File);
return true;
}
@@ -960,7 +1014,7 @@ SpreadData::WriteData(char *FileName)
if(!strcmp(".tsv", FileName+i-4) || !strcmp(".TSV", FileName+i-4)) {
MemList(&buff, FF_TSV);
if(buff){
- fprintf(File, "%s", buff);
+ if(fprintf(File, "%s", buff) <= 0) bErr = true;
free(buff); fclose(File);
return true;
}
@@ -970,7 +1024,20 @@ SpreadData::WriteData(char *FileName)
if(!strcmp(".rlw", FileName+i-4) || !strcmp(".RLW", FileName+i-4)) {
MemList(&buff, FF_RLW);
if(buff){
- fprintf(File, "%s", buff);
+ if(rlw_file != FileName) {
+ if(rlw_file) free(rlw_file); rlw_file = strdup(FileName);
+ }
+ if(fprintf(File, "%s", buff) <= 0) bErr = true;
+ free(buff); fclose(File);
+ return true;
+ }
+ return false;
+ }
+ //test for slk extension
+ if(!strcmp(".slk", FileName+i-4) || !strcmp(".SLK", FileName+i-4)) {
+ MemList(&buff, FF_SYLK);
+ if(buff){
+ if(fprintf(File, "%s", buff) <= 0) bErr = true;
free(buff); fclose(File);
return true;
}
@@ -978,14 +1045,25 @@ SpreadData::WriteData(char *FileName)
}
//else write csv
for(i = 0; i < cRows; i++) {
- for(j = 0; j < cCols; j++) {
- if(etRows[i][j] && etRows[i][j]->GetItem(tmp, sizeof(tmp)))
- fprintf(File, "%s", tmp);
- if(j < (cCols-1)) fprintf(File, ",");
+ for(j = 0; j < cCols; j++) {
+ if(etRows[i][j]) {
+ etRows[i][j]->GetResult(&res, false); TranslateResult(&res);
+ switch(res.type) {
+ case ET_TEXT:
+ fprintf(File, "\"%s\"", res.text);
+ break;
+ case ET_VALUE: case ET_DATE: case ET_TIME:
+ case ET_DATETIME: case ET_BOOL:
+ fprintf(File, "%s", res.text);
+ break;
+ }
+ }
+ if(j < (cCols-1)) fprintf(File, ", ");
}
- fprintf(File, "\n");
+ if(fprintf(File, "\n") <= 0) bErr = true;
}
fclose(File);
+ if(bErr) ErrorBox("An error occured during write,\n\nplease try again!");
return true;
}
@@ -1004,21 +1082,19 @@ SpreadData::ReadData(char *FileName, unsigned char *buffer, int type)
0 == strcmp(".rlw", FileName+strlen(FileName)-4) ||
0 == strcmp(".RLW", FileName+strlen(FileName)-4) ||
IsXmlFile(FileName)){
- if(ReadXML(FileName, buffer, type, 0L)){
- rcCopy.left = rcCopy.top = 0;
- rcCopy.right = cCols; rcCopy.bottom = cRows;
+ if(ReadXML(FileName, buffer, type, 0L)){
+ if(0 == strcmp(".rlw", FileName+strlen(FileName)-4) ||
+ 0 == strcmp(".RLW", FileName+strlen(FileName)-4)) {
+ if(rlw_file) free(rlw_file);
+ rlw_file = strdup(FileName);
+ }
return true;
}
return false;
}
if(0 == strcmp(".tsv", FileName+strlen(FileName)-4) ||
0 == strcmp(".TSV", FileName+strlen(FileName)-4)){
- if(ReadTSV(FileName, buffer, type)){
- rcCopy.left = rcCopy.top = 0;
- rcCopy.right = cCols; rcCopy.bottom = cRows;
- return true;
- }
- return false;
+ return ReadTSV(FileName, buffer, type);
}
if(!(Cache = new ReadCache())) return false;
if(! Cache->Open(FileName)) {
@@ -1066,21 +1142,12 @@ SpreadData::ReadData(char *FileName, unsigned char *buffer, int type)
if(!success && !Cache->IsEOF()) {i++; j = 0;} //eol
}while (ItemText[0] || !Cache->IsEOF()); //eof
- Cache->Close();
- delete Cache;
- Cache = 0L;
- if(FileName) {
- rcCopy.left = rcCopy.top = 0;
- rcCopy.right = cCols;
- rcCopy.bottom = cRows;
- }
+ Cache->Close(); delete Cache; Cache = 0L;
Disp->ssOrg.x = Disp->ssOrg.y = 0;
return true;
ReadError:
- Cache->Close();
- delete Cache;
- Cache = 0L;
+ Cache->Close(); delete Cache; Cache = 0L;
return false;
}
@@ -1586,13 +1653,13 @@ SpreadData::InitCopy(int cmd, void *tmpl, anyOutput *o)
{
int r, c;
AccRange *ar;
- RECT rc_band;
+ RECT rc_band, rcCopy;
bool bRet = false;
-
+
+ rcCopy.left = rcCopy.top = 0;
+ rcCopy.bottom = cRows-1; rcCopy.right = cCols-1;
if(cmd) {
bCopyCut = (cmd == CMD_CUT);
- if(rcCopy.right > cCols) rcCopy.right = cCols;
- if(rcCopy.bottom > cRows) rcCopy.bottom = cRows;
new_mark = false;
if(m_range && m_range[0]) {
if(c_range) free(c_range); c_range = strdup(m_range);
@@ -1613,9 +1680,11 @@ SpreadData::InitCopy(int cmd, void *tmpl, anyOutput *o)
}
}
if(bRet || !cmd) { //calculate animated mark
+ if(c_range && (ar = new AccRange(c_range))) {
+ ar->BoundRec(&rcCopy); delete ar;
+ }
if(rcCopy.right < Disp->ssOrg.x || rcCopy.bottom < Disp->ssOrg.y) {
- HideCopyMark();
- return bRet;
+ HideCopyMark(); return bRet;
}
c = rcCopy.left >= Disp->ssOrg.x ? rcCopy.left : Disp->ssOrg.x;
r = rcCopy.top >= Disp->ssOrg.y ? rcCopy.top : Disp->ssOrg.y;
@@ -1678,7 +1747,7 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
}
switch (mev->Action) {
case MOUSE_LBDOWN:
- if(m_range && (mev->StateFlags & 0x08)) mrk_offs = strlen(m_range);
+ if(m_range && (mev->StateFlags & 0x18)) mrk_offs = strlen(m_range);
else mrk_offs = 0;
bActive = true; new_mark = false;
if(!et_racc && CurrText && !CurrText->isInRect(&p)){
@@ -1709,7 +1778,7 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
i = sprintf(TmpTxt+mrk_offs, "%s%s%d:", mrk_offs? ";" : "", Int2ColLabel(currpos.x, false), currpos.y+1);
sprintf(TmpTxt+mrk_offs+i, "%s%d", Int2ColLabel(cp.x, false), cp.y+1);
}
- if(!CurrText || et_racc)MarkRange(TmpTxt);
+ if(!CurrText || et_racc)MarkRange(TmpTxt, &cp);
return true;
}
if(mev->Action == MOUSE_LBDOUBLECLICK) bActive = false;
@@ -1737,13 +1806,13 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
currpos2.x = cp.x; currpos2.y = cp.y + 1;
}
else if((m_range) && !new_mark) HideMark(false);
- if(et_racc) {
+ if(et_racc && !et_racc->isInRect(&p)) {
CurrText = et_racc;
- if(m_range && m_range[0]) {
+ if(m_range && m_range[0] && (currpos.x != cp.x || currpos.y != cp.y)) {
CurrText->Command(CMD_ADDTXT, o, (DataObj*) m_range);
}
- else if(!m_range) {
- m_range = (char*)malloc(10);
+ else {
+ if(!m_range) m_range = (char*)malloc(20);
sprintf(m_range, "%s%d%", Int2ColLabel(currpos.x, false), currpos.y+1);
CurrText->Command(CMD_ADDTXT, o, (DataObj*) m_range);
free(m_range); m_range = 0L;
@@ -1763,6 +1832,7 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
return Disp->Command(CMD_SETSCROLL, 0L, w);
return false;
case CMD_ETRACC:
+ if(et_racc && tmpl && ((EditText*)tmpl)->parent != this) HideMark(false);
et_racc = (EditText*) tmpl;
if(CurrText && CurrText->parent != this) CurrText = 0L;
return true;
@@ -1794,14 +1864,14 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
if(CurrText){
CurrText->Update(2, w, 0L); CurrText->Update(1, w, 0L);
}
- et_racc = 0L;
+ et_racc = 0L; w->MouseCursor(MC_ARROW, true);
break;
case CMD_UPDHISTORY:
if(w) w->FileHistory();
break;
case CMD_MRK_DIRTY:
move_cr = CMD_CURRDOWN;
- last_err = 0L;
+ err_msg = last_err = 0L;
if(Disp) return Disp->Command(cmd, tmpl, o);
return false;
case CMD_ADDCHAR:
@@ -1971,7 +2041,8 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
else if(CurrText) return CurrText->Command(cmd, o, this);
Disp->Command(CMD_CURRPOS, &currpos, w);
return true;
- case CMD_QUERY_COPY: case CMD_CUT:
+ case CMD_QUERY_COPY: case CMD_CUT:
+ et_racc = 0L;
return InitCopy(cmd, tmpl, w);
case CMD_GET_CELLDIMS:
if(tmpl) {
@@ -2006,6 +2077,12 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
DoPlot(o);
Undo.SetDisp(w);
break;
+ case CMD_GETMARK:
+ if(tmpl && m_range && m_range[0]) {
+ *((char**)tmpl) = m_range;
+ return true;
+ }
+ return false;
case CMD_INSROW:
return InsertRows();
case CMD_INSCOL:
@@ -2028,7 +2105,7 @@ SpreadData::ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flag
char TmpTxt[1024], *tmp_range;
unsigned char *pgr = 0L;
RECT rc_undo;
-
+
if(file) {
if(!(XMLcache = new ReadCache())) return false;
if(! XMLcache->Open(file)) {
@@ -2100,7 +2177,7 @@ SpreadData::ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flag
}while(!(pgr[cpgr-1] == '<' && pgr[cpgr-2] == 0x0a));
pgr[cpgr-2] = 0;
while(XMLcache->Getc() != 0x0a);
- OpenGraph(Disp, 0L, pgr);
+ OpenGraph(Disp, 0L, pgr, false);
free(pgr); tag = 0;
}
else tag = 0;
@@ -2232,18 +2309,26 @@ SpreadData::MemList(unsigned char **ptr, int type)
int i, j, k, nc, nl, cb = 0;
long cbd = 0, size;
char tmptxt[8000];
- double val;
*ptr = (unsigned char *)malloc(size = 10000);
unsigned char *tmpptr;
bool bLimit = true;
- AccRange *ar = 0L;
+ AccRange *ar;
+ anyResult res;
+ RECT rcCopy;
if(!(*ptr))return false;
- if(rcCopy.left < 0) rcCopy.left = 0;
- if(rcCopy.right >= cCols) rcCopy.right = cCols-1;
- if(rcCopy.top < 0) rcCopy.top = 0;
- if(rcCopy.bottom >= cRows) rcCopy.bottom = cRows-1;
- if(type == FF_SYLK) cbd = sprintf((char*)*ptr, "ID;\n");
+ if (c_range && c_range[0]) {
+ ar = new AccRange(c_range); ar->BoundRec(&rcCopy);
+ if(bCopyCut) Undo.DataObject(Disp, w, this, &rcCopy, 0L);
+ }
+ else {
+ ar = 0L; rcCopy.left = rcCopy.top = 0;
+ rcCopy.right = cCols-1; rcCopy.bottom = cRows-1;
+ }
+ if(rcCopy.left < 0) rcCopy.left = 0; if(rcCopy.right >= cCols) rcCopy.right = cCols-1;
+ if(rcCopy.top < 0) rcCopy.top = 0; if(rcCopy.bottom >= cRows) rcCopy.bottom = cRows-1;
+ if(type == FF_SYLK) cbd = sprintf((char*)*ptr, "ID;PWXL;N;E\r\n"
+ "P;Pdd/mm/yyyy\r\nP;Phh:mm:ss\r\nP;Pdd/mm/yyyy hh:mm:ss\r\n");
else if(type == FF_XML) {
cbd = sprintf((char*)*ptr, "<?xml version=\"1.0\"?><!DOCTYPE spreadsheet-snippet>"
"<spreadsheet-snippet rows=\"%d\" columns=\"%d\" >\n", cRows, cCols);
@@ -2258,37 +2343,46 @@ SpreadData::MemList(unsigned char **ptr, int type)
cbd = sprintf((char*)*ptr, "<?xml version=\"1.0\"?><!DOCTYPE RLPlot-workbook>\n"
"<RLPlot-data rows=\"%d\" columns=\"%d\" >\n", cRows, cCols);
}
- if (c_range && c_range[0]) {
- ar = new AccRange(c_range);
- if(bCopyCut) Undo.DataObject(Disp, w, this, &rcCopy, 0L);
- }
for(nl =0, i = rcCopy.top; i <= rcCopy.bottom; i++, nl++) {
for(nc = 0, j = rcCopy.left; j <= rcCopy.right; cb = 0, j++, nc++) {
switch (type) {
case FF_TSV:
if(nl || nc) cb = sprintf(tmptxt,"%s", nc ? "\t" : "\n");
- if(etRows[i] && etRows[i][j] && etRows[i][j]->text){
- if((ar && ar->IsInRange(j,i)) || !ar) {
- for(k = 0; k < 7990 && (etRows[i][j]->text[k]); k++)
- tmptxt[cb++] = etRows[i][j]->text[k];
+ if(etRows[i] && etRows[i][j]){
+ if((ar && ar->IsInRange(j,i)) || !ar) {
+ etRows[i][j]->GetResult(&res, false);
+ TranslateResult(&res);
+ cb += sprintf(tmptxt+cb, "%s", res.text);
}
tmptxt[cb] = 0;
}
break;
case FF_SYLK:
if(etRows[i] && etRows[i][j] && etRows[i][j]->text && ((ar && ar->IsInRange(j,i)) || !ar)){
- cb = sprintf(tmptxt, "C;Y%d;X%d;K", nl+1, nc+1);
- if(etRows[i][j]->GetValue(&val)){
- cb += sprintf(tmptxt+cb, "%lf", val);
- while(tmptxt[cb-1] == '0') tmptxt[--cb] = 0;
- if(tmptxt[cb-1] == '.') tmptxt[--cb] = 0;
- cb += sprintf(tmptxt+cb, "\n");
- }
- else {
- etRows[i][j]->GetItem(TmpTxt, 258);
- cb += sprintf(tmptxt+cb, "%s\n", TmpTxt);
- if(cb >= 267) bLimit = false;
- }
+ etRows[i][j]->GetResult(&res, false);
+ TranslateResult(&res);
+ switch(res.type) {
+ case ET_VALUE: case ET_BOOL:
+ cb = sprintf(tmptxt, "C;Y%d;X%d;K", nl+1, nc+1);
+ cb += sprintf(tmptxt+cb, "%s\r\n", res.text);
+ break;
+ case ET_DATE:
+ cb = sprintf(tmptxt, "F;P0;FG0G;Y%d;X%d\r\n", nl+1, nc+1);
+ cb += sprintf(tmptxt+cb, "C;K%g\r\n", res.value+1.0);
+ break;
+ case ET_DATETIME:
+ cb = sprintf(tmptxt, "F;P2;FG0G;Y%d;X%d\r\n", nl+1, nc+1);
+ cb += sprintf(tmptxt+cb, "C;K%g\r\n", res.value+1.0);
+ break;
+ case ET_TIME:
+ cb = sprintf(tmptxt, "F;P1;FG0G;Y%d;X%d\r\n", nl+1, nc+1);
+ cb += sprintf(tmptxt+cb, "C;K%g\r\n", res.value-floor(res.value));
+ break;
+ case ET_TEXT:
+ cb = sprintf(tmptxt, "C;Y%d;X%d;K", nl+1, nc+1);
+ cb += sprintf(tmptxt+cb, "\"%s\"\r\n", res.text);
+ break;
+ }
if(bCopyCut) etRows[i][j]->SetText("");
}
break;
@@ -2329,7 +2423,10 @@ SpreadData::MemList(unsigned char **ptr, int type)
//note: cbd may be greater than size !
}
if(ar) delete ar;
- bCopyCut = false;
+ if(bCopyCut && type == FF_XML || type == FF_SYLK || type == FF_RLW){
+ bCopyCut = false;
+ DoPlot(w);
+ }
return true;
}
@@ -2338,14 +2435,8 @@ void SpreadMain(bool show)
static SpreadData *w = 0L;
if(show) {
- w = new SpreadData(0L);
- if(!w ||!(w->Init(50, 10))){
- delete w;
- w = 0L;
- }
+ if(w = new SpreadData(0L)) w->Init(50, 10);
do_formula(w, 0L); //init mfcalc
}
- else if (w) {
- delete(w);
- }
+ else if (w) delete(w);
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/rlplot.git
More information about the debian-science-commits
mailing list