[rlplot] 11/23: Imported Upstream version 1.2
Andreas Tille
tille at debian.org
Wed Jun 29 09:50:56 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 26b828ca428cfa6d25d6a29a6c2d35ef20790bb5
Author: Andreas Tille <tille at debian.org>
Date: Wed Jun 29 11:43:56 2016 +0200
Imported Upstream version 1.2
---
Axes.cpp | 79 +-
Export.cpp | 99 +-
Fileio.cpp | 6136 +++++++++----------
ODbuttons.cpp | 8 +-
Output.cpp | 53 +-
PlotObs.cpp | 443 +-
PropertyDlg.cpp | 1751 +++---
QT_Spec.cpp | 4657 +++++++--------
QT_Spec.h | 2 +
RLPLOT.RC | 2 +
TheDialog.cpp | 511 +-
TheDialog.h | 29 +-
UtilObj.cpp | 712 ++-
Utils.cpp | 314 +-
Version.h | 2 +-
WinSpec.cpp | 220 +-
exprlp.cpp | 410 +-
menu.h | 8 +-
mfcalc.cpp | 1396 +++--
mfcalc.y | 470 +-
no_gui.cpp | 30 +-
reports.cpp | 902 ++-
rlp_math.cpp | 406 +-
rlplot.cpp | 17266 +++++++++++++++++++++++++++++-------------------------
rlplot.h | 4827 +++++++--------
rlplot.spec | 6 +-
spreadwi.cpp | 3073 +++++-----
use_gui.cpp | 230 +-
28 files changed, 24389 insertions(+), 19653 deletions(-)
diff --git a/Axes.cpp b/Axes.cpp
index b446a0c..559fbc4 100755
--- a/Axes.cpp
+++ b/Axes.cpp
@@ -154,6 +154,10 @@ GridLine::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_SET_DATAOBJ:
Id = GO_GRIDLINE;
return true;
+ case CMD_SCALE:
+ LineDef.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ LineDef.width *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
case CMD_SETSCROLL:
case CMD_SET_GO3D:
case CMD_REDRAW:
@@ -501,8 +505,7 @@ Tick::SetSize(int select, double value)
case SIZE_AXIS_TICKS:
size = value;
break;
- case SIZE_LB_XDIST:
- case SIZE_LB_YDIST:
+ case SIZE_LB_XDIST: case SIZE_LB_YDIST:
if(label)return label->SetSize(select, value);
break;
case SIZE_TICK_ANGLE:
@@ -547,6 +550,11 @@ Tick::Command(int cmd, void *tmpl, anyOutput *o)
AxisDEF *axis;
switch(cmd){
+ case CMD_SCALE:
+ if(label) label->Command(cmd, tmpl, o);
+ if(Grid) Grid->Command(cmd, tmpl, o);
+ size *= ((scaleINFO*)tmpl)->sy.fy;
+ break;
case CMD_SET_AXDEF:
if(axis = (AxisDEF*)tmpl) {
flags = (flags & AXIS_MINORTICK) | axis->flags;
@@ -641,7 +649,7 @@ Tick::Command(int cmd, void *tmpl, anyOutput *o)
LabelDef->ColTxt = parent ? parent->GetColor(COL_AXIS) : defs.Color(COL_AXIS);
LabelDef->ColBg = parent ? parent->GetColor(COL_BG) : defs.Color(COL_AXIS);
LabelDef->RotBL = LabelDef->RotCHAR = 0.0f;
- LabelDef->fSize = parent ? parent->GetSize(SIZE_TICK_LABELS) : defs.GetSize(SIZE_TICK_LABELS);
+ LabelDef->fSize = parent ? parent->GetSize(SIZE_TICK_LABELS) : DefSize(SIZE_TICK_LABELS);
switch(flags & 0x70) {
case AXIS_USER: LabelDef->Align = TXA_VCENTER | TXA_HCENTER; break;
case AXIS_LEFT: LabelDef->Align = TXA_VCENTER | TXA_HRIGHT; break;
@@ -653,7 +661,7 @@ Tick::Command(int cmd, void *tmpl, anyOutput *o)
LabelDef->Style = TXS_NORMAL;
LabelDef->Mode = TXM_TRANSPARENT;
LabelDef->Font = FONT_HELVETICA;
- LabelDef->text = tmpl && *((char*)tmpl) ? strdup((char*)tmpl) : 0L;
+ LabelDef->text = tmpl && *((char*)tmpl) ? _strdup((char*)tmpl) : 0L;
label = new Label(this, 0L, fix, fiy, LabelDef, LB_X_PARENT | LB_Y_PARENT);
if(LabelDef->text) free(LabelDef->text);
delete (LabelDef);
@@ -671,6 +679,7 @@ Tick::DoPlot(double six, double csx, anyOutput *o)
if(!parent || parent->Id != GO_AXIS) return;
if(mo) DelBitmapClass(mo); mo = 0L;
if(ls) delete(ls); ls = 0L;
+ ip2.x = ip2.y = ip2.z = 0;
if(!((Axis*)parent)->GetValuePos(value, &fix, &fiy, &fiz, o))return;
lbx = fix; lby = fiy;
if(flags & AXIS_ANGULAR) {
@@ -678,8 +687,8 @@ Tick::DoPlot(double six, double csx, anyOutput *o)
dp1.fy = o->co2fiy(parent->GetSize(SIZE_YCENT)+parent->GetSize(SIZE_GRECT_TOP));
dp1.fz = o->un2fix(parent->GetSize(SIZE_DRADIUS));
six = (fix - dp1.fx)/dp1.fz; csx = (dp1.fy - fiy)/dp1.fz;
- lbx += (o->un2fix(defs.GetSize(SIZE_AXIS_TICKS)*3.0*six));
- lby -= (o->un2fiy(defs.GetSize(SIZE_AXIS_TICKS)*3.0*csx));
+ lbx += (o->un2fix(DefSize(SIZE_AXIS_TICKS)*3.0*six));
+ lby -= (o->un2fiy(DefSize(SIZE_AXIS_TICKS)*3.0*csx));
}
switch(type & 0x0f) {
case 1: lsi = sin(angle/57.29577951); lcsi = cos(angle/57.29577951); break;
@@ -829,11 +838,12 @@ Axis::GetSize(int select)
case SIZE_YCENT: return axis->Center.fy;
case SIZE_RADIUS1: case SIZE_RADIUS2: case SIZE_DRADIUS:
return axis->Radius;
+ case SIZE_BOUNDS_XMIN: case SIZE_BOUNDS_XMAX: case SIZE_BOUNDS_YMIN:
+ case SIZE_BOUNDS_YMAX: case SIZE_BOUNDS_ZMIN: case SIZE_BOUNDS_ZMAX:
+ if(parent) return parent->GetSize(select);
+ break;
}
- //DEBUG: we should return a reasonable value for SIZE_BOUNDS_...
- // if the axis is not scaling (i.e. parent == this).
- if(parent) return parent->GetSize(select);
- else return defs.GetSize(select);
+ return DefSize(select);
}
DWORD
@@ -864,10 +874,8 @@ Axis::SetSize(int select, double value)
lbdist.fy = value;
if(axisLabel)axisLabel->SetSize(select,value);
break;
- case SIZE_TLB_XDIST:
- case SIZE_TLB_YDIST:
- case SIZE_AXIS_TICKS:
- case SIZE_TICK_ANGLE:
+ case SIZE_TLB_XDIST: case SIZE_TLB_YDIST:
+ case SIZE_AXIS_TICKS: case SIZE_TICK_ANGLE:
switch (select){
case SIZE_TLB_XDIST:
tlbdist.fx = value; select = SIZE_LB_XDIST;
@@ -1157,7 +1165,7 @@ Axis::DoMark(anyOutput *o, bool mark)
{
LineDEF mrkLine;
int x1, y1, x2, y2;
- double minw = defs.GetSize(SIZE_DATA_LINE);
+ double minw = DefSize(SIZE_DATA_LINE);
if(axis->flags & AXIS_ANGULAR) {
if(mark) {
@@ -1196,16 +1204,34 @@ Axis::Command(int cmd, void *tmpl, anyOutput *o)
MouseEvent *mev;
GraphObj **tmpPlots;
void *sv_ptr;
+ scaleINFO *scale;
int i;
switch (cmd) {
+ case CMD_SCALE:
+ scale = (scaleINFO*)tmpl;
+ lbdist.fx *= scale->sx.fy; lbdist.fy *= scale->sy.fy;
+ tlbdist.fx *= scale->sx.fy; tlbdist.fy *= scale->sy.fy;
+ sizAxTickLabel *= scale->sy.fy; sizAxTick *= scale->sy.fy;
+ sizAxLine *= scale->sy.fy; brksymsize *= scale->sy.fy;
+ brkgap *= scale->sy.fy; GridLine.patlength *= scale->sy.fy;
+ GridLine.width *= scale->sy.fy; tlbdef.fSize *= scale->sy.fy;
+ axis->loc[0].fx *= scale->sx.fy; axis->loc[1].fx *= scale->sx.fy;
+ axis->loc[0].fy *= scale->sy.fy; axis->loc[1].fy *= scale->sy.fy;
+ axis->loc[0].fz *= scale->sz.fy; axis->loc[1].fz *= scale->sz.fy;
+ axis->Center.fx *= scale->sx.fy; axis->Center.fy *= scale->sy.fy;
+ axis->Radius *= scale->sy.fy; tlbdef.iSize = 0;
+ if(axisLabel) axisLabel->Command(cmd, tmpl, o);
+ if(!Ticks && (axis->flags & 0x03) != AXIS_NOTICKS)CreateTicks();
+ if(Ticks) for(i = 0; i < NumTicks; i++) if(Ticks[i]) Ticks[i]->Command(cmd, tmpl, o);
+ return true;
case CMD_HIDE_MARK:
if(!tmpl || !o) return false;
if(tmpl == (void*)axisLabel){
axisLabel->DoMark(o, false);
return true;
}
- if(Ticks && NumTicks) for(i = 0; i < NumTicks; i++) {
+ if(Ticks) for(i = 0; i < NumTicks; i++) {
if(Ticks[i]) {
if(tmpl == (void*)Ticks[i]) {
Ticks[i]->DoMark(o, false);
@@ -1354,7 +1380,6 @@ Axis::Command(int cmd, void *tmpl, anyOutput *o)
}
if(scaleOut) delete(scaleOut);
scaleOut = drawOut = 0L;
- axis->Start = axis->min;
return true;
case CMD_AUTOSCALE: //we receive this command to update ticks after rescaling
if(axis && (AxisDEF*)tmpl == axis && (axis->flags & AXIS_AUTOSCALE) &&
@@ -1386,9 +1411,9 @@ Axis::SetTick(long idx, double val, DWORD flags, char *txt)
Ticks[idx] = new Tick(this, data, val, flags);
if(!txt) {
WriteNatFloatToBuff(TmpTxt, val);
- l = strdup(TmpTxt+1);
+ l = _strdup(TmpTxt+1);
}
- else l = strdup(txt);
+ else l = _strdup(txt);
if(!gl_type) {
}
if(Ticks[idx]) {
@@ -1460,7 +1485,11 @@ Axis::CreateTicks()
if(!Ticks) return;
for(NumTicks = 0; NumTicks < nstep && fVal <= axis->max;
NumTicks++, fVal += axis->Step) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, format, fVal);
+#else
sprintf(TmpTxt, format, fVal);
+#endif
SetTick(NumTicks, fVal, axis->flags, TmpTxt);
}
}
@@ -1479,12 +1508,20 @@ Axis::ManuTicks(double sa, double st, int n, DWORD flags)
format = GetNumFormat(floor(log10(st)));
Ticks = (Tick**)calloc(m, sizeof(Tick*));
for(NumTicks = 0, fVal = sa; NumTicks < m && fVal <= axis->max; NumTicks++) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, format, fVal);
+#else
sprintf(TmpTxt, format, fVal);
+#endif
SetTick(NumTicks, fVal, flags, TmpTxt);
for(j = 0; j < n; j++) {
mival = fVal+mist*(double)j +mist;
if(mival < axis->max) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, format, mival);
+#else
sprintf(TmpTxt, format, mival);
+#endif
NumTicks++;
SetTick(NumTicks, mival, flags | AXIS_MINORTICK, TmpTxt);
}
@@ -1496,7 +1533,7 @@ Axis::ManuTicks(double sa, double st, int n, DWORD flags)
bool
Axis::GetValuePos(double val, double *fix, double *fiy, double *fiz, anyOutput *op)
{
- double tmp1;
+ double tmp1 = 1.0;
int i;
bool bRet = true;
anyOutput *o;
@@ -1546,7 +1583,7 @@ Axis::GetValuePos(double val, double *fix, double *fiy, double *fiz, anyOutput *
*fix = flim[1].fx + tmp1*(flim[0].fx - flim[1].fx);
*fiy = flim[1].fy + tmp1*(flim[0].fy - flim[1].fy);
}
- if(tmp1 < -.005f || tmp1 > 1.005) return false;
+ if(tmp1 < -.005 || tmp1 > 1.005) return false;
return bRet;
}
diff --git a/Export.cpp b/Export.cpp
index 86107e6..7fd0ea2 100755
--- a/Export.cpp
+++ b/Export.cpp
@@ -25,6 +25,9 @@
#include <math.h>
#include <fcntl.h> //file open flags
#include <sys/stat.h> //I/O flags
+#ifdef USE_WIN_SECURE
+ #include <share.h> //I/O flags
+#endif
#ifdef _WINDOWS
#include <io.h> //for read/write
@@ -105,7 +108,7 @@ ExportWMF::ExportWMF(GraphObj *g, char *FileName, float res, DWORD flags)
hPen = 0xffff, hBrush = 0xffff, hFont = 0xffff;
hres = vres = res;
go = g;
- if(FileName)name = strdup(FileName);
+ if(FileName)name = _strdup(FileName);
else name = 0L;
oFile = 0;
rec_size = 28;
@@ -220,8 +223,13 @@ ExportWMF::StartPage()
{
if(!go) return false;
if(name) {
+#ifdef USE_WIN_SECURE
+ if(0 !=(_sopen_s(&oFile, name, _O_RDWR | _O_BINARY | _O_CREAT | _O_TRUNC, _SH_DENYNO,
+ _S_IWRITE | _S_IREAD))) {
+#else
if(-1 ==(oFile = open(name, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
S_IWRITE | S_IREAD))) {
+#endif
ErrorBox("Could not open output file");
return false;
}
@@ -231,7 +239,7 @@ ExportWMF::StartPage()
}
VPorg.fy = -un2fiy(go->GetSize(SIZE_GRECT_TOP));
VPorg.fx = -un2fix(go->GetSize(SIZE_GRECT_LEFT));
- write(oFile, &header, 18);
+ _write(oFile, &header, 18);
return true;
}
@@ -240,15 +248,15 @@ ExportWMF::EndPage()
{
unsigned short end_token[3] = {3, 0, 0};
- write(oFile, &end_token, 6);
- file_size = lseek(oFile, 0L, SEEK_CUR);
- lseek(oFile, 0L, SEEK_SET);
+ _write(oFile, &end_token, 6);
+ file_size = _lseek(oFile, 0L, SEEK_CUR);
+ _lseek(oFile, 0L, SEEK_SET);
header.mtSize0 = (file_size>>1)&0xffff;
header.mtSize1 = file_size>>17;
header.mtNoObj = maxGDIobj;
header.mtMaxRec = rec_size;
- write(oFile, &header, 18);
- oFile = close(oFile);
+ _write(oFile, &header, 18);
+ oFile = _close(oFile);
return true;
}
@@ -297,7 +305,7 @@ ExportWMF::oTextOut(int x, int y, char *txt, int cb)
TXA_HCENTER) ? 6 : 0) | ((TxtSet.Align & TXA_VBOTTOM) ? 8 : 0));
wmfSetBkMode(TxtSet.Mode ? 1 : 2);
wmfTextOut(x, (TxtSet.Align & TXA_VCENTER) ? y - TxtSet.iSize/2 : y, txt,
- (cb > 0) ? cb : strlen(txt));
+ (unsigned short)((cb > 0) ? cb : strlen(txt)));
return true;
}
@@ -359,7 +367,7 @@ ExportWMF::wmfCreateSolidBrush(DWORD color)
{
wmfLogBrush lb = {7, 0x2fc, 0, color, 0};
- write(oFile, &lb, 14);
+ _write(oFile, &lb, 14);
currGDIobj++;
maxGDIobj = currGDIobj > maxGDIobj ? currGDIobj : maxGDIobj;
return currGDIobj-1;
@@ -376,8 +384,8 @@ ExportWMF::wmfCreateFontIndirect(short lfHeight, short lfWidth, short lfEscapeme
lfItalic, lfUnderline, lfStrikeOut, lfCharSet, lfOutPrecision, lfClipPrecision,
lfQuality, lfPitchAndFamily, "Arial"};
- if(FaceName && FaceName[0]) strcpy(lf.face, FaceName);
- write(oFile, &lf, 56);
+ if(FaceName && FaceName[0]) rlp_strcpy(lf.face, 32, FaceName);
+ _write(oFile, &lf, 56);
currGDIobj++;
maxGDIobj = currGDIobj > maxGDIobj ? currGDIobj : maxGDIobj;
return currGDIobj-1;
@@ -388,7 +396,7 @@ ExportWMF::wmfCreateSolidPen(DWORD color, unsigned short width)
{
wmfLogPen lp = {8, 0x2fa, 0, width, color};
- write(oFile, &lp, 16);
+ _write(oFile, &lp, 16);
currGDIobj++;
maxGDIobj = currGDIobj > maxGDIobj ? currGDIobj : maxGDIobj;
return currGDIobj-1;
@@ -410,7 +418,7 @@ ExportWMF::wmfEllipse(unsigned short ix1, unsigned short iy1, unsigned short ix2
{
wmfRect rc = {7, 0x418, iy2, ix2, iy1, ix1};
- write(oFile, &rc, 14);
+ _write(oFile, &rc, 14);
}
void
@@ -420,11 +428,11 @@ ExportWMF::wmfPolyline(POINT *pts, unsigned short cp)
unsigned short v[2];
int i;
- write(oFile, &pl, 8);
+ _write(oFile, &pl, 8);
for(i = 0; i < cp; i++) {
v[0] = (unsigned short)pts[i].x;
v[1] = (unsigned short)pts[i].y;
- write(oFile, &v, 4);
+ _write(oFile, &v, 4);
}
if(pl.Size > rec_size) rec_size = pl.Size;
}
@@ -436,11 +444,11 @@ ExportWMF::wmfPolygon(POINT *pts, unsigned short cp)
unsigned short v[2];
int i;
- write(oFile, &pl, 8);
+ _write(oFile, &pl, 8);
for(i = 0; i < cp; i++) {
v[0] = (unsigned short)pts[i].x;
v[1] = (unsigned short)pts[i].y;
- write(oFile, &v, 4);
+ _write(oFile, &v, 4);
}
if(pl.Size > rec_size) rec_size = pl.Size;
}
@@ -450,7 +458,7 @@ ExportWMF::wmfRectangle(unsigned short ix1, unsigned short iy1, unsigned short i
{
wmfRect rc = {7, 0x41B, iy2, ix2, iy1, ix1};
- write(oFile, &rc, 14);
+ _write(oFile, &rc, 14);
}
void
@@ -458,7 +466,7 @@ ExportWMF::wmfSelectObject(unsigned short o)
{
wmfObjShort so = {4, 0x12D, o};
- write(oFile, &so, 8);
+ _write(oFile, &so, 8);
}
void
@@ -466,8 +474,8 @@ ExportWMF::wmfSetBkColor(DWORD col)
{
wmfObjCol co = {5, 0x201};
- write(oFile, &co, 6);
- write(oFile, &col, 4);
+ _write(oFile, &co, 6);
+ _write(oFile, &col, 4);
}
void
@@ -476,9 +484,9 @@ ExportWMF::wmfSetBkMode(unsigned m)
wmfObjShort mo = {5, 0x102, m & 0xffff};
unsigned short p;
- write(oFile, &mo, 8);
+ _write(oFile, &mo, 8);
p = m>>16;
- write(oFile, &p, 2);
+ _write(oFile, &p, 2);
}
//cmSetMapMode()
@@ -490,9 +498,9 @@ ExportWMF::wmfSetTextAlign(unsigned a)
wmfObjShort ao = {5, 0x12E, a & 0xffff};
unsigned short p;
- write(oFile, &ao, 8);
+ _write(oFile, &ao, 8);
p = a>>16;
- write(oFile, &p, 2);
+ _write(oFile, &p, 2);
}
void
@@ -500,8 +508,8 @@ ExportWMF::wmfSetTextColor(DWORD col)
{
wmfObjCol tc = {5, 0x209};
- write(oFile, &tc, 6);
- write(oFile, &col, 4);
+ _write(oFile, &tc, 6);
+ _write(oFile, &col, 4);
}
//cmSetWindowExt()
@@ -515,9 +523,9 @@ ExportWMF::wmfTextOut(unsigned short ix1, unsigned short iy1, char *txt, unsigne
le = cb &1 ? cb+1 : cb;
to.Size += le>>1;
- write(oFile, &to, 8);
- write(oFile, txt, le);
- write(oFile, &v, 4);
+ _write(oFile, &to, 8);
+ _write(oFile, txt, le);
+ _write(oFile, &v, 4);
if(to.Size > rec_size) rec_size = to.Size;
}
@@ -582,12 +590,12 @@ ExportSVG::ExportSVG(GraphObj *g, char *FileName, DWORD flg)
dFillCol = 0xffffffffL;
hres = vres = 1000.0f;
go = g;
- if(FileName)name = strdup(FileName);
+ if(FileName)name = _strdup(FileName);
else name = 0L;
oFile = 0L;
flags = flg;
- strcpy(indent, " ");
- strcpy(tHatchStyle, "style=\"stroke:black; stroke-width:1\"");
+ rlp_strcpy(indent, 80, " ");
+ rlp_strcpy(tHatchStyle, 80, "style=\"stroke:black; stroke-width:1\"");
bUseGroupLine = false;
}
@@ -620,8 +628,13 @@ ExportSVG::SetFill(FillDEF *fill)
if(hgo) hgo->SetFill(fill);
if(fill->hatch) {
if(1 >(iL = iround(un2fix(fill->hatch->width)))) iL = 1;
+#ifdef USE_WIN_SECURE
+ sprintf_s(tHatchStyle, 80, "style=\"fill:none; stroke:%s; stroke-width:%d\"",
+ ColName(fill->hatch->color), iL);
+#else
sprintf(tHatchStyle, "style=\"fill:none; stroke:%s; stroke-width:%d\"",
ColName(fill->hatch->color), iL);
+#endif
}
}
else {
@@ -655,7 +668,11 @@ ExportSVG::StartPage()
h = un2iy(go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP))/10;
w++; h++;
if(name) {
+#ifdef USE_WIN_SECURE
+ fopen_s(&oFile, name, "w");
+#else
oFile = fopen(name, "w");
+#endif
if(!oFile) {
ErrorBox("Could not open\noutput file!");
return false;
@@ -744,7 +761,7 @@ ExportSVG::oPolyline(POINT *pts, int cp, char *nam)
sprintf(tmptxt, "%d %d ", pts[i].x, pts[i].y);
AddToOutput(tmptxt);
}
- i = strlen(output);
+ i = (int)strlen(output);
if(i) output[i-1] = 0;
strcat(output, "\"");
if(!bUseGroupLine) {
@@ -900,7 +917,7 @@ ExportSVG::oPolygon(POINT *pts, int cp, char *nam)
sprintf(tmptxt, "%d %d ", pts[i].x, pts[i].y);
AddToOutput(tmptxt);
}
- i = strlen(output);
+ i = (int)strlen(output);
if(i) output[i-1] = 0;
strcat(output, "\" ");
sprintf(tmptxt, "style=\"fill:%s; ", ColName(dFillCol));
@@ -928,7 +945,7 @@ ExportSVG::oPolygon(POINT *pts, int cp, char *nam)
void
ExportSVG::Indent(bool ind)
{
- int i = strlen(indent);
+ int i = (int)strlen(indent);
if(i > 20 && ind) return;
if(ind) strcat(indent, " ");
@@ -1313,16 +1330,16 @@ char *
ExportEPS::col2eps(DWORD color)
{
static char txt[50];
- char tmptxt[10];
float r, g, b;
r = (float)(color & 0xff)/255.0f;
g = (float)((color>>8)&0xff)/255.0f;
b = (float)((color>>16)&0xff)/255.0f;
- WriteFloatToBuff(tmptxt, r); strcpy(txt, tmptxt+1);
- WriteFloatToBuff(tmptxt, g); strcat(txt, tmptxt);
- WriteFloatToBuff(tmptxt, b); strcat(txt, tmptxt);
- strcat(txt, " setrgbcolor");
+#ifdef USE_WIN_SECURE
+ sprintf_s(txt, 50, "%g %g %g setrgbcolor", r, g, b);
+#else
+ sprintf(txt, "%g %g %g setrgbcolor", r, g, b);
+#endif
return txt;
}
diff --git a/Fileio.cpp b/Fileio.cpp
index fc7a5d5..7fa8a37 100755
--- a/Fileio.cpp
+++ b/Fileio.cpp
@@ -1,935 +1,1029 @@
-//FileIO.cpp, Copyright (c) 2001-2006 R.Lackner
-//read/write graphic objects
-//
-// This file is part of RLPlot.
-//
-// RLPlot is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// RLPlot is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with RLPlot; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-#include "rlplot.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <math.h>
-#include <ctype.h>
-#include <fcntl.h> //file open flags
-#include <sys/stat.h> //I/O flags
-
-#ifdef _WINDOWS
- #include <io.h> //for read/write
-#else
- #define O_BINARY 0x0
- #include <unistd.h>
-#endif
-
-extern GraphObj *CurrGO; //Selected Graphic Objects
-extern Default defs;
-extern int dlgtxtheight;
-extern char TmpTxt[];
+//FileIO.cpp, Copyright (c) 2001-2006 R.Lackner
+//read/write graphic objects
+//
+// This file is part of RLPlot.
+//
+// RLPlot is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// RLPlot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RLPlot; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#include "rlplot.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+#include <ctype.h>
+#include <fcntl.h> //file open flags
+#include <sys/stat.h> //I/O flags
+
+#ifdef _WINDOWS
+ #include <io.h> //for read/write
+#else
+ #define O_BINARY 0x0
+ #include <unistd.h>
+#endif
+
+extern GraphObj *CurrGO; //Selected Graphic Objects
+extern Default defs;
+extern int dlgtxtheight;
+extern char TmpTxt[];
extern int cPlots;
-
-static notary *Notary = 0L;
-static ReadCache *Cache = 0L;
-
-unsigned long cObsW; //count objects written
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// graphic input/output is driven by tables based on the descIO template
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-typedef struct {
- char *label;
- unsigned short type;
- void *ptr;
- long *count;
- }descIO;
-
-//the type member of descIO describes the following data types pointed to by ptr
-enum {typNONE, typNZINT, typINT, typLFLOAT, typNZLFLOAT,
- typDWORD, typULONG, typFRECT, typNZLFPOINT, typLFPOINT, typPOINT3D,
- typAXDEF, typPTRAXDEF, typLINEDEF, typFILLDEF, typGOBJ, typOBJLST,
- typFPLST, typFPLST3D, typIPLST, typTEXT, typTXTDEF, typPTRTXTDEF,
- typLAST = 0x100};
-
+GraphObj *LastOpenGO;
+
+static notary *Notary = 0L;
+static ReadCache *Cache = 0L;
+
+unsigned long cObsW; //count objects written
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// graphic input/output is driven by tables based on the descIO template
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+typedef struct {
+ char *label;
+ unsigned short type;
+ void *ptr;
+ long *count;
+ }descIO;
+
+//the type member of descIO describes the following data types pointed to by ptr
+enum {typNONE, typNZINT, typINT, typLFLOAT, typNZLFLOAT,
+ typDWORD, typFRECT, typNZLFPOINT, typLFPOINT, typPOINT3D,
+ typAXDEF, typPTRAXDEF, typLINEDEF, typFILLDEF, typGOBJ, typOBJLST,
+ typFPLST, typFPLST3D, typIPLST, typTEXT, typTXTDEF, typPTRTXTDEF,
+ typLAST = 0x100};
+
static char *ptr =0L;
-static long ptr_step = 2048;
-static int cbOut, sizeOut = 0, iFile = 0;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// output graph to file, elementary functions
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int OpenOutputFile(char *file)
-{
- time_t ti;
-
- if(ptr) free(ptr);
- ptr = 0L; cbOut = 0;
- if(file && BackupFile(file)) {
- if(-1 ==(iFile = open(file, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
- S_IWRITE | S_IREAD))) return -1;
- ptr = (char *)malloc(sizeOut = 2048);
- if(!ptr) goto openerr;
- ti = time(0L);
- cbOut = sprintf(ptr,";RLP 1.0\n;File \"%s\" created by RLPlot version "
- ""SZ_VERSION" for %s \n;Date/Time: %s ",
- file,
+static int cbOut, sizeOut = 0, iFile = -1;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// output graph to file, elementary functions
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static int OpenOutputFile(char *file)
+{
+ time_t ti;
+
+ if(ptr) free(ptr);
+ ptr = 0L; cbOut = 0; ti = time(0L);
+ if(file && BackupFile(file)) {
+#ifdef USE_WIN_SECURE
+ if(_sopen_s(&iFile, file, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
+ 0x40, S_IWRITE) || iFile < 0){
+ ErrorBox("Open failed for output file");
+ return -1;
+ }
+#else
+ if(-1 ==(iFile = open(file, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
+ S_IWRITE | S_IREAD))){
+ ErrorBox("Open failed for output file");
+ return -1;
+ }
+#endif
+ ptr = (char *)malloc(sizeOut = 2000);
+ if(!ptr) goto openerr;
+ cbOut = rlp_strcpy(ptr, 20, ";RLP 1.0\n;File \"");
+ add_to_buff(&ptr, &cbOut, &sizeOut, file, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "\" created by RLPlot version "SZ_VERSION" for ", 0);
#ifdef _WINDOWS
- "Windows",
+ add_to_buff(&ptr, &cbOut, &sizeOut, "Windows", 7);
+#else
+ add_to_buff(&ptr, &cbOut, &sizeOut, "Qt", 2);
+#endif
+ add_to_buff(&ptr, &cbOut, &sizeOut, "\n;Date/Time: ", 13);
+#ifdef USE_WIN_SECURE
+ ctime_s(ptr+cbOut, 30, &ti); cbOut += 25;
+#else
+ add_to_buff(&ptr, &cbOut, &sizeOut, ctime(&ti), 25);
+#endif
+ }
+ return iFile;
+openerr:
+ ptr = 0L; cbOut = sizeOut = 0;
+#ifdef USE_WIN_SECURE
+ if(iFile >=0) _close(iFile);
+#else
+ if(iFile >=0) close(iFile);
+#endif
+ return iFile = -1;
+}
+
+static void CloseOutputFile()
+{
+ if(iFile >= 0){
+#ifdef USE_WIN_SECURE
+ if(cbOut) _write(iFile, ptr, cbOut);
+ _close(iFile);
#else
- "Qt",
+ if(cbOut) write(iFile, ptr, cbOut);
+ close(iFile);
#endif
- ctime(&ti));
- }
- return iFile;
-openerr:
- ptr = 0L; cbOut = sizeOut = 0;
- close(iFile);
- iFile = 0;
- return -1;
-}
-
-void CloseOutputFile()
-{
- if(iFile > 0){
- if(cbOut) write(iFile, ptr, cbOut);
- close(iFile);
- }
- if(ptr) free(ptr);
- cbOut = sizeOut = 0;
- ptr = 0L;
-}
-
-void AddStringToOutput(char *str, int length)
-{
- int i;
- char *tmp_ptr;
-
- if((cbOut+length)< sizeOut) { //fit in buffer
- memcpy(ptr+cbOut, str, length);
- cbOut += length;
- }
- else if(iFile > 0){ //buffer full: write to file
- i = sizeOut-cbOut;
- memcpy(ptr+cbOut, str, i);
- write(iFile, ptr, 2048);
- memcpy(ptr, str+i, length-i);
- cbOut = length-i;
- }
- else { //buffer full: resize buffer
- if(tmp_ptr = (char*)realloc(ptr, sizeOut+ptr_step)){
- ptr = tmp_ptr; sizeOut += ptr_step; ptr_step += (ptr_step >> 1);
- AddStringToOutput(str, length);
- }
- }
-}
-
-void WriteTypObjLst(GraphObj **ptr, int count)
-{
- int i, j, c, n;
- char tmp[512];
-
- if(!ptr) return;
- for(i = c = 0; i <= count/16; i++) {
- if(i) c = sprintf(tmp, " ");
- for(j = 0; (n=i*16+j) <count && j < 16; j++) {
- c += sprintf(tmp+c, "%s%ld", j ? " " : "", Notary->RegisterGO(ptr[n]));
- }
- if(n >= count) c += sprintf(tmp+c, "}");
- c += sprintf(tmp+c, "\n");
- AddStringToOutput(tmp, c);
- }
-}
-
-void WriteTypIpLst(POINT *ptr, long count)
-{
- long i, j, c, n;
- char tmp[256];
-
- if(!ptr) return;
- for(i = 0; i <= count/8; i++) {
- for(j = c = 0; (n =i*8+j) <count && j < 8; j++) {
- c += sprintf(tmp+c, " %ld", ptr[n].x);
- c += sprintf(tmp+c, " %ld", ptr[n].y);
- }
- if(n >= count) c += sprintf(tmp+c, "}");
- c += sprintf(tmp+c, "\n");
- AddStringToOutput(tmp, c);
- }
-}
-
-void WriteTypFpLst(lfPOINT *ptr, long count)
-{
- long i, j, c, n;
- char tmp[256];
-
- if(!ptr) return;
- for(i = 0; i <= count/8; i++) {
- for(j = c = 0; (n =i*8+j) <count && j < 8; j++) {
- c += WriteFloatToBuff(tmp+c, ptr[n].fx);
- c += WriteFloatToBuff(tmp+c, ptr[n].fy);
- }
- if(n >= count) c += sprintf(tmp+c, "}");
- c += sprintf(tmp+c, "\n");
- AddStringToOutput(tmp, c);
- }
-}
-
-void WriteTypFpLst3D(fPOINT3D *ptr, long count)
-{
- long i, j, c, n;
- char tmp[256];
-
- if(!ptr) return;
- for(i = 0; i <= count/5; i++) {
- for(j = c = 0; (n =i*5+j) <count && j < 5; j++) {
- c += WriteFloatToBuff(tmp+c, ptr[n].fx);
- c += WriteFloatToBuff(tmp+c, ptr[n].fy);
- c += WriteFloatToBuff(tmp+c, ptr[n].fz);
- }
- if(n >= count && j) c += sprintf(tmp+c, "}\n");
- else if(n < count) c += sprintf(tmp+c, "\n");
- AddStringToOutput(tmp, c);
- }
+ }
+ if(ptr) free(ptr);
+ cbOut = sizeOut = 0;
+ ptr = 0L; iFile = -1;
+}
+
+static void WriteTypObjLst(GraphObj **obs, int c1)
+{
+ int i, j, no, n, *idx;
+
+ if(!obs || !(idx=(int*)malloc(c1*sizeof(int)))) return;
+ for(i = no = 0; i < c1; i++) {
+ if(j = Notary->RegisterGO(obs[i])) idx[no++] = j;
+ }
+ add_to_buff(&ptr, &cbOut, &sizeOut, "(", 1);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, no, false, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "){", 2);
+ for(i = 0; i < no; i += 16) {
+ if(i) add_to_buff(&ptr, &cbOut, &sizeOut, " ", 3);
+ for(j = 0; (n=i+j) < no && j < 16; j++) {
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, idx[n], j != 0, 0);
+ }
+ if(n >= no) add_to_buff(&ptr, &cbOut, &sizeOut, "}", 1);
+ else add_to_buff(&ptr, &cbOut, &sizeOut, "\n", 1);
+ }
+}
+
+static void WriteTypIpLst(POINT *ppt, int count)
+{
+ long i, j, c, n;
+
+ if(!ppt) return;
+ add_to_buff(&ptr, &cbOut, &sizeOut, "(", 1);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, count, false, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "){", 2);
+ for(i = 0; i < count; i += 8) {
+ for(j = c = 0; (n = i+j) <count && j < 8; j++) {
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, ppt[n].x, (j != 0), 0);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, ppt[n].y, true, 0);
+ }
+ if(n >= count) add_to_buff(&ptr, &cbOut, &sizeOut, "}", 1);
+ else add_to_buff(&ptr, &cbOut, &sizeOut, "\n", 1);
+ }
+}
+
+static void WriteTypFpLst(lfPOINT *ppt, long count, bool bPar)
+{
+ int i, j, n;
+
+ if (bPar){
+ if(!ppt) return;
+ add_to_buff(&ptr, &cbOut, &sizeOut, "(", 1);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, count, false, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "){", 2);
+ }
+ else {
+ if(!ppt) count = 0;
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, count, true, 0);
+ if(!count) {
+ add_to_buff(&ptr, &cbOut, &sizeOut, "\n", 1);
+ return;
+ }
+ add_to_buff(&ptr, &cbOut, &sizeOut, " {", 2);
+ }
+ for(i = 0; i < count; i += 8) {
+ for(j = 0; (n = i+j) <count && j < 8; j++) {
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ppt[n].fx, (j != 0));
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ppt[n].fy, true);
+ }
+ if(n >= count) add_to_buff(&ptr, &cbOut, &sizeOut, "}", 1);
+ else add_to_buff(&ptr, &cbOut, &sizeOut, "\n", 1);
+ }
+}
+
+static void WriteTypFpLst3D(fPOINT3D *ppt, int count)
+{
+ long i, j, c, n;
+
+ if(!ppt) return;
+ add_to_buff(&ptr, &cbOut, &sizeOut, "(", 1);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, count, false, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "){", 2);
+ for(i = 0; i < count; i +=5) {
+ for(j = c = 0; (n =i+j) <count && j < 5; j++) {
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ppt[n].fx, (j != 0));
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ppt[n].fy, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ppt[n].fz, true);
+ }
+ if(n >= count) add_to_buff(&ptr, &cbOut, &sizeOut, "}", 1);
+ else add_to_buff(&ptr, &cbOut, &sizeOut, "\n", 1);
+ }
}
static char * esc_str = 0L;
static int esc_str_size = 0;
-int WriteEscString(char *txt, char *buff, int cb)
+static void WriteEscString(char *txt)
{
int i, j, l, lim = 60;
- 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+100));
+ if(!txt || !txt[0]) return;
+ l = (int)strlen(txt);
+ if((l+10) > esc_str_size) if(!(esc_str = (char*)realloc(esc_str, esc_str_size = (l+100))))return;
j = 0; esc_str[j++] = '"';
for(i = 0; txt[i]; i++) {
switch(txt[i]) {
- case '\\': j += sprintf(esc_str+j, "\\\\"); break;
- case '\n': j += sprintf(esc_str+j, "\\n"); break;
- default: esc_str[j++] = txt[i];
+ case '\\':
+ esc_str[j++] = '\\'; esc_str[j++] = '\\';
+ break;
+ case '\n':
+ esc_str[j++] = '\\'; esc_str[j++] = 'n';
+ break;
+ default:
+ if(txt[i] >= ' ') esc_str[j++] = txt[i];
}
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 \"");
+ if(j > lim && (l-i) > 3) {
+ esc_str[j++] = '"'; esc_str[j++] = '\\';
+ esc_str[j++] = '\n'; esc_str[j++] = ' ';
+ esc_str[j++] = ' '; esc_str[j++] = ' ';
+ esc_str[j++] = '"';
lim += 60;
}
}
- j += sprintf(esc_str+j, "\"\n");
- return sprintf(buff+cb, "%s", esc_str);
-}
-
-bool ExecOutput(long id, char *Class, descIO *Desc)
-{
- static char buff[800];
- int i, cb, last;
- fRECT *fr;
- AxisDEF *ax;
- LineDEF *ld;
- FillDEF *fd;
- TextDEF *tx;
-
- cb = sprintf(buff, "\n[%ld=%s]\n", id, Class);
- cObsW++;
- for(i = 0; Desc[i].label; i++) {
- last = cb;
- cb += sprintf(buff+cb,"%s=", Desc[i].label);
- switch(Desc[i].type & 0xff){
- case typNZINT:
- if(!(*(int*)Desc[i].ptr)) {
- cb = last;
- break;
- }
- //if not zero value continue as if int
- case typINT:
- cb += sprintf(buff+cb," %d\n", *(int*)Desc[i].ptr);
- break;
- case typNZLFLOAT:
- if(fabs(*((double*)Desc[i].ptr)) < 1.0e-7) {
- cb = last;
- break;
- }
- //if not zero or negative continue as if float
- case typLFLOAT:
- cb += WriteFloatToBuff(buff+cb, *(double*)Desc[i].ptr);
- cb += sprintf(buff+cb, "\n");
- break;
- case typDWORD:
- cb += sprintf(buff+cb," 0x%08x\n", *(DWORD *)Desc[i].ptr);
- break;
- case typULONG:
- cb += sprintf(buff+cb," %ld\n", *(unsigned long*)Desc[i].ptr);
- break;
- case typFRECT:
- fr = (fRECT*)Desc[i].ptr;
- cb += WriteFloatToBuff(buff+cb, fr->Xmin);
- cb += WriteFloatToBuff(buff+cb, fr->Ymax);
- cb += WriteFloatToBuff(buff+cb, fr->Xmax);
- cb += WriteFloatToBuff(buff+cb, fr->Ymin);
- cb += sprintf(buff+cb, "\n");
- break;
- case typNZLFPOINT:
- if(((lfPOINT *)Desc[i].ptr)->fx == ((lfPOINT *)Desc[i].ptr)->fy &&
- ((lfPOINT *)Desc[i].ptr)->fx == 0.0f){
- cb = last;
- break;
- }
- //if not zero continue as if fPOINT
- case typLFPOINT:
- cb += WriteFloatToBuff(buff+cb, ((lfPOINT *)Desc[i].ptr)->fx);
- cb += WriteFloatToBuff(buff+cb, ((lfPOINT *)Desc[i].ptr)->fy);
- cb += sprintf(buff+cb, "\n");
- break;
- case typPOINT3D:
- cb += WriteFloatToBuff(buff+cb, ((fPOINT3D *)Desc[i].ptr)->fx);
- cb += WriteFloatToBuff(buff+cb, ((fPOINT3D *)Desc[i].ptr)->fy);
- cb += WriteFloatToBuff(buff+cb, ((fPOINT3D *)Desc[i].ptr)->fz);
- cb += sprintf(buff+cb, "\n");
- break;
- case typAXDEF:
- case typPTRAXDEF:
- ax = (Desc[i].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[i].ptr : *(AxisDEF **)Desc[i].ptr;
- //we do not set ownership: reconstruct after read
- cb += sprintf(buff+cb, "0x%08x", ax->flags);
- cb += WriteFloatToBuff(buff+cb, ax->min);
- cb += WriteFloatToBuff(buff+cb, ax->max);
- cb += WriteFloatToBuff(buff+cb, ax->loc[0].fx);
- cb += WriteFloatToBuff(buff+cb, ax->loc[0].fy);
- cb += WriteFloatToBuff(buff+cb, ax->loc[0].fz);
- cb += WriteFloatToBuff(buff+cb, ax->loc[1].fx);
- cb += WriteFloatToBuff(buff+cb, ax->loc[1].fy);
- cb += WriteFloatToBuff(buff+cb, ax->loc[1].fz);
- cb += WriteFloatToBuff(buff+cb, ax->Start);
- cb += WriteFloatToBuff(buff+cb, ax->Step);
- cb += WriteFloatToBuff(buff+cb, ax->Center.fx);
- cb += WriteFloatToBuff(buff+cb, ax->Center.fy);
- cb += WriteFloatToBuff(buff+cb, ax->Radius);
- cb += sprintf(buff+cb," %d", ax->nBreaks);
- if(ax->nBreaks) {
- cb += sprintf(buff+cb, " {");
- AddStringToOutput(buff, cb);
- cb = 0;
- WriteTypFpLst(ax->breaks, ax->nBreaks);
- }
- cb += sprintf(buff+cb, "\n");
- break;
- case typLINEDEF:
- ld = (LineDEF *)Desc[i].ptr;
- cb += WriteFloatToBuff(buff+cb, ld->width);
- cb += WriteFloatToBuff(buff+cb, ld->patlength);
- cb += sprintf(buff+cb, ld->color ? " 0x%08x" : " 0x0", ld->color);
- cb += sprintf(buff+cb, ld->pattern ? " 0x%08x\n" : " 0x0\n", ld->pattern);
- break;
- case typFILLDEF:
- fd = (FillDEF *)Desc[i].ptr;
- //we set the 'hatch' member to zero: reconstruct after read
- cb += sprintf(buff+cb," %d 0x%08x", fd->type, fd->color);
- cb += WriteFloatToBuff(buff+cb, fd->scale);
- cb += sprintf(buff+cb," 0x0 0x%08x\n", fd->color2);
- break;
- case typGOBJ:
- if(*(GraphObj **)(Desc[i].ptr)) cb +=
- sprintf(buff+cb," %ld\n", Notary->RegisterGO(*(GraphObj **)(Desc[i].ptr)));
- else cb = last;
- break;
- case typOBJLST:
- if(!*(GraphObj ***)(Desc[i].ptr)){
- cb = last;
- break;
- }
- cb += sprintf(buff+cb, "(%ld){", Desc[i].count ? *Desc[i].count : 0L);
- AddStringToOutput(buff, cb);
- cb = 0;
- WriteTypObjLst(*(GraphObj ***)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0L);
- break;
- case typIPLST:
- if(!*(POINT**)(Desc[i].ptr)){
- cb = last;
- break;
- }
- cb += sprintf(buff+cb, "(%ld){", Desc[i].count ? *Desc[i].count : 0L);
- AddStringToOutput(buff, cb);
- cb = 0;
- WriteTypIpLst(*(POINT**)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0L);
- break;
- case typFPLST:
- if(!*(lfPOINT**)(Desc[i].ptr)){
- cb = last;
- break;
- }
- cb += sprintf(buff+cb, "(%ld){", Desc[i].count ? *Desc[i].count : 0L);
- AddStringToOutput(buff, cb);
- cb = 0;
- WriteTypFpLst(*(lfPOINT**)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0L);
- break;
- case typFPLST3D:
- if(!*(fPOINT3D**)(Desc[i].ptr)){
- cb = last;
- break;
- }
- cb += sprintf(buff+cb, "(%ld){", Desc[i].count ? *Desc[i].count : 0L);
- AddStringToOutput(buff, cb);
- cb = 0;
- WriteTypFpLst3D(*(fPOINT3D**)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0L);
- break;
- case typTEXT:
- if(!*(char**)(Desc[i].ptr)) cb = last;
- else cb += WriteEscString(*(char**)(Desc[i].ptr), buff, cb);
- break;
- case typTXTDEF:
- case typPTRTXTDEF:
- tx = (Desc[i].type &0xff) == typTXTDEF ? (TextDEF *)Desc[i].ptr : *(TextDEF **)Desc[i].ptr;
- if(!tx) {
- cb = last;
- break;
- }
- cb += sprintf(buff+cb, " 0x%08x 0x%08x %g %g %g %d %d %d %d",
- tx->ColTxt, tx->ColBg, tx->fSize, tx->RotBL, tx->RotCHAR,
- tx->Align, tx->Mode, tx->Style, tx->Font);
- if(tx->text) cb += sprintf(buff+cb, " \"%s\"\n", tx->text);
- else cb += sprintf(buff+cb, "\n");
- break;
- }
- if(Desc[i].type & typLAST) break;
- }
- AddStringToOutput(buff, cb);
- return true;
-}
-
-void ReadTypIpLst(POINT *ptr, long count, unsigned char *first)
-{
- long f[20];
- int j, k;
- long i;
-
- if(!ptr || !first) return;
- k = sscanf((char*)first, "%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld%ld",
- &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
- &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19]);
- for(i = 0, j = 0; j < k && i < count; i++, j += 2) {
- ptr[i].x = f[j]; ptr[i].y = f[j+1];
- }
- while (i < count) {
- if(!Cache->GetInt(&ptr[i].x) || !Cache->GetInt(&ptr[i].y)) return;
- i++;
- }
-}
-
-void ReadTypFpLst(lfPOINT *ptr, long count, unsigned char *first)
-{
- double f[20];
- int j, k;
- long i;
-
- if(!ptr || !first) return;
- k = sscanf((char*)first, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
- &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
- &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19]);
- for(i = 0, j = 0; j < k && i < count; i++, j += 2) {
- ptr[i].fx = f[j]; ptr[i].fy = f[j+1];
- }
- while (i < count) {
- if(!Cache->GetFloat(&ptr[i].fx) || !Cache->GetFloat(&ptr[i].fy)) return;
- i++;
- }
-}
-
-void ReadTypFpLst3D(fPOINT3D *ptr, long count, unsigned char *first)
-{
- double f[21];
- int j, k;
- long i;
-
- if(!ptr || !first) return;
- k = sscanf((char*)first, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
- &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
- &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19], &f[20]);
- for(i = 0, j = 0; j < k && i < count; i++, j += 3) {
- ptr[i].fx = f[j]; ptr[i].fy = f[j+1]; ptr[i].fz = f[j+2];
- }
- while (i < count) {
- if(!Cache->GetFloat(&ptr[i].fx) || !Cache->GetFloat(&ptr[i].fy) ||
- !Cache->GetFloat(&ptr[i].fz)) return;
- i++;
- }
-}
-
-void TranslateEscChar(char *txt)
-{
- int i, j;
-
- if(txt && txt[0]) {
- for(i = j = 0; txt[i]; i++) {
- if(txt[i] == '\\') {
- switch(txt[i+1]) {
- case 'n':
- txt[j++] = 0x0a; i++; break;
- case 'r':
- txt[j++] = 0x0d; i++; break;
- case '"': case 0x27: case '\\':
- txt[j++] = txt[++i]; break;
- default:
- txt[j++] = txt[i]; break;
- }
- }
- else txt[j++] = txt[i];
- }
- txt[j] = 0;
- }
-}
-
-void AddLines(char **txt)
-{
- char tmp[1000], *ntxt;
- bool mlines;
- int i, j, cb = strlen(*txt);
-
- do {
- mlines = false;
- Cache->ReadLine(tmp, sizeof(tmp));
- for(i = strlen(tmp); i > 0 &&(tmp[i-1] < 33 || (tmp[i-1] ==
- '"' && tmp[i-2] != '\\') || (tmp[i-1] == '\\' &&
- (mlines = true))); tmp[--i] = 0);
- for(i = 0; tmp[i] && (tmp[i] < 33 || tmp[i] == '"'); i++);
- TranslateEscChar(tmp);
- if(tmp[0] && (j = strlen(tmp+i)) && (ntxt = (char*)realloc(*txt, cb + j + 1))) {
- strcpy(ntxt+cb, tmp+i);
- cb += j; *(txt) = ntxt;
- }
- } while (mlines);
-}
-
-bool ExecInput(descIO *Desc)
-{
- char c, tmp[1000], tmp2[20];
- int i, j, k, l;
- bool match, mlines;
- unsigned long il, jl;
- AxisDEF *ax;
- POINT *lp;
- lfPOINT *lfp;
- fPOINT3D *lfp3d;
- LineDEF *ld;
- FillDEF *fd;
- fRECT *fr;
- GraphObj **gobs;
- TextDEF *tx;
-
- if(!Desc || !Desc[0].label) return false;
- for(j = k = 0; ; ) {
- do{
- c = Cache->Getc();
- switch (c) {
- case '[': //next object
- case 0: //probably eof
- return true;
- case '}': //a lists hang over
- c = Cache->Getc();
- break;
- }
- } while(c <33);
- for(i = 1, tmp[0] = c; i < sizeof(tmp) && '=' != (tmp[i] = Cache->Getc()); i++){
+ esc_str[j++] = '"';
+ add_to_buff(&ptr, &cbOut, &sizeOut, esc_str, j);
+}
+
+bool ExecOutput(int id, char *Class, descIO *Desc)
+{
+ int i, last;
+ fRECT *fr;
+ AxisDEF *ax;
+ LineDEF *ld;
+ FillDEF *fd;
+ TextDEF *tx;
+
+ add_to_buff(&ptr, &cbOut, &sizeOut, "\n[", 2);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, id, false, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "=", 1);
+ add_to_buff(&ptr, &cbOut, &sizeOut, Class, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "]\n", 2);
+ cObsW++;
+ for(i = 0; Desc[i].label; i++) {
+ if(ptr[cbOut-1] != '\n') add_to_buff(&ptr, &cbOut, &sizeOut, "\n", 1);
+ last = cbOut;
+ add_to_buff(&ptr, &cbOut, &sizeOut, Desc[i].label, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "=", 1);
+ switch(Desc[i].type & 0xff){
+ case typNZINT:
+ if(!(*(int*)Desc[i].ptr)) {
+ cbOut = last; break;
+ }
+ //if not zero value continue as if int
+ case typINT:
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, *(int*)Desc[i].ptr, true, 0);
+ break;
+ case typNZLFLOAT:
+ if(*((double*)Desc[i].ptr) == 0.0) {
+ cbOut = last; break;
+ }
+ //if not zero or negative continue as if float
+ case typLFLOAT:
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, *(double*)Desc[i].ptr, true);
+ break;
+ case typDWORD:
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, *(DWORD *)Desc[i].ptr, true);
+ break;
+ case typFRECT:
+ fr = (fRECT*)Desc[i].ptr;
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, fr->Xmin, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, fr->Ymax, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, fr->Xmax, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, fr->Ymin, true);
+ break;
+ case typNZLFPOINT:
+ if(((lfPOINT *)Desc[i].ptr)->fx == ((lfPOINT *)Desc[i].ptr)->fy &&
+ ((lfPOINT *)Desc[i].ptr)->fx == 0.0f){
+ cbOut = last; break;
+ }
+ //if not zero continue as if fPOINT
+ case typLFPOINT:
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ((lfPOINT *)Desc[i].ptr)->fx, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ((lfPOINT *)Desc[i].ptr)->fy, true);
+ break;
+ case typPOINT3D:
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ((fPOINT3D *)Desc[i].ptr)->fx, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ((fPOINT3D *)Desc[i].ptr)->fy, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ((fPOINT3D *)Desc[i].ptr)->fz, true);
+ break;
+ case typAXDEF: case typPTRAXDEF:
+ ax = (Desc[i].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[i].ptr : *(AxisDEF **)Desc[i].ptr;
+ //we do not set ownership: reconstruct after read
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, ax->flags, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->min, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->max, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->loc[0].fx, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->loc[0].fy, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->loc[0].fz, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->loc[1].fx, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->loc[1].fy, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->loc[1].fz, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->Start, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->Step, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->Center.fx, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->Center.fy, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ax->Radius, true);
+ WriteTypFpLst(ax->breaks, ax->nBreaks, false);
+ break;
+ case typLINEDEF:
+ ld = (LineDEF *)Desc[i].ptr;
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ld->width, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, ld->patlength, true);
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, ld->color, true);
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, ld->pattern, true);
+ break;
+ case typFILLDEF:
+ fd = (FillDEF *)Desc[i].ptr;
+ //we set the 'hatch' member to zero: reconstruct after read
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, fd->type, true, 0);
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, fd->color, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, fd->scale, true);
+ add_to_buff(&ptr, &cbOut, &sizeOut, " 0x0", 4);
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, fd->color2, true);
+ break;
+ case typGOBJ:
+ if(*(GraphObj **)(Desc[i].ptr)) add_int_to_buff(&ptr, &cbOut, &sizeOut,
+ Notary->RegisterGO(*(GraphObj **)(Desc[i].ptr)), true, 0);
+ else cbOut = last;
+ break;
+ case typOBJLST:
+ if(!*(GraphObj ***)(Desc[i].ptr)){
+ cbOut = last; break;
+ }
+ WriteTypObjLst(*(GraphObj ***)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0);
+ break;
+ case typIPLST:
+ if(!*(POINT**)(Desc[i].ptr)){
+ cbOut = last; break;
+ }
+ WriteTypIpLst(*(POINT**)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0L);
+ break;
+ case typFPLST:
+ if(!*(lfPOINT**)(Desc[i].ptr)){
+ cbOut = last; break;
+ }
+ WriteTypFpLst(*(lfPOINT**)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0L, true);
+ break;
+ case typFPLST3D:
+ if(!*(fPOINT3D**)(Desc[i].ptr)){
+ cbOut = last; break;
+ }
+ WriteTypFpLst3D(*(fPOINT3D**)Desc[i].ptr, Desc[i].count ? *Desc[i].count : 0);
+ break;
+ case typTEXT:
+ if(!*(char**)(Desc[i].ptr)) cbOut = last;
+ else WriteEscString(*((char**)Desc[i].ptr));
+ break;
+ case typTXTDEF: case typPTRTXTDEF:
+ tx = (Desc[i].type &0xff) == typTXTDEF ? (TextDEF *)Desc[i].ptr : *(TextDEF **)Desc[i].ptr;
+ if(!tx) {
+ cbOut = last; break;
+ }
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, tx->ColTxt, true);
+ add_hex_to_buff(&ptr, &cbOut, &sizeOut, tx->ColBg, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, tx->fSize, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, tx->RotBL, true);
+ add_dbl_to_buff(&ptr, &cbOut, &sizeOut, tx->RotCHAR, true);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, tx->Align, true, 0);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, tx->Mode, true, 0);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, tx->Style, true, 0);
+ add_int_to_buff(&ptr, &cbOut, &sizeOut, tx->Font, true, 0);
+ if(tx->text && tx->text[0]) {
+ add_to_buff(&ptr, &cbOut, &sizeOut, " \"", 2);
+ add_to_buff(&ptr, &cbOut, &sizeOut, tx->text, 0);
+ add_to_buff(&ptr, &cbOut, &sizeOut, "\"\n", 2);
+ }
+ break;
+ }
+ if(Desc[i].type & typLAST) break;
+ }
+ if(ptr[cbOut-1] != '\n') add_to_buff(&ptr, &cbOut, &sizeOut, "\n", 1);
+ return true;
+}
+
+void ReadTypIpLst(POINT *ptr, long count, unsigned char *first)
+{
+ int i, j, k, f[20];
+
+ if(!ptr || !first) return;
+#ifdef USE_WIN_SECURE
+ k = sscanf_s((char*)first, "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
+ &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
+ &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19]);
+#else
+ k = sscanf((char*)first, "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
+ &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
+ &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19]);
+#endif
+ for(i = 0, j = 0; j < k && i < count; i++, j += 2) {
+ ptr[i].x = f[j]; ptr[i].y = f[j+1];
+ }
+ while (i < count) {
+ if(!Cache->GetInt(&ptr[i].x) || !Cache->GetInt(&ptr[i].y)) return;
+ i++;
+ }
+}
+
+void ReadTypFpLst(lfPOINT *ptr, long count, unsigned char *first)
+{
+ double f[20];
+ int j, k;
+ long i;
+
+ if(!ptr || !first) return;
+#ifdef USE_WIN_SECURE
+ k = sscanf_s((char*)first, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
+ &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
+ &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19]);
+#else
+ k = sscanf((char*)first, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
+ &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
+ &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19]);
+#endif
+ for(i = 0, j = 0; j < k && i < count; i++, j += 2) {
+ ptr[i].fx = f[j]; ptr[i].fy = f[j+1];
+ }
+ while (i < count) {
+ if(!Cache->GetFloat(&ptr[i].fx) || !Cache->GetFloat(&ptr[i].fy)) return;
+ i++;
+ }
+}
+
+void ReadTypFpLst3D(fPOINT3D *ptr, long count, unsigned char *first)
+{
+ double f[21];
+ int j, k;
+ long i;
+
+ if(!ptr || !first) return;
+#ifdef USE_WIN_SECURE
+ k = sscanf_s((char*)first, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
+ &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
+ &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19], &f[20]);
+#else
+ k = sscanf((char*)first, "%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
+ &f[0], &f[1], &f[2], &f[3], &f[4], &f[5], &f[6], &f[7], &f[8], &f[9],
+ &f[10], &f[11], &f[12], &f[13], &f[14], &f[15], &f[16], &f[17], &f[18], &f[19], &f[20]);
+#endif
+ for(i = 0, j = 0; j < k && i < count; i++, j += 3) {
+ ptr[i].fx = f[j]; ptr[i].fy = f[j+1]; ptr[i].fz = f[j+2];
+ }
+ while (i < count) {
+ if(!Cache->GetFloat(&ptr[i].fx) || !Cache->GetFloat(&ptr[i].fy) ||
+ !Cache->GetFloat(&ptr[i].fz)) return;
+ i++;
+ }
+}
+
+void TranslateEscChar(char *txt)
+{
+ int i, j;
+
+ if(txt && txt[0]) {
+ for(i = j = 0; txt[i]; i++) {
+ if(txt[i] == '\\') {
+ switch(txt[i+1]) {
+ case 'n':
+ txt[j++] = 0x0a; i++; break;
+ case 'r':
+ txt[j++] = 0x0d; i++; break;
+ case '"': case 0x27: case '\\':
+ txt[j++] = txt[++i]; break;
+ default:
+ txt[j++] = txt[i]; break;
+ }
+ }
+ else txt[j++] = txt[i];
+ }
+ txt[j] = 0;
+ }
+}
+
+void AddLines(char **txt)
+{
+ char tmp[1000], *ntxt;
+ bool mlines;
+ int i, j, cb = (int)strlen(*txt);
+
+ do {
+ mlines = false;
+ Cache->ReadLine(tmp, sizeof(tmp));
+ for(i = (int)strlen(tmp); i > 0 &&(tmp[i-1] < 33 || (tmp[i-1] ==
+ '"' && tmp[i-2] != '\\') || (tmp[i-1] == '\\' &&
+ (mlines = true))); tmp[--i] = 0);
+ for(i = 0; tmp[i] && (tmp[i] < 33 || tmp[i] == '"'); i++);
+ TranslateEscChar(tmp);
+ if(tmp[0] && (j = (int)strlen(tmp+i)) && (ntxt = (char*)realloc(*txt, cb + j + 1))) {
+ rlp_strcpy(ntxt+cb, j+1, tmp+i);
+ cb += j; *(txt) = ntxt;
+ }
+ } while (mlines);
+}
+
+bool ExecInput(descIO *Desc)
+{
+ unsigned char c, tmp[1000], tmp2[20];
+ int i, j, k, l;
+ bool match, mlines;
+ int il, jl;
+ AxisDEF *ax;
+ POINT *lp;
+ lfPOINT *lfp;
+ fPOINT3D *lfp3d;
+ LineDEF *ld;
+ FillDEF *fd;
+ fRECT *fr;
+ GraphObj **gobs;
+ TextDEF *tx;
+
+ if(!Desc || !Desc[0].label) return false;
+ for(j = k = 0; ; ) {
+ do{
+ c = Cache->Getc();
+ switch (c) {
+ case '[': //next object
+ case 0: //probably eof
+ return true;
+ case '}': //a lists hang over
+ c = Cache->Getc();
+ break;
+ }
+ } while(c <33);
+ for(i = 1, tmp[0] = c; i < sizeof(tmp) && '=' != (tmp[i] = Cache->Getc()); i++){
if(tmp[i] < 32 && tmp[i]) i = -1; //some error conditions
- else if(!tmp[i] && Cache->eof) return true;
- else if(tmp[i] == '[') return true;
- }
- tmp[i] = 0;
- match = mlines = false;
- do {
- if(0 == strcmp(tmp, Desc[j].label)) {
- Cache->ReadLine(tmp, sizeof(tmp));
- switch(Desc[j].type & 0xff){
- case typNZINT:
- case typINT:
- sscanf(tmp, "%d", (int*)Desc[j].ptr);
- break;
- case typNZLFLOAT:
- case typLFLOAT:
- sscanf(tmp, "%lf", (double*)Desc[j].ptr);
- break;
- case typDWORD:
- sscanf(tmp, "%x", (DWORD*)Desc[j].ptr);
- break;
- case typULONG:
- sscanf(tmp, "%ld", (unsigned long*)Desc[j].ptr);
- break;
- case typFRECT:
- fr = (fRECT*) Desc[j].ptr;
- sscanf(tmp, "%lf%lf%lf%lf", &fr->Xmin, &fr->Ymax, &fr->Xmax, &fr->Ymin);
- break;
- case typNZLFPOINT:
- case typLFPOINT:
- lfp = (lfPOINT*) Desc[j].ptr;
- sscanf(tmp, "%lf%lf", &lfp->fx, &lfp->fy);
- break;
- case typPOINT3D:
- lfp3d = (fPOINT3D*) Desc[j].ptr;
- sscanf(tmp, "%lf%lf%lf", &lfp3d->fx, &lfp3d->fy, &lfp3d->fz);
- break;
- case typPTRAXDEF:
- case typAXDEF:
- ax = (Desc[j].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[j].ptr : *(AxisDEF **)Desc[j].ptr;
- //pointer for typPTRAXDEF and memory allocated by the Axis module!
- if(!ax) break;
- sscanf(tmp, "%x%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%d", &ax->flags, &ax->min, &ax->max,
- &ax->loc[0].fx, &ax->loc[0].fy, &ax->loc[0].fz, &ax->loc[1].fx,
- &ax->loc[1].fy, &ax->loc[1].fz, &ax->Start, &ax->Step, &ax->Center.fx,
- &ax->Center.fy, &ax->Radius, &ax->nBreaks);
- if(ax->nBreaks) {
- ax->breaks = (lfPOINT*)calloc(ax->nBreaks, sizeof(lfPOINT));
- for(i = 0; tmp[i] && tmp[i-1] != '{'; i++);
- if(tmp[i]) {
- ReadTypFpLst(ax->breaks, ax->nBreaks, (unsigned char*)tmp+i);
- SortAxisBreaks(ax);
- }
- }
- break;
- case typLINEDEF:
- ld = (LineDEF*) Desc[j].ptr;
- sscanf(tmp,"%lf%lf%x%x", &ld->width, &ld->patlength, &ld->color, &ld->pattern);
- break;
- case typFILLDEF:
- fd = (FillDEF*) Desc[j].ptr;
- sscanf(tmp, "%d%x%lf%x%x", &fd->type, &fd->color, &fd->scale, &fd->hatch, &fd->color2);
- fd->hatch = 0L;
- break;
- case typGOBJ:
- *(GraphObj**)(Desc[j].ptr) = Notary->PopGO(atol(tmp));
- break;
- case typOBJLST:
- for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
- if(!tmp[i]) break;
- if(sscanf(tmp+i+1, "%ld", &il) && il) {
- *Desc[j].count = il;
- if(!*(GraphObj***)(Desc[j].ptr)){
- *(GraphObj***)(Desc[j].ptr) = (GraphObj**)calloc(il, sizeof(GraphObj*));
- }
+ else if(!tmp[i] && Cache->eof) return true;
+ else if(tmp[i] == '[') return true;
+ }
+ tmp[i] = 0;
+ match = mlines = false;
+ do {
+ if(0 == strcmp((char*)tmp, Desc[j].label)) {
+ Cache->ReadLine((char*)tmp, sizeof(tmp));
+ switch(Desc[j].type & 0xff){
+ case typNZINT:
+ case typINT:
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%d", (int*)Desc[j].ptr);
+#else
+ sscanf((char*)tmp, "%d", (int*)Desc[j].ptr);
+#endif
+ break;
+ case typNZLFLOAT: case typLFLOAT:
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%lf", (double*)Desc[j].ptr);
+#else
+ sscanf((char*)tmp, "%lf", (double*)Desc[j].ptr);
+#endif
+ break;
+ case typDWORD:
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%x", (DWORD*)Desc[j].ptr);
+#else
+ sscanf((char*)tmp, "%x", (DWORD*)Desc[j].ptr);
+#endif
+ break;
+ case typFRECT:
+ fr = (fRECT*) Desc[j].ptr;
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%lf%lf%lf%lf", &fr->Xmin, &fr->Ymax, &fr->Xmax, &fr->Ymin);
+#else
+ sscanf((char*)tmp, "%lf%lf%lf%lf", &fr->Xmin, &fr->Ymax, &fr->Xmax, &fr->Ymin);
+#endif
+ break;
+ case typNZLFPOINT: case typLFPOINT:
+ lfp = (lfPOINT*) Desc[j].ptr;
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%lf%lf", &lfp->fx, &lfp->fy);
+#else
+ sscanf((char*)tmp, "%lf%lf", &lfp->fx, &lfp->fy);
+#endif
+ break;
+ case typPOINT3D:
+ lfp3d = (fPOINT3D*) Desc[j].ptr;
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%lf%lf%lf", &lfp3d->fx, &lfp3d->fy, &lfp3d->fz);
+#else
+ sscanf((char*)tmp, "%lf%lf%lf", &lfp3d->fx, &lfp3d->fy, &lfp3d->fz);
+#endif
+ break;
+ case typPTRAXDEF:
+ case typAXDEF:
+ ax = (Desc[j].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[j].ptr : *(AxisDEF **)Desc[j].ptr;
+ //pointer for typPTRAXDEF and memory allocated by the Axis module!
+ if(!ax) break;
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%x%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%d", &ax->flags, &ax->min, &ax->max,
+ &ax->loc[0].fx, &ax->loc[0].fy, &ax->loc[0].fz, &ax->loc[1].fx,
+ &ax->loc[1].fy, &ax->loc[1].fz, &ax->Start, &ax->Step, &ax->Center.fx,
+ &ax->Center.fy, &ax->Radius, &ax->nBreaks);
+#else
+ sscanf((char*)tmp, "%x%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%d", &ax->flags, &ax->min, &ax->max,
+ &ax->loc[0].fx, &ax->loc[0].fy, &ax->loc[0].fz, &ax->loc[1].fx,
+ &ax->loc[1].fy, &ax->loc[1].fz, &ax->Start, &ax->Step, &ax->Center.fx,
+ &ax->Center.fy, &ax->Radius, &ax->nBreaks);
+#endif
+ if(ax->nBreaks) {
+ ax->breaks = (lfPOINT*)calloc(ax->nBreaks, sizeof(lfPOINT));
+ for(i = 0; tmp[i] && tmp[i-1] != '{'; i++);
+ if(tmp[i]) {
+ ReadTypFpLst(ax->breaks, ax->nBreaks, (unsigned char*)tmp+i);
+ SortAxisBreaks(ax);
+ }
+ }
+ break;
+ case typLINEDEF:
+ ld = (LineDEF*) Desc[j].ptr;
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp,"%lf%lf%x%x", &ld->width, &ld->patlength, &ld->color, &ld->pattern);
+#else
+ sscanf((char*)tmp,"%lf%lf%x%x", &ld->width, &ld->patlength, &ld->color, &ld->pattern);
+#endif
+ break;
+ case typFILLDEF:
+ fd = (FillDEF*) Desc[j].ptr;
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%d%x%lf%x%x", &fd->type, &fd->color, &fd->scale, &fd->hatch, &fd->color2);
+#else
+ sscanf((char*)tmp, "%d%x%lf%x%x", &fd->type, &fd->color, &fd->scale, &fd->hatch, &fd->color2);
+#endif
+ fd->hatch = 0L;
+ break;
+ case typGOBJ:
+ *(GraphObj**)(Desc[j].ptr) = Notary->PopGO(atol((char*)tmp));
+ break;
+ case typOBJLST:
+ for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
+ if(!tmp[i]) break;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s((char*)tmp+i+1, "%ld", &il) && il) {
+#else
+ if(sscanf((char*)tmp+i+1, "%ld", &il) && il) {
+#endif
+ *Desc[j].count = il;
+ if(!*(GraphObj***)(Desc[j].ptr)){
+ *(GraphObj***)(Desc[j].ptr) = (GraphObj**)calloc(il, sizeof(GraphObj*));
+ }
if((gobs = *(GraphObj***)(Desc[j].ptr))){
- i += 4;
- while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
- strcat(tmp, " ");
- for( ;il >0; il--) {
- for(l = 0; l < sizeof(tmp2); ){
- if(tmp[i]) c = tmp[i++];
- else if(!(c = Cache->Getc())) break;
- if(c >='0' && c <='9') tmp2[l++] = c;
- else {
- tmp2[l] = 0;
- if(l)break;
- }
- }
- sscanf(tmp2, "%ld", &jl);
- *gobs++ = Notary->PopGO(jl);
- if(c == '}') break;
- }
- }
- }
- break;
- case typIPLST:
- for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
- if(!tmp[i]) break;
- if(sscanf(tmp+i+1, "%ld", &il) && il) {
- *Desc[j].count = il;
- if(!*(POINT**)(Desc[j].ptr)){
- *(POINT**)(Desc[j].ptr) = (POINT*)calloc(il, sizeof(POINT));
- }
- if(!(lp = *(POINT**)(Desc[j].ptr)))return false;
- while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
- ReadTypIpLst(lp, il, (unsigned char*)tmp+i);
- }
- break;
- case typFPLST:
- for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
- if(!tmp[i]) break;
- if(sscanf(tmp+i+1, "%ld", &il) && il) {
- *Desc[j].count = il;
- if(!*(lfPOINT**)(Desc[j].ptr)){
- *(lfPOINT**)(Desc[j].ptr) = (lfPOINT*)calloc(il, sizeof(lfPOINT));
- }
- if(!(lfp = *(lfPOINT**)(Desc[j].ptr)))return false;
- while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
- ReadTypFpLst(lfp, il, (unsigned char*)tmp+i);
- }
- break;
- case typFPLST3D:
- for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
- if(!tmp[i]) break;
- if(sscanf(tmp+i+1, "%ld", &il) && il) {
- *Desc[j].count = il;
- if(!*(fPOINT3D**)(Desc[j].ptr)){
- *(fPOINT3D**)(Desc[j].ptr) = (fPOINT3D*)calloc(il, sizeof(fPOINT3D));
- }
- if(!Desc[j].ptr)return false;
- while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
- ReadTypFpLst3D(*(fPOINT3D**)(Desc[j].ptr), il, (unsigned char*)tmp+i);
- }
- break;
- case typTEXT:
- for(i = strlen(tmp); i > 0 &&(tmp[i-1] < 32 || (tmp[i-1] ==
- '"' && tmp[i-2] != '\\') || (tmp[i-1] == '\\' &&
- (mlines = true))); tmp[--i] = 0);
- for(i = 0; tmp[i] && (tmp[i] < 33 || tmp[i] == '"'); i++);
- TranslateEscChar(tmp);
- if(tmp[0]){
- *(char**)(Desc[j].ptr) = strdup(tmp+i);
- if(mlines) AddLines((char**)(Desc[j].ptr));
- }
- break;
- case typPTRTXTDEF:
- case typTXTDEF:
- tx = (Desc[j].type & 0xff) == typTXTDEF ? (TextDEF *)Desc[j].ptr : *(TextDEF **)Desc[j].ptr;
- if(!tx) {
- if((Desc[j].type & 0xff) == typTXTDEF) break; //prabably wrong usage of typTXTDEF instad of
- // typPTRTXTDEF
- tx = *(TextDEF **)(Desc[j].ptr) = (TextDEF*)calloc(1, sizeof(TextDEF));
- if(!tx) return false; //memory allocation error
- }
- sscanf(tmp, "%x%x%lf%lf%lf%d%d%d%d", &tx->ColTxt, &tx->ColBg,
- &tx->fSize, &tx->RotBL, &tx->RotCHAR,
- &tx->Align, &tx->Mode, &tx->Style, &tx->Font);
- tx->iSize = 0;
- for(i = strlen(tmp); i >0 && tmp[i] != '"'; i--);
- if(i) {
- tmp[i] = 0;
- for(l = 0; l <i && tmp[l] != '"'; l++);
- if(i && tmp[l+1]) tx->text = strdup(tmp+l+1);
- }
- break;
- }
- match = true; j++; k++;
- if(!Desc[j].label || (Desc[j-1].type & typLAST))
- j = k = 0; //rewind: items in file not sorted
- }
- else {
- j++;
- k++;
- if(!Desc[j].label || (Desc[j-1].type & typLAST)) { //Error:
- if(k > j){ // item not defined in Desc
- match = true; // read parameters,
- Cache->ReadLine(tmp, sizeof(tmp)); // then continue
- }
- j= 0;
- }
- }
- }while(!match);
- }
-}
-
-bool SaveGraphAs(GraphObj *g)
-{
- char *name = 0L;
+ i += 4;
+ while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
+#ifdef USE_WIN_SECURE
+ strcat_s((char*)tmp, 1000, " ");
+#else
+ strcat((char*)tmp, " ");
+#endif
+ for( ;il >0; il--) {
+ for(l = 0; l < sizeof(tmp2); ){
+ if(tmp[i]) c = tmp[i++];
+ else if(!(c = Cache->Getc())) break;
+ if(c >='0' && c <='9') tmp2[l++] = c;
+ else {
+ tmp2[l] = 0;
+ if(l)break;
+ }
+ }
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp2, "%d", &jl);
+#else
+ sscanf((char*)tmp2, "%d", &jl);
+#endif
+ *gobs++ = Notary->PopGO(jl);
+ if(c == '}') break;
+ }
+ }
+ }
+ break;
+ case typIPLST:
+ for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
+ if(!tmp[i]) break;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s((char*)tmp+i+1, "%d", &il) && il) {
+#else
+ if(sscanf((char*)tmp+i+1, "%d", &il) && il) {
+#endif
+ *Desc[j].count = il;
+ if(!*(POINT**)(Desc[j].ptr)){
+ *(POINT**)(Desc[j].ptr) = (POINT*)calloc(il, sizeof(POINT));
+ }
+ if(!(lp = *(POINT**)(Desc[j].ptr)))return false;
+ while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
+ ReadTypIpLst(lp, il, (unsigned char*)tmp+i);
+ }
+ break;
+ case typFPLST:
+ for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
+ if(!tmp[i]) break;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s((char*)tmp+i+1, "%d", &il) && il) {
+#else
+ if(sscanf((char*)tmp+i+1, "%d", &il) && il) {
+#endif
+ *Desc[j].count = il;
+ if(!*(lfPOINT**)(Desc[j].ptr)){
+ *(lfPOINT**)(Desc[j].ptr) = (lfPOINT*)calloc(il, sizeof(lfPOINT));
+ }
+ if(!(lfp = *(lfPOINT**)(Desc[j].ptr)))return false;
+ while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
+ ReadTypFpLst(lfp, il, (unsigned char*)tmp+i);
+ }
+ break;
+ case typFPLST3D:
+ for(i = 0; i < 10 && tmp[i] != '(' && tmp[i]; i++);
+ if(!tmp[i]) break;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s((char*)tmp+i+1, "%d", &il) && il) {
+#else
+ if(sscanf((char*)tmp+i+1, "%d", &il) && il) {
+#endif
+ *Desc[j].count = il;
+ if(!*(fPOINT3D**)(Desc[j].ptr)){
+ *(fPOINT3D**)(Desc[j].ptr) = (fPOINT3D*)calloc(il, sizeof(fPOINT3D));
+ }
+ if(!Desc[j].ptr)return false;
+ while(tmp[i-1] != '{') i++; while(tmp[i-1] < 33) i++;
+ ReadTypFpLst3D(*(fPOINT3D**)(Desc[j].ptr), il, (unsigned char*)tmp+i);
+ }
+ break;
+ case typTEXT:
+ for(i = (int)strlen((char*)tmp); i > 0 &&(tmp[i-1] < 32 || (tmp[i-1] ==
+ '"' && tmp[i-2] != '\\') || (tmp[i-1] == '\\' &&
+ (mlines = true))); tmp[--i] = 0);
+ for(i = 0; tmp[i] && (tmp[i] < 33 || tmp[i] == '"'); i++);
+ TranslateEscChar((char*)tmp);
+ if(tmp[0]){
+ *(char**)(Desc[j].ptr) = (char*)memdup((char*)tmp+i, (int)strlen((char*)tmp+i)+1, 0);
+ if(mlines) AddLines((char**)(Desc[j].ptr));
+ }
+ break;
+ case typPTRTXTDEF:
+ case typTXTDEF:
+ tx = (Desc[j].type & 0xff) == typTXTDEF ? (TextDEF *)Desc[j].ptr : *(TextDEF **)Desc[j].ptr;
+ if(!tx) {
+ if((Desc[j].type & 0xff) == typTXTDEF) break; //prabably wrong usage of typTXTDEF instad of
+ // typPTRTXTDEF
+ tx = *(TextDEF **)(Desc[j].ptr) = (TextDEF*)calloc(1, sizeof(TextDEF));
+ if(!tx) return false; //memory allocation error
+ }
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%x%x%lf%lf%lf%d%d%d%d", &tx->ColTxt, &tx->ColBg,
+ &tx->fSize, &tx->RotBL, &tx->RotCHAR,
+ &tx->Align, &tx->Mode, &tx->Style, &tx->Font);
+#else
+ sscanf((char*)tmp, "%x%x%lf%lf%lf%d%d%d%d", &tx->ColTxt, &tx->ColBg,
+ &tx->fSize, &tx->RotBL, &tx->RotCHAR,
+ &tx->Align, &tx->Mode, &tx->Style, &tx->Font);
+#endif
+ tx->iSize = 0;
+ for(i = (int)strlen((char*)tmp); i >0 && tmp[i] != '"'; i--);
+ if(i) {
+ tmp[i] = 0;
+ for(l = 0; l <i && tmp[l] != '"'; l++);
+ if(i && tmp[l+1]) tx->text = (char*)memdup((char*)tmp+l+1, (int)strlen((char*)tmp+l+1)+1, 0);
+ }
+ break;
+ }
+ match = true; j++; k++;
+ if(!Desc[j].label || (Desc[j-1].type & typLAST))
+ j = k = 0; //rewind: items in file not sorted
+ }
+ else {
+ j++;
+ k++;
+ if(!Desc[j].label || (Desc[j-1].type & typLAST)) { //Error:
+ if(k > j){ // item not defined in Desc
+ match = true; // read parameters,
+ Cache->ReadLine((char*)tmp, sizeof(tmp)); // then continue
+ }
+ j= 0;
+ }
+ }
+ }while(!match);
+ }
+}
+
+bool SaveGraphAs(GraphObj *g)
+{
+ char *name = 0L;
int i;
- bool bRet = true;
-
- if(Notary || !g) {
- ErrorBox("Output pending or\nno graph.");
- return false;
- }
- cObsW = 0;
- Notary = new notary();
- if(g->Id == GO_GRAPH || g->Id == GO_PAGE) {
- if(((Graph*)g)->filename) name = ((Graph*)g)->filename;
- }
- name = SaveGraphAsName(name);
- if (name && Notary) {
- iFile = OpenOutputFile(name);
- if(iFile >=0) {
- if(g && g->FileIO(FILE_WRITE)){
- if(g->Id == GO_GRAPH || g->Id == GO_PAGE) {
- g->Command(CMD_FILENAME, name, 0L);
- }
- for(i = strlen(name); i >=0 && name[i] != '/' && name[i] != '\\'; i--);
- if(name[i]) i++;
- g->Command(CMD_SETNAME, name+i, 0L);
- g->Command(CMD_UPDHISTORY, 0L, 0L);
- }
- else ErrorBox("Could not write\ndata to file.");
- }
- else ErrorBox("Open failed for\noutput file.");
- CloseOutputFile();
- }
- else bRet = false;
- if(Notary) delete Notary; Notary = 0L;
- return bRet;
-}
-
-char *GraphToMem(GraphObj *g, long *size)
-{
+ bool bRet = true;
+
+ if(Notary || !g) {
+ ErrorBox("Output pending or\nno graph.");
+ return false;
+ }
+ cObsW = 0;
+ Notary = new notary();
+ if(g->Id == GO_GRAPH || g->Id == GO_PAGE) {
+ if(((Graph*)g)->filename) name = ((Graph*)g)->filename;
+ }
+ name = SaveGraphAsName(name);
+ if (name && Notary) {
+ iFile = OpenOutputFile(name);
+ if(iFile >=0) {
+ if(g && g->FileIO(FILE_WRITE)){
+ if(g->Id == GO_GRAPH || g->Id == GO_PAGE) {
+ g->Command(CMD_FILENAME, name, 0L);
+ }
+ for(i = (int)strlen(name); i >=0 && name[i] != '/' && name[i] != '\\'; i--);
+ if(name[i]) i++;
+ g->Command(CMD_SETNAME, name+i, 0L);
+ g->Command(CMD_UPDHISTORY, 0L, 0L);
+ }
+ else ErrorBox("Could not write\ndata to file.");
+ }
+ else ErrorBox("Open failed for\noutput file.");
+ CloseOutputFile();
+ }
+ else bRet = false;
+ if(Notary) delete Notary; Notary = 0L;
+ return bRet;
+}
+
+char *GraphToMem(GraphObj *g, long *size)
+{
static char *ret;
-
- if(Notary || !g) {
- ErrorBox("Output pending or\nno graph.");
- return false;
- }
- cObsW = 0;
- iFile = cbOut = sizeOut = 0; ptr = 0L; ptr_step = 2048;
- if (Notary = new notary()) {
+
+ if(Notary || !g) {
+ ErrorBox("Output pending or\nno graph.");
+ return false;
+ }
+ cObsW = 0; iFile = -1;
+ cbOut = sizeOut = 0; ptr = 0L;
+ if (Notary = new notary()) {
if(g && g->FileIO(FILE_WRITE)){
- //all done
- }
- delete Notary; Notary = 0L;
+ //all done
+ }
+ delete Notary; Notary = 0L;
if(ptr) ptr[cbOut] = 0;
- ret = ptr; if(size) *size = cbOut;
- iFile = cbOut = sizeOut = 0; ptr = 0L; ptr_step = 2048;
- return ret;
- }
- return 0L;
-}
-
-void UpdGOfromMem(GraphObj *go, unsigned char *buff)
-{
- int i=0;
-
- if(!go || !buff) return;
- iFile = cbOut = sizeOut = 0; ptr = 0L;
- for(i = 0; buff[i] && buff[i] != ']'; i++);
- if(!buff[i])return;
- for(; buff[i] && buff[i] <33; i++);
- if(!buff[i] || i < 4) return;
- if(!(Cache = new MemCache(buff+i-1))) return;
+ ret = ptr; if(size) *size = cbOut;
+ iFile = -1;
+ cbOut = sizeOut = 0; ptr = 0L;
+ return ret;
+ }
+ return 0L;
+}
+
+void UpdGOfromMem(GraphObj *go, unsigned char *buff)
+{
+ int i=0;
+
+ if(!go || !buff) return;
+ iFile = -1; cbOut = sizeOut = 0; ptr = 0L;
+ for(i = 0; buff[i] && buff[i] != ']'; i++);
+ if(!buff[i])return;
+ for(; buff[i] && buff[i] <33; i++);
+ if(!buff[i] || i < 4) return;
+ if(!(Cache = new MemCache(buff+i-1))) return;
if ((Notary = new notary()) && go->Id > GO_UNKNOWN && go->Id < GO_DEFRW) {
- //notary not needed but saver if tree exists
- go->Command(CMD_FLUSH, 0L, 0L);
- go->FileIO(INIT_VARS); go->FileIO(FILE_READ);
- delete Notary; Notary = 0L;
- }
- delete Cache; Cache = 0L;
-}
-
-bool OpenGraph(GraphObj *root, char *name, unsigned char *mem, bool bPaste)
-{
- unsigned char c, tmp[80];
- char debug[80];
- unsigned long id, lid;
- int i;
- unsigned int hv;
- GraphObj *go;
-
- if(Notary || Cache) {
- ErrorBox("Output pending:\nRead Error.");
- return false;
- }
- if(!(Notary = new notary()))return false;
- if(mem) {
- if(!(Cache = new MemCache(mem))) return false;
- }
- else if(Cache = new ReadCache()){
- if(!Cache->Open(name)) {
- delete Notary; delete Cache;
- Notary = 0L; Cache = 0L;
- ErrorBox("Error open file");
- return false;
- }
- }
- else return false;
- //DEBUG: skipping header
- do {
- c = Cache->Getc();
- } while(c && c != '[');
- if(!c) goto ReadErr;
- do {
- for(i = 0; i < sizeof(tmp) && c != '=' && c; i++){
+ //notary not needed but saver if tree exists
+ go->Command(CMD_FLUSH, 0L, 0L);
+ go->FileIO(INIT_VARS); go->FileIO(FILE_READ);
+ delete Notary; Notary = 0L;
+ }
+ delete Cache; Cache = 0L;
+}
+
+bool OpenGraph(GraphObj *root, char *name, unsigned char *mem, bool bPaste)
+{
+ unsigned char c, tmp[80];
+ char debug[80];
+ int i, id, lid;
+ unsigned int hv;
+ GraphObj *go;
+
+ LastOpenGO = 0L;
+ if(Notary || Cache) {
+ ErrorBox("Output pending:\nRead Error.");
+ return false;
+ }
+ if(!(Notary = new notary()))return false;
+ if(mem) {
+ if(!(Cache = new MemCache(mem))) return false;
+ }
+ else if(Cache = new ReadCache()){
+ if(!Cache->Open(name)) {
+ delete Notary; delete Cache;
+ Notary = 0L; Cache = 0L;
+ ErrorBox("Error open file");
+ return false;
+ }
+ }
+ else return false;
+ //DEBUG: skipping header
+ do {
+ c = Cache->Getc();
+ } while(c && c != '[');
+ if(!c) goto ReadErr;
+ do {
+ for(i = 0; i < sizeof(tmp) && c != '=' && c; i++){
tmp[i] = c = Cache->Getc();
if(c == '[') i = -1;
- }
- if(!c) goto ReadErr;
- tmp[i] = tmp[i-1] = 0; id=0;
- sscanf((char*)tmp, "%ld", &id);
- if(!id) goto ReadErr;
- //go to class name
- while((tmp[0] = Cache->Getc())<31 && tmp[0]);
- if(!tmp[0]) goto ReadErr;
- for(i = 1; i < sizeof(tmp) && c!= ']' && c; i++)
- tmp[i] = c = Cache->Getc();
- if(!c) goto ReadErr;
- tmp[i-1] = 0;
- go = 0L;
- hv = HashValue(tmp);
- switch(hv) {
- case 3895: go = new Axis(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 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;
- case 1031437: go = new DropLine(FILE_READ); break;
- case 4839: go = new Tick(FILE_READ); break;
- case 16832: go = new Label(FILE_READ); break;
- case 1071373: go = new GridLine(FILE_READ); break;
- case 963085: go = new DataLine(FILE_READ); break;
- case 61662266: go = new DataPolygon(FILE_READ); break;
- case 435228: go = new segment(FILE_READ); break;
- case 1741325: go = new polyline(FILE_READ); break;
+ }
+ if(!c) goto ReadErr;
+ tmp[i] = tmp[i-1] = 0; id=0;
+#ifdef USE_WIN_SECURE
+ sscanf_s((char*)tmp, "%d", &id);
+#else
+ sscanf((char*)tmp, "%d", &id);
+#endif
+ if(!id) goto ReadErr;
+ //go to class name
+ while((tmp[0] = Cache->Getc())<31 && tmp[0]);
+ if(!tmp[0]) goto ReadErr;
+ for(i = 1; i < sizeof(tmp) && c!= ']' && c; i++)
+ tmp[i] = c = Cache->Getc();
+ if(!c) goto ReadErr;
+ tmp[i-1] = 0;
+ go = 0L;
+ hv = HashValue(tmp);
+ switch(hv) {
+ case 3895: go = new Axis(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 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;
+ case 1031437: go = new DropLine(FILE_READ); break;
+ case 4839: go = new Tick(FILE_READ); break;
+ case 16832: go = new Label(FILE_READ); break;
+ case 1071373: go = new GridLine(FILE_READ); break;
+ case 963085: go = new DataLine(FILE_READ); break;
+ 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 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;
- case 15463: go = new Brick(FILE_READ); break;
- case 69952: go = new Line3D(FILE_READ); break;
- case 386257: go = new ellipse(FILE_READ); break;
- case 95680: go = new mLabel(FILE_READ); break;
- case 4819316: go = new PlotScatt(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;
+ case 15463: go = new Brick(FILE_READ); break;
+ case 69952: go = new Line3D(FILE_READ); break;
+ case 386257: go = new ellipse(FILE_READ); break;
+ case 95680: go = new mLabel(FILE_READ); break;
+ case 4819316: go = new PlotScatt(FILE_READ); break;
case 117848: go = new xyStat(FILE_READ); break;
- case 15935312: go = new BubblePlot(FILE_READ); break;
- case 247376: go = new BoxPlot(FILE_READ); break;
- case 317384: go = new StackBar(FILE_READ); break;
- case 1205932: go = new PieChart(FILE_READ); break;
- case 16664: go = new Graph(FILE_READ); break;
- case 25108: go = new GoGroup(FILE_READ); break;
- case 300976: go = new Scatt3D(FILE_READ); break;
- case 297280: go = new Plane3D(FILE_READ); break;
- case 19227098: go = new Regression(FILE_READ); break;
- case 297997: go = new RegLine(FILE_READ); break;
- case 4318417: go = new SDellipse(FILE_READ); break;
- case 4843600: go = new PolarPlot(FILE_READ); break;
- case 977452: go = new DensDisp(FILE_READ); break;
- case 4465: go = new Page(FILE_READ); break;
- case 75120: go = new Plot3D(FILE_READ); break;
- case 17142080: go = new GridLine3D(FILE_READ); break;
- case 246688: go = new Arrow3D(FILE_READ); break;
- case 75562: go = new Ribbon(FILE_READ); break;
- case 16503104: go = new DropLine3D(FILE_READ); break;
- case 28859579: go = new svgOptions(FILE_READ); break;
- case 70259: go = new Limits(FILE_READ); break;
- case 17145824: go = new GridRadial(FILE_READ); break;
- case 1074714: go = new Function(FILE_READ); break;
- case 256075: go = new FitFunc(FILE_READ); break;
- case 273377: go = new LegItem(FILE_READ); break;
+ case 15935312: go = new BubblePlot(FILE_READ); break;
+ case 247376: go = new BoxPlot(FILE_READ); break;
+ case 317384: go = new StackBar(FILE_READ); break;
+ case 1205932: go = new PieChart(FILE_READ); break;
+ case 16664: go = new Graph(FILE_READ); break;
+ case 25108: go = new GoGroup(FILE_READ); break;
+ case 300976: go = new Scatt3D(FILE_READ); break;
+ case 297280: go = new Plane3D(FILE_READ); break;
+ case 19227098: go = new Regression(FILE_READ); break;
+ case 297997: go = new RegLine(FILE_READ); break;
+ case 4318417: go = new SDellipse(FILE_READ); break;
+ case 4843600: go = new PolarPlot(FILE_READ); break;
+ case 977452: go = new DensDisp(FILE_READ); break;
+ case 4465: go = new Page(FILE_READ); break;
+ case 75120: go = new Plot3D(FILE_READ); break;
+ case 17142080: go = new GridLine3D(FILE_READ); break;
+ case 246688: go = new Arrow3D(FILE_READ); break;
+ case 75562: go = new Ribbon(FILE_READ); break;
+ case 16503104: go = new DropLine3D(FILE_READ); break;
+ case 28859579: go = new svgOptions(FILE_READ); break;
+ case 70259: go = new Limits(FILE_READ); break;
+ case 17145824: go = new GridRadial(FILE_READ); break;
+ case 1074714: go = new Function(FILE_READ); break;
+ case 256075: go = new FitFunc(FILE_READ); break;
+ case 273377: go = new LegItem(FILE_READ); break;
case 1053744: go = new FreqDist(FILE_READ); break;
case 68748: go = new Legend(FILE_READ); break;
- case 66800: go = new Grid3D(FILE_READ); break;
+ case 66800: go = new Grid3D(FILE_READ); break;
case 967843: go = new DefsRW(FILE_READ); break;
- case 66848: go = new Func3D(FILE_READ); break;
- default:
- sprintf(debug, "Object %ld in file\n(Class = \"%s\")\nhash #%d\nis unknown.",
- id, tmp, hv);
- InfoBox(debug);
- }
- if(go) {
- if(((int)id) < 0) DeleteGO(go); //temporary objects have id < 0
- else if(!Notary->PushGO(lid = id, go)) DeleteGO(go);
- }
- if('[' != Cache->Lastc()) do { //search next object
- c = Cache->Getc();
- } while(c && c != '[');
- tmp[0] = 0;
- }while (c);
- Cache->Close();
- if((go = Notary->PopGO(lid))) {
- go->Command(CMD_SET_DATAOBJ, 0L, 0L);
+ case 66848: go = new Func3D(FILE_READ); break;
+ case 5001225: go = new TextFrame(FILE_READ); break;
+ default:
+#ifdef USE_WIN_SECURE
+ sprintf_s(debug, 80, "Object %ld in file\n(Class = \"%s\")\nhash #%d\nis unknown.", id, tmp, hv);
+#else
+ sprintf(debug, "Object %ld in file\n(Class = \"%s\")\nhash #%d\nis unknown.", id, tmp, hv);
+#endif
+ InfoBox(debug);
+ }
+ if(go) {
+ if(((int)id) < 0) DeleteGO(go); //temporary objects have id < 0
+ else if(!Notary->PushGO(lid = id, go)) DeleteGO(go);
+ }
+ if('[' != Cache->Lastc()) do { //search next object
+ c = Cache->Getc();
+ } while(c && c != '[');
+ tmp[0] = 0;
+ }while (c);
+ Cache->Close();
+ if((LastOpenGO = go = Notary->PopGO(lid))) {
+ go->Command(CMD_SET_DATAOBJ, 0L, 0L);
delete Notary; Notary = 0L;
if(bPaste && root->Command(CMD_PASTE_OBJ, (void *)go, 0L)) {
// object accepted
@@ -941,1141 +1035,1204 @@ bool OpenGraph(GraphObj *root, char *name, unsigned char *mem, bool bPaste)
else if(go->Id >= GO_GRAPH
&& !(root->Command(CMD_DROP_GRAPH, (void *)go, 0L))){
DeleteGO(go); go = 0L;
- }
- if(go) go->Command(CMD_FILENAME, name, 0L);
- }
- if(Notary) delete Notary; Notary = 0L;
- delete Cache; Cache = 0L;
- return true;
-
-ReadErr:
- Cache->Close();
- close(iFile);
- delete Notary;
- Notary = 0L;
- delete Cache;
- Cache = 0L;
- if(!name || !defs.IniFile || strcmp(name, defs.IniFile))
- ErrorBox("An error occured during read.");
- return false;
-}
-
-bool InitVarsGO(descIO *Desc)
-{
- int i;
- AxisDEF *ax;
- TextDEF *tx;
-
- for(i = 0; Desc[i].label; i++) {
- switch(Desc[i].type & 0xff) {
- case typNZINT:
- case typINT:
- *(int*)Desc[i].ptr = 0;
- break;
- case typNZLFLOAT:
- case typLFLOAT:
- *(double*)Desc[i].ptr = 0.0;
- break;
- case typDWORD:
- *(DWORD*)Desc[i].ptr = 0x0L;
- break;
- case typULONG:
- *(unsigned long*)Desc[i].ptr = 0L;
- break;
- case typFRECT:
- ((fRECT*)Desc[i].ptr)->Xmin = ((fRECT*)Desc[i].ptr)->Xmax =
- ((fRECT*)Desc[i].ptr)->Ymin = ((fRECT*)Desc[i].ptr)->Ymax = 0.0;
- break;
- case typNZLFPOINT:
- case typLFPOINT:
- ((lfPOINT*)Desc[i].ptr)->fx = ((lfPOINT*)Desc[i].ptr)->fy = 0.0;
- break;
- case typPOINT3D:
- ((fPOINT3D*)Desc[i].ptr)->fx = ((fPOINT3D*)Desc[i].ptr)->fy =
- ((fPOINT3D*)Desc[i].ptr)->fz = 0.0;
- break;
- case typPTRAXDEF:
- case typAXDEF:
- ax = (Desc[i].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[i].ptr : *(AxisDEF **)Desc[i].ptr;
- if(!ax) break;
- ax->owner = 0L; ax->flags = 0L; ax->breaks = 0L; ax->nBreaks = 0;
- ax->min = ax->max = ax->Start = ax->Step = 0.0f;
- ax->loc[0].fx = ax->loc[0].fy = ax->loc[0].fz = 0.0f;
- ax->loc[1].fx = ax->loc[1].fy = ax->loc[1].fz = 0.0f;
- ax->Center.fx = ax->Center.fy = ax->Radius = 0.0f;
- break;
- case typLINEDEF:
- ((LineDEF*)Desc[i].ptr)->width = defs.GetSize(SIZE_HAIRLINE);
- ((LineDEF*)Desc[i].ptr)->patlength = defs.GetSize(SIZE_PATLENGTH);
- ((LineDEF*)Desc[i].ptr)->color = ((LineDEF*)Desc[i].ptr)->pattern = 0x0L;
- break;
- case typFILLDEF:
- ((FillDEF*)Desc[i].ptr)->type = FILL_NONE;
- ((FillDEF*)Desc[i].ptr)->color = 0x00ffffffL;
- ((FillDEF*)Desc[i].ptr)->scale = 1.0f;
- ((FillDEF*)Desc[i].ptr)->hatch = (LineDEF*)0L;
- ((FillDEF*)Desc[i].ptr)->color2 = 0x00ffffffL;
- break;
- case typGOBJ:
- *(GraphObj **)Desc[i].ptr = (GraphObj*)0L;
- break;
- case typOBJLST:
- *Desc[i].count = 0L;
- *(GraphObj ***)Desc[i].ptr = (GraphObj**)0L;
- break;
- case typIPLST:
- *Desc[i].count = 0L;
- *(POINT **)Desc[i].ptr = (POINT*)0L;
- break;
- case typFPLST:
- *Desc[i].count = 0L;
- *(lfPOINT **)Desc[i].ptr = (lfPOINT*)0L;
- break;
- case typFPLST3D:
- *Desc[i].count = 0L;
- *(fPOINT3D **)Desc[i].ptr = (fPOINT3D*)0L;
- break;
- case typTEXT:
- *(char **)Desc[i].ptr = (char*)0L;
- break;
- case typTXTDEF:
- tx = (TextDEF *)Desc[i].ptr;
- tx->ColTxt = 0x0L, tx->ColBg = 0x00ffffffL;
- tx->fSize = defs.GetSize(SIZE_TEXT);
- tx->RotBL = tx->RotCHAR = 0.0;
- tx->Align = tx->Mode = tx->Style = tx->Font = 0L;
- tx->text = 0L;
- break;
- case typPTRTXTDEF:
- *(TextDEF**)Desc[i].ptr = (TextDEF*)0L;
- break;
- }
- if(Desc[i].type & typLAST) break;
- }
- return true;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Save object data to memory block
-static unsigned char *SavVarBuf = 0L;
-static long SavVarSize = 0, SavVarPos = 0;
-void SavVarInit(long len)
-{
- if(SavVarBuf) free(SavVarBuf);
- SavVarBuf = (unsigned char *)malloc(SavVarSize = len+4096);
- SavVarPos = 0;
-}
-
-bool SavVarAdd(void *ptr, int size)
-{
- int len;
-
- if(SavVarBuf) {
- len = sizeof(unsigned char *) + sizeof(int) + size;
- while (SavVarSize <= SavVarPos+len) {
- if(!(SavVarBuf = (unsigned char *)realloc(SavVarBuf, SavVarSize + 4096))) return false;
- SavVarSize += 4096;
- }
- memcpy(SavVarBuf+SavVarPos, &ptr, sizeof(unsigned char *));
- SavVarPos += sizeof(unsigned char *);
- memcpy(SavVarBuf+SavVarPos, &size, sizeof(int)); SavVarPos += sizeof(int);
- memcpy(SavVarBuf+SavVarPos, ptr, size); SavVarPos += size;
- return true;
- }
- return false;
-}
-
-void *SavVarFetch()
-{
- void *tmp;
-
- SavVarAdd(0L, 0);
- tmp = SavVarBuf = (unsigned char *)realloc(SavVarBuf, SavVarPos);
- SavVarSize = SavVarPos = 0; SavVarBuf = 0L;
- return tmp;
-}
-
-bool SaveVarGO(descIO *Desc)
-{
- int i;
- AxisDEF *ax;
- TextDEF *tx;
-
- for(i = 0; Desc[i].label; i++) {
- switch(Desc[i].type & 0xff){
- case typNZINT:
- case typINT:
- SavVarAdd(Desc[i].ptr, sizeof(int));
- break;
- case typNZLFLOAT:
- case typLFLOAT:
- SavVarAdd(Desc[i].ptr, sizeof(double));
- break;
- case typDWORD:
- SavVarAdd(Desc[i].ptr, sizeof(DWORD));
- break;
- case typULONG:
- SavVarAdd(Desc[i].ptr, sizeof(unsigned long));
- break;
- case typFRECT:
- SavVarAdd(Desc[i].ptr, sizeof(fRECT));
- break;
- case typNZLFPOINT:
- case typLFPOINT:
- SavVarAdd(Desc[i].ptr, sizeof(lfPOINT));
- break;
- case typPOINT3D:
- SavVarAdd(Desc[i].ptr, sizeof(fPOINT3D));
- break;
- case typAXDEF:
- case typPTRAXDEF:
- ax = (Desc[i].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[i].ptr : *(AxisDEF **)Desc[i].ptr;
- if(ax) {
- SavVarAdd(ax, sizeof(AxisDEF));
- if(ax->breaks && ax->nBreaks) {
- SavVarAdd(ax->breaks, ax->nBreaks * sizeof(lfPOINT));
- }
- }
- break;
- case typLINEDEF:
- SavVarAdd(Desc[i].ptr, sizeof(LineDEF));
- break;
- case typFILLDEF:
- SavVarAdd(Desc[i].ptr, sizeof(FillDEF));
- break;
- case typGOBJ: case typOBJLST: //not supported
- break;
- case typIPLST: //probably in the future
- break;
- case typFPLST:
- break;
- case typFPLST3D:
- SavVarAdd(*((void **)Desc[i].ptr), sizeof(fPOINT3D) * (*Desc[i].count));
- break;
- case typTEXT:
- if(*(char**)(Desc[i].ptr)) SavVarAdd(Desc[i].ptr, strlen(*(char**)(Desc[i].ptr))+1);
- break;
- case typTXTDEF:
- case typPTRTXTDEF:
- tx = (Desc[i].type &0xff) == typTXTDEF ? (TextDEF *)Desc[i].ptr : *(TextDEF **)Desc[i].ptr;
- if(tx) SavVarAdd(tx, sizeof(TextDEF) - sizeof(char*));
- break;
- }
- if(Desc[i].type & typLAST) break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Graphic object member funtions for IO
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-bool
-svgOptions::FileIO(int rw)
-{
- descIO Desc[] = {
- {"tagAttr", typTEXT, &svgattr, 0L},
- {"Script", typLAST | typTEXT, &script, 0L}};
-
- switch(rw) {
- case INIT_VARS:
- return InitVarsGO(Desc);
- case FILE_READ:
- return ExecInput(Desc);
- }
- return false;
-}
-
-bool
-Symbol::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"Idx", typINT, &idx, 0L},
- {"Pos", typLFPOINT, &fPos, 0L},
- {"Size", typLFLOAT, &size, 0L},
- {"Line", typLINEDEF, &SymLine, 0L},
- {"FillCol", typDWORD, &SymFill.color, 0L},
- {"Text", typPTRTXTDEF, &SymTxt, 0L},
- {"Name", typLAST | typTEXT, &name, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- size = parent ? parent->GetSize(SIZE_SYMBOL): defs.GetSize(SIZE_SYMBOL);
- SymLine.color = parent ? parent->GetColor(COL_SYM_LINE) : defs.Color(COL_SYM_LINE);
- SymLine.width = parent ? parent->GetSize(SIZE_SYM_LINE) : defs.GetSize(SIZE_SYM_LINE);
- SymFill.type = FILL_NONE;
- SymFill.color = parent ? parent->GetColor(COL_SYM_FILL) : defs.Color(COL_SYM_FILL);
- SymFill.scale = 1.0f;
- SymFill.hatch = (LineDEF *) 0L;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- SymFill.hatch = (LineDEF *) 0L;
- return true;
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Symbol", Desc);
- }
- return false;
-}
-
-
-bool
-Bubble::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"Pos", typLFPOINT, &fPos, 0L},
- {"Size", typLFLOAT, &fs, 0L},
- {"Line", typLINEDEF, &BubbleLine, 0L},
- {"FillLine", typLINEDEF, &BubbleFillLine, 0L},
- {"Fill", typFILLDEF, &BubbleFill, 0L},
- {"Name", typLAST | typTEXT, &name, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- BubbleLine.width = defs.GetSize(SIZE_BUBBLE_LINE);
- BubbleFillLine.width = defs.GetSize(SIZE_BUBBLE_HATCH_LINE);
- BubbleLine.color = BubbleFillLine.color = defs.Color(COL_BUBBLE_LINE);
- BubbleFill.color = defs.Color(COL_BUBBLE_FILL);
- ssRef = 0L;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- BubbleFill.hatch = &BubbleFillLine;
- return true;
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Bubble", Desc);
- }
- return false;
-}
-
-bool
-Bar::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"Pos", typLFPOINT, &fPos, 0L},
- {"Size", typLFLOAT, &size, 0L},
- {"Org", typLFPOINT, &BarBase, 0L},
- {"Line", typLINEDEF, &BarLine, 0L},
- {"Fill", typFILLDEF, &BarFill, 0L},
- {"FillLine", typLINEDEF, &HatchLine, 0L},
- {"Name", typLAST | typTEXT, &name, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- type = BAR_VERTB;
- memcpy(&BarFill, defs.GetFill(), sizeof(FillDEF));
- if(BarFill.hatch) memcpy(&HatchLine, BarFill.hatch, sizeof(LineDEF));
- BarFill.hatch = &HatchLine;
- memcpy(&BarLine, defs.GetOutLine(), sizeof(LineDEF));
- size = parent ? parent->GetSize(SIZE_BAR): defs.GetSize(SIZE_BAR);
- mo = 0L;
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- BarFill.hatch = &HatchLine;
- return true;
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Bar", Desc);
- }
- return false;
-}
-
-void
-DataLine::FileValues(char *name, int type, double start, double step)
-{
- FILE *file;
- int i, c;
- double fx;
- lfPOINT *tfp;
-
- if(!(file = fopen(name, "r"))) {
- sprintf(TmpTxt, "DataLine: open failed for file \"%s\"", name);
- ErrorBox(TmpTxt);
- return;
- }
- if(Values) free(Values);
- if(!(Values = (lfPOINT*)calloc( nPnt = 1000, sizeof(lfPOINT)))){
- fclose(file);
- return;
- }
- switch(type) {
- case 1: //x and y values
- i = 0;
- do {
- c = fscanf(file, "%lf%lf", &Values[i].fx, &Values[i].fy);
- i++;
- if(i >= nPnt &&(tfp = (lfPOINT*)realloc(Values, (nPnt+1000)*sizeof(lfPOINT)))){
- Values = tfp; nPnt += 1000;
- }
- else if(i >= nPnt) break;
- }while(c == 2);
- i--;
- break;
- case 2: //only y values
- i = 0; fx = start;
- do {
- c = fscanf(file, "%lf", &Values[i].fy);
- Values[i].fx = fx;
- i++; fx += step;
- if(i >= nPnt &&(tfp = (lfPOINT*)realloc(Values, (nPnt+1000)*sizeof(lfPOINT)))){
- Values = tfp; nPnt += 1000;
- }
- }while(c == 1);
- i--;
- break;
- }
- nPntSet = i-1;
- fclose(file);
-}
-
-bool
-DataLine::FileIO(int rw)
-{
- long i;
- char *file1 = 0L;
- char *file2 = 0L;
- double Start = 0.0f, Step = 0.0f;
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssXref", typTEXT, &ssXref, 0L},
- {"ssYref", typTEXT, &ssYref, 0L},
- {"BgCol", typDWORD, &BgColor, 0L},
- {"Line", typLINEDEF, &LineDef, 0L},
- {"Data", typFPLST, &Values, &i},
- {"file_xy", typTEXT, &file2, 0L},
- {"start_x", typNZLFLOAT, &Start, 0L},
- {"step_x", typNZLFLOAT, &Step, 0L},
- {"file_y", typLAST | typTEXT, &file1, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- isPolygon = false;
- nPnt = nPntSet = cp = 0;
- memcpy(&LineDef, defs.GetLine(), sizeof(LineDEF));
- BgColor = defs.Color(COL_BG);
- pts = 0L; dirty = true; mo = 0L;
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- min.fx = min.fy = max.fx = max.fy = 0.0;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- nPnt = i;
- nPntSet = i-1;
- if(file2)FileValues(file2, 1, 0.0, 1.0);
- else if(file1)FileValues(file1, 2, Start, fabs(Step) > defs.min4log ? Step : 1.0);
- if(file1) free(file1);
- if(file2) free(file2);
- if(i && Values)return true;
- break;
- case FILE_WRITE:
- i = nPntSet+1;
- return ExecOutput(Notary->RegisterGO(this), "DataLine", Desc);
- }
- return false;
-}
-
-bool
-DataPolygon::FileIO(int rw)
-{
- long i;
- char *file1 = 0L;
- char *file2 = 0L;
- double Start = 0.0f, Step = 0.0f;
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssXref", typTEXT, &ssXref, 0L},
- {"ssYref", typTEXT, &ssYref, 0L},
- {"BgCol", typDWORD, &BgColor, 0L},
- {"Line", typLINEDEF, &LineDef, 0L},
- {"FillLine", typLINEDEF, &pgFillLine, 0L},
- {"Fill", typFILLDEF, &pgFill, 0L},
- {"Data", typFPLST, &Values, &i},
- {"file_xy", typTEXT, &file2, 0L},
- {"start_x", typNZLFLOAT, &Start, 0L},
- {"step_x", typNZLFLOAT, &Step, 0L},
- {"file_y", typLAST | typTEXT, &file1, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- isPolygon = true;
- memcpy(&LineDef, defs.GetLine(), sizeof(LineDEF));
- LineDef.pattern = 0L;
- BgColor = defs.Color(COL_BG);
- memcpy(&pgFill, defs.GetFill(), sizeof(FillDEF));
- if(pgFill.hatch) memcpy(&pgFillLine, pgFill.hatch, sizeof(LineDEF));
- pgFill.hatch = &pgFillLine; dirty = true; mo = 0L;
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- min.fx = min.fy = max.fx = max.fy = 0.0f;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- nPnt = i;
- nPntSet = i-1;
- if(file2)FileValues(file2, 1, 0.0f, 1.0f);
- else if(file1)FileValues(file1, 2, Start, fabs(Step) > defs.min4log ? Step : 1.0);
- if(file1) free(file1);
- if(file2) free(file2);
- pgFill.hatch = &pgFillLine;
- if(i && Values)return true;
- break;
- case FILE_WRITE:
- i = nPntSet+1;
- return ExecOutput(Notary->RegisterGO(this), "DataPolygon", Desc);
- }
- return false;
-}
-
-bool
-RegLine::FileIO(int rw)
-{
- descIO Desc[] = {
- {"type", typNZINT, &type, 0L},
- {"nPoints", typINT, &nPoints, 0L},
- {"BgCol", typDWORD, &BgColor, 0L},
- {"Line", typLINEDEF, &LineDef, 0L},
- {"Range", typFRECT, &lim, 0L},
- {"uClip", typFRECT, &uclip, 0L},
- {"mx", typNZLFLOAT, &mx, 0L},
- {"my", typNZLFLOAT, &my, 0L},
- {"li1", typLFPOINT, &l1, 0L},
- {"li2", typLFPOINT, &l2, 0L},
- {"li3", typLFPOINT, &l3, 0L},
- {"li4", typLFPOINT, &l4, 0L},
- {"li5", typLAST | typLFPOINT, &l5, 0L}};
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- cp = 0;
- memcpy(&LineDef, defs.GetLine(), sizeof(LineDEF));
- BgColor = defs.Color(COL_BG);
- pts = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "RegLine", Desc);
- }
- return false;
-}
+ }
+ if(go) go->Command(CMD_FILENAME, name, 0L);
+ }
+ if(Notary) delete Notary; Notary = 0L;
+ delete Cache; Cache = 0L;
+ return true;
-void
-SDellipse::RegGO(void *n)
+ReadErr:
+ Cache->Close();
+#ifdef USE_WIN_SECURE
+ if(iFile >= 0) _close(iFile);
+#else
+ if(iFile >= 0) close(iFile);
+#endif
+ iFile = -1;
+ delete Notary; Notary = 0L;
+ delete Cache; Cache = 0L;
+ if(!name || !defs.IniFile || strcmp(name, defs.IniFile))
+ ErrorBox("An error occured during read.");
+ return false;
+}
+
+bool InitVarsGO(descIO *Desc)
{
- if(n) {
- if(rl)rl->RegGO(n);
- ((notary*)n)->AddRegGO(this);
- }
+ int i;
+ AxisDEF *ax;
+ TextDEF *tx;
+
+ for(i = 0; Desc[i].label; i++) {
+ switch(Desc[i].type & 0xff) {
+ case typNZINT:
+ case typINT:
+ *(int*)Desc[i].ptr = 0;
+ break;
+ case typNZLFLOAT:
+ case typLFLOAT:
+ *(double*)Desc[i].ptr = 0.0;
+ break;
+ case typDWORD:
+ *(DWORD*)Desc[i].ptr = 0x0L;
+ break;
+ case typFRECT:
+ ((fRECT*)Desc[i].ptr)->Xmin = ((fRECT*)Desc[i].ptr)->Xmax =
+ ((fRECT*)Desc[i].ptr)->Ymin = ((fRECT*)Desc[i].ptr)->Ymax = 0.0;
+ break;
+ case typNZLFPOINT:
+ case typLFPOINT:
+ ((lfPOINT*)Desc[i].ptr)->fx = ((lfPOINT*)Desc[i].ptr)->fy = 0.0;
+ break;
+ case typPOINT3D:
+ ((fPOINT3D*)Desc[i].ptr)->fx = ((fPOINT3D*)Desc[i].ptr)->fy =
+ ((fPOINT3D*)Desc[i].ptr)->fz = 0.0;
+ break;
+ case typPTRAXDEF:
+ case typAXDEF:
+ ax = (Desc[i].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[i].ptr : *(AxisDEF **)Desc[i].ptr;
+ if(!ax) break;
+ ax->owner = 0L; ax->flags = 0L; ax->breaks = 0L; ax->nBreaks = 0;
+ ax->min = ax->max = ax->Start = ax->Step = 0.0f;
+ ax->loc[0].fx = ax->loc[0].fy = ax->loc[0].fz = 0.0f;
+ ax->loc[1].fx = ax->loc[1].fy = ax->loc[1].fz = 0.0f;
+ ax->Center.fx = ax->Center.fy = ax->Radius = 0.0f;
+ break;
+ case typLINEDEF:
+ ((LineDEF*)Desc[i].ptr)->width = defs.GetSize(SIZE_HAIRLINE);
+ ((LineDEF*)Desc[i].ptr)->patlength = defs.GetSize(SIZE_PATLENGTH);
+ ((LineDEF*)Desc[i].ptr)->color = ((LineDEF*)Desc[i].ptr)->pattern = 0x0L;
+ break;
+ case typFILLDEF:
+ ((FillDEF*)Desc[i].ptr)->type = FILL_NONE;
+ ((FillDEF*)Desc[i].ptr)->color = 0x00ffffffL;
+ ((FillDEF*)Desc[i].ptr)->scale = 1.0f;
+ ((FillDEF*)Desc[i].ptr)->hatch = (LineDEF*)0L;
+ ((FillDEF*)Desc[i].ptr)->color2 = 0x00ffffffL;
+ break;
+ case typGOBJ:
+ *(GraphObj **)Desc[i].ptr = (GraphObj*)0L;
+ break;
+ case typOBJLST:
+ *Desc[i].count = 0L;
+ *(GraphObj ***)Desc[i].ptr = (GraphObj**)0L;
+ break;
+ case typIPLST:
+ *Desc[i].count = 0L;
+ *(POINT **)Desc[i].ptr = (POINT*)0L;
+ break;
+ case typFPLST:
+ *Desc[i].count = 0L;
+ *(lfPOINT **)Desc[i].ptr = (lfPOINT*)0L;
+ break;
+ case typFPLST3D:
+ *Desc[i].count = 0L;
+ *(fPOINT3D **)Desc[i].ptr = (fPOINT3D*)0L;
+ break;
+ case typTEXT:
+ *(char **)Desc[i].ptr = (char*)0L;
+ break;
+ case typTXTDEF:
+ tx = (TextDEF *)Desc[i].ptr;
+ tx->ColTxt = 0x0L, tx->ColBg = 0x00ffffffL;
+ tx->fSize = defs.GetSize(SIZE_TEXT);
+ tx->RotBL = tx->RotCHAR = 0.0;
+ tx->Align = tx->Mode = tx->Style = tx->Font = 0L;
+ tx->text = 0L;
+ break;
+ case typPTRTXTDEF:
+ *(TextDEF**)Desc[i].ptr = (TextDEF*)0L;
+ break;
+ }
+ if(Desc[i].type & typLAST) break;
+ }
+ return true;
}
-bool
-SDellipse::FileIO(int rw)
-{
- descIO Desc[] = {
- {"type", typNZINT, &type, 0L},
- {"Line", typLINEDEF, &LineDef, 0L},
- {"Range", typFRECT, &lim, 0L},
- {"Regr", typGOBJ, &rl, 0L},
- {"Data", typLAST | typFPLST, &val, &nPoints}};
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- memcpy(&LineDef, defs.GetOutLine(), sizeof(LineDEF));
- pts = 0L;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- if(rl) rl->parent = this;
- return true;
- case FILE_WRITE:
- if(rl) rl->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "SDellipse", Desc);
- }
- return false;
-}
-
-bool
-ErrorBar::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"Pos", typLFPOINT, &fPos, 0L},
- {"Err", typLFLOAT, &ferr, 0L},
- {"Size", typLFLOAT, &SizeBar, 0L},
- {"Line", typLINEDEF, &ErrLine, 0L},
- {"Desc", typLAST | typTEXT, &name, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- 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);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "ErrorBar", Desc);
- }
- return false;
-}
-
-bool
-Arrow::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"moveable", typNZINT, &moveable, 0L},
- {"p1", typLFPOINT, &pos1, 0L},
- {"p2", typLFPOINT, &pos2, 0L},
- {"CapW", typLFLOAT, &cw, 0L},
- {"CapL", typLFLOAT, &cl, 0L},
- {"Line", typLAST | typLINEDEF, &LineDef, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- cw = defs.GetSize(SIZE_ARROW_CAPWIDTH);
- cl = defs.GetSize(SIZE_ARROW_CAPLENGTH);
- LineDef.color = parent ? parent->GetColor(COL_DATA_LINE) : defs.Color(COL_DATA_LINE);
- LineDef.width = parent ? parent->GetSize(SIZE_ARROW_LINE) : defs.GetSize(SIZE_ARROW_LINE);
- type = ARROW_LINE;
- dh1 = dh2 = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Arrow", Desc);
- }
- return false;
-}
-
-bool
-Box::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"High", typLFPOINT, &pos1, 0L},
- {"Low", typLFPOINT, &pos2, 0L},
- {"Size", typLFLOAT, &size, 0L},
- {"Line", typLINEDEF, &Outline, 0L},
- {"FillLine", typLINEDEF, &Hatchline, 0L},
- {"Fill", typFILLDEF, &Fill, 0L},
- {"Name", typLAST | typTEXT, &name, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- memcpy(&Outline, defs.GetOutLine(), sizeof(LineDEF));
- memcpy(&Fill, defs.GetFill(), sizeof(FillDEF));
- if(Fill.hatch)memcpy(&Hatchline, Fill.hatch, sizeof(LineDEF));
- Fill.hatch = &Hatchline;
- size = defs.GetSize(SIZE_BAR);
- ssRef = 0L;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- Fill.hatch = &Hatchline;
- return true;
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Box", Desc);
- }
- return false;
-}
-
-bool
-Whisker::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"High", typLFPOINT, &pos1, 0L},
- {"Low", typLFPOINT, &pos2, 0L},
- {"Size", typLFLOAT, &size, 0L},
- {"Line", typLINEDEF, &LineDef, 0L},
- {"Desc", typLAST | typTEXT, &name, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- 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);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Whisker", Desc);
- }
- return false;
-}
-
-bool
-DropLine::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typINT, &type, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"Pos", typLFPOINT, &fPos, 0L},
- {"Line", typLAST | typLINEDEF, &LineDef, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- LineDef.color = defs.Color(COL_SYM_LINE);
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "DropLine", Desc);
- }
- return false;
-}
-
-bool
-Sphere::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"Line", typLINEDEF, &Line, 0L},
- {"Fill", typFILLDEF, &Fill, 0L},
- {"Pos", typPOINT3D, &fPos, 0L},
- {"Size", typLFLOAT, &size, 0L},
- {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- size = defs.GetSize(SIZE_SYMBOL);
- Line.color = defs.Color(COL_SYM_LINE);
- Line.width = defs.GetSize(SIZE_SYM_LINE);
- Fill.color = defs.Color(COL_SYM_FILL);
- scl = 0L; nscl = 0;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Sphere", Desc);
- }
- return false;
-}
-
-bool
-Plane3D::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Line", typLINEDEF, &Line, 0L},
- {"Fill", typFILLDEF, &Fill, 0L},
- {"values", typLAST | typFPLST3D, &dt, &ndt}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- ipl = 0L; pts = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Plane3D", Desc);
- }
- return false;
-}
-
-bool
-Brick::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Line", typLINEDEF, &Line, 0L},
- {"Fill", typFILLDEF, &Fill, 0L},
- {"Pos", typPOINT3D, &fPos, 0L},
- {"depth", typLFLOAT, &depth, 0L},
- {"width", typLFLOAT, &width, 0L},
- {"height", typLFLOAT, &height, 0L},
- {"flags", typDWORD, &flags, 0L},
- {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- Line.color = defs.Color(COL_SYM_LINE);
- Line.width = defs.GetSize(SIZE_SYM_LINE);
- Fill.color = defs.Color(COL_SYM_FILL);
- faces = (plane**)calloc(6, sizeof(plane*));
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- mo = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Brick", Desc);
- }
- return false;
-}
-
-bool
-DropLine3D::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typINT, &type, 0L},
- {"Line", typLINEDEF, &Line, 0L},
- {"Pos", typPOINT3D, &fPos, 0L},
- {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- Line.color = defs.Color(COL_SYM_LINE);
- Line.width = defs.GetSize(SIZE_HAIRLINE); mo = 0L;
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- ls[0] = ls[1] = ls[2] = ls[3] = ls[4] = ls[5] = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "DropLine3D", Desc);
- }
- return false;
-}
-
-bool
-Arrow3D::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typINT, &type, 0L},
- {"Line", typLINEDEF, &Line, 0L},
- {"Org", typPOINT3D, &fPos1, 0L},
- {"Pos", typPOINT3D, &fPos2, 0L},
- {"CapW", typLFLOAT, &cw, 0L},
- {"CapL", typLFLOAT, &cl, 0L},
- {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- cw = defs.GetSize(SIZE_ARROW_CAPWIDTH);
- cl = defs.GetSize(SIZE_ARROW_CAPLENGTH);
- Line.color = defs.Color(COL_ARROW);
- Line.width = defs.GetSize(SIZE_ARROW_LINE);
- ls[0] = ls[1] = ls[2] = 0L;
- cap = 0L;
- type = ARROW_LINE;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Arrow3D", Desc);
- }
- return false;
-}
-
-bool
-Line3D::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Line", typLINEDEF, &Line, 0L},
- {"ssRefX", typTEXT, &x_range, 0L},
- {"ssRefY", typTEXT, &y_range, 0L},
- {"ssRefZ", typTEXT, &z_range, 0L},
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"values", typLAST | typFPLST3D, &values, &nPts}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- Line.color = defs.Color(COL_DATA_LINE);
- Line.width = defs.GetSize(SIZE_DATA_LINE);
- ls = 0L; pts = 0L; npts = 0L; mo=0L;
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- min.fx = min.fy = min.fz = max.fx = max.fy = max.fz = 0.0;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- if(nPts > 1) ls = (line_segment **)calloc(nPts-1, sizeof(line_segment*));
- return true;
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Line3D", Desc);
- }
- return false;
-}
-
-bool
-Label::FileIO(int rw)
-{
- descIO Desc[] = {
- {"ssRef", typIPLST, &ssRef, &cssRef},
- {"moveable", typNZINT, &moveable, 0L},
- {"Pos", typNZLFPOINT, &fPos, 0L},
- {"Dist", typNZLFPOINT, &fDist, 0L},
- {"Flags", typDWORD, &flags, 0L},
- {"TxtDef", typLAST | typTXTDEF, &TextDef, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- TextDef.ColTxt = 0x0L;
- TextDef.ColBg = 0x00ffffffL;
- TextDef.fSize = defs.GetSize(SIZE_TEXT);
- TextDef.RotBL = TextDef.RotCHAR = 0.0;
- TextDef.iSize = 0;
- TextDef.Align = TXA_VTOP | TXA_HLEFT;
- TextDef.Mode = TXM_TRANSPARENT;
- TextDef.Style = TXS_NORMAL;
- TextDef.Font = FONT_HELVETICA;
- TextDef.text = 0L; bgcolor = 0x00ffffffL;
- bgLine.width = 0.0; bgLine.patlength = 6.0;
- bgLine.color = bgcolor; bgLine.pattern = 0L;
- CursorPos = 0; defDisp = 0L; bBGvalid = bModified = false;
- curr_z = 0.0; is3D = false; fmt_txt = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Label", Desc);
- }
- return false;
-}
-
-void
-mLabel::RegGO(void *n)
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Save object data to memory block
+static unsigned char *SavVarBuf = 0L;
+static long SavVarSize = 0, SavVarPos = 0;
+void SavVarInit(long len)
+{
+ if(SavVarBuf) free(SavVarBuf);
+ SavVarBuf = (unsigned char *)malloc(SavVarSize = len+4096);
+ SavVarPos = 0;
+}
+
+bool SavVarAdd(void *ptr, int size)
+{
+ int len;
+
+ if(SavVarBuf) {
+ len = sizeof(unsigned char *) + sizeof(int) + size;
+ while (SavVarSize <= SavVarPos+len) {
+ if(!(SavVarBuf = (unsigned char *)realloc(SavVarBuf, SavVarSize + 4096))) return false;
+ SavVarSize += 4096;
+ }
+ memcpy(SavVarBuf+SavVarPos, &ptr, sizeof(unsigned char *));
+ SavVarPos += sizeof(unsigned char *);
+ memcpy(SavVarBuf+SavVarPos, &size, sizeof(int)); SavVarPos += sizeof(int);
+ memcpy(SavVarBuf+SavVarPos, ptr, size); SavVarPos += size;
+ return true;
+ }
+ return false;
+}
+
+void *SavVarFetch()
+{
+ void *tmp;
+
+ SavVarAdd(0L, 0);
+ tmp = SavVarBuf = (unsigned char *)realloc(SavVarBuf, SavVarPos);
+ SavVarSize = SavVarPos = 0; SavVarBuf = 0L;
+ return tmp;
+}
+
+bool SaveVarGO(descIO *Desc)
{
int i;
+ AxisDEF *ax;
+ TextDEF *tx;
- if(n) {
- if(Lines) for(i = 0; i < nLines; i++) if(Lines[i]) Lines[i]->RegGO(n);
- ((notary*)n)->AddRegGO(this);
- }
+ for(i = 0; Desc[i].label; i++) {
+ switch(Desc[i].type & 0xff){
+ case typNZINT:
+ case typINT:
+ SavVarAdd(Desc[i].ptr, sizeof(int));
+ break;
+ case typNZLFLOAT:
+ case typLFLOAT:
+ SavVarAdd(Desc[i].ptr, sizeof(double));
+ break;
+ case typDWORD:
+ SavVarAdd(Desc[i].ptr, sizeof(DWORD));
+ break;
+ case typFRECT:
+ SavVarAdd(Desc[i].ptr, sizeof(fRECT));
+ break;
+ case typNZLFPOINT:
+ case typLFPOINT:
+ SavVarAdd(Desc[i].ptr, sizeof(lfPOINT));
+ break;
+ case typPOINT3D:
+ SavVarAdd(Desc[i].ptr, sizeof(fPOINT3D));
+ break;
+ case typAXDEF:
+ case typPTRAXDEF:
+ ax = (Desc[i].type & 0xff) == typAXDEF ? (AxisDEF *)Desc[i].ptr : *(AxisDEF **)Desc[i].ptr;
+ if(ax) {
+ SavVarAdd(ax, sizeof(AxisDEF));
+ if(ax->breaks && ax->nBreaks) {
+ SavVarAdd(ax->breaks, ax->nBreaks * sizeof(lfPOINT));
+ }
+ }
+ break;
+ case typLINEDEF:
+ SavVarAdd(Desc[i].ptr, sizeof(LineDEF));
+ break;
+ case typFILLDEF:
+ SavVarAdd(Desc[i].ptr, sizeof(FillDEF));
+ break;
+ case typGOBJ: case typOBJLST: //not supported
+ break;
+ case typIPLST: //probably in the future
+ break;
+ case typFPLST:
+ break;
+ case typFPLST3D:
+ SavVarAdd(*((void **)Desc[i].ptr), sizeof(fPOINT3D) * (*Desc[i].count));
+ break;
+ case typTEXT:
+ if(*(char**)(Desc[i].ptr)) SavVarAdd(Desc[i].ptr, (int)strlen(*(char**)(Desc[i].ptr))+1);
+ break;
+ case typTXTDEF:
+ case typPTRTXTDEF:
+ tx = (Desc[i].type &0xff) == typTXTDEF ? (TextDEF *)Desc[i].ptr : *(TextDEF **)Desc[i].ptr;
+ if(tx) SavVarAdd(tx, sizeof(TextDEF) - sizeof(char*));
+ break;
+ }
+ if(Desc[i].type & typLAST) break;
+ }
+ return false;
}
-
-bool
-mLabel::FileIO(int rw)
-{
- descIO Desc[] = {
- {"moveable", typNZINT, &moveable, 0L},
- {"Pos", typNZLFPOINT, &fPos, 0L},
- {"Dist", typNZLFPOINT, &fDist, 0L},
- {"lspc", typLFLOAT, &lspc, 0L},
- {"Flags", typDWORD, &flags, 0L},
- {"TxtDef", typTXTDEF, &TextDef, 0L},
- {"Lines", typLAST | typOBJLST, &Lines, &nLines}};
- int i;
-
- switch(rw) {
- case SAVE_VARS:
- //The lines inherit settings from this object.
- //We need not save them in this context
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- TextDef.ColTxt = 0x0L;
- TextDef.ColBg = 0x00ffffffL;
- TextDef.fSize = defs.GetSize(SIZE_TEXT);
- TextDef.RotBL = TextDef.RotCHAR = 0.0;
- TextDef.iSize = 0;
- TextDef.Align = TXA_VTOP | TXA_HLEFT;
- TextDef.Mode = TXM_TRANSPARENT;
- TextDef.Style = TXS_NORMAL;
- TextDef.Font = FONT_HELVETICA;
- TextDef.text = 0L;
- undo_flags = 0L; lspc = 1.0;
- curr_z = 0.0; is3D = false;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- if(Lines) for ( i = 0; i < nLines; i++)
- if(Lines[i]) Lines[i]->parent = this;
- return true;
- case FILE_WRITE:
- if(Lines) for ( i = 0; i < nLines; i++)
- if(Lines[i]) Lines[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "mLabel", Desc);
- }
- return false;
-}
-
-bool
-segment::FileIO(int rw)
-{
- descIO Desc[] = {
- {"moveable", typNZINT, &moveable, 0L},
- {"cent", typLFPOINT, &fCent, 0L},
- {"ri", typNZLFLOAT, &radius1, 0L},
- {"ra", typLFLOAT, &radius2, 0L},
- {"start", typLFLOAT, &angle1, 0L},
- {"end", typLFLOAT, &angle2, 0L},
- {"shout", typNZLFLOAT, &shift, 0L},
- {"Line", typLINEDEF, &segLine, 0L},
- {"FillLine", typLINEDEF, &segFillLine, 0L},
- {"Fill", typLAST | typFILLDEF, &segFill, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- segLine.width = defs.GetSize(SIZE_SEGLINE);
- pts = 0L; nPts = 0;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- segFill.hatch = &segFillLine;
- return true;
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "segment", Desc);
- }
- return false;
-}
-
-bool
-polyline::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:
- InitVarsGO(Desc);
- memcpy(&pgLine, defs.plLineDEF(0L), sizeof(LineDEF));
- memcpy(&pgFill, defs.pgFillDEF(0L), sizeof(FillDEF));
- if(pgFill.hatch) memcpy(&pgFillLine, pgFill.hatch, sizeof(LineDEF));
- pgFill.hatch = &pgFillLine;
- pts = 0L; nPts = 0;
- pHandles = 0L;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- pgFill.hatch = &pgFillLine;
- return true;
- case FILE_WRITE:
- if(type != 1) Desc[3].type |= typLAST; //skip fill for polyline
- return ExecOutput(Notary->RegisterGO(this),
- type == 1 ? (char*)"polygon" : (char*)"polyline", Desc);
- }
- return false;
-}
-
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Graphic object member funtions for IO
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool
-Bezier::FileIO(int rw)
+svgOptions::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"tagAttr", typTEXT, &svgattr, 0L},
+ {"Script", typLAST | typTEXT, &script, 0L}};
+
+ switch(rw) {
+ case INIT_VARS:
+ return InitVarsGO(Desc);
+ case FILE_READ:
+ return ExecInput(Desc);
+ }
+ return false;
+}
+
+bool
+Symbol::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}};
-
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"Idx", typINT, &idx, 0L},
+ {"Pos", typLFPOINT, &fPos, 0L},
+ {"Size", typLFLOAT, &size, 0L},
+ {"Line", typLINEDEF, &SymLine, 0L},
+ {"FillCol", typDWORD, &SymFill.color, 0L},
+ {"Text", typPTRTXTDEF, &SymTxt, 0L},
+ {"Name", typLAST | typTEXT, &name, 0L}};
+
switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
case INIT_VARS:
- //assume that all initialization is done by polyline::FileIO(int rw)
+ InitVarsGO(Desc);
+ size = DefSize(SIZE_SYMBOL);
+ SymLine.color = parent ? parent->GetColor(COL_SYM_LINE) : defs.Color(COL_SYM_LINE);
+ SymLine.width = parent ? parent->GetSize(SIZE_SYM_LINE) : DefSize(SIZE_SYM_LINE);
+ SymFill.type = FILL_NONE;
+ SymFill.color = parent ? parent->GetColor(COL_SYM_FILL) : defs.Color(COL_SYM_FILL);
+ SymFill.scale = 1.0f;
+ SymFill.hatch = (LineDEF *) 0L;
return true;
case FILE_READ:
ExecInput(Desc);
- pgFill.hatch = &pgFillLine;
+ SymFill.hatch = (LineDEF *) 0L;
return true;
case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "bezier", Desc);
+ return ExecOutput(Notary->RegisterGO(this), "Symbol", Desc);
}
return false;
}
-
-bool
-rectangle::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"moveable", typNZINT, &moveable, 0L},
- {"p1", typLFPOINT, &fp1, 0L},
- {"p2", typLFPOINT, &fp2, 0L},
- {"Line", typLINEDEF, &Line, 0L},
- {"FillLine", typLINEDEF, &FillLine, 0L},
- {"Fill", typFILLDEF, &Fill, 0L},
- {"Rad", typNZLFLOAT, &rad, 0L},
- {"Name", typLAST | typTEXT, &name, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- memcpy(&Line, defs.pgLineDEF(0L), sizeof(LineDEF));
- memcpy(&Fill, defs.pgFillDEF(0L), sizeof(FillDEF));
- if(Fill.hatch) memcpy(&FillLine, Fill.hatch, sizeof(LineDEF));
- Fill.hatch = &FillLine;
- pts = 0L; nPts = 0L;
- rad = defs.GetSize(SIZE_RRECT_RAD);
- drc = 0L;
- return true;
- case FILE_READ:
- ExecInput(Desc);
- Fill.hatch = &FillLine;
- return true;
- case FILE_WRITE:
- if(type != 2) rad = 0.0;
- ExecOutput(Notary->RegisterGO(this),
- type == 1? (char*)"ellipse" : type == 2? (char*)"roundrec" :
- (char*)"rectangle", Desc);
- return true;
- }
- return false;
-}
-
+
+
+bool
+Bubble::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"Pos", typLFPOINT, &fPos, 0L},
+ {"Size", typLFLOAT, &fs, 0L},
+ {"Line", typLINEDEF, &BubbleLine, 0L},
+ {"FillLine", typLINEDEF, &BubbleFillLine, 0L},
+ {"Fill", typFILLDEF, &BubbleFill, 0L},
+ {"Name", typLAST | typTEXT, &name, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ BubbleLine.width = DefSize(SIZE_BUBBLE_LINE);
+ BubbleFillLine.width = DefSize(SIZE_BUBBLE_HATCH_LINE);
+ BubbleLine.color = BubbleFillLine.color = defs.Color(COL_BUBBLE_LINE);
+ BubbleFill.color = defs.Color(COL_BUBBLE_FILL);
+ ssRef = 0L;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ BubbleFill.hatch = &BubbleFillLine;
+ return true;
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Bubble", Desc);
+ }
+ return false;
+}
+
+bool
+Bar::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typINT, &type, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"Pos", typLFPOINT, &fPos, 0L},
+ {"Size", typLFLOAT, &size, 0L},
+ {"Org", typLFPOINT, &BarBase, 0L},
+ {"Line", typLINEDEF, &BarLine, 0L},
+ {"Fill", typFILLDEF, &BarFill, 0L},
+ {"FillLine", typLINEDEF, &HatchLine, 0L},
+ {"Name", typLAST | typTEXT, &name, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ type = BAR_VERTB;
+ memcpy(&BarFill, defs.GetFill(), sizeof(FillDEF));
+ if(BarFill.hatch) memcpy(&HatchLine, BarFill.hatch, sizeof(LineDEF));
+ BarFill.hatch = &HatchLine;
+ memcpy(&BarLine, defs.GetOutLine(), sizeof(LineDEF));
+ size = DefSize(SIZE_BAR);
+ mo = 0L;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ BarFill.hatch = &HatchLine;
+ return true;
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Bar", Desc);
+ }
+ return false;
+}
+
+void
+DataLine::FileValues(char *name, int type, double start, double step)
+{
+ FILE *file;
+ int i, c;
+ double fx;
+ lfPOINT *tfp;
+
+#ifdef USE_WIN_SECURE
+ if(fopen_s(&file, name, "r")) {
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "DataLine: open failed for file \"%s\"", name);
+#else
+ if(!(file = fopen(name, "r"))) {
+ sprintf(TmpTxt, "DataLine: open failed for file \"%s\"", name);
+#endif
+ ErrorBox(TmpTxt);
+ return;
+ }
+ if(Values) free(Values);
+ if(!(Values = (lfPOINT*)calloc( nPnt = 1000, sizeof(lfPOINT)))){
+ fclose(file);
+ return;
+ }
+ switch(type) {
+ case 1: //x and y values
+ i = 0;
+ do {
+#ifdef USE_WIN_SECURE
+ c = fscanf_s(file, "%lf%lf", &Values[i].fx, &Values[i].fy);
+#else
+ c = fscanf(file, "%lf%lf", &Values[i].fx, &Values[i].fy);
+#endif
+ i++;
+ if(i >= nPnt &&(tfp = (lfPOINT*)realloc(Values, (nPnt+1000)*sizeof(lfPOINT)))){
+ Values = tfp; nPnt += 1000;
+ }
+ else if(i >= nPnt) break;
+ }while(c == 2);
+ i--;
+ break;
+ case 2: //only y values
+ i = 0; fx = start;
+ do {
+#ifdef USE_WIN_SECURE
+ c = fscanf_s(file, "%lf", &Values[i].fy);
+#else
+ c = fscanf(file, "%lf", &Values[i].fy);
+#endif
+ Values[i].fx = fx;
+ i++; fx += step;
+ if(i >= nPnt &&(tfp = (lfPOINT*)realloc(Values, (nPnt+1000)*sizeof(lfPOINT)))){
+ Values = tfp; nPnt += 1000;
+ }
+ }while(c == 1);
+ i--;
+ break;
+ }
+ nPntSet = i-1;
+ fclose(file);
+}
+
+bool
+DataLine::FileIO(int rw)
+{
+ long i;
+ char *file1 = 0L;
+ char *file2 = 0L;
+ double Start = 0.0f, Step = 0.0f;
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssXref", typTEXT, &ssXref, 0L},
+ {"ssYref", typTEXT, &ssYref, 0L},
+ {"BgCol", typDWORD, &BgColor, 0L},
+ {"Line", typLINEDEF, &LineDef, 0L},
+ {"Data", typFPLST, &Values, &i},
+ {"file_xy", typTEXT, &file2, 0L},
+ {"start_x", typNZLFLOAT, &Start, 0L},
+ {"step_x", typNZLFLOAT, &Step, 0L},
+ {"file_y", typTEXT, &file1, 0L},
+ {"Desc", typLAST | typTEXT, &name, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ isPolygon = false;
+ nPnt = nPntSet = cp = 0;
+ memcpy(&LineDef, defs.GetLine(), sizeof(LineDEF));
+ BgColor = defs.Color(COL_BG);
+ pts = 0L; dirty = true; mo = 0L;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ min.fx = min.fy = max.fx = max.fy = 0.0;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ nPnt = i;
+ nPntSet = i-1;
+ if(file2)FileValues(file2, 1, 0.0, 1.0);
+ else if(file1)FileValues(file1, 2, Start, fabs(Step) > defs.min4log ? Step : 1.0);
+ if(file1) free(file1);
+ if(file2) free(file2);
+ if(i && Values)return true;
+ break;
+ case FILE_WRITE:
+ i = nPntSet+1;
+ return ExecOutput(Notary->RegisterGO(this), "DataLine", Desc);
+ }
+ return false;
+}
+
+bool
+DataPolygon::FileIO(int rw)
+{
+ long i;
+ char *file1 = 0L;
+ char *file2 = 0L;
+ double Start = 0.0f, Step = 0.0f;
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssXref", typTEXT, &ssXref, 0L},
+ {"ssYref", typTEXT, &ssYref, 0L},
+ {"BgCol", typDWORD, &BgColor, 0L},
+ {"Line", typLINEDEF, &LineDef, 0L},
+ {"FillLine", typLINEDEF, &pgFillLine, 0L},
+ {"Fill", typFILLDEF, &pgFill, 0L},
+ {"Data", typFPLST, &Values, &i},
+ {"file_xy", typTEXT, &file2, 0L},
+ {"start_x", typNZLFLOAT, &Start, 0L},
+ {"step_x", typNZLFLOAT, &Step, 0L},
+ {"file_y", typLAST | typTEXT, &file1, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ isPolygon = true;
+ memcpy(&LineDef, defs.GetLine(), sizeof(LineDEF));
+ LineDef.pattern = 0L;
+ BgColor = defs.Color(COL_BG);
+ memcpy(&pgFill, defs.GetFill(), sizeof(FillDEF));
+ if(pgFill.hatch) memcpy(&pgFillLine, pgFill.hatch, sizeof(LineDEF));
+ pgFill.hatch = &pgFillLine; dirty = true; mo = 0L;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ min.fx = min.fy = max.fx = max.fy = 0.0f;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ nPnt = i;
+ nPntSet = i-1;
+ if(file2)FileValues(file2, 1, 0.0f, 1.0f);
+ else if(file1)FileValues(file1, 2, Start, fabs(Step) > defs.min4log ? Step : 1.0);
+ if(file1) free(file1);
+ if(file2) free(file2);
+ pgFill.hatch = &pgFillLine;
+ if(i && Values)return true;
+ break;
+ case FILE_WRITE:
+ i = nPntSet+1;
+ return ExecOutput(Notary->RegisterGO(this), "DataPolygon", Desc);
+ }
+ return false;
+}
+
+bool
+RegLine::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"type", typNZINT, &type, 0L},
+ {"nPoints", typINT, &nPoints, 0L},
+ {"BgCol", typDWORD, &BgColor, 0L},
+ {"Line", typLINEDEF, &LineDef, 0L},
+ {"Range", typFRECT, &lim, 0L},
+ {"uClip", typFRECT, &uclip, 0L},
+ {"mx", typNZLFLOAT, &mx, 0L},
+ {"my", typNZLFLOAT, &my, 0L},
+ {"li1", typLFPOINT, &l1, 0L},
+ {"li2", typLFPOINT, &l2, 0L},
+ {"li3", typLFPOINT, &l3, 0L},
+ {"li4", typLFPOINT, &l4, 0L},
+ {"li5", typLAST | typLFPOINT, &l5, 0L}};
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ cp = 0;
+ memcpy(&LineDef, defs.GetLine(), sizeof(LineDEF));
+ BgColor = defs.Color(COL_BG);
+ pts = 0L;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "RegLine", Desc);
+ }
+ return false;
+}
+
+void
+SDellipse::RegGO(void *n)
+{
+ if(n) {
+ if(rl)rl->RegGO(n);
+ ((notary*)n)->AddRegGO(this);
+ }
+}
+
+bool
+SDellipse::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"type", typNZINT, &type, 0L},
+ {"Line", typLINEDEF, &LineDef, 0L},
+ {"Range", typFRECT, &lim, 0L},
+ {"Regr", typGOBJ, &rl, 0L},
+ {"Data", typLAST | typFPLST, &val, &nPoints}};
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ memcpy(&LineDef, defs.GetOutLine(), sizeof(LineDEF));
+ pts = 0L;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ if(rl) rl->parent = this;
+ return true;
+ case FILE_WRITE:
+ if(rl) rl->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "SDellipse", Desc);
+ }
+ return false;
+}
+
+bool
+ErrorBar::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"Pos", typLFPOINT, &fPos, 0L},
+ {"Err", typLFLOAT, &ferr, 0L},
+ {"Size", typLFLOAT, &SizeBar, 0L},
+ {"Line", typLINEDEF, &ErrLine, 0L},
+ {"Desc", typLAST | typTEXT, &name, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ SizeBar = DefSize(SIZE_ERRBAR);
+ ErrLine.width = DefSize(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);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "ErrorBar", Desc);
+ }
+ return false;
+}
+
+bool
+Arrow::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"moveable", typNZINT, &moveable, 0L},
+ {"p1", typLFPOINT, &pos1, 0L},
+ {"p2", typLFPOINT, &pos2, 0L},
+ {"CapW", typLFLOAT, &cw, 0L},
+ {"CapL", typLFLOAT, &cl, 0L},
+ {"Line", typLAST | typLINEDEF, &LineDef, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ cw = DefSize(SIZE_ARROW_CAPWIDTH);
+ cl = DefSize(SIZE_ARROW_CAPLENGTH);
+ LineDef.color = parent ? parent->GetColor(COL_DATA_LINE) : defs.Color(COL_DATA_LINE);
+ LineDef.width = parent ? parent->GetSize(SIZE_ARROW_LINE) : DefSize(SIZE_ARROW_LINE);
+ type = ARROW_LINE;
+ dh1 = dh2 = 0L;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Arrow", Desc);
+ }
+ return false;
+}
+
+bool
+Box::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"High", typLFPOINT, &pos1, 0L},
+ {"Low", typLFPOINT, &pos2, 0L},
+ {"Size", typLFLOAT, &size, 0L},
+ {"Line", typLINEDEF, &Outline, 0L},
+ {"FillLine", typLINEDEF, &Hatchline, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"Name", typLAST | typTEXT, &name, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ memcpy(&Outline, defs.GetOutLine(), sizeof(LineDEF));
+ memcpy(&Fill, defs.GetFill(), sizeof(FillDEF));
+ if(Fill.hatch)memcpy(&Hatchline, Fill.hatch, sizeof(LineDEF));
+ Fill.hatch = &Hatchline;
+ size = DefSize(SIZE_BAR);
+ ssRef = 0L;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ Fill.hatch = &Hatchline;
+ return true;
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Box", Desc);
+ }
+ return false;
+}
+
+bool
+Whisker::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"High", typLFPOINT, &pos1, 0L},
+ {"Low", typLFPOINT, &pos2, 0L},
+ {"Size", typLFLOAT, &size, 0L},
+ {"Line", typLINEDEF, &LineDef, 0L},
+ {"Desc", typLAST | typTEXT, &name, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ size = DefSize(SIZE_WHISKER);
+ LineDef.width = DefSize(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);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Whisker", Desc);
+ }
+ return false;
+}
+
+bool
+DropLine::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typINT, &type, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"Pos", typLFPOINT, &fPos, 0L},
+ {"Line", typLAST | typLINEDEF, &LineDef, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ LineDef.color = defs.Color(COL_SYM_LINE);
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "DropLine", Desc);
+ }
+ return false;
+}
+
+bool
+Sphere::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"Pos", typPOINT3D, &fPos, 0L},
+ {"Size", typLFLOAT, &size, 0L},
+ {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ size = DefSize(SIZE_SYMBOL);
+ Line.color = defs.Color(COL_SYM_LINE);
+ Line.width = DefSize(SIZE_SYM_LINE);
+ Fill.color = defs.Color(COL_SYM_FILL);
+ scl = 0L; nscl = 0;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Sphere", Desc);
+ }
+ return false;
+}
+
+bool
+Plane3D::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Line", typLINEDEF, &Line, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"values", typLAST | typFPLST3D, &dt, &ndt}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ ipl = 0L; pts = 0L;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Plane3D", Desc);
+ }
+ return false;
+}
+
+bool
+Brick::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Line", typLINEDEF, &Line, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"Pos", typPOINT3D, &fPos, 0L},
+ {"depth", typLFLOAT, &depth, 0L},
+ {"width", typLFLOAT, &width, 0L},
+ {"height", typLFLOAT, &height, 0L},
+ {"flags", typDWORD, &flags, 0L},
+ {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ Line.color = defs.Color(COL_SYM_LINE);
+ Line.width = DefSize(SIZE_SYM_LINE);
+ Fill.color = defs.Color(COL_SYM_FILL);
+ faces = (plane**)calloc(6, sizeof(plane*));
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ mo = 0L;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Brick", Desc);
+ }
+ return false;
+}
+
+bool
+DropLine3D::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typINT, &type, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"Pos", typPOINT3D, &fPos, 0L},
+ {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ Line.color = defs.Color(COL_SYM_LINE);
+ Line.width = DefSize(SIZE_HAIRLINE); mo = 0L;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ ls[0] = ls[1] = ls[2] = ls[3] = ls[4] = ls[5] = 0L;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "DropLine3D", Desc);
+ }
+ return false;
+}
+
+bool
+Arrow3D::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typINT, &type, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"Org", typPOINT3D, &fPos1, 0L},
+ {"Pos", typPOINT3D, &fPos2, 0L},
+ {"CapW", typLFLOAT, &cw, 0L},
+ {"CapL", typLFLOAT, &cl, 0L},
+ {"ssRef", typLAST | typIPLST, &ssRef, &cssRef}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ cw = DefSize(SIZE_ARROW_CAPWIDTH);
+ cl = DefSize(SIZE_ARROW_CAPLENGTH);
+ Line.color = defs.Color(COL_ARROW);
+ Line.width = DefSize(SIZE_ARROW_LINE);
+ ls[0] = ls[1] = ls[2] = 0L;
+ cap = 0L;
+ type = ARROW_LINE;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Arrow3D", Desc);
+ }
+ return false;
+}
+
+bool
+Line3D::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Line", typLINEDEF, &Line, 0L},
+ {"ssRefX", typTEXT, &x_range, 0L},
+ {"ssRefY", typTEXT, &y_range, 0L},
+ {"ssRefZ", typTEXT, &z_range, 0L},
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"values", typLAST | typFPLST3D, &values, &nPts}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ Line.color = defs.Color(COL_DATA_LINE);
+ Line.width = DefSize(SIZE_DATA_LINE);
+ ls = 0L; pts = 0L; npts = 0L; mo=0L;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ min.fx = min.fy = min.fz = max.fx = max.fy = max.fz = 0.0;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ if(nPts > 1) ls = (line_segment **)calloc(nPts-1, sizeof(line_segment*));
+ return true;
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Line3D", Desc);
+ }
+ return false;
+}
+
+bool
+Label::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"ssRef", typIPLST, &ssRef, &cssRef},
+ {"moveable", typNZINT, &moveable, 0L},
+ {"Pos", typNZLFPOINT, &fPos, 0L},
+ {"Dist", typNZLFPOINT, &fDist, 0L},
+ {"Flags", typDWORD, &flags, 0L},
+ {"TxtDef", typLAST | typTXTDEF, &TextDef, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ TextDef.ColTxt = 0x0L;
+ TextDef.ColBg = 0x00ffffffL;
+ TextDef.fSize = DefSize(SIZE_TEXT);
+ TextDef.RotBL = TextDef.RotCHAR = 0.0;
+ TextDef.iSize = 0;
+ TextDef.Align = TXA_VTOP | TXA_HLEFT;
+ TextDef.Mode = TXM_TRANSPARENT;
+ TextDef.Style = TXS_NORMAL;
+ TextDef.Font = FONT_HELVETICA;
+ TextDef.text = 0L; bgcolor = 0x00ffffffL;
+ bgLine.width = 0.0; bgLine.patlength = 6.0;
+ bgLine.color = bgcolor; bgLine.pattern = 0L;
+ CursorPos = 0; defDisp = 0L; bBGvalid = bModified = false;
+ curr_z = 0.0; is3D = false; fmt_txt = 0L;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(parent && parent->Id != GO_MLABEL) {
+ if(!TextDef.text || !TextDef.text[0]) return false;
+ }
+ return ExecOutput(Notary->RegisterGO(this), "Label", Desc);
+ }
+ return false;
+}
+
+void
+mLabel::RegGO(void *n)
+{
+ int i;
+
+ if(n) {
+ if(Lines) for(i = 0; i < nLines; i++) if(Lines[i]) Lines[i]->RegGO(n);
+ ((notary*)n)->AddRegGO(this);
+ }
+}
+
+bool
+mLabel::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"moveable", typNZINT, &moveable, 0L},
+ {"Pos", typNZLFPOINT, &fPos, 0L},
+ {"Dist", typNZLFPOINT, &fDist, 0L},
+ {"lspc", typLFLOAT, &lspc, 0L},
+ {"Flags", typDWORD, &flags, 0L},
+ {"TxtDef", typTXTDEF, &TextDef, 0L},
+ {"Lines", typLAST | typOBJLST, &Lines, &nLines}};
+ int i;
+
+ switch(rw) {
+ case SAVE_VARS:
+ //The lines inherit settings from this object.
+ //We need not save them in this context
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ TextDef.ColTxt = 0x0L;
+ TextDef.ColBg = 0x00ffffffL;
+ TextDef.fSize = DefSize(SIZE_TEXT);
+ TextDef.RotBL = TextDef.RotCHAR = 0.0;
+ TextDef.iSize = 0;
+ TextDef.Align = TXA_VTOP | TXA_HLEFT;
+ TextDef.Mode = TXM_TRANSPARENT;
+ TextDef.Style = TXS_NORMAL;
+ TextDef.Font = FONT_HELVETICA;
+ TextDef.text = 0L;
+ undo_flags = 0L; lspc = 1.0;
+ curr_z = 0.0; is3D = false;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ if(Lines) for ( i = 0; i < nLines; i++)
+ if(Lines[i]) Lines[i]->parent = this;
+ return true;
+ case FILE_WRITE:
+ if(Lines) for ( i = 0; i < nLines; i++)
+ if(Lines[i]) Lines[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "mLabel", Desc);
+ }
+ return false;
+}
+
+bool
+TextFrame::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"moveable", typNZINT, &moveable, 0L},
+ {"Pos1", typNZLFPOINT, &pos1, 0L},
+ {"Pos2", typNZLFPOINT, &pos2, 0L},
+ {"lspc", typLFLOAT, &lspc, 0L},
+ {"Pad", typFRECT, &pad, 0L},
+ {"TxtDef", typTXTDEF, &TextDef, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"FillLine", typLINEDEF, &FillLine, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"Text", typLAST | typTEXT, &text, 0L}};
+ switch(rw) {
+ case SAVE_VARS:
+ return false;
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ TextDef.ColTxt = 0x0L;
+ TextDef.ColBg = 0x00ffffffL;
+ TextDef.fSize = DefSize(SIZE_TEXT);
+ TextDef.RotBL = TextDef.RotCHAR = 0.0;
+ TextDef.iSize = 0;
+ TextDef.Align = TXA_VBOTTOM | TXA_HLEFT;
+ TextDef.Mode = TXM_TRANSPARENT;
+ TextDef.Style = TXS_NORMAL;
+ TextDef.Font = FONT_HELVETICA;
+ TextDef.text = 0L;
+ lines = 0L; nlines = 0; drc = 0L;
+ cur_pos.x = cur_pos.y = tm_c = 0; tm_rec = 0L;
+ bModified = bResize = has_m1 = has_m2 = false;
+ if(Fill.hatch) memcpy(&FillLine, Fill.hatch, sizeof(LineDEF));
+ Fill.hatch = &FillLine; c_char = m1_char = m2_char = '?';
+ pad.Xmin = pad.Xmax = pad.Ymin = pad.Ymax = DefSize(SIZE_SYMBOL)/2.0;
+ Cursor.left = Cursor.right = Cursor.top = Cursor.bottom = 0;
+ pad.Xmax *= 2.0;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc); Fill.hatch = &FillLine;
+ return true;
+ case FILE_WRITE:
+ if(lines)lines2text();
+ if(!text || !text[0]) return false;
+ return ExecOutput(Notary->RegisterGO(this), "TextFrame", Desc);
+ }
+ return false;
+}
+
+bool
+segment::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"moveable", typNZINT, &moveable, 0L},
+ {"cent", typLFPOINT, &fCent, 0L},
+ {"ri", typNZLFLOAT, &radius1, 0L},
+ {"ra", typLFLOAT, &radius2, 0L},
+ {"start", typLFLOAT, &angle1, 0L},
+ {"end", typLFLOAT, &angle2, 0L},
+ {"shout", typNZLFLOAT, &shift, 0L},
+ {"Line", typLINEDEF, &segLine, 0L},
+ {"FillLine", typLINEDEF, &segFillLine, 0L},
+ {"Fill", typLAST | typFILLDEF, &segFill, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ segLine.width = DefSize(SIZE_SEGLINE);
+ pts = 0L; nPts = 0;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ segFill.hatch = &segFillLine;
+ return true;
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "segment", Desc);
+ }
+ return false;
+}
+
+bool
+polyline::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:
+ InitVarsGO(Desc);
+ memcpy(&pgLine, defs.plLineDEF(0L), sizeof(LineDEF));
+ memcpy(&pgFill, defs.pgFillDEF(0L), sizeof(FillDEF));
+ if(pgFill.hatch) memcpy(&pgFillLine, pgFill.hatch, sizeof(LineDEF));
+ pgFill.hatch = &pgFillLine;
+ pts = 0L; nPts = 0;
+ pHandles = 0L;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ pgFill.hatch = &pgFillLine;
+ return true;
+ case FILE_WRITE:
+ if(type != 1) Desc[3].type |= typLAST; //skip fill for polyline
+ return ExecOutput(Notary->RegisterGO(this),
+ 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)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"moveable", typNZINT, &moveable, 0L},
+ {"p1", typLFPOINT, &fp1, 0L},
+ {"p2", typLFPOINT, &fp2, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"FillLine", typLINEDEF, &FillLine, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"Rad", typNZLFLOAT, &rad, 0L},
+ {"Name", typLAST | typTEXT, &name, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ memcpy(&Line, defs.pgLineDEF(0L), sizeof(LineDEF));
+ memcpy(&Fill, defs.pgFillDEF(0L), sizeof(FillDEF));
+ if(Fill.hatch) memcpy(&FillLine, Fill.hatch, sizeof(LineDEF));
+ Fill.hatch = &FillLine;
+ pts = 0L; nPts = 0L;
+ rad = DefSize(SIZE_RRECT_RAD);
+ drc = 0L;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ Fill.hatch = &FillLine;
+ return true;
+ case FILE_WRITE:
+ if(type != 2) rad = 0.0;
+ ExecOutput(Notary->RegisterGO(this),
+ type == 1? (char*)"ellipse" : type == 2? (char*)"roundrec" :
+ (char*)"rectangle", Desc);
+ return true;
+ }
+ return false;
+}
+
void
LegItem::RegGO(void *n)
{
@@ -2085,40 +2242,40 @@ LegItem::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-LegItem::FileIO(int rw)
-{
- descIO Des[] = {
- {"D_Line", typLINEDEF, &DataLine, 0L},
- {"O_Line", typLINEDEF, &OutLine, 0L},
- {"H_Line", typLINEDEF, &HatchLine, 0L},
- {"Fill", typFILLDEF, &Fill, 0L},
- {"Sym", typGOBJ, &Sym, 0L},
- {"Text", typGOBJ, &Desc, 0L},
- {"flags", typLAST | typDWORD, &flags, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Des);
- case INIT_VARS:
- InitVarsGO(Des);
- Fill.hatch = &HatchLine;
- return true;
- case FILE_READ:
- ExecInput(Des);
- Fill.hatch = &HatchLine;
- if(Sym) Sym->parent=this;
- if(Desc) Desc->parent=this;
- return true;
- case FILE_WRITE:
- if(Sym) Sym->FileIO(rw);
- if(Desc) Desc->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "LegItem", Des);
- }
- return false;
-}
-
+
+bool
+LegItem::FileIO(int rw)
+{
+ descIO Des[] = {
+ {"D_Line", typLINEDEF, &DataLine, 0L},
+ {"O_Line", typLINEDEF, &OutLine, 0L},
+ {"H_Line", typLINEDEF, &HatchLine, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"Sym", typGOBJ, &Sym, 0L},
+ {"Text", typGOBJ, &Desc, 0L},
+ {"flags", typLAST | typDWORD, &flags, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Des);
+ case INIT_VARS:
+ InitVarsGO(Des);
+ Fill.hatch = &HatchLine;
+ return true;
+ case FILE_READ:
+ ExecInput(Des);
+ Fill.hatch = &HatchLine;
+ if(Sym) Sym->parent=this;
+ if(Desc) Desc->parent=this;
+ return true;
+ case FILE_WRITE:
+ if(Sym) Sym->FileIO(rw);
+ if(Desc) Desc->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "LegItem", Des);
+ }
+ return false;
+}
+
void
Legend::RegGO(void *n)
{
@@ -2129,47 +2286,49 @@ Legend::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-Legend::FileIO(int rw)
-{
- descIO Desc[] = {
- {"pos", typLFPOINT, &pos, 0L},
- {"rec1", typFRECT, &B_Rect, 0L},
- {"rec2", typFRECT, &D_Rect, 0L},
+
+bool
+Legend::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"pos", typLFPOINT, &pos, 0L},
+ {"rec1", typFRECT, &B_Rect, 0L},
+ {"rec2", typFRECT, &D_Rect, 0L},
{"rec3", typFRECT, &F_Rect, 0L},
- {"Items", typLAST | typOBJLST, &Items, &nItems}};
- int i;
- double d;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- B_Rect.Ymin = defs.GetSize(SIZE_DRECT_TOP);
- B_Rect.Xmin = defs.GetSize(SIZE_DRECT_LEFT);
- B_Rect.Xmax = B_Rect.Xmin + 1.5*(d = defs.GetSize(SIZE_BAR));
- B_Rect.Ymin += d*0.2;
- B_Rect.Ymax = B_Rect.Ymin + d/2.0;
- D_Rect.Ymin = 0.0; D_Rect.Xmin = d*0.7;
- D_Rect.Xmax = d*1.3; D_Rect.Ymax = d*0.4;
+ {"Items", typLAST | typOBJLST, &Items, &nItems}};
+ int i;
+ double d;
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ B_Rect.Ymin = DefSize(SIZE_DRECT_TOP); B_Rect.Xmin = DefSize(SIZE_DRECT_LEFT);
+ B_Rect.Xmax = B_Rect.Xmin + 1.5*(d = DefSize(SIZE_BAR));
+ B_Rect.Ymin += d*0.2;
+ B_Rect.Ymax = B_Rect.Ymin + d/2.0;
+ D_Rect.Ymin = 0.0; D_Rect.Xmin = d*0.7;
+ 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; hasLine = false;
+ to = 0L; hasLine = false;
trc.left = trc.right = trc.top = trc.bottom = 0;
- if(!name) name=strdup("Legend");
- return true;
- case FILE_READ:
- nItems = 0L;
- ExecInput(Desc);
- if(Items) for(i = 0; i < nItems; i++) if(Items[i]) Items[i]->parent=this;
- return true;
- case FILE_WRITE:
- if(Items) for(i = 0; i < nItems; i++) if(Items[i]) Items[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Legend", Desc);
- }
- return false;
-}
-
+ if(!name) {
+ name = (char*)malloc(20 * sizeof(char));
+ rlp_strcpy(name, 20, "Legend");
+ }
+ return true;
+ case FILE_READ:
+ nItems = 0L;
+ ExecInput(Desc);
+ if(Items) for(i = 0; i < nItems; i++) if(Items[i]) Items[i]->parent=this;
+ return true;
+ case FILE_WRITE:
+ if(Items) for(i = 0; i < nItems; i++) if(Items[i]) Items[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Legend", Desc);
+ }
+ return false;
+}
+
void
PlotScatt::RegGO(void *n)
{
@@ -2187,46 +2346,53 @@ PlotScatt::RegGO(void *n)
}
}
-bool
-PlotScatt::FileIO(int rw)
-{
+bool
+PlotScatt::FileIO(int rw)
+{
descIO Desc[] = {
- {"hide", typNZINT, &hidden, 0L},
- {"Bounds", typFRECT, &Bounds, 0L},
- {"DefSym", typNZINT, &DefSym, 0L},
- {"baDist", typLFPOINT, &BarDist, 0L},
- {"xRange", typTEXT, &xRange, 0L},
- {"yRange", typTEXT, &yRange, 0L},
- {"eRange", typTEXT, &ErrRange, 0L},
- {"lRange", typTEXT, &LbRange, 0L},
- {"x_axis", typNZINT, &use_xaxis, 0L},
- {"y_axis", typNZINT, &use_yaxis, 0L},
- {"Bars", typOBJLST, &Bars, &nPoints},
- {"Symbols", typOBJLST, &Symbols, &nPoints},
- {"PL", typGOBJ, &TheLine, 0L},
- {"ErrBars", typOBJLST, &Errors, &nPoints},
- {"Arrows", typOBJLST, &Arrows, &nPoints},
- {"dLines", typOBJLST, &DropLines, &nPoints},
- {"Labels", typLAST | typOBJLST, &Labels, &nPoints}};
+ {"hide", typNZINT, &hidden, 0L},
+ {"Bounds", typFRECT, &Bounds, 0L},
+ {"DefSym", typNZINT, &DefSym, 0L},
+ {"baDist", typLFPOINT, &BarDist, 0L},
+ {"xRange", typTEXT, &xRange, 0L},
+ {"yRange", typTEXT, &yRange, 0L},
+ {"eRange", typTEXT, &ErrRange, 0L},
+ {"lRange", typTEXT, &LbRange, 0L},
+ {"x_axis", typNZINT, &use_xaxis, 0L},
+ {"y_axis", typNZINT, &use_yaxis, 0L},
+ {"Bars", typOBJLST, &Bars, &nPoints},
+ {"Symbols", typOBJLST, &Symbols, &nPoints},
+ {"PL", typGOBJ, &TheLine, 0L},
+ {"ErrBars", typOBJLST, &Errors, &nPoints},
+ {"Arrows", typOBJLST, &Arrows, &nPoints},
+ {"dLines", typOBJLST, &DropLines, &nPoints},
+ {"Labels", typOBJLST, &Labels, &nPoints},
+ {"x_info", typTEXT, &x_info, 0L},
+ {"y_info", typLAST | typTEXT, &y_info, 0L}};
int i;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- DefSym = SYM_CIRCLE;
- DefSel = 0x01;
- dirty = true;
+
+ switch(rw) {
+ case INIT_VARS:
+ x_info = y_info = z_info = 0L;
+ InitVarsGO(Desc);
+ DefSym = SYM_CIRCLE;
+ DefSel = 0x01;
+ dirty = true;
if(name) {
- sprintf(TmpTxt, "xy-plot (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "xy-plot (%s)", name);
+#else
+ i = sprintf(TmpTxt, "xy-plot (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- nPoints = 0L;
+ return true;
+ case FILE_READ:
+ nPoints = 0L;
ExecInput(Desc);
ForEach(FE_PARENT, 0L, 0L);
- return true;
- case FILE_WRITE:
+ return true;
+ case FILE_WRITE:
if(TheLine) TheLine->FileIO(rw);
if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->FileIO(rw);
if(Errors) for(i = 0; i < nPoints; i++) if(Errors[i]) Errors[i]->FileIO(rw);
@@ -2234,9 +2400,9 @@ PlotScatt::FileIO(int rw)
if(DropLines) for(i = 0; i < nPoints; i++) if(DropLines[i]) DropLines[i]->FileIO(rw);
if(Labels) for(i = 0; i < nPoints; i++) if(Labels[i]) Labels[i]->FileIO(rw);
if(Bars) for(i = 0; i < nPoints; i++) if(Bars[i]) Bars[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "PlotScatt", Desc);
- }
- return false;
+ return ExecOutput(Notary->RegisterGO(this), "PlotScatt", Desc);
+ }
+ return false;
}
bool
@@ -2258,7 +2424,9 @@ xyStat::FileIO(int rw)
{"Symbols", typOBJLST, &Symbols, &nPoints},
{"PL", typGOBJ, &TheLine, 0L},
{"ErrBars", typOBJLST, &Errors, &nPoints},
- {"Labels", typLAST | typOBJLST, &Labels, &nPoints}};
+ {"Labels", typOBJLST, &Labels, &nPoints},
+ {"x_info", typTEXT, &x_info, 0L},
+ {"y_info", typLAST | typTEXT, &y_info, 0L}};
int i;
switch(rw) {
@@ -2296,7 +2464,7 @@ FreqDist::RegGO(void *n)
}
bool
-FreqDist::FileIO(int rw)
+FreqDist::FileIO(int rw)
{
descIO Desc[] = {
{"Type", typNZINT, &type, 0L},
@@ -2320,11 +2488,14 @@ FreqDist::FileIO(int rw)
if(BarFill.hatch) memcpy(&HatchLine, BarFill.hatch, sizeof(LineDEF));
BarFill.hatch = &HatchLine;
memcpy(&BarLine, defs.GetOutLine(), sizeof(LineDEF));
- curr_data=0L;
- dirty = true;
+ curr_data=0L; dirty = true;
if(name) {
- sprintf(TmpTxt, "freq. dist. (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "freq. dist. (%s)", name);
+#else
+ i = sprintf(TmpTxt, "freq. dist. (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
return true;
case FILE_READ:
@@ -2350,44 +2521,48 @@ Regression::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-Regression::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
+
+bool
+Regression::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},
- {"x_axis", typNZINT, &use_xaxis, 0L},
- {"y_axis", typNZINT, &use_yaxis, 0L},
- {"Line", typGOBJ, &rLine, 0L},
- {"Ellipse", typGOBJ, &sde, 0L},
- {"Symbols", typLAST | typOBJLST, &Symbols, &nPoints}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- dirty = true;
+ {"Bounds", typFRECT, &Bounds, 0L},
+ {"xRange", typTEXT, &xRange, 0L},
+ {"yRange", typTEXT, &yRange, 0L},
+ {"x_axis", typNZINT, &use_xaxis, 0L},
+ {"y_axis", typNZINT, &use_yaxis, 0L},
+ {"Line", typGOBJ, &rLine, 0L},
+ {"Ellipse", typGOBJ, &sde, 0L},
+ {"Symbols", typLAST | typOBJLST, &Symbols, &nPoints}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ dirty = true;
if(name) {
- sprintf(TmpTxt, "regression (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "regression (%s)", name);
+#else
+ i = sprintf(TmpTxt, "regression (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- nPoints = 0L;
- return ExecInput(Desc);
- case FILE_WRITE:
- if(rLine) rLine->FileIO(rw);
- if(sde) sde->FileIO(rw);
- if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Regression", Desc);
- }
- return false;
-}
-
+ return true;
+ case FILE_READ:
+ nPoints = 0L;
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(rLine) rLine->FileIO(rw);
+ if(sde) sde->FileIO(rw);
+ if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Regression", Desc);
+ }
+ return false;
+}
+
void
BubblePlot::RegGO(void *n)
{
@@ -2399,44 +2574,48 @@ BubblePlot::RegGO(void *n)
}
}
-bool
-BubblePlot::FileIO(int rw)
-{
- descIO Desc[] = {
+bool
+BubblePlot::FileIO(int rw)
+{
+ descIO Desc[] = {
{"hide", typNZINT, &hidden, 0L},
- {"Bounds", typFRECT, &Bounds, 0L},
- {"x_axis", typNZINT, &use_xaxis, 0L},
- {"y_axis", typNZINT, &use_yaxis, 0L},
- {"Line", typLINEDEF, &BubbleLine, 0L},
- {"FillLine", typLINEDEF, &BubbleFillLine, 0L},
- {"Fill", typFILLDEF, &BubbleFill, 0L},
- {"Bubbles", typLAST | typOBJLST, &Bubbles, &nPoints}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- BubbleFill.color = defs.Color(COL_BUBBLE_FILL);
- BubbleLine.color = defs.Color(COL_BUBBLE_LINE);
- BubbleLine.width = defs.GetSize(SIZE_BUBBLE_LINE);
- BubbleFillLine.color = defs.Color(COL_BUBBLE_FILLLINE);
- BubbleFillLine.width = defs.GetSize(SIZE_BUBBLE_HATCH_LINE);
- BubbleFill.hatch = &BubbleFillLine;
- dirty = true;
+ {"Bounds", typFRECT, &Bounds, 0L},
+ {"x_axis", typNZINT, &use_xaxis, 0L},
+ {"y_axis", typNZINT, &use_yaxis, 0L},
+ {"Line", typLINEDEF, &BubbleLine, 0L},
+ {"FillLine", typLINEDEF, &BubbleFillLine, 0L},
+ {"Fill", typFILLDEF, &BubbleFill, 0L},
+ {"Bubbles", typLAST | typOBJLST, &Bubbles, &nPoints}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ BubbleFill.color = defs.Color(COL_BUBBLE_FILL);
+ BubbleLine.color = defs.Color(COL_BUBBLE_LINE);
+ BubbleLine.width = DefSize(SIZE_BUBBLE_LINE);
+ BubbleFillLine.color = defs.Color(COL_BUBBLE_FILLLINE);
+ BubbleFillLine.width = DefSize(SIZE_BUBBLE_HATCH_LINE);
+ BubbleFill.hatch = &BubbleFillLine;
+ dirty = true;
if(name) {
- sprintf(TmpTxt, "bubbles (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "bubbles (%s)", name);
+#else
+ i = sprintf(TmpTxt, "bubbles (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- if(Bubbles) for(i = 0; i < nPoints; i++) if(Bubbles[i]) Bubbles[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "BubblePlot", Desc);
- }
- return false;
-}
-
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(Bubbles) for(i = 0; i < nPoints; i++) if(Bubbles[i]) Bubbles[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "BubblePlot", Desc);
+ }
+ return false;
+}
+
void
PolarPlot::RegGO(void *n)
{
@@ -2448,40 +2627,44 @@ PolarPlot::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-PolarPlot::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
+
+bool
+PolarPlot::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
{"hide", typNZINT, &hidden, 0L},
- {"Bounds", typFRECT, &Bounds, 0L},
- {"ang_offs", typLFLOAT, &offs, 0L},
- {"Plots", typOBJLST, &Plots, (long*)&nPlots},
- {"Axes", typOBJLST, &Axes, (long*)&nAxes},
- {"FillLine", typLINEDEF, &FillLine, 0L},
- {"Fill", typLAST | typFILLDEF, &Fill, 0L}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- CurrDisp = 0L;
+ {"Bounds", typFRECT, &Bounds, 0L},
+ {"ang_offs", typLFLOAT, &offs, 0L},
+ {"Plots", typOBJLST, &Plots, (long*)&nPlots},
+ {"Axes", typOBJLST, &Axes, (long*)&nAxes},
+ {"FillLine", typLINEDEF, &FillLine, 0L},
+ {"Fill", typLAST | typFILLDEF, &Fill, 0L}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ CurrDisp = 0L;
InitVarsGO(Desc);
if(name) {
- sprintf(TmpTxt, "polar root (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "polar root (%s)", name);
+#else
+ i = sprintf(TmpTxt, "polar root (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- if(Plots) for(i = 0; i < nPlots; i++) if(Plots[i]) Plots[i]->FileIO(rw);
- if(Axes) for(i = 0; i < nAxes; i++) if(Axes[i]) Axes[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "PolarPlot", Desc);
- }
- return false;
-}
-
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(Plots) for(i = 0; i < nPlots; i++) if(Plots[i]) Plots[i]->FileIO(rw);
+ if(Axes) for(i = 0; i < nAxes; i++) if(Axes[i]) Axes[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "PolarPlot", Desc);
+ }
+ return false;
+}
+
void
BoxPlot::RegGO(void *n)
{
@@ -2496,55 +2679,58 @@ BoxPlot::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-BoxPlot::FileIO(int rw)
-{
+
+bool
+BoxPlot::FileIO(int rw)
+{
descIO Desc[] = {
{"Type", typNZINT, &type, 0L},
{"hide", typNZINT, &hidden, 0L},
- {"Bounds", typFRECT, &Bounds, 0L},
+ {"Bounds", typFRECT, &Bounds, 0L},
{"xRange", typTEXT, &xRange, 0L},
{"yRange", typTEXT, &yRange, 0L},
{"prefix", typTEXT, &case_prefix, 0L},
{"boDist", typLFPOINT, &BoxDist, 0L},
{"ci_box", typNZLFLOAT, &ci_box, 0L},
- {"ci_err", typNZLFLOAT, &ci_err, 0L},
- {"x_axis", typNZINT, &use_xaxis, 0L},
- {"y_axis", typNZINT, &use_yaxis, 0L},
- {"Boxes", typOBJLST, &Boxes, &nPoints},
- {"Whiskers", typOBJLST, &Whiskers, &nPoints},
- {"Symbols", typOBJLST, &Symbols, &nPoints},
+ {"ci_err", typNZLFLOAT, &ci_err, 0L},
+ {"x_axis", typNZINT, &use_xaxis, 0L},
+ {"y_axis", typNZINT, &use_yaxis, 0L},
+ {"Boxes", typOBJLST, &Boxes, &nPoints},
+ {"Whiskers", typOBJLST, &Whiskers, &nPoints},
+ {"Symbols", typOBJLST, &Symbols, &nPoints},
{"Labels", typOBJLST, &Labels, &nPoints},
- {"Line", typLAST | typGOBJ, &TheLine, 0L}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- dirty = true;
- InitVarsGO(Desc);
+ {"Line", typLAST | typGOBJ, &TheLine, 0L}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ dirty = true; InitVarsGO(Desc);
if(name) {
- sprintf(TmpTxt, "boxes (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "boxes (%s)", name);
+#else
+ i = sprintf(TmpTxt, "boxes (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
curr_data = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- if(Boxes) for(i = 0; i < nPoints; i++)
- if(Boxes[i]) Boxes[i]->FileIO(rw);
- if(Whiskers) for(i = 0; i < nPoints; i++)
- if(Whiskers[i]) Whiskers[i]->FileIO(rw);
- if(Symbols) for(i = 0; i < nPoints; i++)
- if(Symbols[i]) Symbols[i]->FileIO(rw);
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(Boxes) for(i = 0; i < nPoints; i++)
+ if(Boxes[i]) Boxes[i]->FileIO(rw);
+ if(Whiskers) for(i = 0; i < nPoints; i++)
+ if(Whiskers[i]) Whiskers[i]->FileIO(rw);
+ if(Symbols) for(i = 0; i < nPoints; i++)
+ if(Symbols[i]) Symbols[i]->FileIO(rw);
if(Labels) for(i = 0; i < nPoints; i++)
if(Labels[i]) Labels[i]->FileIO(rw);
- if(TheLine) TheLine->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "BoxPlot", Desc);
- }
- return false;
-}
+ if(TheLine) TheLine->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "BoxPlot", Desc);
+ }
+ return false;
+}
void
DensDisp::RegGO(void *n)
@@ -2558,33 +2744,33 @@ DensDisp::RegGO(void *n)
}
bool
-DensDisp::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
+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},
- {"x_axis", typNZINT, &use_xaxis, 0L},
- {"y_axis", typNZINT, &use_yaxis, 0L},
- {"Line", typLINEDEF, &DefLine, 0L},
- {"FillLine", typLINEDEF, &DefFillLine, 0L},
- {"Fill", typFILLDEF, &DefFill, 0L},
- {"Boxes", typLAST | typOBJLST, &Boxes, &nPoints}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- return InitVarsGO(Desc);
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- if(Boxes) for(i = 0; i < nPoints; i++) if(Boxes[i]) Boxes[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "DensDisp", Desc);
- }
- return false;
-}
+ {"Bounds", typFRECT, &Bounds, 0L},
+ {"xRange", typTEXT, &xRange, 0L},
+ {"yRange", typTEXT, &yRange, 0L},
+ {"x_axis", typNZINT, &use_xaxis, 0L},
+ {"y_axis", typNZINT, &use_yaxis, 0L},
+ {"Line", typLINEDEF, &DefLine, 0L},
+ {"FillLine", typLINEDEF, &DefFillLine, 0L},
+ {"Fill", typFILLDEF, &DefFill, 0L},
+ {"Boxes", typLAST | typOBJLST, &Boxes, &nPoints}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ return InitVarsGO(Desc);
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(Boxes) for(i = 0; i < nPoints; i++) if(Boxes[i]) Boxes[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "DensDisp", Desc);
+ }
+ return false;
+}
void
StackBar::RegGO(void *n)
@@ -2600,47 +2786,51 @@ StackBar::RegGO(void *n)
}
}
-bool
-StackBar::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Bounds", typFRECT, &Bounds, 0L},
+bool
+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},
- {"StartVal", typNZLFLOAT, &StartVal, 0L},
- {"Dspm", typNZLFPOINT, &dspm, 0L},
- {"ssXrange", typTEXT, &ssXrange, 0L},
- {"ssYrange", typTEXT, &ssYrange, 0L},
- {"BoxBars", typOBJLST, &Boxes, (long*)&numPlots},
- {"Plots", typOBJLST, &xyPlots, (long*)&numXY},
- {"Polygons", typOBJLST, &Polygons, (long*)&numPG},
- {"Lines", typLAST | typOBJLST, &Lines, (long*)&numPL}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- dirty = true; CumData = 0L;
+ {"x_axis", typNZINT, &use_xaxis, 0L},
+ {"y_axis", typNZINT, &use_yaxis, 0L},
+ {"cumData", typNZINT, &cum_data_mode, 0L},
+ {"StartVal", typNZLFLOAT, &StartVal, 0L},
+ {"Dspm", typNZLFPOINT, &dspm, 0L},
+ {"ssXrange", typTEXT, &ssXrange, 0L},
+ {"ssYrange", typTEXT, &ssYrange, 0L},
+ {"BoxBars", typOBJLST, &Boxes, (long*)&numPlots},
+ {"Plots", typOBJLST, &xyPlots, (long*)&numXY},
+ {"Polygons", typOBJLST, &Polygons, (long*)&numPG},
+ {"Lines", typLAST | typOBJLST, &Lines, (long*)&numPL}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ dirty = true; CumData = 0L;
InitVarsGO(Desc);
if(name) {
- sprintf(TmpTxt, "stack (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "stack (%s)", name);
+#else
+ i = sprintf(TmpTxt, "stack (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
+ return true;
case FILE_READ:
- ExecInput(Desc);
- return true;
- case FILE_WRITE:
- if(Boxes) for(i = 0; i < numPlots; i++) if(Boxes[i]) Boxes[i]->FileIO(rw);
- if(xyPlots) for(i = 0; i < numXY; i++) if(xyPlots[i]) xyPlots[i]->FileIO(rw);
- if(Polygons) for(i = 0; i < numPG; i++) if(Polygons[i]) Polygons[i]->FileIO(rw);
- if(Lines) for(i = 0; i < numPL; i++) if(Lines[i]) Lines[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Stacked", Desc);
- }
- return false;
-}
-
+ ExecInput(Desc);
+ return true;
+ case FILE_WRITE:
+ if(Boxes) for(i = 0; i < numPlots; i++) if(Boxes[i]) Boxes[i]->FileIO(rw);
+ if(xyPlots) for(i = 0; i < numXY; i++) if(xyPlots[i]) xyPlots[i]->FileIO(rw);
+ if(Polygons) for(i = 0; i < numPG; i++) if(Polygons[i]) Polygons[i]->FileIO(rw);
+ if(Lines) for(i = 0; i < numPL; i++) if(Lines[i]) Lines[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Stacked", Desc);
+ }
+ return false;
+}
+
void
PieChart::RegGO(void *n)
{
@@ -2651,40 +2841,44 @@ PieChart::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-PieChart::FileIO(int rw)
-{
- descIO Desc[] = {
- {"ssRefA", typTEXT, &ssRefA, 0L},
- {"ssRefR", typTEXT, &ssRefR, 0L},
+
+bool
+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}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- Bounds.Xmax = Bounds.Ymax = 100.0f;
- Bounds.Xmin = Bounds.Ymin = -100.0f;
- InitVarsGO(Desc);
- CtDef.fx = 90.0; CtDef.fy = 360.0;
- FacRad = 1.0;
+ {"CtDef", typLFPOINT, &CtDef, 0L},
+ {"FacRad", typLFLOAT, &FacRad, 0L},
+ {"Segs", typLAST | typOBJLST, &Segments, (long*)&nPts}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ Bounds.Xmax = Bounds.Ymax = 100.0f;
+ Bounds.Xmin = Bounds.Ymin = -100.0f;
+ InitVarsGO(Desc);
+ CtDef.fx = 90.0; CtDef.fy = 360.0;
+ FacRad = 1.0;
if(name) {
- sprintf(TmpTxt, "pie chart (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "pie chart (%s)", name);
+#else
+ i = sprintf(TmpTxt, "pie chart (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- if(Segments) for(i = 0; i < nPts; i++) if(Segments[i]) Segments[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "SegChart", Desc);
- }
- return false;
-}
-
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(Segments) for(i = 0; i < nPts; i++) if(Segments[i]) Segments[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "SegChart", Desc);
+ }
+ return false;
+}
+
void
GoGroup::RegGO(void *n)
{
@@ -2695,29 +2889,29 @@ GoGroup::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-GoGroup::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Pos", typNZLFPOINT, &fPos, 0L},
+
+bool
+GoGroup::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Pos", typNZLFPOINT, &fPos, 0L},
{"hide", typNZINT, &hidden, 0L},
- {"Items", typLAST | typOBJLST, &Objects, (long*)&nObs}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- Bounds.Xmax = Bounds.Ymax = 100.0f;
- Bounds.Xmin = Bounds.Ymin = -100.0f;
- return InitVarsGO(Desc);
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- if(Objects) for(i = 0; i < nObs; i++) if(Objects[i]) Objects[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "group", Desc);
- }
- return false;
-}
+ {"Items", typLAST | typOBJLST, &Objects, (long*)&nObs}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ Bounds.Xmax = Bounds.Ymax = 100.0f;
+ Bounds.Xmin = Bounds.Ymin = -100.0f;
+ return InitVarsGO(Desc);
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ if(Objects) for(i = 0; i < nObs; i++) if(Objects[i]) Objects[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "group", Desc);
+ }
+ return false;
+}
void
Scatt3D::RegGO(void *n)
@@ -2734,58 +2928,62 @@ Scatt3D::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-Scatt3D::FileIO(int rw)
-{
- descIO Desc[] = {
- {"ssRefX", typTEXT, &ssRefX, 0L},
- {"ssRefY", typTEXT, &ssRefY, 0L},
- {"ssRefZ", typTEXT, &ssRefZ, 0L},
+
+bool
+Scatt3D::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"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},
+ {"Line", typGOBJ, &Line, 0L},
+ {"Balls", typOBJLST, &Balls, &nBalls},
+ {"Columns", typOBJLST, &Columns, &nColumns},
{"DropLines", typOBJLST, &DropLines, &nDropLines},
- {"ParaV", typGOBJ, &rib, 0L},
- {"Arrows", typLAST | typOBJLST, &Arrows, &nArrows}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- c_flags = 0L;
- Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
- xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
- xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
- dirty = true;
+ {"ParaV", typGOBJ, &rib, 0L},
+ {"Arrows", typLAST | typOBJLST, &Arrows, &nArrows}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ c_flags = 0L;
+ Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
+ xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
+ xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
+ dirty = true;
if(name) {
- sprintf(TmpTxt, "xyz-plot (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "xyz-plot (%s)", name);
+#else
+ i = sprintf(TmpTxt, "xyz-plot (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- ExecInput(Desc);
- //now set parent in all children
- if(Balls) for(i = 0; i < nBalls; i++) if(Balls[i]) Balls[i]->parent = this;
- if(Columns) for(i = 0; i < nColumns; i++) if(Columns[i]) Columns[i]->parent = this;
- if(DropLines) for(i = 0; i < nDropLines; i++) if(DropLines[i]) DropLines[i]->parent = this;
- if(Arrows) for(i = 0; i < nArrows; i++) if(Arrows[i]) Arrows[i]->parent = this;
- if(Line) Line->parent = this;
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ //now set parent in all children
+ if(Balls) for(i = 0; i < nBalls; i++) if(Balls[i]) Balls[i]->parent = this;
+ if(Columns) for(i = 0; i < nColumns; i++) if(Columns[i]) Columns[i]->parent = this;
+ if(DropLines) for(i = 0; i < nDropLines; i++) if(DropLines[i]) DropLines[i]->parent = this;
+ if(Arrows) for(i = 0; i < nArrows; i++) if(Arrows[i]) Arrows[i]->parent = this;
+ if(Line) Line->parent = this;
if(rib) rib->parent = this;
- return true;
- case FILE_WRITE:
+ return true;
+ case FILE_WRITE:
if(Line) Line->FileIO(rw);
- if(rib) rib->FileIO(rw);
- if(Balls) for(i = 0; i < nBalls; i++) if(Balls[i]) Balls[i]->FileIO(rw);
- if(Columns) for(i = 0; i < nColumns; i++) if(Columns[i]) Columns[i]->FileIO(rw);
- if(DropLines) for(i = 0; i < nDropLines; i++) if(DropLines[i]) DropLines[i]->FileIO(rw);
- if(Arrows) for(i = 0; i < nArrows; i++) if(Arrows[i]) Arrows[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Scatt3D", Desc);
- }
- return false;
-}
-
+ if(rib) rib->FileIO(rw);
+ if(Balls) for(i = 0; i < nBalls; i++) if(Balls[i]) Balls[i]->FileIO(rw);
+ if(Columns) for(i = 0; i < nColumns; i++) if(Columns[i]) Columns[i]->FileIO(rw);
+ if(DropLines) for(i = 0; i < nDropLines; i++) if(DropLines[i]) DropLines[i]->FileIO(rw);
+ if(Arrows) for(i = 0; i < nArrows; i++) if(Arrows[i]) Arrows[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Scatt3D", Desc);
+ }
+ return false;
+}
+
void
Ribbon::RegGO(void *n)
{
@@ -2795,48 +2993,52 @@ Ribbon::RegGO(void *n)
if(planes) for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->RegGO(n);
((notary*)n)->AddRegGO(this);
}
-}
-
-bool
-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},
- {"ssRefX", typTEXT, &ssRefX, 0L},
- {"ssRefY", typTEXT, &ssRefY, 0L},
- {"ssRefZ", typTEXT, &ssRefZ, 0L},
- {"Line", typLINEDEF, &Line, 0L},
- {"Fill", typFILLDEF, &Fill, 0L},
- {"values", typFPLST3D, &values, &nVal},
- {"Planes", typLAST | typOBJLST, &planes, &nPlanes}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
- xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
- xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
- relwidth = 0.6; dirty = true;
- if(name) {
- sprintf(TmpTxt, "ribbon (%s)", name);
- free(name); name=strdup(TmpTxt);
- }
- return true;
- case FILE_READ:
- ExecInput(Desc);
- //now set parent in all children
- if(planes) for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->parent = this;
- return true;
- case FILE_WRITE:
- if(planes) for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Ribbon", Desc);
- }
- return false;
+}
+
+bool
+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},
+ {"ssRefX", typTEXT, &ssRefX, 0L},
+ {"ssRefY", typTEXT, &ssRefY, 0L},
+ {"ssRefZ", typTEXT, &ssRefZ, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"Fill", typFILLDEF, &Fill, 0L},
+ {"values", typFPLST3D, &values, &nVal},
+ {"Planes", typLAST | typOBJLST, &planes, &nPlanes}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
+ xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
+ xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
+ relwidth = 0.6; dirty = true;
+ if(name) {
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "ribbon (%s)", name);
+#else
+ i = sprintf(TmpTxt, "ribbon (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
+ }
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ //now set parent in all children
+ if(planes) for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->parent = this;
+ return true;
+ case FILE_WRITE:
+ if(planes) for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Ribbon", Desc);
+ }
+ return false;
}
void
@@ -2872,8 +3074,12 @@ Grid3D::FileIO(int rw)
xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
step.fx = step.fz = 1.0;
if(name) {
- sprintf(TmpTxt, "grid (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "grid (%s)", name);
+#else
+ i = sprintf(TmpTxt, "grid (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
return true;
case FILE_READ:
@@ -2888,28 +3094,33 @@ Grid3D::FileIO(int rw)
return ExecOutput(Notary->RegisterGO(this), "Grid3D", Desc);
}
return false;
-}
-
-bool
-Limits::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Bounds", typLAST | typFRECT, &Bounds, 0L}};
-
- switch(rw) {
- case INIT_VARS:
+}
+
+bool
+Limits::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Bounds", typLAST | typFRECT, &Bounds, 0L}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
if(name) {
- sprintf(TmpTxt, "limits (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "limits (%s)", name);
+#else
+ i = sprintf(TmpTxt, "limits (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this), "Limits", Desc);
- }
- return false;
-}
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this), "Limits", Desc);
+ }
+ return false;
+}
void
Function::RegGO(void *n)
@@ -2919,43 +3130,49 @@ Function::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-Function::FileIO(int rw)
-{
- descIO Desc[] = {
+
+bool
+Function::FileIO(int rw)
+{
+ descIO Desc[] = {
{"hide", typNZINT, &hidden, 0L},
- {"x1", typNZLFLOAT, &x1, 0L},
- {"x2", typNZLFLOAT, &x2, 0L},
- {"xstep", typNZLFLOAT, &xstep, 0L},
- {"Line", typLINEDEF, &Line, 0L},
- {"f_xy", typTEXT, &cmdxy, 0L},
- {"param", typTEXT, ¶m, 0L},
- {"DataLine", typLAST | typGOBJ, &dl, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- cmdxy = param = 0L;
- memcpy(&Line, defs.GetLine(), sizeof(LineDEF));
+ {"x1", typNZLFLOAT, &x1, 0L},
+ {"x2", typNZLFLOAT, &x2, 0L},
+ {"xstep", typNZLFLOAT, &xstep, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"f_xy", typTEXT, &cmdxy, 0L},
+ {"param", typTEXT, ¶m, 0L},
+ {"DataLine", typGOBJ, &dl, 0L},
+ {"Desc", typLAST | typTEXT, &name, 0L}};
+ int i;
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ cmdxy = param = 0L;
+ memcpy(&Line, defs.GetLine(), sizeof(LineDEF));
if(name) {
- sprintf(TmpTxt, "function (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "function (%s)", name);
+#else
+ i = sprintf(TmpTxt, "function (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- ExecInput(Desc);
- if(dl) dl->parent = this;
- return true;
- case FILE_WRITE:
- if(dl) dl->FileIO(rw);
- ExecOutput(Notary->RegisterGO(this), "Function", Desc);
- }
- return false;
-}
-
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ if(dl) dl->parent = this;
+ return true;
+ case FILE_WRITE:
+ if(dl) dl->FileIO(rw);
+ ExecOutput(Notary->RegisterGO(this), "Function", Desc);
+ }
+ return false;
+}
+
void
FitFunc::RegGO(void *n)
{
@@ -2966,77 +3183,81 @@ FitFunc::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-FitFunc::FileIO(int rw)
-{
- descIO Desc[] = {
+
+bool
+FitFunc::FileIO(int rw)
+{
+ descIO Desc[] = {
{"hide", typNZINT, &hidden, 0L},
- {"ssXref", typTEXT, &ssXref, 0L},
- {"ssYref", typTEXT, &ssYref, 0L},
- {"x1", typNZLFLOAT, &x1, 0L},
- {"x2", typNZLFLOAT, &x2, 0L},
- {"xstep", typNZLFLOAT, &xstep, 0L},
- {"conv", typNZLFLOAT, &conv, 0L},
+ {"ssXref", typTEXT, &ssXref, 0L},
+ {"ssYref", typTEXT, &ssYref, 0L},
+ {"x1", typNZLFLOAT, &x1, 0L},
+ {"x2", typNZLFLOAT, &x2, 0L},
+ {"xstep", typNZLFLOAT, &xstep, 0L},
+ {"conv", typNZLFLOAT, &conv, 0L},
{"chi2", typNZLFLOAT, &chi2, 0L},
- {"maxiter", typNZINT, &maxiter, 0L},
- {"Line", typLINEDEF, &Line, 0L},
- {"f_xy", typTEXT, &cmdxy, 0L},
+ {"maxiter", typNZINT, &maxiter, 0L},
+ {"Line", typLINEDEF, &Line, 0L},
+ {"f_xy", typTEXT, &cmdxy, 0L},
{"p_xy", typTEXT, &parxy, 0L},
- {"Symbols", typLAST | typOBJLST, &Symbols, &nPoints}};
- int i;
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
- cmdxy = parxy = 0L;
- memcpy(&Line, defs.GetLine(), sizeof(LineDEF));
- conv = 1.0e-15; maxiter = 100;
- dl = 0L;
+ {"Symbols", typLAST | typOBJLST, &Symbols, &nPoints}};
+ int i;
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ cmdxy = parxy = 0L;
+ memcpy(&Line, defs.GetLine(), sizeof(LineDEF));
+ conv = 1.0e-15; maxiter = 100;
+ dl = 0L;
if(name) {
- sprintf(TmpTxt, "fit function (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "fit function (%s)", name);
+#else
+ i = sprintf(TmpTxt, "fit function (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
- case FILE_READ:
- ExecInput(Desc);
- if(Symbols) for(i = 0; i < nPoints; i++)
- if(Symbols[i]) Symbols[i]->parent = this;
- return true;
- case FILE_WRITE:
- if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "FitFunc", Desc);
- }
- return false;
-}
-
-bool
-GridLine::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"Line", typLINEDEF, &LineDef, 0L},
- {"flags", typLAST | typDWORD, &flags, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- return SaveVarGO(Desc);
- case INIT_VARS:
- InitVarsGO(Desc);
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ if(Symbols) for(i = 0; i < nPoints; i++)
+ if(Symbols[i]) Symbols[i]->parent = this;
+ return true;
+ case FILE_WRITE:
+ if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "FitFunc", Desc);
+ }
+ return false;
+}
+
+bool
+GridLine::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"Line", typLINEDEF, &LineDef, 0L},
+ {"flags", typLAST | typDWORD, &flags, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ return SaveVarGO(Desc);
+ case INIT_VARS:
+ InitVarsGO(Desc);
ncpts = 0; cpts = 0L; gl1 = gl2 = gl3 = 0L; ls = 0L;
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0; mo = 0L;
- return true;
- case FILE_READ:
- return ExecInput(Desc);
- case FILE_WRITE:
- return ExecOutput(Notary->RegisterGO(this),
- Id == GO_GRIDLINE ?(char*)"GridLine" :
- Id == GO_GRIDRADIAL? (char*)"GridRadial" : (char*)"GridLine3D", Desc);
- }
- return false;
-}
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0; mo = 0L;
+ return true;
+ case FILE_READ:
+ return ExecInput(Desc);
+ case FILE_WRITE:
+ return ExecOutput(Notary->RegisterGO(this),
+ Id == GO_GRIDLINE ?(char*)"GridLine" :
+ Id == GO_GRIDRADIAL? (char*)"GridRadial" : (char*)"GridLine3D", Desc);
+ }
+ return false;
+}
void
Tick::RegGO(void *n)
@@ -3047,95 +3268,99 @@ Tick::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-Tick::FileIO(int rw)
-{
- GraphObj *gl = Grid;
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"Val", typLFLOAT, &value, 0L},
- {"Flags", typDWORD, &flags, 0L},
- {"Rot", typNZLFLOAT, &angle, 0L},
- {"GridType", typINT, &gl_type, 0L},
- {"Grid", typGOBJ, &gl, 0L},
- {"Label", typGOBJ, &label, 0L},
- {"Size", typLAST | typLFLOAT, &size, 0L}};
-
- switch(rw) {
- case SAVE_VARS:
- if(Grid && (flags & AXIS_GRIDLINE)) Grid->FileIO(rw);
- if(label) label->FileIO(rw);
- return SaveVarGO(Desc);
- case INIT_VARS:
+
+bool
+Tick::FileIO(int rw)
+{
+ GraphObj *gl = Grid;
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"Val", typLFLOAT, &value, 0L},
+ {"Flags", typDWORD, &flags, 0L},
+ {"Rot", typNZLFLOAT, &angle, 0L},
+ {"GridType", typINT, &gl_type, 0L},
+ {"Grid", typGOBJ, &gl, 0L},
+ {"Label", typGOBJ, &label, 0L},
+ {"Size", typLAST | typLFLOAT, &size, 0L}};
+
+ switch(rw) {
+ case SAVE_VARS:
+ if(Grid && (flags & AXIS_GRIDLINE)) Grid->FileIO(rw);
+ if(label) label->FileIO(rw);
+ return SaveVarGO(Desc);
+ case INIT_VARS:
InitVarsGO(Desc);
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- fix = fiy = 0.0f; ls = 0L; Grid = 0L; mo = 0L;
- size = defs.GetSize(SIZE_AXIS_TICKS);
- return true;
- case FILE_READ:
- ExecInput(Desc);
- Grid = (GridLine*) gl;
- if(Grid)Grid->parent = this;
- if(label)label->parent = this;
- return true;
- case FILE_WRITE:
- if(Grid && (flags & AXIS_GRIDLINE)) Grid->FileIO(rw);
- else gl = 0L;
- if(label) label->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Tick", Desc);
- }
- return false;
-}
-
-void
-Axis::TickFile(char *name)
-{
- ReadCache *ca;
- int i, j, k, nt;
- char line[500], item[20];
- Tick **ttck;
-
- if(!name) return;
- if(!(ca = new ReadCache())) return;
- if(! ca->Open(name)) {
- delete ca;
- sprintf(TmpTxt, "Error open file \"%s\"\nfor axis ticks", name);
- ErrorBox(TmpTxt);
- return;
- }
- Command(CMD_FLUSH, 0L, 0L);
- if(!(Ticks = ((Tick**)calloc(nt = 100, sizeof(Tick*))))) return;
- for(i = 0; ; i++) {
- j = k = 0;
- ca->ReadLine(line, sizeof(line));
- if(!line[0]) break;
- while(line[j] && line[j] < 33) j++;
- do{ item[k] = line[j++]; }
- while(item[k] >32 && item[k++] != '=' && k <sizeof(item) && j <sizeof(line));
- item[k--] = 0; if(!line[j-1])j--;
- while(k && !(isdigit(item[k])))item[k--]=0;
- while(line[j] && (line[j]<33 || line[j] == '"'))j++;
- k = strlen(line);
- while(k >=j && (line[k] < 33 || line[k] == '"')) line[k--] = 0;
- //realloc table if necessary
- if(NumTicks >= nt) {
- if((ttck= (Tick**)realloc(Ticks, (nt += 1000)*sizeof(Tick*))))Ticks= ttck;
- else NumTicks--;
- }
- //now add tick to table
- if(!(Ticks[NumTicks] = new Tick(this, data, atof(item),
- line[j] ? axis->flags : axis->flags | AXIS_MINORTICK)))break;
- Ticks[NumTicks]->Command(CMD_SETTEXT, line+j, 0L);
- NumTicks++;
- }
- ca->Close();
- if(!NumTicks && Ticks) {
- free(Ticks);
- NumTicks = 0;
- }
- delete ca;
-}
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ fix = fiy = 0.0f; ls = 0L; Grid = 0L; mo = 0L;
+ size = DefSize(SIZE_AXIS_TICKS);
+ return true;
+ case FILE_READ:
+ ExecInput(Desc);
+ Grid = (GridLine*) gl;
+ if(Grid)Grid->parent = this;
+ if(label)label->parent = this;
+ return true;
+ case FILE_WRITE:
+ if(Grid && (flags & AXIS_GRIDLINE)) Grid->FileIO(rw);
+ else gl = 0L;
+ if(label) label->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Tick", Desc);
+ }
+ return false;
+}
+
+void
+Axis::TickFile(char *name)
+{
+ ReadCache *ca;
+ int i, j, k, nt;
+ char line[500], item[20];
+ Tick **ttck;
+
+ if(!name) return;
+ if(!(ca = new ReadCache())) return;
+ if(! ca->Open(name)) {
+ delete ca;
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "Error open file \"%s\"\nfor axis ticks", name);
+#else
+ sprintf(TmpTxt, "Error open file \"%s\"\nfor axis ticks", name);
+#endif
+ ErrorBox(TmpTxt);
+ return;
+ }
+ Command(CMD_FLUSH, 0L, 0L);
+ if(!(Ticks = ((Tick**)calloc(nt = 100, sizeof(Tick*))))) return;
+ for(i = 0; ; i++) {
+ j = k = 0;
+ ca->ReadLine(line, sizeof(line));
+ if(!line[0]) break;
+ while(line[j] && line[j] < 33) j++;
+ do{ item[k] = line[j++]; }
+ while(item[k] >32 && item[k++] != '=' && k <sizeof(item) && j <sizeof(line));
+ item[k--] = 0; if(!line[j-1])j--;
+ while(k && !(isdigit(item[k])))item[k--]=0;
+ while(line[j] && (line[j]<33 || line[j] == '"'))j++;
+ k = (int)strlen(line);
+ while(k >=j && (line[k] < 33 || line[k] == '"')) line[k--] = 0;
+ //realloc table if necessary
+ if(NumTicks >= nt) {
+ if((ttck= (Tick**)realloc(Ticks, (nt += 1000)*sizeof(Tick*))))Ticks= ttck;
+ else NumTicks--;
+ }
+ //now add tick to table
+ if(!(Ticks[NumTicks] = new Tick(this, data, atof(item),
+ line[j] ? axis->flags : axis->flags | AXIS_MINORTICK)))break;
+ Ticks[NumTicks]->Command(CMD_SETTEXT, line+j, 0L);
+ NumTicks++;
+ }
+ ca->Close();
+ if(!NumTicks && Ticks) {
+ free(Ticks);
+ NumTicks = 0;
+ }
+ delete ca;
+}
void
Axis::RegGO(void *n)
@@ -3148,83 +3373,83 @@ Axis::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-Axis::FileIO(int rw)
-{
- char *tickfile = 0L;
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"sAxLine", typLFLOAT, &sizAxLine, 0L},
- {"sAxTick", typLFLOAT, &sizAxTick, 0L},
- {"BrkGap", typLFLOAT, &brkgap, 0L},
- {"BrkSymSize", typLFLOAT, &brksymsize, 0L},
- {"BrkSym", typINT, &brksym, 0L},
- {"sTickLabel", typLFLOAT, &sizAxTickLabel, 0L},
- {"tick_type", typNZINT, &tick_type, 0L},
- {"tick_angle", typNZLFLOAT, &tick_angle, 0L},
- {"LbDist", typNZLFPOINT, &lbdist, 0L},
- {"TickLbDist", typNZLFPOINT, &tlbdist, 0L},
- {"Color", typDWORD, &colAxis, 0L},
- {"AxisDef", typPTRAXDEF, &axis},
- {"GridLine", typLINEDEF, &GridLine, 0L},
- {"GridType", typINT, &gl_type, 0L},
- {"Ticks", typOBJLST, &Ticks, (long*)&NumTicks},
- {"Label", typGOBJ, &axisLabel, 0L},
- {"TickFile", typTEXT, &tickfile, 0L},
- {"ssRefTV", typTEXT, &ssMATval, 0L},
- {"ssRefTL", typTEXT, &ssMATlbl, 0L},
- {"ssRefMT", typTEXT, &ssMITval, 0L},
- {"tlbDef", typLAST | typTXTDEF, &tlbdef, 0L}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- sizAxLine = defs.GetSize(SIZE_AXIS_LINE);
- sizAxTick = defs.GetSize(SIZE_AXIS_TICKS);
- sizAxTickLabel = defs.GetSize(SIZE_TICK_LABELS);
- colAxis = parent ? parent->GetColor(COL_AXIS) : defs.Color(COL_AXIS);
- GridLine.color = 0x00808080L;
- GridLine.pattern = 0xf8f8f8f8L;
- brksymsize = defs.GetSize(SIZE_TICK_LABELS);
- brkgap = defs.GetSize(SIZE_AXIS_TICKS);
- brksym = 2;
- tlbdef.ColTxt = parent ? parent->GetColor(COL_AXIS) : defs.Color(COL_AXIS);
- tlbdef.ColBg = parent ? parent->GetColor(COL_BG) : defs.Color(COL_AXIS);
- tlbdef.RotBL = tlbdef.RotCHAR = 0.0f;
- tlbdef.fSize = parent ? parent->GetSize(SIZE_TICK_LABELS) : defs.GetSize(SIZE_TICK_LABELS);
- tlbdef.Align = TXA_VCENTER | TXA_HCENTER;
- tlbdef.Style = TXS_NORMAL;
- tlbdef.Mode = TXM_TRANSPARENT;
- tlbdef.Font = FONT_HELVETICA;
- tlbdef.text = 0L; l_segs = 0L; nl_segs = 0;
- drawOut = scaleOut = 0L; bModified = false;
- mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
- mo = 0L;
- return true;
- case FILE_READ:
- if(axisLabel)DeleteGO(axisLabel);
- if(tickfile) free(tickfile); if(ssMATval) free(ssMATval);
- if(ssMATlbl) free(ssMATlbl); if(ssMITval) free(ssMITval);
- tickfile = 0L;
- if(ExecInput(Desc) && tickfile && tickfile[0]){
- TickFile(tickfile);
- free(tickfile); tickfile = 0L;
- }
- if(axis) axis->owner = this;
- if(axisLabel)axisLabel->parent = this;
- if(Ticks) for(i = 0; i < NumTicks; i++) if(Ticks[i]) Ticks[i]->parent = this;
- return true;
- case FILE_WRITE:
- //do all ticks
- for(i = 0; Ticks && i< NumTicks; i++) if(Ticks[i]) Ticks[i]->FileIO(rw);
- if(axisLabel) axisLabel->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Axis", Desc);
- }
- return false;
-}
-
+
+bool
+Axis::FileIO(int rw)
+{
+ char *tickfile = 0L;
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"sAxLine", typLFLOAT, &sizAxLine, 0L},
+ {"sAxTick", typLFLOAT, &sizAxTick, 0L},
+ {"BrkGap", typLFLOAT, &brkgap, 0L},
+ {"BrkSymSize", typLFLOAT, &brksymsize, 0L},
+ {"BrkSym", typINT, &brksym, 0L},
+ {"sTickLabel", typLFLOAT, &sizAxTickLabel, 0L},
+ {"tick_type", typNZINT, &tick_type, 0L},
+ {"tick_angle", typNZLFLOAT, &tick_angle, 0L},
+ {"LbDist", typNZLFPOINT, &lbdist, 0L},
+ {"TickLbDist", typNZLFPOINT, &tlbdist, 0L},
+ {"Color", typDWORD, &colAxis, 0L},
+ {"AxisDef", typPTRAXDEF, &axis},
+ {"GridLine", typLINEDEF, &GridLine, 0L},
+ {"GridType", typINT, &gl_type, 0L},
+ {"Ticks", typOBJLST, &Ticks, (long*)&NumTicks},
+ {"Label", typGOBJ, &axisLabel, 0L},
+ {"TickFile", typTEXT, &tickfile, 0L},
+ {"ssRefTV", typTEXT, &ssMATval, 0L},
+ {"ssRefTL", typTEXT, &ssMATlbl, 0L},
+ {"ssRefMT", typTEXT, &ssMITval, 0L},
+ {"tlbDef", typLAST | typTXTDEF, &tlbdef, 0L}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ sizAxLine = DefSize(SIZE_AXIS_LINE);
+ sizAxTick = DefSize(SIZE_AXIS_TICKS);
+ sizAxTickLabel = DefSize(SIZE_TICK_LABELS);
+ colAxis = parent ? parent->GetColor(COL_AXIS) : defs.Color(COL_AXIS);
+ GridLine.color = 0x00808080L;
+ GridLine.pattern = 0xf8f8f8f8L;
+ brksymsize = DefSize(SIZE_TICK_LABELS);
+ brkgap = DefSize(SIZE_AXIS_TICKS);
+ brksym = 2;
+ tlbdef.ColTxt = parent ? parent->GetColor(COL_AXIS) : defs.Color(COL_AXIS);
+ tlbdef.ColBg = parent ? parent->GetColor(COL_BG) : defs.Color(COL_AXIS);
+ tlbdef.RotBL = tlbdef.RotCHAR = 0.0f;
+ tlbdef.fSize = DefSize(SIZE_TICK_LABELS);
+ tlbdef.Align = TXA_VCENTER | TXA_HCENTER;
+ tlbdef.Style = TXS_NORMAL;
+ tlbdef.Mode = TXM_TRANSPARENT;
+ tlbdef.Font = FONT_HELVETICA;
+ tlbdef.text = 0L; l_segs = 0L; nl_segs = 0;
+ drawOut = scaleOut = 0L; bModified = false;
+ mrc.left = mrc.right = mrc.top = mrc.bottom = 0;
+ mo = 0L;
+ return true;
+ case FILE_READ:
+ if(axisLabel)DeleteGO(axisLabel);
+ if(tickfile) free(tickfile); if(ssMATval) free(ssMATval);
+ if(ssMATlbl) free(ssMATlbl); if(ssMITval) free(ssMITval);
+ tickfile = 0L;
+ if(ExecInput(Desc) && tickfile && tickfile[0]){
+ TickFile(tickfile);
+ free(tickfile); tickfile = 0L;
+ }
+ if(axis) axis->owner = this;
+ if(axisLabel)axisLabel->parent = this;
+ if(Ticks) for(i = 0; i < NumTicks; i++) if(Ticks[i]) Ticks[i]->parent = this;
+ return true;
+ case FILE_WRITE:
+ //do all ticks
+ for(i = 0; Ticks && i< NumTicks; i++) if(Ticks[i]) Ticks[i]->FileIO(rw);
+ if(axisLabel) axisLabel->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Axis", Desc);
+ }
+ return false;
+}
+
void
Plot3D::RegGO(void *n)
{
@@ -3237,66 +3462,70 @@ Plot3D::RegGO(void *n)
}
}
-bool
-Plot3D::FileIO(int rw)
-{
- fPOINT3D rot_vec, rot_ang;
- descIO Desc[] = {
- {"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", typLAST | typOBJLST, &plots, (long*)&nPlots}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- InitVarsGO(Desc);
- drag = 0L; moveable = 1;
- //set up RotDef
- RotDef[0] = 0.919384; RotDef[1] = 0.389104; RotDef[2] = -0.057709;
- RotDef[3] = 0.327146; RotDef[4] = 0.944974; RotDef[5] = 1.0-RotDef[4];
- cub1.fx = defs.GetSize(SIZE_GRECT_LEFT) + defs.GetSize(SIZE_DRECT_LEFT);
- cub2.fx = defs.GetSize(SIZE_GRECT_LEFT) + defs.GetSize(SIZE_DRECT_RIGHT);
- cub1.fy = defs.GetSize(SIZE_GRECT_TOP) + defs.GetSize(SIZE_DRECT_BOTTOM);
- cub2.fy = defs.GetSize(SIZE_GRECT_TOP) + defs.GetSize(SIZE_DRECT_TOP);
- cub1.fy += defs.GetSize(SIZE_DRECT_TOP); cub2.fy += defs.GetSize(SIZE_DRECT_TOP);
- cub1.fz = 0.0;
- cub2.fz = defs.GetSize(SIZE_DRECT_BOTTOM) - defs.GetSize(SIZE_DRECT_TOP);
- rotC.fx = (cub1.fx + cub2.fx)/2.0; rotC.fy = (cub1.fy + cub2.fy)/2.0;
- rotC.fz = (cub1.fz + cub2.fz)/2.0;
- dispObs = 0L; nmaxObs = 0; crea_flags = 0L; dirty = true;
- Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
- xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
- xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
+bool
+Plot3D::FileIO(int rw)
+{
+ fPOINT3D rot_vec, rot_ang;
+ descIO Desc[] = {
+ {"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", typLAST | typOBJLST, &plots, (long*)&nPlots}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ InitVarsGO(Desc);
+ drag = 0L; moveable = 1;
+ //set up RotDef
+ RotDef[0] = 0.919384; RotDef[1] = 0.389104; RotDef[2] = -0.057709;
+ RotDef[3] = 0.327146; RotDef[4] = 0.944974; RotDef[5] = 1.0-RotDef[4];
+ cub1.fx = DefSize(SIZE_GRECT_LEFT) + DefSize(SIZE_DRECT_LEFT);
+ cub2.fx = DefSize(SIZE_GRECT_LEFT) + DefSize(SIZE_DRECT_RIGHT);
+ cub1.fy = DefSize(SIZE_GRECT_TOP) + DefSize(SIZE_DRECT_BOTTOM);
+ cub2.fy = DefSize(SIZE_GRECT_TOP) + DefSize(SIZE_DRECT_TOP);
+ cub1.fy += DefSize(SIZE_DRECT_TOP); cub2.fy += DefSize(SIZE_DRECT_TOP);
+ cub1.fz = 0.0;
+ cub2.fz = DefSize(SIZE_DRECT_BOTTOM) - DefSize(SIZE_DRECT_TOP);
+ rotC.fx = (cub1.fx + cub2.fx)/2.0; rotC.fy = (cub1.fy + cub2.fy)/2.0;
+ rotC.fz = (cub1.fz + cub2.fz)/2.0;
+ dispObs = 0L; nmaxObs = 0; crea_flags = 0L; dirty = true;
+ Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
+ xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
+ xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
if(name) {
- sprintf(TmpTxt, "3D-root (%s)", name);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "3D-root (%s)", name);
+#else
+ i = sprintf(TmpTxt, "3D-root (%s)", name);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
- return true;
+ 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);
- return ExecOutput(Notary->RegisterGO(this), "Plot3D", Desc);
- }
- return false;
-}
+ 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);
+ return ExecOutput(Notary->RegisterGO(this), "Plot3D", Desc);
+ }
+ return false;
+}
void
Func3D::RegGO(void *n)
@@ -3339,16 +3568,20 @@ Func3D::FileIO(int rw)
z1 = -20.0; z2 = 20.0; zstep = 2.0;
gda = 0L; gob = 0L;
param = cmdxy = 0L;
- Line.width = defs.GetSize(SIZE_HAIRLINE);
- Line.patlength = defs.GetSize(SIZE_PATLENGTH);
+ Line.width = DefSize(SIZE_HAIRLINE);
+ Line.patlength = DefSize(SIZE_PATLENGTH);
Line.color = Line.pattern = 0x0L;
Fill.color = 0x00c0c0c0;
Fill.color2 = 0x00ffffff;
Fill.hatch = 0L;
Fill.type = FILL_LIGHT3D;
if(name) {
- sprintf(TmpTxt, "3D function (Plot %d)", cPlots);
- free(name); name=strdup(TmpTxt);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "3D function (Plot %d)", cPlots);
+#else
+ i = sprintf(TmpTxt, "3D function (Plot %d)", cPlots);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
return true;
case FILE_READ:
@@ -3416,16 +3649,20 @@ FitFunc3D::FileIO(int rw)
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.width = DefSize(SIZE_HAIRLINE);
+ Line.patlength = DefSize(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);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "FitFunc3D (Plot %d)", cPlots);
+#else
+ i = sprintf(TmpTxt, "FitFunc3D (Plot %d)", cPlots);
+#endif
+ free(name); name = (char*)memdup(TmpTxt, i+1, 0);
}
return true;
case FILE_READ:
@@ -3446,7 +3683,7 @@ FitFunc3D::FileIO(int rw)
}
return false;
}
-
+
void
Graph::RegGO(void *n)
{
@@ -3459,77 +3696,78 @@ Graph::RegGO(void *n)
}
}
-bool
-Graph::FileIO(int rw)
-{
- int ixax, iyax;
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"Units", typNZINT, &units, 0L},
- {"GRect", typFRECT, &GRect, 0L},
- {"DRect", typFRECT, &DRect, 0L},
- {"Bounds", typFRECT, &Bounds, 0L},
- {"ColFrame", typDWORD, &ColGR, 0L},
- {"ColFrameL", typDWORD, &ColGRL, 0L},
- {"ColRec", typDWORD, &ColDR, 0L},
- {"ColAxis", typDWORD, &ColAX, 0L},
- {"Xaxis", typAXDEF, &x_axis, 0L},
- {"Yaxis", typAXDEF, &y_axis, 0L},
- {"DefXAxis", typINT, &ixax, 0L},
- {"DefYAxis", typINT, &iyax, 0L},
- {"Axes", typOBJLST, &Axes, (long*)&NumAxes},
- {"Plots", typLAST | typOBJLST, &Plots, (long*)&NumPlots}};
- int i;
- bool bConvert = false;
-
- ixax = iyax = -1;
- switch(rw) {
- case INIT_VARS:
- 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);
- DRect.Xmin = defs.GetSize(SIZE_DRECT_LEFT); DRect.Xmax = defs.GetSize(SIZE_DRECT_RIGHT);
- 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;
- 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;
+bool
+Graph::FileIO(int rw)
+{
+ int ixax, iyax;
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"Units", typNZINT, &units, 0L},
+ {"Scale", typNZLFLOAT, &scale, 0L},
+ {"GRect", typFRECT, &GRect, 0L},
+ {"DRect", typFRECT, &DRect, 0L},
+ {"Bounds", typFRECT, &Bounds, 0L},
+ {"ColFrame", typDWORD, &ColGR, 0L},
+ {"ColFrameL", typDWORD, &ColGRL, 0L},
+ {"ColRec", typDWORD, &ColDR, 0L},
+ {"ColAxis", typDWORD, &ColAX, 0L},
+ {"Xaxis", typAXDEF, &x_axis, 0L},
+ {"Yaxis", typAXDEF, &y_axis, 0L},
+ {"DefXAxis", typINT, &ixax, 0L},
+ {"DefYAxis", typINT, &iyax, 0L},
+ {"Axes", typOBJLST, &Axes, (long*)&NumAxes},
+ {"Plots", typLAST | typOBJLST, &Plots, (long*)&NumPlots}};
+ int i;
+ bool bConvert = false;
+
+ ixax = iyax = -1;
+ switch(rw) {
+ case INIT_VARS:
+ 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);
+ DRect.Xmin = defs.GetSize(SIZE_DRECT_LEFT); DRect.Xmax = defs.GetSize(SIZE_DRECT_RIGHT);
+ 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;
+ 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; PasteObj = 0L; filename = 0L;
- rc_mrk.left = rc_mrk.right = rc_mrk.top = rc_mrk.bottom = -1;
- return true;
- case FILE_READ:
- units = 0; //default to mm if statement mising in file
- if((bConvert =ExecInput(Desc)) && ixax>=0 && iyax >=0 && Axes &&
- NumAxes >= ixax+1 && NumAxes >= iyax) {
- if(Axes[ixax]) Axes[ixax]->Command(CMD_SET_AXDEF, &x_axis, 0L);
- if(Axes[iyax]) Axes[iyax]->Command(CMD_SET_AXDEF, &y_axis, 0L);
- return true;
- }
- return bConvert;
- case FILE_WRITE:
- bModified = false;
- //find default axes
- if(Axes) for(i = 0; Axes && i < NumAxes; i++) {
- if(Axes[i] && Axes[i]->GetAxis() == &x_axis) ixax = i;
- else if(Axes[i] && Axes[i]->GetAxis() == &y_axis) iyax = i;
+ 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:
+ units = 0; //default to mm if statement mising in file
+ if((bConvert =ExecInput(Desc)) && ixax>=0 && iyax >=0 && Axes &&
+ NumAxes >= ixax+1 && NumAxes >= iyax) {
+ if(Axes[ixax]) Axes[ixax]->Command(CMD_SET_AXDEF, &x_axis, 0L);
+ if(Axes[iyax]) Axes[iyax]->Command(CMD_SET_AXDEF, &y_axis, 0L);
+ return true;
+ }
+ return bConvert;
+ case FILE_WRITE:
+ bModified = false; if(scale == 1.0) scale = 0.0;
+ //find default axes
+ if(Axes) for(i = 0; Axes && i < NumAxes; i++) {
+ if(Axes[i] && Axes[i]->GetAxis() == &x_axis) ixax = i;
+ else if(Axes[i] && Axes[i]->GetAxis() == &y_axis) iyax = i;
}
- if(Id == GO_GRAPH)RegGO(Notary);
- //do all plots
- if(Plots) for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->FileIO(rw);
- //do all axes
- if(Axes) for(i = 0; i< NumAxes; i++) if(Axes[i]) Axes[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Graph", Desc);
- }
- return false;
-}
-
+ if(Id == GO_GRAPH)RegGO(Notary);
+ //do all plots
+ if(Plots) for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->FileIO(rw);
+ //do all axes
+ if(Axes) for(i = 0; i< NumAxes; i++) if(Axes[i]) Axes[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Graph", Desc);
+ }
+ return false;
+}
+
void
Page::RegGO(void *n)
{
@@ -3541,75 +3779,79 @@ Page::RegGO(void *n)
((notary*)n)->AddRegGO(this);
}
}
-
-bool
-Page::FileIO(int rw)
-{
- descIO Desc[] = {
- {"Type", typNZINT, &type, 0L},
- {"Units", typNZINT, &units, 0L},
- {"GRect", typFRECT, &GRect, 0L},
- {"Plots", typLAST | typOBJLST, &Plots, (long*)&NumPlots}};
- int i;
-
- switch(rw) {
- case INIT_VARS:
- //assume that Graph::FileIO(INIT_VARS) has been executed
- GRect.Xmin = GRect.Ymin = 0.0;
- GetPaper(&GRect.Xmax, &GRect.Ymax);
- ColBG = 0x00e8e8e8L;
- LineDef.width = 0.0; LineDef.patlength = 1.0;
- LineDef.color = LineDef.pattern = 0x0L;
- FillDef.type = FILL_NONE;
- FillDef.color = 0x00ffffffL; //use white paper
- FillDef.scale = 1.0;
- FillDef.hatch = 0L; filename =0L;
- return true;
- case FILE_READ:
- Graph::FileIO(rw);
- return true;
- case FILE_WRITE:
- //do all plots
+
+bool
+Page::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"Type", typNZINT, &type, 0L},
+ {"Units", typNZINT, &units, 0L},
+ {"GRect", typFRECT, &GRect, 0L},
+ {"Plots", typLAST | typOBJLST, &Plots, (long*)&NumPlots}};
+ int i;
+
+ switch(rw) {
+ case INIT_VARS:
+ //assume that Graph::FileIO(INIT_VARS) has been executed
+ GRect.Xmin = GRect.Ymin = 0.0;
+ GetPaper(&GRect.Xmax, &GRect.Ymax);
+ ColBG = 0x00e8e8e8L;
+ LineDef.width = 0.0; LineDef.patlength = 1.0;
+ LineDef.color = LineDef.pattern = 0x0L;
+ FillDef.type = FILL_NONE;
+ FillDef.color = 0x00ffffffL; //use white paper
+ FillDef.scale = 1.0;
+ FillDef.hatch = 0L; filename =0L;
+ return true;
+ case FILE_READ:
+ Graph::FileIO(rw);
+ return true;
+ case FILE_WRITE:
+ //do all plots
bModified = false;
if(Id == GO_PAGE)RegGO(Notary);
- if(Plots) for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->FileIO(rw);
- return ExecOutput(Notary->RegisterGO(this), "Page", Desc);
- }
- return false;
-}
-
-bool
-DefsRW::FileIO(int rw)
-{
- descIO Desc[] = {
- {"dUnits", typINT, &defs.dUnits, 0L},
- {"cUnits", typINT, &defs.dUnits, 0L},
+ if(Plots) for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->FileIO(rw);
+ return ExecOutput(Notary->RegisterGO(this), "Page", Desc);
+ }
+ return false;
+}
+
+bool
+DefsRW::FileIO(int rw)
+{
+ descIO Desc[] = {
+ {"dUnits", typINT, &defs.dUnits, 0L},
+ {"cUnits", typINT, &defs.dUnits, 0L},
{"dtHeight", typINT, &dlgtxtheight, 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},
- {"curr_path", typTEXT, &defs.currPath, 0L},
- {"File1", typTEXT, &defs.File1, 0L},
- {"File2", typTEXT, &defs.File2, 0L},
- {"File3", typTEXT, &defs.File3, 0L},
- {"File4", typTEXT, &defs.File4, 0L},
- {"File5", typTEXT, &defs.File5, 0L},
- {"File6", typLAST | typTEXT, &defs.File6, 0L}};
-
- switch(rw) {
- case FILE_READ:
- ExecInput(Desc);
- return true;
- case FILE_WRITE:
- Notary = new notary();
- unlink(defs.IniFile);
- iFile = OpenOutputFile(defs.IniFile);
- if(iFile >=0) {
- ExecOutput(-1, "Defaults", Desc);
- }
- CloseOutputFile(); if(Notary) delete Notary; Notary = 0L;
- return true;
- }
- return false;
-}
+ {"curr_path", typTEXT, &defs.currPath, 0L},
+ {"File1", typTEXT, &defs.File1, 0L},
+ {"File2", typTEXT, &defs.File2, 0L},
+ {"File3", typTEXT, &defs.File3, 0L},
+ {"File4", typTEXT, &defs.File4, 0L},
+ {"File5", typTEXT, &defs.File5, 0L},
+ {"File6", typLAST | typTEXT, &defs.File6, 0L}};
+
+ switch(rw) {
+ case FILE_READ:
+ ExecInput(Desc);
+ return true;
+ case FILE_WRITE:
+ Notary = new notary();
+#ifdef USE_WIN_SECURE
+ _unlink(defs.IniFile);
+#else
+ unlink(defs.IniFile);
+#endif
+ iFile = OpenOutputFile(defs.IniFile);
+ if(iFile >=0) {
+ ExecOutput(-1, "Defaults", Desc);
+ }
+ CloseOutputFile(); if(Notary) delete Notary; Notary = 0L;
+ return true;
+ }
+ return false;
+}
diff --git a/ODbuttons.cpp b/ODbuttons.cpp
index 14cd26f..6d64b7d 100755
--- a/ODbuttons.cpp
+++ b/ODbuttons.cpp
@@ -116,7 +116,7 @@ int ExecDrawOrderButt(GraphObj *parent, GraphObj *obj, int id)
void OD_LineStyleTempl(int cmd, void *par, RECT *rec, anyOutput *o,
void *data, int id)
{
- LineDEF Line = {.1f, 1.0f, 0x0L, 0x0L};
+ LineDEF Line = {0.0, 1.0, 0x0L, 0x0L};
FillDEF Fill = {FILL_NONE, 0x00ffffffL, 1.0, 0L};
POINT *pts;
int i, ix, iy, np;
@@ -245,7 +245,7 @@ void OD_LineStyleTempl(int cmd, void *par, RECT *rec, anyOutput *o,
void OD_ErrBarTempl(int cmd, void *par, RECT *rec, anyOutput *o,
void *data, int id)
{
- LineDEF Line = {.1f, 1.0f, 0x0L, 0x0L};
+ LineDEF Line = {0.0, 1.0, 0x0L, 0x0L};
FillDEF Fill = {FILL_NONE, 0x00ffffffL, 1.0, 0L};
POINT pts[6];
int ix, iy;
@@ -309,7 +309,7 @@ void OD_ErrBarTempl(int cmd, void *par, RECT *rec, anyOutput *o,
void OD_WhiskerTempl(int cmd, void *par, RECT *rec, anyOutput *o,
void *data, int id)
{
- LineDEF Line = {.1f, 1.0f, 0x0L, 0x0L};
+ LineDEF Line = {0.0, 1.0, 0x0L, 0x0L};
FillDEF Fill = {FILL_NONE, 0x00ffffffL, 1.0, 0L};
POINT pts[6];
int ix, iy;
@@ -551,7 +551,7 @@ void OD_AxisDesc3D(int cmd, void *par, RECT *rec, anyOutput *o,
void OD_BreakTempl(int cmd, void *par, RECT *rec, anyOutput *o,
void *data, int id)
{
- LineDEF Line = {.1f, 1.0f, 0x0L, 0x0L};
+ LineDEF Line = {0.0, 1.0, 0x0L, 0x0L};
FillDEF Fill = {FILL_NONE, 0x00ffffffL, 1.0, 0L};
POINT pts[15];
int i, ix, iy;
diff --git a/Output.cpp b/Output.cpp
index 6ee7048..82e3083 100755
--- a/Output.cpp
+++ b/Output.cpp
@@ -356,7 +356,6 @@ anyOutput::GetLine(LineDEF *lDef)
return false;
}
-
bool
anyOutput::SetTextSpec(TextDEF *set)
{
@@ -365,7 +364,6 @@ anyOutput::SetTextSpec(TextDEF *set)
return true;
}
-
bool
anyOutput::ShowMark(void *src, int Mode)
{
@@ -424,7 +422,7 @@ anyOutput::CalcCursorPos(char *txt, POINT p, POINT *fit)
d = TxtSet.iSize >>2;
if(!txt || !fit) return 0;
- if (!(i = strlen(txt)))return 0;
+ if (!(i = (int)strlen(txt)))return 0;
//right justified text
if(TXA_HRIGHT == (TxtSet.Align & TXA_HRIGHT)){
if((p.x - fit->x) < d) return i;
@@ -455,7 +453,7 @@ anyOutput::TextCursor(char *txt, POINT p, POINT *fit, int *pos, int dx)
//recalculate caret position
if(txt && pos && !fit){
if(TxtSet.Align & TXA_HRIGHT) { //right justfied text
- if((i = strlen(txt)-(*pos))){
+ if((i = (int)strlen(txt)-(*pos))){
if(!oGetTextExtent(txt+(*pos), i, &w, &h)) return false;
w = p.x - w;
}
@@ -470,7 +468,7 @@ anyOutput::TextCursor(char *txt, POINT p, POINT *fit, int *pos, int dx)
else if(!fit)return false;
//right justified text: search caret and cursor position
else if(txt && (TxtSet.Align & TXA_HRIGHT)){
- i = strlen(txt);
+ i = (int)strlen(txt);
if(i == CurrPos) w = 1;
else if(!oGetTextExtent(txt+CurrPos, i-CurrPos, &w, &h)) return false;
w = p.x - w;
@@ -638,7 +636,7 @@ anyOutput::oGetTextExtent(char *text, int cb, int *width, int *height)
case FONT_COURIER: CharWidth = Cour_Char_Width; break;
default: CharWidth = Helv_Char_Width; break;
}
- if(!cb && text) cb = strlen(text);
+ if(!cb && text) cb = (int)strlen(text);
for(i = w = 0; i < cb; i++) w += CharWidth[text[i]];
*width = iround(((double)w * (double)TxtSet.iSize)/52.0);
*height = TxtSet.iSize;
@@ -676,7 +674,7 @@ anyOutput::oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
enum {HO_NONE, HO_RECT, HO_CIRCLE, HO_ELLIPSE, HO_BIGELLYPSE,
HO_POLYGON};
-struct {
+struct _HatchDef{
union {
struct {
RECT rec;
@@ -1768,7 +1766,7 @@ ExportTif::ExportTif(GraphObj *g, char *FileName, DWORD flags, double res, doubl
bmo->Erase(0x00ffffffL);
g->DoPlot(bmo);
}
- name = strdup(FileName);
+ name = (char*)memdup(FileName, (int)strlen(FileName)+1, 0);
}
oFile = 0;
}
@@ -1820,24 +1818,40 @@ ExportTif::StartPage()
};
DWORD res_info[4] = {iround(hres), 0x01, iround(vres), 0x01};
char prog_name[20];
-
+ int cb;
if(name && bmo) {
+#ifdef USE_WIN_SECURE
+ if(_sopen_s(&oFile, name, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
+ 0x40, S_IWRITE) || oFile < 0){
+ ErrorBox("Could not open output file");
+ return false;
+ }
+#else
if(-1 ==(oFile = open(name, O_RDWR | O_BINARY | O_CREAT | O_TRUNC,
- S_IWRITE | S_IREAD))) {
+ S_IWRITE | S_IREAD))){
ErrorBox("Could not open output file");
return false;
}
+#endif
*((int*)(header+30))= w; *((int*)(header+42))= h;
*((DWORD*)(header+126)) = (DWORD)(w * h * 3);
*((int*)(header+90)) = sizeof(header) + sizeof(res_info) + 20;
*((int*)(header+138)) = sizeof(header);
*((int*)(header+150)) = sizeof(header)+8;
*((int*)(header+186)) = sizeof(header)+16;
- sprintf(prog_name, "RLPlot %s", SZ_VERSION);
+ cb = rlp_strcpy(prog_name, 20, "RLPlot ");
+ rlp_strcpy(prog_name+cb, 20-cb, SZ_VERSION);
+#ifdef USE_WIN_SECURE
+ _write(oFile, &header, sizeof(header));
+ _write(oFile, &res_info, sizeof(res_info));
+ _write(oFile, &prog_name, 20);
+
+#else
write(oFile, &header, sizeof(header));
write(oFile, &res_info, sizeof(res_info));
- write(oFile, &res_info, 20);
+ write(oFile, &prog_name, 20);
+#endif
return true;
}
return false;
@@ -1856,15 +1870,28 @@ ExportTif::EndPage()
bmo->oGetPix(j, i, &pix); pix_data[c++] = cpix[0];
pix_data[c++] = cpix[1]; pix_data[c++] = cpix[2];
if(c >= 3072) {
+#ifdef USE_WIN_SECURE
+ _write(oFile, pix_data, 3072);
+#else
write(oFile, pix_data, 3072);
+#endif
c = 0;
}
}
}
+#ifdef USE_WIN_SECURE
+ _write(oFile, pix_data, c);
+#else
write(oFile, pix_data, c);
+#endif
free(pix_data);
}
- oFile = close(oFile);
+#ifdef USE_WIN_SECURE
+ _close(oFile);
+#else
+ close(oFile);
+#endif
+ oFile = -1;
return true;
}
diff --git a/PlotObs.cpp b/PlotObs.cpp
index 926bec2..8a7fe3a 100755
--- a/PlotObs.cpp
+++ b/PlotObs.cpp
@@ -43,12 +43,16 @@ int AxisTempl3D = 0;
Plot::Plot(GraphObj *par, DataObj *d):GraphObj(par, d)
{
+ int pos, nsize;
+
Id = GO_PLOT;
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
- sprintf(TmpTxt, "Plot %d", ++cPlots);
- name = strdup(TmpTxt);
- use_xaxis = use_yaxis = 0;
- hidden = 0;
+ if(name = (char*)malloc((nsize = 20)*sizeof(char))){
+ pos = rlp_strcpy(name, nsize, (char*)"Plot");
+ add_int_to_buff(&name, &pos, &nsize, ++cPlots, true, 0);
+ }
+ use_xaxis = use_yaxis = 0; hidden = 0;
+ x_info = y_info = z_info = 0L;
}
double
@@ -70,8 +74,7 @@ Plot::GetSize(int select)
case SIZE_BARMINY:
return 1.0f;
default:
- if(parent) return parent->GetSize(select);
- else return defs.GetSize(select);
+ return DefSize(select);
}
}
@@ -172,53 +175,52 @@ DataObj *
Plot::CreaCumData(char *xr, char *yr, int mode, double base)
{
char **yranges;
- int i, j, nc, nr, ir, ic;
+ int i, j, nc, nr, ir, ic, n;
double value, old_val;
DataObj *CumData = 0L;
AccRange *ax = 0L, *ay = 0L;
if(!xr || !yr || !mode || !data) return 0L;
if(!(CumData = new DataObj()))return 0L;
+ //count valid data lines
if(!(ax = new AccRange(xr))) {
- delete CumData; return 0L;
+ delete CumData; CumData = 0L; return 0L;
}
- nr = ax->CountItems();
+ for(nr = 0, ax->GetFirst(&ic, &ir); ax->GetNext(&ic, &ir); )
+ if(data->GetValue(ir, ic, &value))nr++;
if(!(yranges = split(yr, '&', &nc))){
delete CumData; delete ax; return 0L;
}
if(CumData->Init(mode == 1 || mode == 2 ? nr : nr * 2, nc+2)){
// set x values as first column
- for(i = 0, ax->GetFirst(&ic, &ir); ax->GetNext(&ic, &ir); i++) {
- if(data->GetValue(ir, ic, &value)) CumData->SetValue(i, 0, value);
- CumData->SetValue(i, 1, base);
+ for(i = n = 0, ax->GetFirst(&ic, &ir); ax->GetNext(&ic, &ir); i++) {
+ if(data->GetValue(ir, ic, &value)){
+ CumData->SetValue(n, 0, value); CumData->SetValue(n++, 1, base);
+ }
}
- if(mode == 3 || mode == 4) for(i = 1; i <= nr; i++) { //complete polygon data
+ if(mode == 3 || mode == 4) for(i = 1; i <= nr; i++) { //complete polygon data
if(CumData->GetValue(nr-i, 0, &value)) CumData->SetValue(i-1+nr, 0, value);
}
//process all y-ranges
for (j = 2; j <= (nc+1); j++) if(ay = new AccRange(yranges[j-2])){
- for(i = 0; i < nr; i++) {
- if(CumData->GetValue(i, j-1, &value)) CumData->SetValue(i, j, value);
+ for(i = n = 0; i < nr; i++) {
+ if(CumData->GetValue(n, j-1, &value)) CumData->SetValue(n++, j, value);
}
- for(i = 0, ay->GetFirst(&ic, &ir); ay->GetNext(&ic, &ir) && i < nr; i++) {
- if(data->GetValue(ir, ic, &value) && CumData->GetValue(i, j, &old_val)){
+ for(i = n = 0, ay->GetFirst(&ic, &ir); ay->GetNext(&ic, &ir) && n < nr; i++) {
+ if(data->GetValue(ir, ic, &value) && CumData->GetValue(n, j, &old_val)){
switch (mode) {
case 1: case 3: value += old_val; break;
case 2: case 4: value = old_val -value; break;
}
- CumData->SetValue(i, j, value);
+ CumData->SetValue(n++, j, value);
}
}
- if(mode == 3 || mode == 4) for(i = 1; i <= nr; i++) {
- //complete polygon data
+ if(mode == 3 || mode == 4) for(i = 1; i <= nr; i++) { //complete polygon data
if(CumData->GetValue(nr-i, j-1, &value)) CumData->SetValue(i-1+nr, j, value);
}
delete ay; ay = 0L;
}
}
-
-
-
for(i = 0; i < nc; i++) if(yranges[i]) free(yranges[i]);
if(ax) delete ax; if(ay) delete ay;
free(yranges);
@@ -280,6 +282,8 @@ PlotScatt::~PlotScatt()
{
ForEach(FE_FLUSH, 0L, 0L);
if(name) free(name); name=0L;
+ if(x_info) free(x_info); x_info = 0L;
+ if(y_info) free(x_info); y_info = 0L;
Undo.InvalidGO(this);
}
@@ -413,11 +417,11 @@ PlotScatt::Command(int cmd, void *tmpl, anyOutput *o)
if(Symbols) {
if(TheLine && TheLine->Id == GO_DATALINE) {
for (i = 0; i < nPoints && i < 100; i++)
- if(Symbols[i]) ((Legend*)tmpl)->HasSym(&TheLine->LineDef, Symbols[i]);
+ if(Symbols[i]) ((Legend*)tmpl)->HasSym(&TheLine->LineDef, Symbols[i], 0L);
}
else {
for (i = 0; i < nPoints && i < 100; i++)
- if(Symbols[i]) ((Legend*)tmpl)->HasSym(0L, Symbols[i]);
+ if(Symbols[i]) ((Legend*)tmpl)->HasSym(0L, Symbols[i], 0L);
}
if(TheLine && TheLine->Id == GO_DATAPOLYGON) TheLine->Command(cmd, tmpl, o);
}
@@ -472,7 +476,7 @@ PlotScatt::Command(int cmd, void *tmpl, anyOutput *o)
((Plot*)parent)->CheckBounds(Bounds.Xmax, Bounds.Ymax);
}
return true;
- case CMD_HIDE_MARK:
+ case CMD_SCALE: case CMD_HIDE_MARK:
return ForEach(cmd, tmpl, o);
case CMD_MUTATE: case CMD_REPL_GO:
dirty = true;
@@ -566,9 +570,7 @@ PlotScatt::ForEach(int cmd, void *tmp, anyOutput *o)
}
if(TheLine) TheLine->parent = this;
return true;
- case CMD_UPDATE:
- case CMD_SET_DATAOBJ:
- case CMD_AUTOSCALE:
+ case CMD_UPDATE: case CMD_SET_DATAOBJ: case CMD_AUTOSCALE: case CMD_SCALE:
for(j = 0; j < 6; j++){
if(obs[j]) for(i = 0; i < nPoints; i++){
if(obs[j][i]) obs[j][i]->Command(cmd, tmp, o);
@@ -680,6 +682,8 @@ xyStat::~xyStat()
if(yRange) free(yRange); yRange = 0L;
if(xRange) free(xRange); xRange = 0L;
if(name) free(name); name=0L;
+ if(x_info) free(x_info); x_info = 0L;
+ if(y_info) free(x_info); y_info = 0L;
Undo.InvalidGO(this);
}
@@ -721,9 +725,9 @@ xyStat::CreateData()
lfPOINT *xy;
AccRange *rX, *rY;
- if(curr_data) delete curr_data; curr_data = 0L;
if(!data || !xRange || !yRange || !xRange[0] || !yRange[0]) return;
if(!(rX = new AccRange(xRange)) || !(rY = new AccRange(yRange))) return;
+ if(!x_info) x_info = rX->RangeDesc(data, 0); if(!y_info) y_info = rY->RangeDesc(data, 0);
m = rX->CountItems(); n = 0;
if(m < 2 || !(xy = (lfPOINT*) malloc(m * sizeof(lfPOINT)))) {
delete rX; delete rY;
@@ -781,7 +785,7 @@ xyStat::CreateData()
else type &= (~0x0480);
}
else q1 = q2 = q3 = 0L;
- if((curr_data = new DataObj()) && curr_data->Init(j, 6)) {
+ if((curr_data = curr_data ? curr_data : new DataObj()) && curr_data->Init(j, 6)) {
for(i = 0; i < j; i++) curr_data->SetValue(i,0,ax[i]); // set x-values
for(i = 0; i < j; i++) { // set y-values
if(ny[i] > 1) switch(type & 0x00f0) {
@@ -811,11 +815,11 @@ xyStat::CreateData()
curr_data->SetValue(i, 2, sqrt(ss));
break;
case 0x0200:
- curr_data->SetValue(i, 2, sqrt(ss)/sqrt(ny[i]));
+ curr_data->SetValue(i, 2, sqrt(ss)/sqrt((double)ny[i]));
break;
case 0x1000:
d = distinv(t_dist, ny[i]-1, 1, 1.0-(ci/100.0), 2.0);
- curr_data->SetValue(i, 2, d * sqrt(ss)/sqrt(ny[i]));
+ curr_data->SetValue(i, 2, d * sqrt(ss)/sqrt((double)ny[i]));
break;
}
}
@@ -839,14 +843,14 @@ xyStat::CreateData()
}
}
if(type & 0x6000) for(i = 0; i < j; i++) { // number of cases
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%s%d", case_prefix ? case_prefix : "", ny[i]);
+#else
sprintf(TmpTxt, "%s%d", case_prefix ? case_prefix : "", ny[i]);
+#endif
curr_data->SetText(i, 5, TmpTxt);
}
}
- else {
- if(curr_data) delete curr_data;
- curr_data = 0L;
- }
if(q1) free(q1); if(q2) free(q2); if(q3) free(q3);
for(i = 0; i < m; i++) if(ay[i]) free(ay[i]);
free(tay); free(ay); free(ax); free(ny); free(xy);
@@ -886,7 +890,8 @@ FreqDist::~FreqDist()
free(plots); plots=0L;
}
if(name) free(name); name=0L;
-
+ if(x_info) free(x_info); x_info = 0L;
+ if(y_info) free(y_info); y_info = 0L;
}
void
@@ -926,6 +931,9 @@ FreqDist::Command(int cmd, void *tmpl, anyOutput *o)
}
}
return false;
+ case CMD_SCALE:
+ if(plots) for(i = 0; i < nPlots; i++) if(plots[i]) plots[i]->Command(cmd, tmpl, o);
+ return true;
case CMD_HIDE_MARK:
if(plots) for(i = 0; i < nPlots; i++) if(plots[i]){
if(tmpl == (void*)plots[i]) {
@@ -1012,28 +1020,37 @@ void
FreqDist::ProcData(int sel)
{
AccRange *ar;
- int nv, i, j, r, c, ncl, *f_data, cb;
- double min = HUGE_VAL, max = -HUGE_VAL, sum, mean, sd, tmp, *s_data, *t_data;
+ int nv, i, j, r, c, ncl, *f_data, cb_f, size_fo, pos_fo;
+ double dmin = HUGE_VAL, dmax = -HUGE_VAL, min, max, sum, mean, sd, tmp, *s_data, *t_data, lstep;
+ double chi2, df, x, y;
+ anyResult *result;
Bar **bars = 0L;
- char *fo;
+ TextDEF td;
+ char *fo, *fdesc = 0L, formula[500];
if(!parent || !data || !ssRef || !plots) return;
if(curr_data) delete(curr_data);
if((curr_data = new DataObj()) && (ar = new AccRange(ssRef))) {
+ //copy spreadsheet data into array
nv = ar->CountItems(); ar->GetFirst(&c, &r);
if(!(s_data = (double*)malloc(nv * sizeof(double)))
|| !(t_data = (double*)malloc(nv * sizeof(double)))) {
delete(ar); return;
}
for(sum = 0.0, nv = 0; ar->GetNext(&c, &r); ) if(data->GetValue(r, c, &tmp)) {
- if(tmp > max) max = tmp; if(tmp < min) min = tmp;
+ if(tmp > dmax) dmax = tmp; if(tmp < dmin) dmin = tmp;
s_data[nv] = tmp;
switch (type & 0xff){
- case 2: t_data[nv] = log(tmp); break;
+ case 2:
+ if(tmp > 0.0) t_data[nv] = log(tmp);
+ else nv--;
+ break;
default: t_data[nv] = tmp; break;
}
nv++;
}
+ min = dmin; max = dmax;
+ lstep = (max-min)/100.0;
delete(ar);
d_variance(nv, t_data, &mean, &sd);
sd = sqrt(sd/((double)(nv-1)));
@@ -1057,14 +1074,17 @@ FreqDist::ProcData(int sel)
}
if(f_data[ncl]) ncl++;
curr_data->Init(ncl, 2);
+ //create data object containg the counts / bin and bars
for(i = 0; i< ncl; i++) {
curr_data->SetValue(i, 0, tmp = start + i * step + step * .5);
curr_data->SetValue(i, 1, (double)f_data[i]);
if(bars) {
- bars[i] = new Bar(this, 0L, tmp, (double)f_data[i], BAR_VERTB | BAR_RELWIDTH, 0, i, 1, i);
+ if(bars[i] = new Bar(this, 0L, tmp, (double)f_data[i], BAR_VERTB | BAR_RELWIDTH,
+ 0, i, 1, i, "Count")) bars[i]->SetSize(SIZE_BAR, 100.0);
}
}
free(s_data); free(t_data); free(f_data);
+ //create bar chart
if(bars && (plots[0] = new PlotScatt(this, data, ncl, bars))){
plots[0]->Command(CMD_BAR_FILL, &BarFill, 0L);
plots[0]->SetColor(COL_BAR_LINE, BarLine.color);
@@ -1074,22 +1094,128 @@ FreqDist::ProcData(int sel)
plots[0]->Command(CMD_SET_DATAOBJ, curr_data, 0L);
plots[0]->Command(CMD_AUTOSCALE, 0L, 0L);
}
- if((type & 0xff) && (fo = (char*)malloc(1000))) {
- cb = sprintf(fo, "[1=Function]\n");
- cb += sprintf(fo+cb,"x1= %g\n", min);
- cb += sprintf(fo+cb,"x2= %g\n", max);
- cb += sprintf(fo+cb,"xstep= %g\n", (max-min)/100.0);
- cb += sprintf(fo+cb,"Line= 0.4 6 0x000000ff 0x0\n");
+ //create function
+ if((type & 0xff) && (fo = (char*)malloc(size_fo = 1000))) {
+ pos_fo = rlp_strcpy(fo, 1000, (char*) "[1=Function]\nx1=");
+ add_dbl_to_buff(&fo, &pos_fo, &size_fo, min, true);
+ add_to_buff(&fo, &pos_fo, &size_fo,(char*)"\nx2=", 4);
+ add_dbl_to_buff(&fo, &pos_fo, &size_fo, max, true);
+ add_to_buff(&fo, &pos_fo, &size_fo,(char*)"\nxstep=", 7);
+ add_dbl_to_buff(&fo, &pos_fo, &size_fo, lstep, true);
+ add_to_buff(&fo, &pos_fo, &size_fo,(char*)"\nLine=", 6);
+ add_dbl_to_buff(&fo, &pos_fo, &size_fo, DefSize(SIZE_DATA_LINE), true);
+ add_to_buff(&fo, &pos_fo, &size_fo,(char*)" 6 0x000000ff 0x0\n", 18);
+ cb_f = 0;
switch (type & 0xff){
- case 2:
- cb += sprintf(fo+cb,"f_xy=\"y=%g*lognormfreq(x,%g,%g)\"",nv*step, mean, sd);
+ case 2: //lognormal
+#ifdef USE_WIN_SECURE
+ cb_f = sprintf_s(formula, 500, "%g*lognormfreq(x,%g,%g)",nv*step, mean, sd);
+#else
+ cb_f = sprintf(formula,"%g*lognormfreq(x,%g,%g)",nv*step, mean, sd);
+#endif
+ fdesc = (char*)"Desc=\"Lognormal Dist.\"\n";
+ break;
+ case 3: //exponential
+#ifdef USE_WIN_SECURE
+ cb_f = sprintf_s(formula, 500, "%g*expfreq(x,%g)",nv*step, 1.0/mean);
+#else
+ cb_f = sprintf(formula,"%g*expfreq(x,%g)",nv*step, 1.0/mean);
+#endif
+ fdesc = (char*)"Desc=\"Exponential Dist.\"\n";
+ break;
+ case 4: //rectangular
+#ifdef USE_WIN_SECURE
+ cb_f = sprintf_s(formula, 500, "%g*%g*(x>=%g&&x<=%g)",nv*step, 1.0/(dmax-dmin), dmin, dmax);
+#else
+ cb_f = sprintf(formula,"%g*%g*(x>=%g&&x<=%g)",nv*step, 1.0/(dmax-dmin), dmin, dmax);
+#endif
+ fdesc = (char*)"Desc=\"Rectangular Dist.\"\n";
+ break;
+ case 5: //chi-square
+#ifdef USE_WIN_SECURE
+ cb_f = sprintf_s(formula, 500, "%g*chifreq(x,%g)",nv*step, mean);
+#else
+ cb_f = sprintf(formula,"%g*chifreq(x,%g)",nv*step, mean);
+#endif
+ fdesc = (char*)"Desc=\"Chi<sup>2</sup> Dist.\"\n";
break;
- default:
- cb += sprintf(fo+cb,"f_xy=\"y=%g*normfreq(x,%g,%g)\"",nv*step, mean, sd);
+ case 10: //binomial
+#ifdef USE_WIN_SECURE
+ cb_f = sprintf_s(formula, 500, "%g*binomfreq(x,%g,%g)*(x>0)",nv*step, dmax, mean/dmax);
+#else
+ cb_f = sprintf(formula,"%g*binomfreq(x,%g,%g)*(x>0)",nv*step, dmax, mean/dmax);
+#endif
+ fdesc = (char*)"Desc=\"Binomial Dist.\"\n";
+ break;
+ case 11: //poisson
+#ifdef USE_WIN_SECURE
+ cb_f = sprintf_s(formula, 500, "%g*poisfreq(x,%g)*(x>0)",nv*step, mean);
+#else
+ cb_f = sprintf(formula,"%g*poisfreq(x,%g)*(x>0)",nv*step, mean);
+#endif
+ fdesc = (char*)"Desc=\"Poisson Dist.\"\n";
+ break;
+ default: //normal
+#ifdef USE_WIN_SECURE
+ cb_f = sprintf_s(formula, 500, "%g*normfreq(x,%g,%g)",nv*step, mean, sd);
+#else
+ cb_f = sprintf(formula,"%g*normfreq(x,%g,%g)",nv*step, mean, sd);
+#endif
+ fdesc = (char*)"Desc=\"Normal Dist.\"\n";
break;
}
+ if(cb_f) {
+ add_to_buff(&fo, &pos_fo, &size_fo, "f_xy=\"y=" , 8);
+ add_to_buff(&fo, &pos_fo, &size_fo, formula , cb_f);
+ add_to_buff(&fo, &pos_fo, &size_fo, "\\n\"\n" , 4);
+ }
+ if(fdesc)add_to_buff(&fo, &pos_fo, &size_fo, fdesc, 0);
OpenGraph(this, 0L, (unsigned char *)fo, false);
- free(fo);
+ free(fo); chi2 = df = 0.0;
+ //calculate chi-square test of fit
+ if(curr_data) for(i = 0; i< ncl; i++) {
+ if(curr_data->GetValue(i,0, &x) && curr_data->GetValue(i,1, &y)){
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "x=%g;%s", x, formula);
+#else
+ sprintf(TmpTxt, "x=%g;%s", x, formula);
+#endif
+ result = do_formula(curr_data, TmpTxt);
+ if(result->type == ET_VALUE && fabs(result->value) > 0.0) {
+ tmp = y-result->value;
+ tmp = (tmp*tmp)/result->value;
+ chi2 += tmp; df += 1.0;
+ }
+ }
+ }
+ //report result of the chi-square test
+ if(chi2 > 0.0 && parent && (fo = (char*)malloc(size_fo = 1000))) {
+ tmp = chi_dist(chi2, df-1.0, 1.0);
+ pos_fo = rlp_strcpy(fo, 1000, (char*)"chi<sup> 2</sup> =");
+ add_dbl_to_buff(&fo, &pos_fo, &size_fo, chi2, true);
+ add_to_buff(&fo, &pos_fo, &size_fo, (char*)", n =", 5);
+ add_dbl_to_buff(&fo, &pos_fo, &size_fo, df, true);
+ add_to_buff(&fo, &pos_fo, &size_fo, (char*)", df =", 6);
+ add_dbl_to_buff(&fo, &pos_fo, &size_fo, df-1.0, true);
+ add_to_buff(&fo, &pos_fo, &size_fo, (char*)", p =", 5);
+ if(tmp < 0.0001) {
+ pos_fo--; add_to_buff(&fo, &pos_fo, &size_fo, (char*)"< 0.0001", 8);
+ }
+ else add_dbl_to_buff(&fo, &pos_fo, &size_fo, tmp, true);
+ if(!plots[2]) {
+ x = (parent->GetSize(SIZE_GRECT_RIGHT) - parent->GetSize(SIZE_GRECT_LEFT))/2.0;
+ y = parent->GetSize(SIZE_GRECT_BOTTOM) - DefSize(SIZE_TEXT)*5;
+ y -= parent->GetSize(SIZE_DRECT_TOP);
+ td.Align = TXA_VTOP | TXA_HCENTER; td.ColBg = 0x00ffffffL;
+ td.ColTxt = 0x00ff0000L; td.Font = FONT_HELVETICA;
+ td.fSize = DefSize(SIZE_TEXT); td.iSize = 0;
+ td.Mode = TXM_TRANSPARENT; td.RotBL = td.RotCHAR = 0.0;
+ td.Style = TXS_NORMAL; td.text = 0L;
+ plots[2] = new Label(this, data, x, y, &td, 0x0L);
+ plots[2]->moveable = 1;
+ }
+ plots[2]->Command(CMD_SETTEXT, fo, 0L); free(fo);
+ }
}
}
}
@@ -1204,9 +1330,9 @@ Regression::Command(int cmd, void *tmpl, anyOutput *o)
ld = rLine->GetLine();
if(Symbols) {
for (i = 0; i < nPoints && i < 100; i++)
- if(Symbols[i]) ((Legend*)tmpl)->HasSym(ld, Symbols[i]);
+ if(Symbols[i]) ((Legend*)tmpl)->HasSym(ld, Symbols[i], "Regression");
}
- else ((Legend*)tmpl)->HasFill(ld, 0L);
+ else ((Legend*)tmpl)->HasFill(ld, 0L, "Regression");
return true;
}
return false;
@@ -1254,6 +1380,9 @@ Regression::Command(int cmd, void *tmpl, anyOutput *o)
if(Symbols) for (i = 0; i < nPoints; i++)
if(Symbols[i]) Symbols[i]->Command(cmd, tmpl, o);
return true;
+ case CMD_SCALE:
+ if(rLine) rLine->Command(cmd, tmpl, o);
+ if(sde) sde->Command(cmd, tmpl, o);
case CMD_SYMTEXT: case CMD_SYM_RANGETEXT:
case CMD_SYMTEXTDEF: case CMD_SYM_TYPE:
if(Symbols) for(i = 0; i < nPoints; i++)
@@ -1454,6 +1583,16 @@ BubblePlot::Command(int cmd, void *tmpl, anyOutput *o)
if(Bubbles) for (i = 0; i < nPoints; i++)
if(Bubbles[i]) Bubbles[i]->Command(cmd, tmpl, o);
return true;
+ case CMD_SCALE:
+ if(!tmpl) return false;
+ BubbleLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleFillLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleFillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleFill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ if(Bubbles) for(i = 0; i < nPoints; i++)
+ if(Bubbles[i]) Bubbles[i]->Command(cmd, tmpl, o);
+ return true;
case CMD_MRK_DIRTY:
dirty = true;
case CMD_SETSCROLL: case CMD_REDRAW:
@@ -1560,7 +1699,7 @@ PolarPlot::GetSize(int select)
default:
if(parent) return parent->GetSize(select);
}
- return defs.GetSize(select);
+ return DefSize(select);
}
void
@@ -1611,6 +1750,13 @@ PolarPlot::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_CONFIG:
Config();
return true;
+ case CMD_SCALE:
+ FillLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ FillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ if(Axes) for(i = 0; i< nAxes; i++) if(Axes[i]) Axes[i]->Command(cmd, tmpl, o);
+ if(Plots) for(i = 0; i < nPlots; i++) if(Plots[i]) Plots[i]->Command(cmd, tmpl, o);
+ return true;
case CMD_SET_DATAOBJ:
Id = GO_POLARPLOT;
data = (DataObj *)tmpl;
@@ -1705,7 +1851,6 @@ BoxPlot::BoxPlot(GraphObj *par, DataObj *d):Plot(par, d)
{
FileIO(INIT_VARS);
Id = GO_BOXPLOT;
- if (!d && parent) parent->Command(CMD_DELOBJ, this, NULL);
}
BoxPlot::BoxPlot(int src):Plot(0L, 0L)
@@ -1728,19 +1873,20 @@ BoxPlot::BoxPlot(int src):Plot(0L, 0L)
}
}
-BoxPlot::BoxPlot(GraphObj *par, DataObj *dt, int mode, int c1, int c2, int c3):Plot(par, dt)
+BoxPlot::BoxPlot(GraphObj *par, DataObj *dt, int mode, int c1, int c2, int c3, char *box_name):Plot(par, dt)
{
- int i, nr;
+ int i, nr, cb;
lfPOINT fp;
- FileIO(INIT_VARS); Id = GO_BOXPLOT; fp.fx = fp.fy = 0.0;
+ FileIO(INIT_VARS); Id = GO_BOXPLOT; fp.fx = fp.fy = 0.0; cb = 0;
if(data && data->GetSize(&i, &nr)) {
- nPoints = nr;
+ nPoints = nr; if(box_name) cb = (int)strlen(box_name);
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, 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);
+ if(box_name && box_name[0] && Boxes[i]) Boxes[i]->name = (char*)memdup(box_name, cb+1, 0);
}
}
}
@@ -1887,11 +2033,11 @@ BoxPlot::Command(int cmd, void *tmpl, anyOutput *o)
if(Symbols) {
if(TheLine && TheLine->Id == GO_DATALINE) {
for (i = 0; i < nPoints && i < 100; i++)
- if(Symbols[i]) ((Legend*)tmpl)->HasSym(&TheLine->LineDef, Symbols[i]);
+ if(Symbols[i]) ((Legend*)tmpl)->HasSym(&TheLine->LineDef, Symbols[i], 0L);
}
else {
for (i = 0; i < nPoints && i < 100; i++)
- if(Symbols[i]) ((Legend*)tmpl)->HasSym(0L, Symbols[i]);
+ if(Symbols[i]) ((Legend*)tmpl)->HasSym(0L, Symbols[i], 0L);
}
if(TheLine && TheLine->Id == GO_DATAPOLYGON) TheLine->Command(cmd, tmpl, o);
}
@@ -1905,6 +2051,7 @@ BoxPlot::Command(int cmd, void *tmpl, anyOutput *o)
CreateData();
return ForEach(CMD_SET_DATAOBJ, curr_data, o);
}
+ case CMD_SCALE:
return ForEach(cmd, tmpl, o);
case CMD_AUTOSCALE:
if(hidden) return false;
@@ -2142,26 +2289,26 @@ BoxPlot::CreateData()
curr_data->SetValue(i, 2, y - ss); curr_data->SetValue(i, 3, y + ss);
}
else if((type & 0x00f0) == 0x0020) {
- curr_data->SetValue(i, 2, y - ss/sqrt(ny[i]));
- curr_data->SetValue(i, 3, y + ss/sqrt(ny[i]));
+ curr_data->SetValue(i, 2, y - ss/sqrt((double)ny[i]));
+ curr_data->SetValue(i, 3, y + ss/sqrt((double)ny[i]));
}
else if((type & 0x00f0) == 0x0050) {
d = ny[i] > 1 ? distinv(t_dist, ny[i]-1, 1, 1.0-(ci_box/100.0), 2.0) : 0;
- curr_data->SetValue(i, 2, y - d*ss/sqrt(ny[i]));
- curr_data->SetValue(i, 3, y + d*ss/sqrt(ny[i]));
+ curr_data->SetValue(i, 2, y - d*ss/(double)sqrt((double)ny[i]));
+ curr_data->SetValue(i, 3, y + d*ss/(double)sqrt((double)ny[i]));
}
//Whisker info is in cols 4 & 5
if((type & 0x0f0f) == 0x0101) {
curr_data->SetValue(i, 4, y - ss); curr_data->SetValue(i, 5, y + ss);
}
else if((type & 0x0f0f) == 0x0201) {
- curr_data->SetValue(i, 4, y - ss/sqrt(ny[i]));
- curr_data->SetValue(i, 5, y + ss/sqrt(ny[i]));
+ curr_data->SetValue(i, 4, y - ss/sqrt((double)ny[i]));
+ curr_data->SetValue(i, 5, y + ss/sqrt((double)ny[i]));
}
else if((type & 0x0f0f) == 0x0501) {
d = ny[i] > 1 ? distinv(t_dist, ny[i]-1, 1, 1.0-(ci_err/100.0), 2.0) : 0;
- curr_data->SetValue(i, 4, y - d*ss/sqrt(ny[i]));
- curr_data->SetValue(i, 5, y + d*ss/sqrt(ny[i]));
+ curr_data->SetValue(i, 4, y - d*ss/sqrt((double)ny[i]));
+ curr_data->SetValue(i, 5, y + d*ss/sqrt((double)ny[i]));
}
}
if((type & 0x00f0) == 0x0040 || (type & 0x0f00) == 0x0400) for(i = 0; i < j; i++) {
@@ -2192,7 +2339,11 @@ BoxPlot::CreateData()
if(type & 0xc000) for(i = 0; i < j; i++) {
//labels ...
if((type & 0x4000) && curr_data->GetValue(i, 5, &y)) curr_data->SetValue(i, 6, y);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%s%d", case_prefix ? case_prefix : "", ny[i]);
+#else
sprintf(TmpTxt, "%s%d", case_prefix ? case_prefix : "", ny[i]);
+#endif
curr_data->SetText(i, 7, TmpTxt);
}
}
@@ -2238,6 +2389,8 @@ DensDisp::~DensDisp()
if(yRange) free(yRange); if(xRange) free(xRange);
yRange = xRange = 0L;
if(name) free(name); name=0L;
+ if(x_info) free(x_info); x_info = 0L;
+ if(y_info) free(y_info); y_info = 0L;
Undo.InvalidGO(this);
}
@@ -2302,6 +2455,14 @@ DensDisp::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_SETSCROLL: case CMD_REDRAW:
if(parent) return parent->Command(cmd, tmpl, o);
return false;
+ case CMD_SCALE:
+ DefLine.width *= ((scaleINFO*)tmpl)->sy.fy; DefLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ DefFillLine.width *= ((scaleINFO*)tmpl)->sy.fy; DefFillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ DefFill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ for(i = 0; i < nPoints; i++){
+ if(Boxes[i]) Boxes[i]->Command(cmd, tmpl, o);
+ }
+ return true;
case CMD_USEAXIS:
UseAxis(*((int*)tmpl));
return true;
@@ -2574,6 +2735,9 @@ StackBar::Command(int cmd, void *tmpl, anyOutput *o)
if(xyPlots) for(i = 0; i < numXY; i++) if(xyPlots[i])
((ObjTree*)tmpl)->Command(CMD_UPDATE, xyPlots[i], 0L);
return true;
+ case CMD_SCALE:
+ dspm.fx *= ((scaleINFO*)tmpl)->sx.fy;
+ dspm.fy *= ((scaleINFO*)tmpl)->sy.fy;
case CMD_LEGEND:
if(Boxes) for (i = 0; i < numPlots; i++)
if(Boxes[i]) Boxes[i]->Command(cmd, tmpl, o);
@@ -2773,6 +2937,10 @@ PieChart::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_SET_DATAOBJ:
Id = GO_PIECHART;
data = (DataObj *)tmpl;
+ case CMD_SCALE:
+ if(cmd == CMD_SCALE) {
+ CtDef.fx *= ((scaleINFO*)tmpl)->sx.fy; CtDef.fy *= ((scaleINFO*)tmpl)->sx.fy;
+ }
case CMD_SHIFT_OUT: case CMD_SEG_FILL: case CMD_SEG_LINE:
case CMD_SEG_MOVEABLE: case CMD_LEGEND:
if(Segments) for(i = 0; i < nPts; i++)
@@ -3214,13 +3382,13 @@ Scatt3D::Command(int cmd, void *tmpl, anyOutput *o)
if(Balls) {
if(Line && Line->Id == GO_LINE3D) {
for (i = 0; i < nBalls && i < 100; i++)
- if(Balls[i]) ((Legend*)tmpl)->HasSym(&Line->Line, Balls[i]);
+ if(Balls[i]) ((Legend*)tmpl)->HasSym(&Line->Line, Balls[i], 0L);
}
else {
for (i = 0; i < nBalls && i < 100; i++) {
if(Balls[i]) {
if(Balls[i]->type) Balls[i]->Command(cmd, tmpl, o);
- else ((Legend*)tmpl)->HasSym(0L, Balls[i]);
+ else ((Legend*)tmpl)->HasSym(0L, Balls[i], 0L);
}
}
}
@@ -3233,7 +3401,7 @@ Scatt3D::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_SET_DATAOBJ:
Id = GO_SCATT3D;
data = (DataObj *)tmpl;
- case CMD_UPDATE:
+ case CMD_UPDATE: case CMD_SCALE:
if(Balls) {
SavVarObs((GraphObj**)Balls, nBalls, UNDO_CONTINUE);
for(i = 0; i < nBalls; i++) if(Balls[i]) Balls[i]->Command(cmd, tmpl, o);
@@ -3328,16 +3496,19 @@ Ribbon::Ribbon(GraphObj *par, DataObj *d, double z, double width, char *xr, char
:Plot(par, d)
{
FileIO(INIT_VARS); Id = GO_RIBBON; type = 1;
- if(xr) ssRefX = strdup(xr); if(yr) ssRefY = strdup(yr);
+ if(xr && xr[0]) ssRefX = (char*)memdup(xr, (int)strlen(xr)+1, 0L);
+ if(yr && yr[0]) ssRefY = (char*)memdup(yr, (int)strlen(yr)+1, 0L);
z_value = z; z_width = width;
}
-Ribbon::Ribbon(GraphObj *par, DataObj *d, char *xr, char *yr, char *zr)
+Ribbon::Ribbon(GraphObj *par, DataObj *d, int which, char *xr, char *yr, char *zr)
:Plot(par, d)
{
- FileIO(INIT_VARS); Id = GO_RIBBON; type = 2;
- if(xr) ssRefX = strdup(xr); if(yr) ssRefY = strdup(yr);
- if(zr) ssRefZ = strdup(zr);
+ FileIO(INIT_VARS); Id = GO_RIBBON; type = which;
+ if(xr && xr[0]) ssRefX = (char*)memdup(xr, (int)strlen(xr)+1, 0L);
+ if(yr && yr[0]) ssRefY = (char*)memdup(yr, (int)strlen(yr)+1, 0L);
+ if(zr && zr[0]) ssRefZ = (char*)memdup(zr, (int)strlen(zr)+1, 0L);
+ CreateObs();
}
Ribbon::Ribbon(GraphObj *par, DataObj *d, GraphObj **go, int ngo)
@@ -3458,6 +3629,11 @@ Ribbon::Command(int cmd, void *tmpl, anyOutput *o)
break;
}
break;
+ case CMD_SCALE:
+ z_value *= ((scaleINFO*)tmpl)->sz.fy;
+ z_width *= ((scaleINFO*)tmpl)->sz.fy;
+ for(i = 0; i < nPlanes; i++) if(planes[i]) planes[i]->Command(cmd, tmpl, o);
+ break;
case CMD_MRK_DIRTY:
dirty = true;
case CMD_SET_GO3D: case CMD_SETSCROLL: case CMD_REDRAW:
@@ -3509,10 +3685,11 @@ Ribbon::Command(int cmd, void *tmpl, anyOutput *o)
void
Ribbon::CreateObs()
{
- int i, rx, cx, ry, cy, rz, cz;
+ int i, j, n, rx, cx, ry, cy, rz, cz;
double fx, fy, fz, tmp;
fPOINT3D pg[5];
AccRange *rX, *rY, *rZ;
+ Triangle *trl, *trc, *trn;
if(planes || !data) return;
rX = rY = rZ = 0L;
@@ -3575,7 +3752,19 @@ Ribbon::CreateObs()
}
break;
case 3:
- //external creation of planes;
+ if(!ssRefX || !ssRefY || !ssRefZ) break;
+ Undo.InvalidGO(this);
+ trl = Triangulate1(ssRefX, ssRefZ, ssRefY, data);
+ for(i = 0, trc = trl; trc; i++) trc = trc->next;
+ if((n = i) && (planes = (Plane3D**)malloc(n*sizeof(Plane3D*))))
+ for(i = nPlanes = 0, trc = trl; trc && i < n; i++) {
+ for(j = 0; j < 4; j++) { //swap y and z values;
+ tmp = trc->pt[j].fz; trc->pt[j].fz = trc->pt[j].fy; trc->pt[j].fy = tmp;
+ }
+ planes[nPlanes++] = new Plane3D(this, data, trc->pt, 4);
+ trn = trc->next; delete trc; trc = trn;
+ }
+ dirty = true; Command(CMD_AUTOSCALE, 0L, 0L);
break;
}
if(rX) delete rX; if(rY) delete rY; if(rZ) delete rZ;
@@ -3589,7 +3778,7 @@ Ribbon::UpdateObs(bool bNewData)
AccRange *rX, *rY, *rZ;
int sel_id[] = {SIZE_XPOS, SIZE_YPOS, SIZE_ZPOS};
- if(!planes || !values) return;
+ if(!planes || (!values && type < 3)) return;
rX = rY = rZ = 0L;
switch(type) {
case 1:
@@ -3649,6 +3838,12 @@ Ribbon::UpdateObs(bool bNewData)
}
}
break;
+ case 3:
+ if(planes) {
+ for(i = 0; i < nPlanes; i++) if(planes[i]) DeleteGO(planes[i]);
+ free(planes); planes = 0L; nPlanes = 0;
+ }
+ CreateObs();
}
if(rX) delete rX; if(rY) delete rY; if(rZ) delete rZ;
}
@@ -3761,7 +3956,7 @@ Grid3D::Command(int cmd, void *tmpl, anyOutput *o)
}
break;
case CMD_LEGEND:
- if(!hidden) ((Legend*)tmpl)->HasFill(&Line, planes ? &Fill : 0L);
+ if(!hidden) ((Legend*)tmpl)->HasFill(&Line, planes ? &Fill : 0L, 0L);
break;
case CMD_CONFIG:
return Configure();
@@ -3920,17 +4115,18 @@ Limits::Command(int cmd, void *tmpl, anyOutput *o)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Calculate and display a user defined function
-Function::Function(GraphObj *par, DataObj *d):Plot(par, d)
+Function::Function(GraphObj *par, DataObj *d, char *desc):Plot(par, d)
{
- FileIO(INIT_VARS);
+ FileIO(INIT_VARS); cmdxy = (char*)malloc(20*sizeof(char));
if(parent && parent->Id == GO_POLARPLOT) {
x1 = 0.0; x2 = 360.0; xstep = 0.5;
- cmdxy = strdup("sin(pi*x/30)+1.1");
+ if(cmdxy)rlp_strcpy(cmdxy, 20, (char*)"sin(pi*x/30)+1.1");
}
else {
x1 = 0.0; x2 = 100.0; xstep = 0.5;
- cmdxy = strdup("sin(x)/x");
+ if(cmdxy)rlp_strcpy(cmdxy, 20, (char*)"sin(x)/x");
}
+ if(desc) name = (char*)memdup(desc, (int)strlen(desc)+1, 0);
Id = GO_FUNCTION;
}
@@ -3986,6 +4182,9 @@ Function::Command(int cmd, void *tmpl, anyOutput *o)
return true;
}
return false;
+ case CMD_SCALE:
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
case CMD_DELOBJ:
if(parent && tmpl && tmpl == dl) return parent->Command(CMD_DELOBJ, this, o);
break;
@@ -4005,15 +4204,15 @@ Function::Command(int cmd, void *tmpl, anyOutput *o)
return true;
case CMD_SETPARAM:
if(tmpl) {
- if(param) free(param);
- param = strdup((char*)tmpl);
+ if(param) free(param); param = 0L;
+ if(*((char*)tmpl))param = (char*)memdup(tmpl, (int)strlen((char*)tmpl)+1, 0);
}
dirty = true;
return true;
case CMD_SETFUNC:
if(tmpl) {
- if(cmdxy) free(cmdxy);
- cmdxy = strdup((char*)tmpl);
+ if(cmdxy) free(cmdxy); cmdxy = 0L;
+ if(*((char*)tmpl))cmdxy = (char*)memdup(tmpl, (int)strlen((char*)tmpl)+1, 0);
}
dirty = true;
return true;
@@ -4048,7 +4247,7 @@ Function::Update(anyOutput *o, DWORD flags)
if(!parent || !cmdxy) return false;
do_xyfunc(data, x1, x2, xstep, cmdxy, &xydata, &ndata, param);
if(xydata && ndata >1) {
- if(!dl) dl = new DataLine(this, data, xydata, ndata);
+ if(!dl) dl = new DataLine(this, data, xydata, ndata, name);
else dl->LineData(xydata, ndata);
dirty = true;
Command(CMD_AUTOSCALE, 0L, 0L);
@@ -4062,9 +4261,10 @@ Function::Update(anyOutput *o, DWORD flags)
FitFunc::FitFunc(GraphObj *par, DataObj *d):Plot(par, d)
{
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;");
+ x1 = 0.0; x2 = 100.0; xstep = 0.5; dl = 0L;
+ cmdxy = (char*)malloc(20*sizeof(char)); parxy = (char*)malloc(20*sizeof(char));
+ if(cmdxy) rlp_strcpy(cmdxy, 20, "a+b*x^c");
+ if(parxy) rlp_strcpy(parxy, 20, "a=1; b=1; c=0.1;");
Id = GO_FITFUNC;
}
@@ -4132,7 +4332,7 @@ FitFunc::DoPlot(anyOutput *o)
if(!data || x1 >= x2) return;
dirty = false;
- if(!dl && (dl = new Function(this, data))) {
+ if(!dl && (dl = new Function(this, data, "Fitted function"))) {
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);
@@ -4160,12 +4360,17 @@ FitFunc::Command(int cmd, void *tmpl, anyOutput *o)
ld = dl->GetLine();
if(Symbols) {
for (i = 0; i < nPoints && i < 100; i++)
- if(Symbols[i]) ((Legend*)tmpl)->HasSym(ld, Symbols[i]);
+ if(Symbols[i]) ((Legend*)tmpl)->HasSym(ld, Symbols[i], "Fitted function");
}
- else ((Legend*)tmpl)->HasFill(ld, 0L);
+ else ((Legend*)tmpl)->HasFill(ld, 0L, dl->name);
return true;
}
return false;
+ case CMD_SCALE:
+ if(dl) return dl->Command(cmd, tmpl, o);
+ if(Symbols) for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->Command(cmd, tmpl, o);
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
case CMD_HIDE_MARK:
if(dl) return dl->Command(cmd, tmpl, o);
return false;
@@ -4183,7 +4388,7 @@ FitFunc::Command(int cmd, void *tmpl, anyOutput *o)
return false;
case CMD_AUTOSCALE:
if(dirty) {
- if(!dl && (dl = new Function(this, data))) {
+ if(!dl && (dl = new Function(this, data, "Fitted function"))) {
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);
@@ -4204,7 +4409,7 @@ FitFunc::Command(int cmd, void *tmpl, anyOutput *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) dl = new Function(this, data, "Fitted function");
if(dl){
dl->SetSize(SIZE_MIN_X, x1); dl->SetSize(SIZE_MAX_X, x2);
dl->SetSize(SIZE_XSTEP, xstep); dl->Command(CMD_SETFUNC, cmdxy, 0L);
@@ -4343,8 +4548,7 @@ Plot3D::GetSize(int select)
case SIZE_YCENTER: return rotC.fy;
case SIZE_ZCENTER: return rotC.fz;
default:
- if(parent) return parent->GetSize(select);
- else return defs.GetSize(select);
+ return DefSize(select);
}
}
@@ -4441,6 +4645,17 @@ Plot3D::Command(int cmd, void *tmpl, anyOutput *o)
GraphObj **tmpPlots;
switch (cmd) {
+ case CMD_SCALE:
+ cub1.fx *= ((scaleINFO*)tmpl)->sx.fy; cub1.fy *= ((scaleINFO*)tmpl)->sy.fy;
+ cub1.fz *= ((scaleINFO*)tmpl)->sz.fy; cub2.fx *= ((scaleINFO*)tmpl)->sx.fy;
+ cub2.fy *= ((scaleINFO*)tmpl)->sy.fy; cub2.fz *= ((scaleINFO*)tmpl)->sz.fy;
+ rotC.fx *= ((scaleINFO*)tmpl)->sx.fy; rotC.fy *= ((scaleINFO*)tmpl)->sy.fy;
+ rotC.fz *= ((scaleINFO*)tmpl)->sz.fy;
+ if(plots) for(i = 0; i < nPlots; i++)
+ if(plots[i]) plots[i]->Command(cmd, tmpl, o);
+ if(Axes) for(i = 0; i < nAxes; i++)
+ if(Axes[i]) Axes[i]->Command(cmd, tmpl, o);
+ return true;
case CMD_MOUSE_EVENT:
if(hidden || ((MouseEvent*)tmpl)->Action != MOUSE_LBUP || CurrGO) return false;
if(dispObs) for (i = nObs; i > 0; i--) {
@@ -4649,24 +4864,24 @@ Plot3D::CreateAxes()
int txa;
}Axis3Ddef;
AxisDEF tmp_axis;
- double ts = defs.GetSize(SIZE_AXIS_TICKS);
+ double ts = DefSize(SIZE_AXIS_TICKS);
int i;
if(Axes || !parent)return;
- TextDEF tlbdef = {parent->GetColor(COL_AXIS), 0x00ffffffL, defs.GetSize(SIZE_TICK_LABELS),
+ TextDEF tlbdef = {parent->GetColor(COL_AXIS), 0x00ffffffL, DefSize(SIZE_TICK_LABELS),
0.0, 0.0, 0, TXA_HLEFT | TXA_VCENTER, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, 0L};
Axis3Ddef *at = 0L;
Axis3Ddef at1[] = {
{cub1.fx, cub1.fy, 0.0, cub2.fx, cub1.fy, 0.0,
AXIS_3D | AXIS_DEFRECT | AXIS_AUTOTICK | AXIS_AUTOSCALE | AXIS_NEGTICKS, 1, 3,
- 0.0, NiceValue((ts+defs.GetSize(SIZE_AXIS_TICKS))*2.0), 0.0,
+ 0.0, NiceValue((ts+DefSize(SIZE_AXIS_TICKS))*2.0), 0.0,
NiceValue(ts * 2.0), TXA_HCENTER | TXA_VTOP},
{cub1.fx, cub1.fy, 0.0, cub1.fx, cub2.fy, 0.0,
AXIS_3D | AXIS_DEFRECT | AXIS_AUTOTICK | AXIS_AUTOSCALE | AXIS_NEGTICKS, 2, 2,
- -NiceValue((ts+defs.GetSize(SIZE_AXIS_TICKS))*3.0), 0.0,
+ -NiceValue((ts+DefSize(SIZE_AXIS_TICKS))*3.0), 0.0,
-NiceValue(ts * 2.0), 0.0, TXA_HRIGHT | TXA_VCENTER},
{cub1.fx, cub1.fy, 0.0, cub1.fx, cub1.fy, cub2.fz,
AXIS_3D | AXIS_DEFRECT | AXIS_AUTOTICK | AXIS_AUTOSCALE | AXIS_NEGTICKS, 3, 2,
- -NiceValue((ts+defs.GetSize(SIZE_AXIS_TICKS))*3.0), 0.0,
+ -NiceValue((ts+DefSize(SIZE_AXIS_TICKS))*3.0), 0.0,
-NiceValue(ts * 2.0), 0.0, TXA_HRIGHT | TXA_VCENTER}};
Axis3Ddef at2[] = {
{at1[0].x1, at1[0].y1, at1[2].z2, at1[0].x2, at1[0].y2, at1[2].z2,
@@ -4915,6 +5130,8 @@ Plot3D::Rotate(double dx, double dy, double dz, anyOutput *o, bool accept)
double rotM[3][3], newM[3][3]; //rotation matrices
bool bRet = true;
+ o->SetSpace(&cu1, &cu2, defs.cUnits, RotDef, &rc, Axes[0]->GetAxis(),
+ Axes[1]->GetAxis(), Axes[2]->GetAxis());
for(i = 0; i < 3; i++) {
switch (i){
case 0:
@@ -5031,7 +5248,8 @@ Func3D::Func3D(GraphObj *par, DataObj *d)
:Plot3D(par, d, 0x0L)
{
FileIO(INIT_VARS);
- cmdxy = strdup("r=sqrt(x*x+z*z)\ny=1-exp(-8/(r+1))");
+ if(cmdxy = (char*)malloc(40*sizeof(char)))
+ rlp_strcpy(cmdxy, 40, (char*)"r=sqrt(x*x+z*z)\ny=1-exp(-8/(r+1))");
Id = GO_FUNC3D;
}
@@ -5110,8 +5328,9 @@ 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;");
+ cmdxy = (char*)malloc(20*sizeof(char)); param = (char*)malloc(20*sizeof(char));
+ if(cmdxy) rlp_strcpy(cmdxy, 20, (char*)"a+b*x^c");
+ if(param) rlp_strcpy(param, 20, (char*)"a=1; b=1; c=0.1;");
Id = GO_FITFUNC3D;
}
diff --git a/PropertyDlg.cpp b/PropertyDlg.cpp
index d5df21c..68ceff3 100755
--- a/PropertyDlg.cpp
+++ b/PropertyDlg.cpp
@@ -68,9 +68,9 @@ Symbol::PropertyDlg()
{104, 105, 0, TOUCHEXIT, INCDECVAL1, &SymLine.width, 55, 37, 32, 10},
{105, 106, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 89, 37, 20, 8},
{106, 107, 0, 0x0L, RTEXT, (void*)"line color", 5, 49, 45, 8},
- {107, 108, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)SymLine.color, 55, 49, 25, 10},
+ {107, 108, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&SymLine.color, 55, 49, 25, 10},
{108, 109, 0, 0x0L, RTEXT, (void*)"fill color" , 5, 61, 45, 8},
- {109, 0, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)SymFill.color, 55, 61, 25, 10},
+ {109, 0, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&SymFill.color, 55, 61, 25, 10},
{200, 204, 201, CHECKED | ISPARENT, GROUPBOX, (void*)" font ", 12, 28, 50, 45},
{201, 202, 0, TOUCHEXIT, RADIO1, (void*)"Helvetica", 15, 35, 45, 8},
{202, 203, 0, TOUCHEXIT, RADIO1, (void*)"Times", 15, 45, 45, 8},
@@ -114,9 +114,13 @@ Symbol::PropertyDlg()
lfPOINT o_pos, n_pos;
if(!parent) return false;
- if(!Command(CMD_GETTEXT, (void*)text1, 0L)) sprintf(text1, "text");
+ if(!Command(CMD_GETTEXT, (void*)text1, 0L)) rlp_strcpy(text1, 40, "text");
+#ifdef USE_WIN_SECURE
+ if(data && data->GetSize(&width, &height)) sprintf_s(text2, 100, "b1:b%d", height);
+#else
if(data && data->GetSize(&width, &height)) sprintf(text2, "b1:b%d", height);
- else sprintf(text2, "(not available)");
+#endif
+ else rlp_strcpy(text2, 100, "(not available)");
if((PrevSym = new Symbol(0L, data, 0.0f, 0.0f, type))){
PrevSym->SetColor(COL_SYM_LINE, SymLine.color);
PrevSym->SetColor(COL_SYM_FILL, SymFill.color);
@@ -129,7 +133,7 @@ Symbol::PropertyDlg()
PrevSym->Command(CMD_SETTEXTDEF, &textdef, 0L);
PrevSym->idx = idx;
}
- if(PrevSym && (Dlg = new DlgRoot(SymDlg))) {
+ if(PrevSym && (Dlg = new DlgRoot(SymDlg, data))) {
Dlg->TextFont(201, FONT_HELVETICA);
Dlg->TextFont(202, FONT_TIMES);
Dlg->TextFont(203, FONT_COURIER);
@@ -148,8 +152,12 @@ Symbol::PropertyDlg()
if(textdef.Style & TXS_UNDERLINE) Dlg->SetCheck(207, 0L, true);
}
else return false;
- if(parent->name) sprintf(TmpTxt, "Symbol of %s", parent->name);
- else strcpy(TmpTxt, "Symbol properties");
+ if(parent->name) {
+ width = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Symbol of ");
+ rlp_strcpy(TmpTxt+width, TMP_TXT_SIZE-width, parent->name);
+ width =10;
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Symbol properties");
if(!(hDlg = CreateDlgWnd(TmpTxt, 50, 50, 430, 260, Dlg, 0x0L)))return false;
tmpCol = 0x00c0c0c0L; o_size = size; o_lwidth = SymLine.width;
Dlg->GetValue(101, &o_size); Dlg->GetValue(104, &o_lwidth);
@@ -165,7 +173,7 @@ Symbol::PropertyDlg()
case 1:
Undo.SetDisp(cdisp);
if(PrevSym->type == SYM_TEXT && Dlg->GetCheck(250)){
- Dlg->GetText(251, text1);
+ Dlg->GetText(251, text1, 40);
if(PrevSym->Command(CMD_GETTEXT, (void *)text2, 0L) && strcmp(text1, text2)) {
PrevSym->Command(CMD_SETTEXT, (void *)text1, 0L);
Dlg->DoPlot(NULL);
@@ -173,7 +181,7 @@ Symbol::PropertyDlg()
}
}
else if(PrevSym->type == SYM_TEXT && Dlg->GetCheck(252)) {
- if(Dlg->GetCheck(252) && Dlg->GetText(253, text2))
+ if(Dlg->GetCheck(252) && Dlg->GetText(253, text2, 100))
PrevSym->Command(CMD_RANGETEXT, &text2, 0L);
}
Dlg->GetValue(101, &n_size); Dlg->GetValue(104, &n_lwidth);
@@ -205,8 +213,8 @@ Symbol::PropertyDlg()
case 252: //use spreadsheet text
if(!data) Dlg->SetCheck(250, 0L, true);
case 250: //use fixed text
- if(Dlg->GetCheck(250) && Dlg->GetText(251,text1))PrevSym->Command(CMD_SETTEXT, text1, 0L);
- else if(Dlg->GetCheck(252) && Dlg->GetText(253, text2))
+ if(Dlg->GetCheck(250) && Dlg->GetText(251,text1,40))PrevSym->Command(CMD_SETTEXT, text1, 0L);
+ else if(Dlg->GetCheck(252) && Dlg->GetText(253, text2, 100))
PrevSym->Command(CMD_RANGETEXT, text2, 0L);
Dlg->DoPlot(NULL);
res = -1;
@@ -231,8 +239,8 @@ Symbol::PropertyDlg()
if(Dlg->GetValue(101, &tmpVal)) PrevSym->SetSize(SIZE_SYMBOL, tmpVal);
if(Dlg->GetValue(104, &tmpVal)) PrevSym->SetSize(SIZE_SYM_LINE, tmpVal);
if(PrevSym->type == SYM_TEXT) {
- if(Dlg->GetCheck(250) && Dlg->GetText(251,text1))PrevSym->Command(CMD_SETTEXT, text1, 0L);
- else if(Dlg->GetCheck(252) && Dlg->GetText(253, text2))
+ if(Dlg->GetCheck(250) && Dlg->GetText(251,text1,40))PrevSym->Command(CMD_SETTEXT, text1, 0L);
+ else if(Dlg->GetCheck(252) && Dlg->GetText(253, text2,100))
PrevSym->Command(CMD_RANGETEXT, text2, 0L);
}
Dlg->DoPlot(NULL);
@@ -270,7 +278,7 @@ Symbol::PropertyDlg()
if(PrevSym->type == SYM_TEXT) {
if(Dlg->GetCheck(250) && PrevSym->Command(CMD_GETTEXT, text1, 0L))
parent->Command(CMD_SYMTEXT_UNDO, text1, 0L);
- else if(Dlg->GetCheck(252) && Dlg->GetText(253, text2))
+ else if(Dlg->GetCheck(252) && Dlg->GetText(253, text2, 100))
parent->Command(CMD_SYM_RANGETEXT, text2, 0L);
if(PrevSym->Command(CMD_GETTEXTDEF, &textdef, 0L))
parent->Command(CMD_SYMTEXTDEF, &textdef, 0L);
@@ -286,45 +294,52 @@ Symbol::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Bubble properties dialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *BubDlg_DlgTmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,1,130,10,60,12\n"
+ "2,3,,,PUSHBUTTON,2,130,25,60,12\n"
+ "3,4,,,PUSHBUTTON,-2,130,40,60,12\n"
+ "4,,5,CHECKED | ISPARENT,GROUP,0,0,0,0,0\n"
+ "5,6,100,ISPARENT | CHECKED,SHEET,3,5,10,120,100\n"
+ "6,7,200,ISPARENT,SHEET,4,5,10,120,100\n"
+ "7,,300,ISPARENT,SHEET,5,5,10,120,100\n"
+ "100,109,,NOSELECT,ODBUTTON,6,18,57,90,50\n"
+ "109,110,,,SYMRADIO,7,30,30,20,20\n"
+ "110,111,,,SYMRADIO,8,50,30,20,20\n"
+ "111,112,,,SYMRADIO,9,70,30,20,20\n"
+ "112,,,,SYMRADIO,10,90,30,20,20\n"
+ "200,201,,,LTEXT,11,10,30,110,8\n"
+ "201,202,210, ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "202,203,,,LTEXT,12,10,64,110,8\n"
+ "203,, 220,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "210,211,,,RADIO1,-3,40,38,45,8\n"
+ "211,212,,,RADIO1,13,40,46,45,8\n"
+ "212,,,,RADIO1,14,40,54,45,8\n"
+ "220,221,,,RADIO1,15,40,72,45,8\n"
+ "221,222,,,RADIO1,16,40,80,45,8\n"
+ "222,0,,,RADIO1,17,40,88,45,8\n"
+ "300,301,,,RTEXT,-12,10,40,45,8\n"
+ "301,302,,,EDVAL1,18,60,40,35,10\n"
+ "302,303,,,RTEXT,-13,10,60,45,8\n"
+ "303,304,,,EDVAL1,19,60,60,35,10\n"
+ "304,305,,,RTEXT,20,10,80,45,8\n"
+ "305,,,LASTOBJ, EDVAL1,21,60,80,35,10";
+
bool
Bubble::PropertyDlg()
{
- TabSHEET tab1 = {0, 50, 10, "Shape & Color"};
- TabSHEET tab2 = {50, 90, 10, "Scaling"};
- TabSHEET tab3 = {90, 120, 10, "Edit"};
+ TabSHEET tab1 = {0, 52, 10, "Shape & Color"};
+ TabSHEET tab2 = {52, 84, 10, "Scaling"};
+ TabSHEET tab3 = {84, 106, 10, "Edit"};
int syms[] = {SYM_CIRCLE, SYM_RECT, SYM_TRIAU, SYM_TRIAD};
- DlgInfo BubDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"Apply to BUBBLE", 130, 10, 60, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Apply to PLOT", 130, 25, 60, 12},
- {3, 4, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 130, 40, 60, 12},
- {4, 0, 5, CHECKED | ISPARENT, GROUP, NULL, 138, 40, 55, 12},
- {5, 6, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 120, 100},
- {6, 7, 200, ISPARENT, SHEET, &tab2, 5, 10, 120, 100},
- {7, 0, 300, ISPARENT, SHEET, &tab3, 5, 10, 120, 100},
- {100, 109, 0, NOSELECT, ODBUTTON, (void*)OD_filldef, 18, 57, 90, 50},
- {109, 110, 0, 0x0L, SYMRADIO, (void *)&syms[0], 30, 30, 20, 20},
- {110, 111, 0, 0x0L, SYMRADIO, (void *)&syms[1], 50, 30, 20, 20},
- {111, 112, 0, 0x0L, SYMRADIO, (void *)&syms[2], 70, 30, 20, 20},
- {112, 0, 0, 0x0L, SYMRADIO, (void *)&syms[3], 90, 30, 20, 20},
- {200, 201, 0, 0x0L, LTEXT, (void*)"Sizes are given as", 10, 30, 110, 8},
- {201, 202, 210, ISPARENT | CHECKED, GROUP, NULL, 0, 0, 0, 0},
- {202, 203, 0, 0x0L, LTEXT, (void*)"Proportionality (relative to circle)", 10, 64, 110, 8},
- {203, 0, 220, ISPARENT | CHECKED, GROUP, NULL, 0, 0, 0, 0},
- {210, 211, 0, 0x0L, RADIO1, (void *) Units[defs.cUnits].display, 40, 38, 45, 8},
- {211, 212, 0, 0x0L, RADIO1, (void*)"scaling with X axis", 40, 46, 45, 8},
- {212, 0, 0, 0x0L, RADIO1, (void*)"scaling with Y axis", 40, 54, 45, 8},
- {220, 221, 0, 0x0L, RADIO1, (void*)"diameter", 40, 72, 45, 8},
- {221, 222, 0, 0x0L, RADIO1, (void*)"circumference", 40, 80, 45, 8},
- {222, 0, 0, 0x0L, RADIO1, (void*)"area", 40, 88, 45, 8},
- {300, 301, 0, 0x0L, RTEXT, (void*)"x-value", 10, 40, 45, 8},
- {301, 302, 0, 0x0L, EDVAL1, &fPos.fx, 60, 40, 35, 10},
- {302, 303, 0, 0x0L, RTEXT, (void*)"y-value", 10, 60, 45, 8},
- {303, 304, 0, 0x0L, EDVAL1, &fPos.fy, 60, 60, 35, 10},
- {304, 305, 0, 0x0L, RTEXT, (void*)"size", 10, 80, 45, 8},
- {305, 0, 0, LASTOBJ, EDVAL1, &fs, 60, 80, 35, 10}};
+ void *dyndata[] = {(void*)"Apply to BUBBLE", (void*)"Apply to PLOT", (void*)&tab1, (void*)&tab2,
+ (void*)&tab3, (void*)&OD_filldef, (void *)&syms[0], (void *)&syms[1], (void *)&syms[2], (void *)&syms[3],
+ (void*)"Sizes are given as", (void*)"Proportionality (relative to circle)", (void*)"scaling with X axis",
+ (void*)"scaling with Y axis", (void*)"diameter", (void*)"circumference", (void*)"area", (void*)&fPos.fx,
+ (void*)&fPos.fy, (void*)"size", (void*)&fs};
+ DlgInfo *BubDlg = CompileDialog(BubDlg_DlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
- int res, tmpType;
+ int cb, res, tmpType;
lfPOINT o_pos, n_pos;
LineDEF newLine, newFillLine;
FillDEF newFill;
@@ -336,7 +351,7 @@ Bubble::PropertyDlg()
if(!parent) return false;
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&BubbleLine, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&BubbleFill, 0);
- Dlg = new DlgRoot(BubDlg);
+ Dlg = new DlgRoot(BubDlg, data);
switch(type & 0x00f) {
case BUBBLE_SQUARE: Dlg->SetCheck(110, 0L, true); break;
case BUBBLE_UPTRIA: Dlg->SetCheck(111, 0L, true); break;
@@ -357,9 +372,12 @@ Bubble::PropertyDlg()
if(!Dlg->GetValue(303, &o_pos.fy)) o_pos.fy = fPos.fy;
if(!Dlg->GetValue(305, &o_size)) o_size = fs;
n_pos.fx = o_pos.fx; n_pos.fy = o_pos.fy; n_size = o_size;
- if(parent->name) sprintf(TmpTxt, "Bubble of %s", parent->name);
- else strcpy(TmpTxt, "Bubble properties");
- hDlg = CreateDlgWnd(TmpTxt, 50, 50, 390, 260, Dlg, 0x0L);
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Bubble of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Bubble properties");
+ hDlg = CreateDlgWnd(TmpTxt, 50, 50, 396, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
res = Dlg->GetResult();
@@ -413,14 +431,45 @@ Bubble::PropertyDlg()
bRet = true;
break;
}
- CloseDlgWnd(hDlg);
- delete Dlg;
- return bRet;
+ CloseDlgWnd(hDlg); delete Dlg; return bRet; free(BubDlg);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Bar properties dialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *BarDlg_DlgTmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,1,130,10,55,12\n"
+ "2,3,,,PUSHBUTTON,2,130,25,55,12\n"
+ "3,4,,,PUSHBUTTON,-2,130,40,55,12\n"
+ "4,,5,CHECKED | ISPARENT,GROUP,0,138,40,55,12\n"
+ "5,6,100,ISPARENT | CHECKED,SHEET,3,5,10,120,120\n"
+ "6,7,200,ISPARENT,SHEET,4,5,10,120,120\n"
+ "7,,300,ISPARENT,SHEET,5,5,10,120,120\n"
+ "100,109,,NOSELECT,ODBUTTON,6,18,30,90,50\n"
+ "109,110,,,LTEXT,7,10,80,45,8\n"
+ "110,111,,,RADIO1,8,20,92,25,8\n"
+ "111,112,,,EDTEXT,9,60,92,25,10\n"
+ "112,113,,,LTEXT,-3,87,92,20,8\n"
+ "113,114,,,RADIO1,10,20,104,25,8\n"
+ "114,115,,,EDTEXT,11,60,104,25,10\n"
+ "115,,,,LTEXT,-10,87,104,10,8\n"
+ "200,201,,TOUCHEXIT,RADIO2,12,20,30,45,8\n"
+ "201,205,202,CHECKED | ISPARENT,GROUP,0,0,0,0,0\n"
+ "202,203,,TOUCHEXIT,RADIO1,13,30,40,35,8\n"
+ "203,204,,TOUCHEXIT,RADIO1,14,30,48,35,8\n"
+ "204,,,TOUCHEXIT,RADIO1,15,30,56,35,8\n"
+ "205,206,,,EDVAL1,16,65,56,35,10\n"
+ "206,207,,TOUCHEXIT,RADIO2,17,20,70,45,8\n"
+ "207,211,208,CHECKED | ISPARENT,GROUP,0,0,0,0,0\n"
+ "208,209,,TOUCHEXIT,RADIO1,18,30,80,35,8\n"
+ "209,210,,TOUCHEXIT,RADIO1,19,30,88,35,8\n"
+ "210,,,TOUCHEXIT,RADIO1,20,30,96,35,8\n"
+ "211,212,,,EDVAL1,21,65,96,35,10\n"
+ "212,,,,CHECKBOX,22,20,113,50,8\n"
+ "300,301,,,RTEXT,-12,10,50,45,8\n"
+ "301,302,,,EDVAL1,23,60,50,40,10\n"
+ "302,303,,,RTEXT,-13,10,75,45,8\n"
+ "303,,,LASTOBJ,EDVAL1,24,60,75,40,10";
bool
Bar::PropertyDlg()
{
@@ -428,43 +477,17 @@ Bar::PropertyDlg()
TabSHEET tab2 = {50, 90, 10, "Baseline"};
TabSHEET tab3 = {90, 120, 10, "Edit"};
char sTxt1[20], sTxt2[20];
- DlgInfo BarDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"Apply to BAR", 130, 10, 55, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Apply to PLOT", 130, 25, 55, 12},
- {3, 4, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 130, 40, 55, 12},
- {4, 0, 5, CHECKED | ISPARENT, GROUP, NULL, 138, 40, 55, 12},
- {5, 6, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 120, 120},
- {6, 7, 200, ISPARENT, SHEET, &tab2, 5, 10, 120, 120},
- {7, 0, 300, ISPARENT, SHEET, &tab3, 5, 10, 120, 120},
- {100, 109, 0, NOSELECT, ODBUTTON, (void*)OD_filldef, 18, 30, 90, 50},
- {109, 110, 0, 0x0L, LTEXT, (void*)"bar width:", 10, 80, 45, 8},
- {110, 111, 0, 0x0L, RADIO1, (void*)" fixed", 20, 92, 25, 8},
- {111, 112, 0, 0x0L, EDTEXT, &sTxt1[1], 60, 92, 25, 10},
- {112, 113, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 87, 92, 20, 8},
- {113, 114, 0, 0x0L, RADIO1, (void*)" relative", 20, 104, 25, 8},
- {114, 115, 0, 0x0L, EDTEXT, &sTxt2[1], 60, 104, 25, 10},
- {115, 0, 0, 0x0L, LTEXT, (void*)"%", 87, 104, 10, 8},
- {200, 201, 0, TOUCHEXIT, RADIO2, (void*)"vertical bars", 20, 30, 45, 8},
- {201, 205, 202, CHECKED | ISPARENT, GROUP, NULL, 0, 0, 0, 0},
- {202, 203, 0, TOUCHEXIT, RADIO1, (void*)"bottom baseline", 30, 40, 35, 8},
- {203, 204, 0, TOUCHEXIT, RADIO1, (void*)"top", 30, 48, 35, 8},
- {204, 0, 0, TOUCHEXIT, RADIO1, (void*)"user y =", 30, 56, 35, 8},
- {205, 206, 0, 0x0L, EDVAL1, &BarBase.fy, 65, 56, 35, 10},
- {206, 207, 0, TOUCHEXIT, RADIO2, (void*)"horizontal bars", 20, 70, 45, 8},
- {207, 211, 208, CHECKED | ISPARENT, GROUP, NULL, 0, 0, 0, 0},
- {208, 209, 0, TOUCHEXIT, RADIO1, (void*)"left baseline", 30, 80, 35, 8},
- {209, 210, 0, TOUCHEXIT, RADIO1, (void*)"right", 30, 88, 35, 8},
- {210, 0, 0, TOUCHEXIT, RADIO1, (void*)"user x =", 30, 96, 35, 8},
- {211, 212, 0, 0x0L, EDVAL1, &BarBase.fx, 65, 96, 35, 10},
- {212, 0, 0, 0x0L, CHECKBOX, (void*)"bars centered across baseline", 20, 113, 50, 8},
- {300, 301, 0, 0x0L, RTEXT, (void*)"x-value", 10, 50, 45, 8},
- {301, 302, 0, 0x0L, EDVAL1, &fPos.fx, 60, 50, 40, 10},
- {302, 303, 0, 0x0L, RTEXT, (void*)"y-value", 10, 75, 45, 8},
- {303, 0, 0, LASTOBJ, EDVAL1, &fPos.fy, 60, 75, 40, 10}};
+ void *dyndata[] = {(void*)"Apply to BAR", (void*)"Apply to PLOT", (void*)&tab1,
+ (void*)&tab2, (void*)&tab3, (void*)OD_filldef, (void*)"bar width:", (void*)" fixed",
+ (void*)&sTxt1[1], (void*)" relative", (void*)&sTxt2[1], (void*)"vertical bars",
+ (void*)"bottom baseline", (void*)"top", (void*)"user y =", (void*)&BarBase.fy,
+ (void*)"horizontal bars", (void*)"left baseline", (void*)"right", (void*)"user x =",
+ (void*)&BarBase.fx, (void*)"bars centered across baseline", (void*)&fPos.fx, (void*)&fPos.fy};
+ DlgInfo *BarDlg = CompileDialog(BarDlg_DlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
double n_size;
- int res, tmpType = type;
+ int cb, res, tmpType = type;
bool bRet = false;
LineDEF newLine, newFillLine;
FillDEF newFill;
@@ -477,13 +500,13 @@ Bar::PropertyDlg()
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&BarFill, 0);
if(type & BAR_RELWIDTH) {
WriteNatFloatToBuff(sTxt2, size);
- WriteNatFloatToBuff(sTxt1, defs.GetSize(SIZE_BAR));
+ WriteNatFloatToBuff(sTxt1, DefSize(SIZE_BAR));
}
else {
WriteNatFloatToBuff(sTxt1, size);
- strcpy(sTxt2, " 50");
+ rlp_strcpy(sTxt2, 20, " 50");
}
- Dlg = new DlgRoot(BarDlg);
+ Dlg = new DlgRoot(BarDlg, data);
switch (type & 0xff) {
case BAR_VERTB: case BAR_VERTT: case BAR_VERTU:
Dlg->SetCheck(200, 0L, true);
@@ -507,8 +530,11 @@ Bar::PropertyDlg()
if(type & BAR_RELWIDTH) Dlg->SetCheck(113, 0L, true);
else Dlg->SetCheck(110, 0L, true);
if(type & BAR_CENTERED) Dlg->SetCheck(212, 0L, true);
- if(parent && parent->name) sprintf(TmpTxt, "Bar of %s", parent->name);
- else strcpy(TmpTxt, "Bar properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Bar of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Bar properties");
if(!Dlg->GetValue(211, &o_bl.fx)) o_bl.fx = BarBase.fx;
if(!Dlg->GetValue(205, &o_bl.fy)) o_bl.fy = BarBase.fy;
if(!Dlg->GetValue(301, &o_pos.fx)) o_pos.fx = fPos.fx;
@@ -516,7 +542,7 @@ Bar::PropertyDlg()
n_bl.fx = o_bl.fx; n_bl.fy = o_bl.fy;
n_pos.fx = o_pos.fx; n_pos.fy = o_pos.fy;
n_size = size;
- hDlg = CreateDlgWnd(TmpTxt, 50, 50, 390, 296, Dlg, 0x0L);
+ hDlg = CreateDlgWnd(TmpTxt, 50, 50, 390, 300, Dlg, 0x0L);
do {
LoopDlgWnd();
res = Dlg->GetResult();
@@ -606,47 +632,51 @@ Bar::PropertyDlg()
bRet = true;
break;
}
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(BarDlg);
return bRet;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Data line properties dialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *LineDlg_DlgTmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,-1,150,10,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,150,25,45,12\n"
+ "3,,4,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "4,5,100,ISPARENT | CHECKED,SHEET,1,5,10,139,120\n"
+ "5,6,200,ISPARENT,SHEET,2,5,10,139,120\n"
+ "6,,300,ISPARENT | HIDDEN,SHEET,3,5,10,139,120\n"
+ "100,,,NOSELECT,ODBUTTON,9,10,38,130,100\n"
+ "200,201,,,LTEXT,4,10,32,130,100\n"
+ "201,202,,EXRADIO,ODBUTTON,10,12,45,25,25\n"
+ "202,203,,EXRADIO,ODBUTTON,10,37,45,25,25\n"
+ "203,204,,EXRADIO,ODBUTTON,10,62,45,25,25\n"
+ "204,205,,EXRADIO,ODBUTTON,10,87,45,25,25\n"
+ "205,206,,EXRADIO,ODBUTTON,10,112,45,25,25\n"
+ "206,207,,EXRADIO,ODBUTTON,10,37,70,25,25\n"
+ "207,208,,EXRADIO,ODBUTTON,10,62,70,25,25\n"
+ "208,209,,EXRADIO,ODBUTTON,10,87,70,25,25\n"
+ "209,210,,EXRADIO,ODBUTTON,10,112,70,25,25\n"
+ "210,211,,EXRADIO,ODBUTTON,10,37,95,25,25\n"
+ "211,,,EXRADIO,ODBUTTON,10,62,95,25,25\n"
+ "300,301,,,LTEXT,5,15,30,80,9\n"
+ "301,302,,,EDTEXT,7,15,40,119,10\n"
+ "302,303,,,LTEXT,6,15,55,80,9\n"
+ "303,,,LASTOBJ,EDTEXT,8,15,65,119,10";
+
bool
DataLine::PropertyDlg()
{
TabSHEET tab1 = {0, 40, 10, "Line"};
TabSHEET tab2 = {40, 80, 10, "Style"};
TabSHEET tab3 = {80, 120, 10, "Edit"};
- DlgInfo LineDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 150, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 150, 25, 45, 12},
- {3, 0, 4, ISPARENT | CHECKED, GROUP, NULL, 138, 40, 55, 12},
- {4, 5, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 139, 120},
- {5, 6, 200, ISPARENT, SHEET, &tab2, 5, 10, 139, 120},
- {6, 0, 300, ISPARENT | HIDDEN, SHEET, &tab3, 5, 10, 139, 120},
- {100, 0, 0, NOSELECT, ODBUTTON, (void*)OD_linedef, 10, 38, 130, 100},
- {200, 201, 0, 0x0L, LTEXT, (void*)"select style:", 10, 32, 130, 100},
- {201, 202, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 12, 45, 25, 25},
- {202, 203, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 37, 45, 25, 25},
- {203, 204, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 62, 45, 25, 25},
- {204, 205, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 87, 45, 25, 25},
- {205, 206, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 112, 45, 25, 25},
- {206, 207, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 37, 70, 25, 25},
- {207, 208, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 62, 70, 25, 25},
- {208, 209, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 87, 70, 25, 25},
- {209, 210, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 112, 70, 25, 25},
- {210, 211, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 37, 95, 25, 25},
- {211, 0, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_LineStyleTempl), 62, 95, 25, 25},
- {300, 301, 0, 0x0L, LTEXT, (void*)"range for x-values", 15, 30, 80, 9},
- {301, 302, 0, 0x0L, EDTEXT, (void*)ssXref, 15, 40, 119, 10},
- {302, 303, 0, 0x0L, LTEXT, (void*)"range for y-values", 15, 55, 80, 9},
- {303, 0, 0, LASTOBJ, EDTEXT, (void*)ssYref, 15, 65, 119, 10}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)&tab3, (void*)"select style:",
+ (void*)"range for x-values", (void*)"range for y-values", (void*)ssXref, (void*)ssYref,
+ (void*)OD_linedef, (void*)(OD_LineStyleTempl)};
+ DlgInfo *LineDlg = CompileDialog(LineDlg_DlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
- int res, tmpType = type;
+ int cb, res, tmpType = type;
DWORD undo_flags = 0L;
LineDEF newLine;
bool bRet = false;
@@ -655,11 +685,14 @@ DataLine::PropertyDlg()
if(!parent) return false;
if(parent->Id == GO_FUNCTION) return parent->PropertyDlg();
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
- if(!(Dlg = new DlgRoot(LineDlg)))return false;
+ if(!(Dlg = new DlgRoot(LineDlg, data)))return false;
Dlg->SetCheck(201 + (type & 0x0f), 0L, true);
if(ssXref && ssYref) Dlg->ShowItem(6, true);
- if(parent && parent->name) sprintf(TmpTxt, "Line of %s", parent->name);
- else strcpy(TmpTxt, "Line properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Line of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Line properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 410, 300, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -678,15 +711,13 @@ DataLine::PropertyDlg()
if(res == 1){ //OK pressed
Undo.SetDisp(cdisp);
if(ssXref && ssYref) {
- if(Dlg->GetText(301, TmpTxt) && strcmp(ssXref, TmpTxt)) {
- Undo.String(this, &ssXref, undo_flags); undo_flags |= UNDO_CONTINUE;
- if(ssXref = (char*)realloc(ssXref, strlen(TmpTxt)+1))
- strcpy(ssXref, TmpTxt);
+ if(Dlg->GetText(301, TmpTxt, TMP_TXT_SIZE) && strcmp(ssXref, TmpTxt)) {
+ cb = Undo.String(this, &ssXref, undo_flags); undo_flags |= UNDO_CONTINUE;
+ if(ssXref = (char*)realloc(ssXref, (cb+=2))) rlp_strcpy(ssXref, cb, TmpTxt);
}
- if(Dlg->GetText(303, TmpTxt) && strcmp(ssYref, TmpTxt)) {
- Undo.String(this, &ssYref, undo_flags); undo_flags |= UNDO_CONTINUE;
- if(ssYref = (char*)realloc(ssYref, strlen(TmpTxt)+1))
- strcpy(ssYref, TmpTxt);
+ if(Dlg->GetText(303, TmpTxt, TMP_TXT_SIZE) && strcmp(ssYref, TmpTxt)) {
+ cb = Undo.String(this, &ssYref, undo_flags); undo_flags |= UNDO_CONTINUE;
+ if(ssYref = (char*)realloc(ssYref, (cb+=2))) rlp_strcpy(ssYref, cb, TmpTxt);
}
if(undo_flags & UNDO_CONTINUE) Command(CMD_UPDATE, 0L, cdisp);
parent->Command(CMD_MRK_DIRTY, 0L, cdisp);
@@ -700,8 +731,7 @@ DataLine::PropertyDlg()
if(undo_flags & UNDO_CONTINUE) bRet = true;
}
CloseDlgWnd(hDlg);
- delete Dlg;
- return bRet;
+ delete Dlg; free(LineDlg); return bRet;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -722,15 +752,18 @@ DataPolygon::PropertyDlg()
FillDEF newFill;
DWORD undo_flags = 0L;
anyOutput *cdisp = Undo.cdisp;
- int res;
+ int cb, res;
bool bRet = false;
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&pgFill, 0);
- Dlg = new DlgRoot(LineDlg);
- if(parent && parent->name) sprintf(TmpTxt, "Polygon of %s", parent->name);
- else strcpy(TmpTxt, "Polygon properties");
- hDlg = CreateDlgWnd(TmpTxt, 50, 50, 310, 204, Dlg, 0x0L);
+ Dlg = new DlgRoot(LineDlg, data);
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Polygon of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Polygon properties");
+ hDlg = CreateDlgWnd(TmpTxt, 50, 50, 310, 210, Dlg, 0x0L);
do{
LoopDlgWnd();
res = Dlg->GetResult();
@@ -809,7 +842,7 @@ RegLine::PropertyDlg()
{313, 0, 0, LASTOBJ, LTEXT, (void*)"[data]", 119, 101, 15, 8}};
DlgRoot *Dlg;
void *hDlg;
- int res, tmpType;
+ int cb, res, tmpType;
bool bRet = false;
LineDEF newLine;
DWORD undo_flags = 0L;
@@ -831,12 +864,20 @@ RegLine::PropertyDlg()
case 0x3000: ty = "sqrt(y)"; break;
default: ty = "y"; break;
}
+#ifdef USE_WIN_SECURE
+ sprintf_s(text1, 40, "%s = %.3lf + %.3lf * %s (n = %ld)", ty, l1.fx, l1.fy, tx, nPoints);
+ sprintf_s(text2, 40, "%s = %.3lf + %.3lf * %s", ty, l2.fx, l2.fy, tx);
+ sprintf_s(text3, 40, "%s = %.3lf + %.3lf * %s", ty, l3.fx, l3.fy, tx);
+ sprintf_s(text4, 40, "%s = %.3lf + %.3lf * %s", ty, l4.fx, l4.fy, tx);
+ sprintf_s(text5, 40, "%s = a + b * %s", ty, tx);
+#else
sprintf(text1, "%s = %.3lf + %.3lf * %s (n = %ld)", ty, l1.fx, l1.fy, tx, nPoints);
sprintf(text2, "%s = %.3lf + %.3lf * %s", ty, l2.fx, l2.fy, tx);
sprintf(text3, "%s = %.3lf + %.3lf * %s", ty, l3.fx, l3.fy, tx);
sprintf(text4, "%s = %.3lf + %.3lf * %s", ty, l4.fx, l4.fy, tx);
sprintf(text5, "%s = a + b * %s", ty, tx);
- if(!(Dlg = new DlgRoot(LineDlg))) return false;
+#endif
+ if(!(Dlg = new DlgRoot(LineDlg, data))) return false;
Dlg->Activate(211, false); Dlg->Activate(213, false);
switch(type & 0x07) {
case 1: Dlg->SetCheck(202, 0L, true); break;
@@ -869,10 +910,11 @@ RegLine::PropertyDlg()
if(!Dlg->GetValue(310, &o_clip.Ymin)) o_clip.Ymin = uclip.Ymin;
if(!Dlg->GetValue(312, &o_clip.Ymax)) o_clip.Ymax = uclip.Ymax;
memcpy(&n_clip, &o_clip, sizeof(fRECT));
- if(parent && parent->name) {
- sprintf(TmpTxt, "Regression line of %s", parent->name);
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Regression line of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
}
- else strcpy(TmpTxt, "Regression line properties");
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Regression line properties");
hDlg = CreateDlgWnd(cp ? TmpTxt :
(char*)"Linear regression analysis step 2/2", 50, 50, 420, 320, Dlg, 0x0L);
if(!cp) Dlg->SetCheck(5, 0L, true);
@@ -959,7 +1001,7 @@ SDellipse::PropertyDlg()
{259, 0, 0, LASTOBJ, LTEXT, 0L, 82, 108, 30, 8}};
DlgRoot *Dlg;
void *hDlg;
- int res, tmpType;
+ int cb, res, tmpType;
LineDEF newLine;
bool bRet = false;
DWORD undo_flags = 0L;
@@ -967,16 +1009,19 @@ SDellipse::PropertyDlg()
if(!parent) return false;
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
- if(!(Dlg = new DlgRoot(ellDlg))) return false;
+ if(!(Dlg = new DlgRoot(ellDlg, data))) return false;
if(!(type & 0x10000)) Dlg->SetCheck(200, 0L, true);
WriteNatFloatToBuff(TmpTxt, mx); Dlg->SetText(252, TmpTxt+1);
WriteNatFloatToBuff(TmpTxt, my); Dlg->SetText(254, TmpTxt+1);
- strcpy(TmpTxt, "+/-");
+ rlp_strcpy(TmpTxt, 4, "+/-");
WriteNatFloatToBuff(TmpTxt+3, sd1); Dlg->SetText(259, TmpTxt);
WriteNatFloatToBuff(TmpTxt+3, sd2); Dlg->SetText(257, TmpTxt);
tmpType = type;
- if(parent && parent->name) sprintf(TmpTxt, "SD ellipse of %s", parent->name);
- else strcpy(TmpTxt, "SD ellipse properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "SD ellipse of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "SD ellipse properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 410, 300, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -1022,7 +1067,7 @@ ErrorBar::PropertyDlg()
{104, 105, 0, 0x0L, EDVAL1, &ErrLine.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 *)ErrLine.color, 46, 70, 25, 10},
+ {107, 0, 0, OWNDIALOG, COLBUTT, (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, 30, 28, 8},
{301, 302, 0, 0x0L, EDVAL1, &fPos.fx, 46, 30, 35, 10},
@@ -1040,7 +1085,7 @@ ErrorBar::PropertyDlg()
{505, 0, 0, LASTOBJ | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)(OD_ErrBarTempl), 62, 65, 25, 25}};
DlgRoot *Dlg;
void *hDlg;
- int res, tmpType = type;
+ int cb, res, tmpType = type;
double n_sb, o_sb, n_lw, o_lw, n_err, o_err;
lfPOINT n_pos, o_pos;
DWORD n_col, undo_flags = 0L;
@@ -1050,7 +1095,7 @@ ErrorBar::PropertyDlg()
if(!parent) return false;
desc[0] = 0;
- if(!(Dlg = new DlgRoot(ErrDlg)))return false;
+ if(!(Dlg = new DlgRoot(ErrDlg, data)))return false;
Dlg->SetCheck(500 + (type & 0x7), 0L, true);
if(!(Dlg->GetValue(101, &o_sb))) o_sb = SizeBar;
if(!(Dlg->GetValue(104, &o_lw))) o_lw = ErrLine.width;
@@ -1058,8 +1103,11 @@ ErrorBar::PropertyDlg()
if(!(Dlg->GetValue(301, &o_pos.fx))) o_pos.fx = fPos.fx;
if(!(Dlg->GetValue(303, &o_pos.fy))) o_pos.fy = fPos.fy;
n_sb = o_sb; n_lw = o_lw; n_err = o_err; n_pos.fx = o_pos.fx; n_pos.fy = o_pos.fy;
- if(parent && parent->name) sprintf(TmpTxt, "Error bar of %s", parent->name);
- else strcpy(TmpTxt, "Error properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Error bar of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Error bar properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 328, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -1072,7 +1120,7 @@ ErrorBar::PropertyDlg()
Dlg->Activate(307, true); res = -1; break;
case 1: //accept for this object
case 2: // or all objects of plot
- Undo.SetDisp(cdisp); Dlg->GetText(307, desc);
+ Undo.SetDisp(cdisp); Dlg->GetText(307, desc, 80);
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);
@@ -1081,17 +1129,20 @@ ErrorBar::PropertyDlg()
}while (res <0);
switch (res) {
case 1: //new setting for current error bar only
+ undo_flags = CheckNewFloat(&ferr, o_err, n_err, parent, undo_flags);
+ undo_flags = CheckNewLFPoint(&fPos, &o_pos, &n_pos, parent, undo_flags);
+ if(undo_flags & UNDO_CONTINUE) parent->Command(CMD_MRK_DIRTY, 0L, 0L);
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;
+ cb = Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, (cb+=2));
+ rlp_strcpy(name, cb, 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(desc[0] && !name) {
+ cb = Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, (cb+=2));
+ rlp_strcpy(name, cb, desc); undo_flags |= UNDO_CONTINUE;
}
- else if(name && name[0]) {
+ else if(!desc[0] && name && name[0]) {
Undo.String(this, &name, undo_flags);
name[0] = 0; undo_flags |= UNDO_CONTINUE;
}
@@ -1099,8 +1150,6 @@ ErrorBar::PropertyDlg()
undo_flags = CheckNewFloat(&ErrLine.width, o_lw, n_lw, parent, undo_flags);
undo_flags = CheckNewDword(&ErrLine.color, ErrLine.color, n_col, parent, undo_flags);
undo_flags = CheckNewInt(&type, type, tmpType, parent, undo_flags);
- undo_flags = CheckNewFloat(&ferr, o_err, n_err, parent, undo_flags);
- undo_flags = CheckNewLFPoint(&fPos, &o_pos, &n_pos, parent, undo_flags);
if(undo_flags & UNDO_CONTINUE) bRet = true;
break;
case 2: //new settings to all error bars of plot
@@ -1148,7 +1197,7 @@ Arrow::PropertyDlg()
{107, 108, 0, 0x0L, EDVAL1, &LineDef.width, 46, 70, 25, 10},
{108, 109, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 73, 70, 20, 8},
{109, 110, 0, 0x0L, RTEXT, (void*)"color", 15, 82, 28, 8},
- {110, 0, 0, OWNDIALOG, COLBUTTON, (void *)LineDef.color, 46, 82, 25, 10},
+ {110, 0, 0, OWNDIALOG, COLBUTT, (void *)&LineDef.color, 46, 82, 25, 10},
{200, 201, 0, TOUCHEXIT, RADIO1, (void*)"line only", 15, 40, 60, 8},
{201, 202, 0, TOUCHEXIT, RADIO1, (void*)"arrow with lines", 15, 55, 60, 8},
{202, 0, 0, TOUCHEXIT, RADIO1, (void*)"filled arrow", 15, 70, 60, 8},
@@ -1170,13 +1219,13 @@ Arrow::PropertyDlg()
void *hDlg;
lfPOINT o_pos1, o_pos2, n_pos1, n_pos2;
double o_cw, o_cl, n_cw, n_cl, o_lw, n_lw;
- int res, tmptype = type, undo_level = *Undo.pcb;
+ int cb, res, tmptype = type, undo_level = *Undo.pcb;
bool bRet = false;
DWORD o_col, n_col, undo_flags = 0L;
anyOutput *cdisp = Undo.cdisp;
if(!parent) return false;
- if(!(Dlg = new DlgRoot(ArrowDlg))) return false;
+ if(!(Dlg = new DlgRoot(ArrowDlg, data))) return false;
Dlg->GetValue(301, &o_pos2.fx); Dlg->GetValue(303, &o_pos2.fy);
Dlg->GetValue(305, &o_pos1.fx); Dlg->GetValue(307, &o_pos1.fy);
Dlg->GetValue(101, &o_cw); Dlg->GetValue(104, &o_cl);
@@ -1191,8 +1240,11 @@ Arrow::PropertyDlg()
Dlg->ShowItem(2, false);
Dlg->ShowItem(308, false); Dlg->ShowItem(309, false);
}
- if(parent && parent->name) sprintf(TmpTxt, "Arrow of %s", parent->name);
- else strcpy(TmpTxt, "Arrow properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Arrow of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Arrow properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 328, 260, Dlg, 0x0L);
do {
LoopDlgWnd(); res = Dlg->GetResult();
@@ -1296,7 +1348,7 @@ Box::PropertyDlg()
};
DlgRoot *Dlg;
void *hDlg;
- int res, tmpType = type;
+ int cb, res, tmpType = type;
FillDEF newFill;
LineDEF newLine, newHatchLine;
DWORD undo_flags = 0L;
@@ -1312,21 +1364,24 @@ Box::PropertyDlg()
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&Fill, 0);
if(type & BAR_RELWIDTH) {
WriteNatFloatToBuff(sTxt2, size);
- WriteNatFloatToBuff(sTxt1, defs.GetSize(SIZE_BAR));
+ WriteNatFloatToBuff(sTxt1, DefSize(SIZE_BAR));
}
else {
WriteNatFloatToBuff(sTxt1, size);
- strcpy(sTxt2, " 50");
+ rlp_strcpy(sTxt2, 20, " 50");
}
- Dlg = new DlgRoot(BoxDlg);
+ Dlg = new DlgRoot(BoxDlg, data);
if(type & BAR_WIDTHDATA) {
Dlg->ShowItem(105, false);
Dlg->ShowItem(308, true); Dlg->ShowItem(309, true);
}
if(type & BAR_RELWIDTH) Dlg->SetCheck(113, 0L, true);
else Dlg->SetCheck(110, 0L, true);
- if(parent && parent->name) sprintf(TmpTxt, "Box of %s", parent->name);
- else strcpy(TmpTxt, "Box properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Box of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Box properties");
Dlg->GetValue(309, &o_size);
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 390, 290, Dlg, 0x0L);
do {
@@ -1453,7 +1508,7 @@ Whisker::PropertyDlg()
DlgInfo *ErrDlg = CompileDialog(WhiskerDlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
- int res, tmp_type;
+ int cb, res, tmp_type;
DWORD undo_flags = 0L, n_col = LineDef.color;
anyOutput *cdisp = Undo.cdisp;
lfPOINT n_pos;
@@ -1463,11 +1518,14 @@ Whisker::PropertyDlg()
if(!parent) return false;
desc[0] = 0; tmp_type = type;
- Dlg = new DlgRoot(ErrDlg);
+ Dlg = new DlgRoot(ErrDlg, data);
Dlg->SetCheck(500 + (tmp_type & 0x03), 0L, true);
Dlg->GetValue(101, &o_size); Dlg->GetValue(104, &o_lw);
- if(parent && parent->name) sprintf(TmpTxt, "Whisker of %s", parent->name);
- else strcpy(TmpTxt, "Whisker properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Whisker of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Whisker properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 339, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -1480,25 +1538,25 @@ 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);
+ Dlg->GetText(309, desc, 80);
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;
+ cb = Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, (cb+=2));
+ rlp_strcpy(name, cb, 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;
+ cb = Undo.String(this, &name, undo_flags);
+ name = (char*)realloc(name, (cb+=2));
+ rlp_strcpy(name, cb, desc); undo_flags |= UNDO_CONTINUE;
}
else if(name && name[0]) {
Undo.String(this, &name, undo_flags);
- name[0] = 0; undo_flags |= UNDO_CONTINUE;
+ name[0] = 0; undo_flags |= UNDO_CONTINUE;
}
if(Dlg->GetValue(301, &tmpVal)) n_pos.fx = tmpVal;
else n_pos.fx = pos1.fx;
@@ -1562,7 +1620,7 @@ DropLine::PropertyDlg()
{256, 0, 0, LASTOBJ, CHECKBOX, (void*)"x-axis", 86, 100, 35, 8}};
DlgRoot *Dlg;
void *hDlg;
- int res, tmptype;
+ int cb, res, tmptype;
bool bRet = false;
LineDEF newLine;
DWORD undo_flags = 0L;
@@ -1571,7 +1629,7 @@ DropLine::PropertyDlg()
if(!parent) return false;
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
- Dlg = new DlgRoot(LineDlg);
+ Dlg = new DlgRoot(LineDlg, data);
Dlg->SetCheck(251, 0L, type & DL_LEFT ? true : false);
Dlg->SetCheck(252, 0L, type & DL_RIGHT ? true : false);
Dlg->SetCheck(253, 0L, type & DL_YAXIS ? true : false);
@@ -1579,8 +1637,11 @@ DropLine::PropertyDlg()
Dlg->SetCheck(255, 0L, type & DL_BOTTOM ? true : false);
Dlg->SetCheck(256, 0L, type & DL_XAXIS ? true : false);
Dlg->GetValue(201, &o_pos.fx); Dlg->GetValue(203, &o_pos.fy);
- if(parent->name) sprintf(TmpTxt, "Dropline of %s", parent->name);
- else strcpy(TmpTxt, "Dropline properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Dropline of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Dropline properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 415, 300, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -1656,7 +1717,7 @@ DropLine3D::PropertyDlg()
{256, 0, 0, LASTOBJ, CHECKBOX, (void*)"right", 86, 100, 35, 8}};
DlgRoot *Dlg;
void *hDlg;
- int res, tmptype, i;
+ int cb, res, tmptype, i;
bool bRet = false;
LineDEF newLine;
DWORD undo_flags = 0L;
@@ -1665,14 +1726,17 @@ DropLine3D::PropertyDlg()
if(!parent) return false;
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
- Dlg = new DlgRoot(LineDlg);
+ Dlg = new DlgRoot(LineDlg, data);
for(i = 0; i < 6; i++) {
Dlg->SetCheck(251+i, 0L, (type & (1<<i)) ? true : false);
}
Dlg->GetValue(201, &o_pos.fx); Dlg->GetValue(203, &o_pos.fy);
Dlg->GetValue(205, &o_pos.fz);
- if(parent->name) sprintf(TmpTxt, "Dropline of %s", parent->name);
- else strcpy(TmpTxt, "Dropline properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Dropline of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Dropline properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 415, 300, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -1742,7 +1806,7 @@ Sphere::PropertyDlg()
{104, 105, 0, 0x0L, EDVAL1, &Line.width, 46, 47, 25, 10},
{105, 106, 0, 0x0L, LTEXT, (void*)Units[defs.cUnits].display, 73, 47, 15, 8},
{106, 107, 0, 0x0L, RTEXT, (void*)"line color", 15, 59, 28, 8},
- {107, 108, 0, OWNDIALOG, COLBUTTON, (void *)Line.color, 46, 59, 25, 10},
+ {107, 108, 0, OWNDIALOG, COLBUTT, (void *)&Line.color, 46, 59, 25, 10},
{108, 109, 0, 0x0L, RTEXT, (void*)"fill color", 15, 71, 28, 8},
{109, 0, 0, OWNDIALOG, SHADE3D, &newFill, 46, 71, 25, 10},
{200, 201, 0, 0x0L, RTEXT, (void*)"x-value", 15, 35, 28, 8},
@@ -1753,7 +1817,7 @@ Sphere::PropertyDlg()
{205, 0, 0, LASTOBJ, EDVAL1, &fPos.fz, 46, 59, 35, 10}};
DlgRoot *Dlg;
void *hDlg;
- int res;
+ int cb, res;
bool bRet = false, bContinue = false;
fPOINT3D n_pos, o_pos;
DWORD new_lcolor = Line.color, undo_flags = 0L;
@@ -1762,13 +1826,16 @@ Sphere::PropertyDlg()
if(!parent) return false;
memcpy(&newFill, &Fill, sizeof(FillDEF));
- Dlg = new DlgRoot(BallDlg);
+ Dlg = new DlgRoot(BallDlg, data);
Dlg->GetValue(201, &o_pos.fx); Dlg->GetValue(203, &o_pos.fy);
Dlg->GetValue(205, &o_pos.fz); Dlg->GetValue(101, &o_size);
Dlg->GetValue(104, &o_lsize);
- if(parent->name) sprintf(TmpTxt, "Ball of %s", parent->name);
- else strcpy(TmpTxt, "Ball properties");
- hDlg = CreateDlgWnd(TmpTxt, 50, 50, 335, 216, Dlg, 0x0L);
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Ball of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Ball properties");
+ hDlg = CreateDlgWnd(TmpTxt, 50, 50, 335, 220, Dlg, 0x0L);
do{
LoopDlgWnd();
res = Dlg->GetResult();
@@ -1854,7 +1921,7 @@ Plane3D::PropertyDlg()
DlgInfo *PlaneDlg = CompileDialog(Plane3D_DlgTmpl, dyndata);
DlgRoot *Dlg;
void *hDlg;
- int res;
+ int cb, res;
bool bRet = false;
DWORD new_lcolor = Line.color, undo_flags = 0L;
anyOutput *cdisp = Undo.cdisp;
@@ -1867,14 +1934,17 @@ Plane3D::PropertyDlg()
rb_width = parent->GetSize(SIZE_CELLWIDTH) *100.0;
rb_z = parent->GetSize(SIZE_ZPOS);
}
- Dlg = new DlgRoot(PlaneDlg);
+ Dlg = new DlgRoot(PlaneDlg, data);
Dlg->GetValue(101, &o_lsize); Dlg->GetValue(202, &o_rbw);
Dlg->GetValue(205, &o_rbz);
if(parent && ((parent->Id==GO_RIBBON && parent->type > 1) || parent->Id==GO_GRID3D))
Dlg->ShowItem(200, false); //paravent plot
- if(parent->Id == GO_RIBBON && parent->type >2) sprintf(TmpTxt, "3D Surface Properties");
- else if(parent->name) sprintf(TmpTxt, "Plane of %s", parent->name);
- else strcpy(TmpTxt, "Plane properties");
+ if(parent->Id == GO_RIBBON && parent->type >2) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "3D Surface Properties");
+ else if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Plane of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Plane properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 355, 226, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -1936,7 +2006,7 @@ Brick::PropertyDlg()
{101, 102, 0, 0x0L, EDVAL1, &Line.width, 60, 30, 25, 10},
{102, 103, 0, 0x0L, LTEXT, (void*)Units[defs.cUnits].display, 87, 30, 20, 8},
{103, 104, 0, 0x0L, RTEXT, (void*)"outline color", 18, 42, 40, 8},
- {104, 105, 0, OWNDIALOG, COLBUTTON, (void *)Line.color, 60, 42, 25, 10},
+ {104, 105, 0, OWNDIALOG, COLBUTT, (void *)&Line.color, 60, 42, 25, 10},
{105, 106, 0, 0x0L, RTEXT,(void*)"fill color" , 18, 54, 40, 8},
{106, 107, 0, OWNDIALOG, SHADE3D, &newFill, 60, 54, 25, 10},
{107, 108, 0, 0x0L, RTEXT, (void*)"column width", 18, 74, 40, 8},
@@ -1955,7 +2025,7 @@ Brick::PropertyDlg()
{307, 0, 0, LASTOBJ, EDVAL1, &height, 50, 87, 30, 10}};
DlgRoot *Dlg;
void *hDlg;
- int res;
+ int cb, res;
bool bRet = false;
DWORD col1 = Line.color, undo_flags = 0L;
anyOutput *cdisp = Undo.cdisp;
@@ -1965,14 +2035,17 @@ Brick::PropertyDlg()
if(!parent) return false;
memcpy(&newFill, &Fill, sizeof(FillDEF));
- Dlg = new DlgRoot(ColumnDlg);
+ Dlg = new DlgRoot(ColumnDlg, data);
Dlg->GetValue(101, &o_lw); Dlg->GetValue(301, &o_pos.fx);
Dlg->GetValue(303, &o_pos.fy); Dlg->GetValue(305, &o_pos.fz);
Dlg->GetValue(307, &o_height); Dlg->GetValue(108, &o_width);
Dlg->GetValue(111, &o_depth);
memcpy(&n_pos, &o_pos, sizeof(fPOINT3D));
- if(parent->name) sprintf(TmpTxt, "Column of %s", parent->name);
- else strcpy(TmpTxt, "Column properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Column of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Column properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 405, 296, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -2082,13 +2155,13 @@ Arrow3D::PropertyDlg()
void *hDlg;
fPOINT3D o_pos1, o_pos2, n_pos1, n_pos2;
double o_cw, o_cl, n_cw, n_cl, o_lw, n_lw;
- int res, tmptype = type, undo_level = *Undo.pcb;
+ int cb, res, tmptype = type, undo_level = *Undo.pcb;
bool bRet = false;
DWORD o_col, n_col, undo_flags = 0L;
anyOutput *cdisp = Undo.cdisp;
if(!parent) return false;
- if(!(Dlg = new DlgRoot(ArrowDlg))) return false;
+ if(!(Dlg = new DlgRoot(ArrowDlg, data))) return false;
Dlg->GetValue(301, &o_pos2.fx); Dlg->GetValue(303, &o_pos2.fy);
Dlg->GetValue(305, &o_pos2.fz); Dlg->GetValue(307, &o_pos1.fx);
Dlg->GetValue(309, &o_pos1.fy); Dlg->GetValue(311, &o_pos1.fz);
@@ -2099,8 +2172,11 @@ Arrow3D::PropertyDlg()
case ARROW_TRIANGLE: Dlg->SetCheck(202, 0L, true); break;
default: Dlg->SetCheck(200, 0L, true); break;
}
- if(parent->name) sprintf(TmpTxt, "Arrow of %s", parent->name);
- else strcpy(TmpTxt, "Arrow properties");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Arrow of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Arrow properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 328, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -2176,7 +2252,7 @@ Line3D::PropertyDlg()
{100, 0, 0, LASTOBJ | NOSELECT, ODBUTTON, (void*)OD_linedef, 10, 30, 130, 90}};
DlgRoot *Dlg;
void *hDlg;
- int res;
+ int cb, res;
bool bRet = false;
LineDEF newLine;
anyOutput *cdisp = Undo.cdisp;
@@ -2184,8 +2260,12 @@ Line3D::PropertyDlg()
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);
+ if(!(Dlg = new DlgRoot(LineDlg, data)))return false;
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Line of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Line properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 410, 314, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -2238,7 +2318,7 @@ Label::PropertyDlg()
{101, 102, 0, 0x0L, INCDECVAL1, &TextDef.fSize, 80, 33, 33, 10},
{102, 103, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 115, 33, 20, 8},
{103, 104, 0, 0x0L, RTEXT, (void*)"color", 30, 45, 45, 8},
- {104, 107, 0, OWNDIALOG, COLBUTTON, (void *)TextDef.ColTxt, 80, 45, 25, 10},
+ {104, 107, 0, OWNDIALOG, COLBUTT, (void *)&TextDef.ColTxt, 80, 45, 25, 10},
{105, 106, 0, 0x0L, LTEXT, (void*)"text:", 10, 83, 25, 8},
{106, 0, 0, TOUCHEXIT, EDTEXT, (void*)TextDef.text, 10, 95, 149, 10},
{107, 108, 0, 0x0L, RTEXT, (void*)"rotation", 30, 57, 45, 8},
@@ -2281,7 +2361,7 @@ Label::PropertyDlg()
{603, 0, 0, LASTOBJ | TOUCHEXIT, ODBUTTON, (void*)OD_DrawOrder, 185, 90, 15, 15}};
DlgRoot *Dlg;
void *hDlg;
- int res, i, c_style, c_font;
+ int cb, res, i, c_style, c_font;
bool RetVal = false, check;
double tmp;
DWORD undo_flags = 0x0;
@@ -2296,7 +2376,7 @@ Label::PropertyDlg()
lspc = 100.0 * parent->GetSize(SIZE_LSPC);
}
if (lspc < 50.0) lspc = 100.0;
- if(Dlg = new DlgRoot(LabelDlg)) {
+ if(Dlg = new DlgRoot(LabelDlg, data)) {
if(parent->Id == GO_MLABEL) Dlg->ShowItem(150, true);
Dlg->TextFont(221, FONT_HELVETICA); Dlg->TextFont(222, FONT_TIMES);
Dlg->TextFont(223, FONT_COURIER); Dlg->TextFont(224, FONT_GREEK);
@@ -2325,12 +2405,12 @@ Label::PropertyDlg()
Dlg->SetText(303, " ");
TmpTxt[0] = 0;
if(parent->Id == GO_MLABEL) {
- if(parent->parent->Id == GO_AXIS) strcpy(TmpTxt, "(axis)");
- else if(parent->parent->Id == GO_TICK) strcpy(TmpTxt, "(tick)");
+ if(parent->parent->Id == GO_AXIS) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(axis)");
+ else if(parent->parent->Id == GO_TICK) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(tick)");
}
else {
- if(parent->Id == GO_AXIS) strcpy(TmpTxt, "(axis)");
- else if(parent->Id == GO_TICK) strcpy(TmpTxt, "(tick)");
+ if(parent->Id == GO_AXIS) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(axis)");
+ else if(parent->Id == GO_TICK) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(tick)");
}
if(TmpTxt[0]) {
Dlg->SetText(302, TmpTxt); Dlg->Activate(302, false);
@@ -2347,12 +2427,12 @@ Label::PropertyDlg()
case LB_Y_PARENT:
Dlg->SetText(306, " "); TmpTxt[0] = 0;
if(parent->Id == GO_MLABEL) {
- if(parent->parent->Id == GO_AXIS) strcpy(TmpTxt, "(axis)");
- if(parent->parent->Id == GO_TICK) strcpy(TmpTxt, "(tick)");
+ if(parent->parent->Id == GO_AXIS) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(axis)");
+ if(parent->parent->Id == GO_TICK) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(tick)");
}
else {
- if(parent->Id == GO_AXIS) strcpy(TmpTxt, "(axis)");
- if(parent->Id == GO_TICK) strcpy(TmpTxt, "(tick)");
+ if(parent->Id == GO_AXIS) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(axis)");
+ if(parent->Id == GO_TICK) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "(tick)");
}
if(TmpTxt[0]) {
Dlg->SetText(305, TmpTxt); Dlg->Activate(305, false);
@@ -2369,7 +2449,7 @@ Label::PropertyDlg()
Dlg->GetValue(302, &o_pos.fx); Dlg->GetValue(305, &o_pos.fy);
Dlg->GetValue(309, &o_dist.fx); Dlg->GetValue(312, &o_dist.fy);
n_pos.fx = o_pos.fx; n_pos.fy = o_pos.fy; n_dist.fx = o_dist.fx; n_dist.fy = o_dist.fy;
- hDlg = CreateDlgWnd("Label properties", 50, 50, isDataLabel ? 470 : 450, 254, Dlg, 0x0L);
+ hDlg = CreateDlgWnd("Label properties", 50, 50, isDataLabel ? 470 : 450, 258, Dlg, 0x0L);
do{
LoopDlgWnd(); res = Dlg->GetResult();
switch (res) {
@@ -2389,7 +2469,7 @@ Label::PropertyDlg()
Dlg->GetValue(309, &n_dist.fx); Dlg->GetValue(312, &n_dist.fy);
break;
case 106: //text modified
- if(!(Dlg->GetText(res, TmpTxt))) TmpTxt[0] = 0;
+ if(!(Dlg->GetText(res, TmpTxt, TMP_TXT_SIZE))) TmpTxt[0] = 0;
else {
if(!fmt) fmt = new fmtText(0L, 0, 0, TmpTxt);
else fmt->SetText(0L, TmpTxt, 0L, 0L);
@@ -2451,10 +2531,12 @@ Label::PropertyDlg()
o_dist.fy != n_dist.fy)){
pa->Command(CMD_SAVE_TICKS, 0L, 0L); undo_flags |= UNDO_CONTINUE;
}
- TmpTxt[0] = 0; Dlg->GetText(106, TmpTxt);
+ TmpTxt[0] = 0; Dlg->GetText(106, TmpTxt, TMP_TXT_SIZE);
if(res == 1 && TextDef.text && TextDef.text[0] && strcmp(TextDef.text, TmpTxt)) {
- Undo.String(this, &TextDef.text, undo_flags); undo_flags |= UNDO_CONTINUE;
- if(TextDef.text) free(TextDef.text); TextDef.text = strdup(TmpTxt);
+ Undo.String(this, &TextDef.text, undo_flags);
+ undo_flags |= UNDO_CONTINUE; cb = (int)strlen(TmpTxt);
+ TextDef.text = (char*)realloc(TextDef.text, (cb+=2));
+ rlp_strcpy(TextDef.text, cb, TmpTxt);
}
if(cmpTextDEF(&OldTxtDef, &NewTxtDef)){
if(NewTxtDef.ColTxt != TextDef.ColTxt) bBGvalid = false;
@@ -2502,6 +2584,103 @@ Label::PropertyDlg()
return RetVal;
}
+bool
+TextFrame::PropertyDlg()
+{
+ TabSHEET tab1 = {0, 27, 10, "Text"};
+ TabSHEET tab2 = {27, 57, 10, "Frame"};
+ double lspc2, lspc1 = lspc2 = lspc * 100.0;
+ DlgInfo TextFrmDlg[] = {
+ {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 130, 10, 45, 12},
+ {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 130, 25, 45, 12},
+ {3, 50, 4, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
+ {4, 5, 100, ISPARENT | CHECKED, SHEET, &tab1, 5, 10, 119, 100},
+ {5, 0, 200, ISPARENT, SHEET, &tab2, 5, 10, 119, 100},
+ {50, 0, 600, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
+ {100, 101, 0, 0x0L, RTEXT, (void*)"size", 10, 33, 45, 8},
+ {101, 102, 0, 0x0L, INCDECVAL1, &TextDef.fSize, 60, 33, 33, 10},
+ {102, 103, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 95, 33, 20, 8},
+ {103, 104, 0, 0x0L, RTEXT, (void*)"color", 10, 45, 45, 8},
+ {104, 150, 0, OWNDIALOG, COLBUTT, (void *)&TextDef.ColTxt, 60, 45, 25, 10},
+ {150, 0, 151, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
+ {151, 152, 0, 0x0L, RTEXT, (void *)"line spacing", 10, 57, 45, 8},
+ {152, 153, 0, 0x0L, INCDECVAL1, &lspc1, 60, 57, 33, 10},
+ {153, 0, 0, 0x0L, LTEXT, (void *)"%", 95, 57, 20, 8},
+ {200, 0, 0, NOSELECT, ODBUTTON, (void*)OD_filldef, 20, 30, 90, 50},
+ {600, 601, 0, TOUCHEXIT, ODBUTTON, (void*)OD_DrawOrder, 145, 45, 15, 15},
+ {601, 602, 0, TOUCHEXIT, ODBUTTON, (void*)OD_DrawOrder, 145, 60, 15, 15},
+ {602, 603, 0, TOUCHEXIT, ODBUTTON, (void*)OD_DrawOrder, 145, 75, 15, 15},
+ {603, 0, 0, LASTOBJ | TOUCHEXIT, ODBUTTON, (void*)OD_DrawOrder, 145, 90, 15, 15}};
+ DlgRoot *Dlg;
+ void *hDlg;
+ anyOutput *cdisp = Undo.cdisp;
+ int i, res;
+ bool bRet = false;
+ LineDEF newLine, newFillLine;
+ FillDEF newFill;
+ DWORD undo_flags = 0L;
+ TextDEF OldTxtDef, NewTxtDef;
+
+ if(!parent || !data) return false;
+ OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
+ OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&Fill, 0);
+ if(!(Dlg = new DlgRoot(TextFrmDlg, data)))return false;
+ memcpy(&OldTxtDef, &TextDef, sizeof(TextDEF)); OldTxtDef.text = 0L;
+ Dlg->GetValue(101, &OldTxtDef.fSize); memcpy(&NewTxtDef, &OldTxtDef, sizeof(TextDEF));
+ Dlg->GetValue(152, &lspc1);
+ hDlg = CreateDlgWnd("Text Frame", 50, 50, 370, 258, Dlg, 0x0L);
+ do{
+ LoopDlgWnd(); res = Dlg->GetResult();
+ switch (res) {
+ case 1:
+ Dlg->GetValue(101, &NewTxtDef.fSize); Dlg->GetColor(104, &NewTxtDef.ColTxt);
+ Dlg->GetValue(152, &lspc2); lspc1 /= 100.0; lspc2 /= 100.0;
+ break;
+ case 600: case 601: case 602: case 603:
+ Undo.SetDisp(cdisp);
+ res = ExecDrawOrderButt(parent, this, res);
+ break;
+ }
+ }while (res < 0);
+ if(res == 1){ //OK pressed
+ Undo.SetDisp(cdisp);
+ OD_filldef(OD_GETLINE, 0L, 0L, 0L, (void *)&newLine, 0);
+ OD_filldef(OD_GETFILL, 0L, 0L, 0L, (void *)&newFill, 0);
+ memcpy(&newFillLine, &FillLine, sizeof(LineDEF));
+ if(newFill.hatch) memcpy(&newFillLine, newFill.hatch, sizeof(LineDEF));
+ if(cmpTextDEF(&OldTxtDef, &NewTxtDef)){
+ Undo.TextDef(this, &TextDef, undo_flags);
+ memcpy(&TextDef, &NewTxtDef, sizeof(TextDEF));
+ undo_flags |= UNDO_CONTINUE; TextDef.text = 0L;
+ }
+ undo_flags = CheckNewFloat(&lspc, lspc1, lspc2, parent, undo_flags);
+ if(cmpLineDEF(&Line, &newLine)) {
+ Undo.Line(parent, &Line, undo_flags); undo_flags |= UNDO_CONTINUE;
+ memcpy(&Line, &newLine, sizeof(LineDEF));
+ }
+ if(newFill.type && cmpLineDEF(&FillLine, &newFillLine)) {
+ Undo.Line(parent, &FillLine, undo_flags); undo_flags |= UNDO_CONTINUE;
+ memcpy(&FillLine, &newFillLine, sizeof(LineDEF));
+ }
+ if(cmpFillDEF(&Fill, &newFill)) {
+ Undo.Fill(parent, &Fill, undo_flags); undo_flags |= UNDO_CONTINUE;
+ memcpy(&Fill, &newFill, sizeof(FillDEF));
+ }
+ Fill.hatch = &FillLine;
+ if(undo_flags & UNDO_CONTINUE){
+ bRet = bModified = true; lines2text();
+ Undo.TextBuffer(this, &csize, &cpos, &text, undo_flags, cdisp);
+ if(lines) {
+ for(i = 0; i < nlines; i++) if(lines[i]) free(lines[i]);
+ free(lines); lines = 0L;
+ }
+ HideTextCursor(); cur_pos.x = cur_pos.y = 0;
+ }
+ }
+ CloseDlgWnd(hDlg); delete Dlg;
+ return bRet;
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// segment properties dialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2556,7 +2735,7 @@ segment::PropertyDlg()
if(!parent) return false;
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&segLine, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&segFill, 0);
- Dlg = new DlgRoot(SegDlg);
+ Dlg = new DlgRoot(SegDlg, data);
Dlg->GetValue(216, &old_r1); new_r1 = old_r1;
Dlg->GetValue(213, &old_r2); new_r2 = old_r2;
Dlg->GetValue(201, &old_cent.fx); new_cent.fx = old_cent.fx;
@@ -2662,7 +2841,7 @@ polyline::PropertyDlg()
if(!parent) return false;
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&pgLine, 0);
- if(!(Dlg = new DlgRoot(LineDlg)))return false;
+ if(!(Dlg = new DlgRoot(LineDlg, data)))return false;
if(parent->Id == GO_GRAPH || parent->Id == GO_PAGE) Dlg->ShowItem(50, true);
hDlg = CreateDlgWnd("line properties", 50, 50, 410, 314, Dlg, 0x0L);
do{
@@ -2727,7 +2906,7 @@ polygon::PropertyDlg()
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&pgLine, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&pgFill, 0);
- Dlg = new DlgRoot(PolygDlg);
+ Dlg = new DlgRoot(PolygDlg, data);
if(parent->Id == GO_GRAPH || parent->Id == GO_PAGE) Dlg->ShowItem(50, true);
hDlg = CreateDlgWnd("polygon properties", 50, 50, 310, 224, Dlg, 0x0L);
do{
@@ -2826,7 +3005,7 @@ rectangle::PropertyDlg()
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&Fill, 0);
- if(!(Dlg = new DlgRoot(RecDlg)))return false;
+ if(!(Dlg = new DlgRoot(RecDlg, data)))return false;
Dlg->GetValue(201, &old_fp1.fx); Dlg->GetValue(204, &old_fp1.fy);
Dlg->GetValue(207, &old_fp2.fx); Dlg->GetValue(210, &old_fp2.fy);
if(type != 2) Dlg->ShowItem(101, false);
@@ -2937,8 +3116,7 @@ PlotScatt::CreateBarChart()
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&Fill, 0);
UseRangeMark(data, 1, TmpTxt);
- if(!(Dlg = new DlgRoot(BarDlg)))return false;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(BarDlg, data)))return false;
hDlg = CreateDlgWnd("Simple Bar Chart", 50, 50, 370, 280, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -2949,8 +3127,13 @@ PlotScatt::CreateBarChart()
break;
case 1:
if(rY) delete rY;
- if(Dlg->GetText(101, TmpTxt)) rY = new AccRange(TmpTxt);
- yRange = strdup(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)){
+ rY = new AccRange(TmpTxt);
+ yRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
+ }
+ else {
+ rY = 0L; yRange = 0L;
+ }
if(!(n = rY ? rY->CountItems() : 0)) {
res = -1;
ErrorBox("Data range not valid.");
@@ -3054,7 +3237,7 @@ PlotScatt::PropertyDlg()
double x, y, e;
lfPOINT fp1, fp2;
bool bRet = false, bLayout = false, bContinue = false;
- TextDEF lbdef = {defs.Color(COL_TEXT), defs.Color(COL_BG), defs.GetSize(SIZE_TEXT), 0.0f, 0.0f, 0,
+ TextDEF lbdef = {defs.Color(COL_TEXT), defs.Color(COL_BG), DefSize(SIZE_TEXT), 0.0f, 0.0f, 0,
TXA_HLEFT | TXA_VBOTTOM, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, TmpTxt};
AccRange *rX, *rY, *rE, *rL;
@@ -3062,9 +3245,7 @@ PlotScatt::PropertyDlg()
if(Id == GO_BARCHART) return CreateBarChart();
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);
+ if(!(Dlg = new DlgRoot(XYDlg, data)))return false;
#ifdef _WINDOWS
for(i = 104; i <= 107; i++) Dlg->TextSize(i, 12);
#else
@@ -3101,7 +3282,7 @@ PlotScatt::PropertyDlg()
case 1: // OK
if(rX) delete rX; if(rY) delete rY; if(rE) delete rE;
rX = rY = rE = 0L; // check x-range
- if(Dlg->GetText(101, TmpTxt)) rX = new AccRange(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) rX = new AccRange(TmpTxt);
if(!(n = rX ? rX->CountItems() : 0)) {
Dlg->SetCheck(4, 0L, true);
res = -1;
@@ -3109,7 +3290,7 @@ PlotScatt::PropertyDlg()
ErrorBox("X-range not specified\nor not valid.");
}
else { // check y-range
- if(Dlg->GetText(103, TmpTxt)) rY = new AccRange(TmpTxt);
+ if(Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE)) rY = new AccRange(TmpTxt);
if(n != (rY ? rY->CountItems() : 0)) {
Dlg->SetCheck(4, 0L, true);
res = -1;
@@ -3120,7 +3301,7 @@ PlotScatt::PropertyDlg()
}
//check for error bar
if(res >0 && Dlg->GetCheck(301)) {
- if(Dlg->GetText(304, TmpTxt)) rE = new AccRange(TmpTxt);
+ if(Dlg->GetText(304, TmpTxt, TMP_TXT_SIZE)) rE = new AccRange(TmpTxt);
if(n != (rE ? rE->CountItems() : 0)) {
Dlg->SetCheck(6, 0L, true);
res = -1;
@@ -3133,7 +3314,7 @@ PlotScatt::PropertyDlg()
}
//check for data labels
if(res >0 && Dlg->GetCheck(400)) {
- if(Dlg->GetText(402, TmpTxt)) rL = new AccRange(TmpTxt);
+ if(Dlg->GetText(402, TmpTxt, TMP_TXT_SIZE)) rL = new AccRange(TmpTxt);
if(n != (rL ? rL->CountItems() : 0)) {
Dlg->SetCheck(7, 0L, true);
res = -1;
@@ -3164,8 +3345,8 @@ PlotScatt::PropertyDlg()
if(res == 1 && n && rX && rY){ //OK pressed
Command(CMD_FLUSH, 0L, 0L);
nPoints = n;
- if(Dlg->GetText(101, TmpTxt)) xRange = strdup(TmpTxt);
- if(Dlg->GetText(103, TmpTxt)) yRange = strdup(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) xRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
+ if(Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE)) yRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
//Create graphic objects
rX->GetFirst(&i, &j); rY->GetFirst(&k, &l);
@@ -3180,12 +3361,17 @@ PlotScatt::PropertyDlg()
if(Dlg->GetCheck(203)) Arrows = (Arrow**)calloc(nPoints, sizeof(Arrow*));
if(Dlg->GetCheck(301) && rE) { //error bars ?
Errors = (ErrorBar**)calloc(nPoints, sizeof(ErrorBar*));
- if(Dlg->GetText(304, TmpTxt)) ErrRange = strdup(TmpTxt);
- rE->GetFirst(&m, &n); rE->GetNext(&m, &n);
+ if(Dlg->GetText(304, TmpTxt, TMP_TXT_SIZE)){
+ ErrRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
+ rE->GetFirst(&m, &n); rE->GetNext(&m, &n);
+ }
+ else {
+ rE = 0L; ErrRange = 0L;
+ }
}
if(Dlg->GetCheck(400) && rL) { //labels ?
Labels = (Label**)calloc(nPoints, sizeof(Label*));
- if(Dlg->GetText(402, TmpTxt)) LbRange = strdup(TmpTxt);
+ if(Dlg->GetText(402, TmpTxt, TMP_TXT_SIZE)) LbRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
rL->GetFirst(&o, &p); rL->GetNext(&o, &p);
}
if(Dlg->GetCheck(250) && nPoints >1) TheLine = new DataLine(this, data, xRange, yRange);
@@ -3282,18 +3468,16 @@ xyStat::PropertyDlg()
DlgRoot *Dlg;
void *hDlg;
bool bRet = false;
- int i, res, width, height;
+ int i, res, width, height, cb_mdesc;
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,
+ char errdesc[40], *mdesc;
+ TextDEF lbdef = {defs.Color(COL_TEXT), defs.Color(COL_BG), DefSize(SIZE_TEXT), 0.0f, 0.0f, 0,
TXA_HLEFT | TXA_VBOTTOM, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, TmpTxt};
if(!parent || !data) return false;
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);
+ if(!(Dlg = new DlgRoot(StatDlg, data)))return false;
text1[0] = text2[0] = 0;
hDlg = CreateDlgWnd("Mean and Error Plot", 50, 50, 370, 450, Dlg, 0x0L);
do {
@@ -3304,12 +3488,13 @@ xyStat::PropertyDlg()
if(Dlg->GetCheck(10)) res=-1;
break;
case 1:
- if(!(Dlg->GetText(102, text1) && Dlg->GetText(104, text2) && text1[0] && text2[0])) res = 2;
+ if(!(Dlg->GetText(102, text1, 100) && Dlg->GetText(104, text2, 100) && text1[0] && text2[0])) res = 2;
break;
}
}while (res <0);
if(res == 1) {
- xRange = strdup(text1); yRange = strdup(text2);
+ xRange = (char*)memdup(text1, ((int)strlen(text1))+2, 0);
+ yRange = (char*)memdup(text2, ((int)strlen(text2))+2, 0);
type = 0;
if(Dlg->GetCheck(201)) type |= 0x0001; if(Dlg->GetCheck(202)) type |= 0x0002;
if(Dlg->GetCheck(203)) type |= 0x0004;
@@ -3320,41 +3505,65 @@ xyStat::PropertyDlg()
if(Dlg->GetCheck(305)) type |= 0x1000;
if(Dlg->GetCheck(401)) type |= 0x2000; if(Dlg->GetCheck(402)) type |= 0x4000;
Dlg->GetValue(306, &ci); TmpTxt[0] = 0;
- if(Dlg->GetText(404, TmpTxt) && TmpTxt[0]) case_prefix = strdup(TmpTxt);
+ if(Dlg->GetText(404, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0]) case_prefix = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
CreateData();
if(type && curr_data) {
+ switch (type & 0x00f0) {
+ case 0x0010: mdesc = "Mean"; break;
+ case 0x0020: mdesc = "Geometric mean"; break;
+ case 0x0040: mdesc = "Harmonic mean"; break;
+ case 0x0080: mdesc = "Median"; break;
+ default: mdesc = "n.a."; break;
+ }
+ cb_mdesc = (int)strlen(mdesc);
curr_data->GetSize(&width, &height); nPoints = height;
+#ifdef USE_WIN_SECURE
+ sprintf_s(text1, 100, "a1:a%d", height); sprintf_s(text2, 100, "b1:b%d", height);
+#else
sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
+#endif
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))
CheckBounds(x, y);
}
if(type & 0x0001) {
- if(nPoints >1) TheLine = new DataLine(this, curr_data, text1, text2);
+ if(nPoints >1 && (TheLine = new DataLine(this, curr_data, text1, text2)) &&
+ (TheLine->name = (char*)malloc(cb_mdesc+2))) rlp_strcpy(TheLine->name, cb_mdesc+2, mdesc);
+
}
if((type & 0x0002) && (Symbols = (Symbol**)calloc(nPoints, sizeof(Symbol*)))) {
for(i = 0; i < height; i++) {
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 1, &y)
- && (Symbols[i] = new Symbol(this, curr_data, x, y, DefSym, 0, i, 1, i)))
+ && (Symbols[i] = new Symbol(this, curr_data, x, y, DefSym, 0, i, 1, i))){
Symbols[i]->idx = i;
+ if(Symbols[i]->name = (char*)malloc(cb_mdesc+2))
+ rlp_strcpy(Symbols[i]->name, cb_mdesc+2, mdesc);
+ }
}
}
if((type & 0x0004) && (Bars = (Bar**)calloc(nPoints, sizeof(Bar*)))) {
for(i = 0; i < height; i++) {
- if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 1, &y))
- Bars[i] = new Bar(this, curr_data, x, y, BAR_VERTB | BAR_RELWIDTH, 0, i, 1, i);
+ if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 1, &y)
+ && (Bars[i] = new Bar(this, curr_data, x, y, BAR_VERTB | BAR_RELWIDTH, 0, i, 1, i))){
+ if(Bars[i]->name = (char*)malloc(cb_mdesc+2))
+ rlp_strcpy(Bars[i]->name, cb_mdesc+2, mdesc);
+ }
}
}
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");
+ case 0x0100: rlp_strcpy(errdesc, 40, "Std. Dev."); break;
+ case 0x0200: rlp_strcpy(errdesc, 40, "Std. Err."); break;
+ case 0x0400: rlp_strcpy(errdesc, 40, "25, 75% Perc."); break;
+ case 0x0800: rlp_strcpy(errdesc, 40, "Min./Max."); break;
+#ifdef USE_WIN_SECURE
+ case 0x1000: sprintf_s(errdesc, 40, "'%g%% CI", ci); break;
+#else
+ case 0x1000: sprintf(errdesc, "'%g%% CI", ci); break;
+#endif
+ default: rlp_strcpy(errdesc, 40, "error");
}
}
if((type & 0x1300) && Errors) {
@@ -3376,7 +3585,7 @@ xyStat::PropertyDlg()
}
}
if((type & 0x6000) && (Labels = (Label**)calloc(nPoints, sizeof(Label*)))) {
- dy = -0.4 * defs.GetSize(SIZE_SYMBOL);
+ dy = -0.4 * DefSize(SIZE_SYMBOL);
if(type & 0x2000){
lbdef.Align = TXA_HCENTER | TXA_VBOTTOM;
dx = 0.0;
@@ -3411,48 +3620,63 @@ xyStat::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Frequency distribution
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *FreqDlg_Tmpl =
+ "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,153\n"
+ "5,10,200,ISPARENT,SHEET,2,5,10,120,153\n"
+ "10,,,CHECKED,CHECKPIN,0,5,0,12,8\n"
+ "100,101,,,LTEXT,3,10,25,60,8\n"
+ "101,102,,,RANGEINPUT,-15,10,38,110,10\n"
+ "102,103,120,ISPARENT | CHECKED,GROUPBOX,4,10,55,110,42\n"
+ "103,,150,ISPARENT | CHECKED,GROUPBOX,5,10,102,110,57\n"
+ "120,121,,CHECKED,RADIO1,6,15,60,30,9\n"
+ "121,122,,, EDVAL1,7,47,60,15,10\n"
+ "122,123,,, LTEXT,8,64,60,35,8\n"
+ "123,124,,, RADIO1,9, 15, 72, 45, 9\n"
+ "124,125,,, EDTEXT,-16,65,72,50,10\n"
+ "125,126,,, RTEXT,10,15,84, 47,8\n"
+ "126,,,,EDTEXT,-16,65,84,50,10\n"
+ "150,151,,ISRADIO,CHECKBOX,13,15,107,30, 8\n"
+ "151,152,,ISRADIO,CHECKBOX,14,15,117,30, 8\n"
+ "152,153,,ISRADIO,CHECKBOX,15,65,107,30, 8\n"
+ "153,154,,ISRADIO,CHECKBOX,16,65,117,30,8\n"
+ "154,155,,ISRADIO,CHECKBOX,17,15,127,30,8\n"
+ "155,156,,ISRADIO,CHECKBOX,18,15,137,30,8\n"
+ "156,,,ISRADIO,CHECKBOX,19,15,147,30,8\n"
+ "200,, 210,ISPARENT | CHECKED,GROUPBOX,11,10,27,110,61\n"
+ "210,,,LASTOBJ | NOSELECT,ODBUTTON,12,25,34,90,50";
+
bool
FreqDist::PropertyDlg()
{
TabSHEET tab1 = {0, 25, 10, "Data"};
TabSHEET tab2 = {25, 52, 10, "Style"};
- DlgInfo FreqDlg[] = {
- {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, 113},
- {5, 10, 200, ISPARENT, SHEET, &tab2, 5, 10, 120, 113},
- {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, 102, 0, 0x0L, RANGEINPUT, TmpTxt, 10, 38, 110, 10},
- {102, 103, 120, ISPARENT | CHECKED, GROUPBOX, (void*)" classes ", 10, 55, 110, 42},
- {103, 0, 150, ISPARENT | CHECKED, GROUPBOX, (void*)" plot distribution ", 10, 102, 110, 17},
- {120, 121, 0, CHECKED, RADIO1, (void*)"create", 15, 60, 30, 9},
- {121, 122, 0, 0x0L, EDTEXT, (void*)"7", 47, 60, 15, 10},
- {122, 123, 0, 0x0L, LTEXT, (void*)"classes and bars", 64, 60, 35, 8},
- {123, 124, 0, 0x0L, RADIO1, (void*)"class size is", 15, 72, 45, 9},
- {124, 125, 0, 0x0L, EDTEXT, 0L, 65, 72, 50, 10},
- {125, 126, 0, 0x0L, RTEXT, (void*)"starting at", 15, 84, 47, 8},
- {126, 0, 0, 0x0L, EDTEXT, 0L, 65, 84, 50, 10},
- {150, 151, 0, ISRADIO, CHECKBOX, (void*)" normal", 15, 107, 30, 8},
- {151, 0, 0, ISRADIO, CHECKBOX, (void*)" log-normal", 65, 107, 30, 8},
- {200, 0, 210, ISPARENT | CHECKED, GROUPBOX, (void*)" bar style ", 10, 27, 110, 61},
- {210, 0, 0, NOSELECT, ODBUTTON, (void*)OD_filldef, 25, 34, 90, 50},
- {800, 0, 0, LASTOBJ, NONE, 0L, 0, 0, 0, 0}};
+ void *dyndata[] = {(void*)&tab1, (void*)&tab2, (void*)"spread sheet range for values",
+ (void*)" classes ", (void*)" plot distribution ", (void*)"create", (void*)&step,
+ (void*)"classes and bars", (void*)"class size is", (void*)"starting at",
+ (void*)" bar style ", (void*)OD_filldef, (void*)" normal", (void*)" log-normal",
+ (void*)" binomial", (void*)" poisson", (void*)" exponential", (void*)" rectangular",
+ (void*)" chi-square"};
+ DlgInfo *FreqDlg;
DlgRoot *Dlg;
void *hDlg;
bool bRet = false;
- int res;
+ int res, r, c;
+ double tmp;
char *mrk;
+ AccRange *aR;
if(!parent || !data) return false;
+ if(!(FreqDlg = CompileDialog(FreqDlg_Tmpl, dyndata))) return false;
+ step = 7; TmpTxt[100] = 0;
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&BarLine, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&BarFill, 0);
- if(data->Command(CMD_GETMARK, &mrk, 0L)) strcpy(TmpTxt, mrk);
+ if(data->Command(CMD_GETMARK, &mrk, 0L)) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, mrk);
else TmpTxt[0] = 0;
- if(!(Dlg = new DlgRoot(FreqDlg)))return false;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data);
- hDlg = CreateDlgWnd("Frequency Distribution", 50, 50, 370, 280, Dlg, 0x0L);
+ if(!(Dlg = new DlgRoot(FreqDlg, data)))return false;
+ hDlg = CreateDlgWnd("Frequency Distribution", 50, 50, 370, 370, Dlg, 0x0L);
do {
LoopDlgWnd();
res = Dlg->GetResult();
@@ -3461,17 +3685,19 @@ FreqDist::PropertyDlg()
if(Dlg->GetCheck(10)) res=-1;
break;
case 1:
- if(Dlg->GetText(101, TmpTxt) && TmpTxt[0]) {
- if(ssRef) free(ssRef);
- ssRef = strdup(TmpTxt);
- }
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) ssRef = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
if(Dlg->GetCheck(150)) type = 1;
else if(Dlg->GetCheck(151)) type = 2;
+ else if(Dlg->GetCheck(154)) type = 3;
+ else if(Dlg->GetCheck(155)) type = 4;
+ else if(Dlg->GetCheck(156)) type = 5;
+ else if(Dlg->GetCheck(152)) type = 10;
+ else if(Dlg->GetCheck(153)) type = 11;
else type = 0;
break;
}
}while (res <0);
- if(res==1 && (plots = (GraphObj**)calloc(nPlots=2, sizeof(GraphObj*)))) {
+ if(res==1 && (plots = (GraphObj**)calloc(nPlots=3, sizeof(GraphObj*)))) {
OD_filldef(OD_GETLINE, 0L, 0L, 0L, (void *)&BarLine, 0);
OD_filldef(OD_GETFILL, 0L, 0L, 0L, (void *)&BarFill, 0);
if(BarFill.hatch) memcpy(&HatchLine, BarFill.hatch, sizeof(LineDEF));
@@ -3480,10 +3706,18 @@ FreqDist::PropertyDlg()
else {
Dlg->GetValue(121, &step); ProcData(-1);
}
+ if(y_info = (char*)malloc(25*sizeof(char))) rlp_strcpy(y_info, 25, "No. of observations");
+ if(x_info = (char*)malloc(25*sizeof(char))){
+ rlp_strcpy(x_info, 25, "Categories");
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE) && (aR = new AccRange(TmpTxt))) {
+ if(aR->GetFirst(&c, &r) && !data->GetValue(r, c, &tmp) && data->GetText(r, c, TmpTxt, 150, false))
+ rlp_strcpy(x_info, 25, TmpTxt);
+ delete aR;
+ }
+ }
if(plots[0]) bRet = true;
}
- CloseDlgWnd(hDlg);
- delete Dlg;
+ CloseDlgWnd(hDlg); delete Dlg; free(FreqDlg);
return bRet;
}
@@ -3530,8 +3764,7 @@ Regression::PropertyDlg()
if(!parent || !data) return false;
rX = rY = 0L;
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);
+ if(!(Dlg = new DlgRoot(RegDlg, data)))return false;
hDlg = CreateDlgWnd("Linear regression analysis step 1/2", 50, 50, 380, 225, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -3547,7 +3780,7 @@ Regression::PropertyDlg()
case 1: // OK
if(rX) delete rX; if(rY) delete rY;
rX = rY = 0L; // check x-range
- if(Dlg->GetText(101, TmpTxt)) rX = new AccRange(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) rX = new AccRange(TmpTxt);
if(!(n = rX ? rX->CountItems() : 0)) {
Dlg->SetCheck(4, 0L, true);
res = -1;
@@ -3555,7 +3788,7 @@ Regression::PropertyDlg()
ErrorBox("X-range not specified\nor not valid.");
}
else { // check y-range
- if(Dlg->GetText(103, TmpTxt)) rY = new AccRange(TmpTxt);
+ if(Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE)) rY = new AccRange(TmpTxt);
if(n != (rY ? rY->CountItems() : 0)) {
res = -1;
bContinue = true;
@@ -3567,8 +3800,8 @@ Regression::PropertyDlg()
}while (res <0);
if(res==1 && n && rX && rY && (values =(lfPOINT*)calloc(nPoints=n, sizeof(lfPOINT)))){ //OK pressed
Command(CMD_FLUSH, 0L, 0L);
- if(Dlg->GetText(101, TmpTxt)) xRange = strdup(TmpTxt);
- if(Dlg->GetText(103, TmpTxt)) yRange = strdup(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) xRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
+ if(Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE)) yRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
rX->GetFirst(&i, &j); rY->GetFirst(&k, &l);
rX->GetNext(&i, &j); rY->GetNext(&k, &l);
@@ -3665,13 +3898,13 @@ BubblePlot::PropertyDlg()
{204, 205, 0, 0x0L, SYMRADIO, (void *)&syms[3], 90, 40, 20, 20},
{205, 206, 0, 0x0L, LTEXT, (void*)"outline:", 7, 67, 45, 8},
{206, 207, 0, 0x0L, RTEXT, (void*)"color", 7, 75, 20, 8},
- {207, 208, 0, OWNDIALOG, COLBUTTON, (void *)BubbleLine.color, 29, 75, 25, 10},
+ {207, 208, 0, OWNDIALOG, COLBUTT, (void *)&BubbleLine.color, 29, 75, 25, 10},
{208, 209, 0, 0x0L, RTEXT, (void*)"line width", 67, 75, 20, 8},
{209, 210, 0, 0x0L, EDVAL1, &BubbleLine.width, 88, 75, 25, 10},
{210, 211, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 114, 75, 15, 8},
{211, 212, 0, 0x0L, LTEXT, (void*)"fill:", 7, 97, 45, 8},
{212, 213, 0, 0x0L, RTEXT, (void*)"color", 7, 105, 20, 8},
- {213, 214, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)BubbleFill.color, 29, 105, 25, 10},
+ {213, 214, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&BubbleFill.color, 29, 105, 25, 10},
{214, 215, 0, 0x0L, RTEXT, (void*)"pattern", 67, 105, 20, 8},
{215, 0, 0, TOUCHEXIT | OWNDIALOG, FILLBUTTON, (void *)&ShowFill, 88, 105, 25, 10},
{300, 301, 0, 0x0L, LTEXT, (void*)"Sizes are given as", 10, 30, 110, 8},
@@ -3698,10 +3931,7 @@ BubblePlot::PropertyDlg()
memcpy(&ShowFill, &BubbleFill, sizeof(FillDEF));
if(BubbleFill.hatch) memcpy(&ShowFillLine, BubbleFill.hatch, sizeof(LineDEF));
ShowFill.hatch = &ShowFillLine;
- if(!(Dlg = new DlgRoot(PlotDlg)))return false;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data);
- Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
- Dlg->ItemCmd(105, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(PlotDlg, data)))return false;
hDlg = CreateDlgWnd("Create Bubble Plot", 50, 50, 400, 300, Dlg, 0x0L);
rX = rY = rS = 0L;
do {
@@ -3726,8 +3956,8 @@ BubblePlot::PropertyDlg()
res = -1;
break;
case 1: //OK button
- if(Dlg->GetText(101, text1) && Dlg->GetText(103, text2) &&
- Dlg->GetText(105, text3) && (rX = new AccRange(text1)) &&
+ if(Dlg->GetText(101, text1, 100) && Dlg->GetText(103, text2, 100) &&
+ Dlg->GetText(105, text3, 100) && (rX = new AccRange(text1)) &&
(rY = new AccRange(text2)) && (rS = new AccRange(text3))) {
if((i = rX->CountItems()) == rY->CountItems() && i == rS->CountItems()){
// OK pressed and ranges checked: exit loop and process data
@@ -3778,27 +4008,32 @@ BubblePlot::PropertyDlg()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Polar plot properties dialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *AddPolDlg_Tmpl =
+ "1,2,,DEFAULT,PUSHBUTTON,-1,140,14,45,12\n"
+ "2,3,,,PUSHBUTTON,-2,140,29,45,12\n"
+ "3,10,200,ISPARENT | CHECKED,GROUPBOX,1,5,14,131,96\n"
+ "10,,,CHECKED,CHECKPIN,0,5,0,12,8\n"
+ "200,201,,CHECKED | EXRADIO,ODBUTTON,2,10,24,20,20\n"
+ "201,202,,EXRADIO,ODBUTTON,2,30,24,20,20\n"
+ "202,203,,EXRADIO,ODBUTTON,2,50,24,20,20\n"
+ "203,204,,EXRADIO,ODBUTTON,2,70,24,20,20\n"
+ "204,210,,EXRADIO,ODBUTTON,2,90,24,20,20\n"
+ "210,211,,,LTEXT,3,10,50,50,8\n"
+ "211,212,,,RANGEINPUT,-15,20,62,100,10\n"
+ "212,213,,,LTEXT,4,10,75,50,8\n"
+ "213,,,LASTOBJ,RANGEINPUT,-16,20,87,100,10";
+
bool
PolarPlot::AddPlot()
{
- char text1[100], text2[100];
- DlgInfo PolDlg[] = {
- {1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 140, 10, 45, 12},
- {2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 140, 25, 45, 12},
- {3, 0, 200, ISPARENT | CHECKED, GROUPBOX, (void*)" select template and data range ", 5, 10, 131, 100},
- {200, 201, 0, CHECKED | TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PolarTempl, 10, 20, 20, 20},
- {201, 202, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PolarTempl, 30, 20, 20, 20},
- {202, 203, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PolarTempl, 50, 20, 20, 20},
- {203, 204, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PolarTempl, 70, 20, 20, 20},
- {204, 210, 0, TOUCHEXIT | ISRADIO, ODBUTTON, (void*)OD_PolarTempl, 90, 20, 20, 20},
- {210, 211, 0, 0x0L, LTEXT, (void*)"range for x-data (circular or angular data)", 10, 50, 50, 8},
- {211, 212, 0, 0x0L, RANGEINPUT, (void*)text1, 20, 62, 100, 10},
- {212, 213, 0, 0x0L, LTEXT, (void*)"range for y-data (radial data)", 10, 75, 50, 8},
- {213, 0, 0, LASTOBJ, RANGEINPUT, (void*)text2, 20, 87, 100, 10}};
+ void *dyndata[] = {(void*)" select template and data range ", (void*)OD_PolarTempl,
+ (void*)"range for x-data (circular or angular data)",
+ (void*)"range for y-data (radial data)"};
+ DlgInfo *PolDlg;
DlgRoot *Dlg;
void *hDlg;
int i, j, k, l, ic, n, res, cType = 200;
- bool bRet = false;
+ bool bRet = false, bContinue = false;
double x, y;
AccRange *rX = 0L, *rY = 0L;
Symbol **Symbols = 0L;
@@ -3808,14 +4043,21 @@ PolarPlot::AddPlot()
anyOutput *cdisp = Undo.cdisp;
if(!parent || !data) return false;
- UseRangeMark(data, 1, text1, text2);
- if(!(Dlg = new DlgRoot(PolDlg)))return false;
- Dlg->ItemCmd(211, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(213, CMD_SET_DATAOBJ, data);
+ if(!(PolDlg = CompileDialog(AddPolDlg_Tmpl, dyndata))) return false;
+ UseRangeMark(data, 1, TmpTxt, TmpTxt+100);
+ if(!(Dlg = new DlgRoot(PolDlg, data)))return false;
hDlg = CreateDlgWnd("Add Polar Plot", 50, 50, 388, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
res = Dlg->GetResult();
switch (res) {
+ case 0: // focus lost
+ if(bContinue) res = -1;
+ else if(Dlg->GetCheck(10)) res = -1;
+ break;
+ case -1:
+ bContinue = false;
+ break;
case 200: case 201: case 202: case 203: case 204:
if(res == 204) {
Dlg->Activate(211, false); Dlg->Activate(213, false);
@@ -3831,8 +4073,8 @@ PolarPlot::AddPlot()
break;
}
}while (res <0);
- if(res == 1 && Dlg->GetText(211, text1) && Dlg->GetText(213, text2) &&
- (rX = new AccRange(text1)) && (rY = new AccRange(text2)) &&
+ if(res == 1 && Dlg->GetText(211, TmpTxt, 100) && Dlg->GetText(213, TmpTxt+100, 100) &&
+ (rX = new AccRange(TmpTxt)) && (rY = new AccRange(TmpTxt+100)) &&
(n = rX ? rX->CountItems() : 0) &&
(tmpPlots = (Plot**)realloc(Plots, (nPlots+2)*sizeof(Plot*)))) {
Undo.SetDisp(cdisp);
@@ -3840,11 +4082,11 @@ PolarPlot::AddPlot()
if(Dlg->GetCheck(200) || Dlg->GetCheck(201))
Symbols = (Symbol**) calloc(n+1, sizeof(Symbol*));
if(Dlg->GetCheck(201) || Dlg->GetCheck(202))
- TheLine = new DataLine(this, data, text1, text2);
+ TheLine = new DataLine(this, data, TmpTxt, TmpTxt+100);
else if(Dlg->GetCheck(203))
- TheLine = new DataPolygon(this, data, text1, text2);
+ TheLine = new DataPolygon(this, data, TmpTxt, TmpTxt+100);
else if(Dlg->GetCheck(204)) {
- if(func = new Function(this, data)){
+ if(func = new Function(this, data, "Function")){
if(bRet = func->PropertyDlg()){
Undo.SetGO(this, (GraphObj**) &Plots[nPlots++], func, 0L);
memcpy(&Bounds, &Plots[nPlots-1]->Bounds, sizeof(fRECT));
@@ -3868,7 +4110,7 @@ PolarPlot::AddPlot()
}
}
CloseDlgWnd(hDlg);
- delete Dlg;
+ delete Dlg; free(PolDlg);
if(rX) delete rX; if(rY) delete rY;
return bRet;
}
@@ -3896,7 +4138,7 @@ PolarPlot::Config()
}
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)&OutLine, 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)&Fill, 0);
- Dlg = new DlgRoot(PPDlg);
+ Dlg = new DlgRoot(PPDlg, data);
if(!(type & 0x01))Dlg->SetCheck(101, 0L, true);
hDlg = CreateDlgWnd("Polar Plot properties", 50, 50, 310, 234, Dlg, 0x0L);
do{
@@ -3980,14 +4222,13 @@ PolarPlot::PropertyDlg()
tlbdef.ColTxt = defs.Color(COL_AXIS);
tlbdef.ColBg = 0x00ffffffL;
tlbdef.RotBL = tlbdef.RotCHAR = 0.0f;
- tlbdef.fSize = defs.GetSize(SIZE_TICK_LABELS);
+ tlbdef.fSize = DefSize(SIZE_TICK_LABELS);
tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
tlbdef.Style = TXS_NORMAL;
tlbdef.Mode = TXM_TRANSPARENT;
tlbdef.Font = FONT_HELVETICA;
tlbdef.text = 0L;
- if(!(Dlg = new DlgRoot(PolDlg)))return false;
- Dlg->ItemCmd(211, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(213, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(PolDlg, data)))return false;
hDlg = CreateDlgWnd("Create Polar Plot", 50, 50, 388, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -4046,7 +4287,7 @@ PolarPlot::PropertyDlg()
parent->GetSize(SIZE_GRECT_LEFT) + parent->GetSize(SIZE_DRECT_LEFT);
rad_axis.loc[0].fy = rad_axis.Center.fy - rad_axis.Radius;
rad_axis.loc[1].fy = rad_axis.Center.fy;
- if(Dlg->GetText(211, text1) && Dlg->GetText(213, text2) &&
+ if(Dlg->GetText(211, text1, 100) && Dlg->GetText(213, text2, 100) &&
(rX = new AccRange(text1)) && (rY = new AccRange(text2)) &&
(n = rX ? rX->CountItems() : 0) && (Plots = (Plot**)calloc(2, sizeof(Plot*)))) {
if(Dlg->GetCheck(200) || Dlg->GetCheck(201))
@@ -4056,7 +4297,7 @@ PolarPlot::PropertyDlg()
else if(Dlg->GetCheck(203))
TheLine = new DataPolygon(this, data, text1, text2);
else if(Dlg->GetCheck(204)) {
- if(Plots[nPlots++] = new Function(this, data)){
+ if(Plots[nPlots++] = new Function(this, data, "Function")){
if(bRet = Plots[nPlots-1]->PropertyDlg())
memcpy(&Bounds, &Plots[nPlots-1]->Bounds, sizeof(fRECT));
else {
@@ -4085,9 +4326,9 @@ PolarPlot::PropertyDlg()
Axes[1] = new Axis(this, data, &rad_axis,
rad_axis.flags | AXIS_AUTOTICK | AXIS_NEGTICKS);
Axes[1]->SetSize(SIZE_LB_XDIST,
- NiceValue(-defs.GetSize(SIZE_AXIS_TICKS)*6.0));
+ NiceValue(-DefSize(SIZE_AXIS_TICKS)*6.0));
Axes[1]->SetSize(SIZE_TLB_XDIST,
- NiceValue(-defs.GetSize(SIZE_AXIS_TICKS)*2.0));
+ NiceValue(-DefSize(SIZE_AXIS_TICKS)*2.0));
Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
nAxes = 2;
bRet = true;
@@ -4106,7 +4347,6 @@ PolarPlot::PropertyDlg()
bool
BoxPlot::PropertyDlg()
{
- char text1[50], text2[50], text3[50], text4[50], text5[50], text6[50];
DlgInfo PlotDlg[] = {
{1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 130, 10, 45, 12},
{2, 10, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 130, 25, 45, 12},
@@ -4118,9 +4358,9 @@ BoxPlot::PropertyDlg()
{60, 61, 100, HIDDEN | ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
{61, 0, 200, ISPARENT | CHECKED, GROUP, 0L, 0, 0, 0, 0},
{100, 102, 0, 0x0L, LTEXT, (void*)"range for grouping variable (X data)", 10, 39, 140, 9},
- {102, 103, 0, 0x0L, RANGEINPUT, text1, 10, 49, 165, 10},
+ {102, 103, 0, 0x0L, RANGEINPUT, TmpTxt+100, 10, 49, 165, 10},
{103, 104, 0, 0x0L, LTEXT, (void*)"range for Y data", 10, 60, 90, 9},
- {104, 150, 0, 0x0L, RANGEINPUT, text2, 10, 70, 165, 10},
+ {104, 150, 0, 0x0L, RANGEINPUT, TmpTxt+200, 10, 70, 165, 10},
{150, 160, 151, ISPARENT | CHECKED, GROUPBOX, (void*) " draw means ", 10, 87, 165, 45},
{151, 152, 0, 0x0L, CHECKBOX, (void*)" line", 15, 92, 50, 9},
{152, 153, 0, CHECKED, CHECKBOX, (void*)" symbols", 15, 101, 50, 9},
@@ -4146,27 +4386,27 @@ BoxPlot::PropertyDlg()
{176, 177, 0, 0x0L, EDVAL1, &ci_err, 28, 203, 15, 10},
{177, 0, 0, 0x0L, LTEXT, (void*) "% conf. interval", 45, 203, 70, 9},
{200, 202, 0, 0x0L, LTEXT, (void*)"range for common X values", 10, 39, 140, 9},
- {202, 250, 0, 0x0L, RANGEINPUT, text1, 10, 49, 165, 10},
+ {202, 250, 0, 0x0L, RANGEINPUT, TmpTxt+100, 10, 49, 165, 10},
{250, 260, 251, ISPARENT | CHECKED, GROUPBOX, (void*) " ", 10, 68, 165, 30},
{251, 252, 0, 0x0L, CHECKBOX, (void*)" draw line", 15, 63, 50, 9},
{252, 253, 0, 0x0L, LTEXT, (void*)"range for line values", 15, 73, 80, 9},
- {253, 0, 0, 0x0L, RANGEINPUT, text2, 15, 83, 155, 10},
+ {253, 0, 0, 0x0L, RANGEINPUT, TmpTxt+200, 15, 83, 155, 10},
{260, 270, 261, ISPARENT | CHECKED, GROUPBOX, (void*) " ", 10, 106, 165, 30},
{261, 262, 0, CHECKED, CHECKBOX, (void*)" draw symbols", 15, 101, 50, 9},
{262, 263, 0, 0x0L, LTEXT, (void*)"range for symbol values", 15, 111, 80, 9},
- {263, 0, 0, 0x0L, RANGEINPUT, text2, 15, 121, 155, 10},
+ {263, 0, 0, 0x0L, RANGEINPUT, TmpTxt+200, 15, 121, 155, 10},
{270, 280, 271, ISPARENT | CHECKED, GROUPBOX, (void*) " ", 10, 144, 165, 50},
{271, 272, 0, CHECKED, CHECKBOX, (void*)" draw boxes", 15, 139, 50, 9},
{272, 273, 0, 0x0L, LTEXT, (void*)"range for HI values", 15, 149, 80, 9},
- {273, 274, 0, 0x0L, RANGEINPUT, text3, 15, 159, 155, 10},
+ {273, 274, 0, 0x0L, RANGEINPUT, TmpTxt+300, 15, 159, 155, 10},
{274, 275, 0, 0x0L, LTEXT, (void*)"range for LO values", 15, 169, 80, 9},
- {275, 0, 0, 0x0L, RANGEINPUT, text4, 15, 179, 155, 10},
+ {275, 0, 0, 0x0L, RANGEINPUT, TmpTxt+400, 15, 179, 155, 10},
{280, 0, 281, ISPARENT | CHECKED, GROUPBOX, (void*) " ", 10, 202, 165, 50},
{281, 282, 0, CHECKED, CHECKBOX, (void*)" draw whiskers", 15, 197, 50, 9},
{282, 283, 0, 0x0L, LTEXT, (void*)"range for HI values", 15, 207, 80, 9},
- {283, 284, 0, 0x0L, RANGEINPUT, text5, 15, 217, 155, 10},
+ {283, 284, 0, 0x0L, RANGEINPUT, TmpTxt+500, 15, 217, 155, 10},
{284, 285, 0, 0x0L, LTEXT, (void*)"range for LO values", 15, 227, 80, 9},
- {285, 0, 0, 0x0L, RANGEINPUT, text6, 15, 237, 155, 10},
+ {285, 0, 0, 0x0L, RANGEINPUT, TmpTxt+600, 15, 237, 155, 10},
{400, 0, 401, ISPARENT | CHECKED, GROUPBOX, (void*) " number of cases ", 10, 223, 165, 30},
{401, 402, 0, ISRADIO | CHECKED, CHECKBOX, (void*)" on top of error", 15, 228, 70, 9},
{402, 403, 0, ISRADIO, CHECKBOX, (void*)" on top of mean", 95, 228, 70, 9},
@@ -4175,21 +4415,19 @@ BoxPlot::PropertyDlg()
DlgRoot *Dlg;
void *hDlg;
bool bRet = false;
- int i, j, k, k1, l, l1, n, ic, c, res, width, height;
+ int i, j, k, k1, l, l1, n, ic, c, res, cb, width, height;
double x, y1, y2, dx, dy;
- char errdesc[40];
+ char errdesc[40], boxdesc[40], symdesc[40];
lfPOINT fp1, fp2;
- TextDEF lbdef = {defs.Color(COL_TEXT), defs.Color(COL_BG), defs.GetSize(SIZE_TEXT), 0.0f, 0.0f, 0,
+ TextDEF lbdef = {defs.Color(COL_TEXT), defs.Color(COL_BG), DefSize(SIZE_TEXT), 0.0f, 0.0f, 0,
TXA_HLEFT | TXA_VBOTTOM, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, TmpTxt};
AccRange *rX = 0L, *rY1 = 0L, *rY2 = 0L;
- int it_racc[] = {102, 104, 202, 253, 263, 273, 275, 283, 285};
if(!parent || !data) return false;
- UseRangeMark(data, 1, text1, text2, text3, text4, text5, text6);
+ UseRangeMark(data, 1, TmpTxt+100, TmpTxt+200, TmpTxt+300, TmpTxt+400, TmpTxt+500, TmpTxt+600);
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);
- text1[0] = text2[0] = 0;
+ if(!(Dlg = new DlgRoot(PlotDlg, data)))return false;
+ TmpTxt[0] = TmpTxt[100] = 0;
hDlg = CreateDlgWnd("Box and Whisker Plot", 50, 50, 370, 550, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -4211,19 +4449,19 @@ BoxPlot::PropertyDlg()
}while (res <0);
if(res == 1) {
type = 0; dirty = true;
- if(Dlg->GetCheck(52) && Dlg->GetText(202, text1) && text1[0] &&(rX = new AccRange(text1))) {
- xRange = strdup(text1);
+ if(Dlg->GetCheck(52) && Dlg->GetText(202, TmpTxt+100, 50) && TmpTxt[100] &&(rX = new AccRange(TmpTxt+100))) {
+ xRange = (char*)memdup(TmpTxt+100, ((int)strlen(TmpTxt+100))+2, 0);
n = rX->CountItems(); nPoints = n;
// data line
- if(n > 1 && Dlg->GetCheck(251) && Dlg->GetText(253, TmpTxt)) {
- TheLine = new DataLine(this, data, text1, TmpTxt);
+ if(n > 1 && Dlg->GetCheck(251) && Dlg->GetText(253, TmpTxt, TMP_TXT_SIZE)) {
+ TheLine = new DataLine(this, data, TmpTxt+100, TmpTxt);
bRet = true;
}
// symbols
- if(n > 0 && Dlg->GetCheck(261) && Dlg->GetText(263, TmpTxt) && TmpTxt[0]
+ if(n > 0 && Dlg->GetCheck(261) && Dlg->GetText(263, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0]
&& (Symbols = (Symbol**)calloc(n, sizeof(Symbol*)))
&& (rY1 = new AccRange(TmpTxt))) {
- yRange = strdup(TmpTxt);
+ yRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
rX->GetFirst(&i, &j); rY1->GetFirst(&k, &l);
rX->GetNext(&i, &j); rY1->GetNext(&k, &l);
ic = c = 0;
@@ -4238,9 +4476,9 @@ BoxPlot::PropertyDlg()
if(ic) bRet = true;
}
// boxes
- if(n > 0 && Dlg->GetCheck(271) && Dlg->GetText(273, text3) && Dlg->GetText(275, text4)
+ if(n > 0 && Dlg->GetCheck(271) && Dlg->GetText(273, TmpTxt+300, 50) && Dlg->GetText(275, TmpTxt+400, 50)
&& (Boxes = (Box**)calloc(n, sizeof(Box*)))
- && (rY1 = new AccRange(text3)) && (rY2 = new AccRange(text4))) {
+ && (rY1 = new AccRange(TmpTxt+300)) && (rY2 = new AccRange(TmpTxt+400))) {
rX->GetFirst(&i, &j); rY1->GetFirst(&k, &l); rY2->GetFirst(&k1, &l1);
rX->GetNext(&i, &j); rY1->GetNext(&k, &l); rY2->GetNext(&k1, &l1);
ic = 0;
@@ -4255,9 +4493,9 @@ BoxPlot::PropertyDlg()
if(ic) bRet = true;
}
// whiskers
- if(n > 0 && Dlg->GetCheck(281) && Dlg->GetText(283, text3) && Dlg->GetText(285, text4)
+ if(n > 0 && Dlg->GetCheck(281) && Dlg->GetText(283, TmpTxt+300, 50) && Dlg->GetText(285, TmpTxt+400, 50)
&& (Whiskers = (Whisker**)calloc(n, sizeof(Whisker*)))
- && (rY1 = new AccRange(text3)) && (rY2 = new AccRange(text4))) {
+ && (rY1 = new AccRange(TmpTxt+300)) && (rY2 = new AccRange(TmpTxt+400))) {
rX->GetFirst(&i, &j); rY1->GetFirst(&k, &l); rY2->GetFirst(&k1, &l1);
rX->GetNext(&i, &j); rY1->GetNext(&k, &l); rY2->GetNext(&k1, &l1);
ic = 0;
@@ -4272,8 +4510,9 @@ BoxPlot::PropertyDlg()
}
if (bRet) Command(CMD_AUTOSCALE, 0L, 0L);
}
- else if(Dlg->GetText(102, text1) && text1[0] && Dlg->GetText(104, text2) && text2[0]){
- xRange = strdup(text1); yRange = strdup(text2);
+ else if(Dlg->GetText(102, TmpTxt+100, 50) && TmpTxt[100] && Dlg->GetText(104, TmpTxt+200, 50) && TmpTxt[200]){
+ xRange = (char*)memdup(TmpTxt+100, ((int)strlen(TmpTxt+100))+2, 0);
+ yRange = (char*)memdup(TmpTxt+200, ((int)strlen(TmpTxt+200))+2, 0);
if(Dlg->GetCheck(154)) type |= 0x0001; if(Dlg->GetCheck(155)) type |= 0x0002;
if(Dlg->GetCheck(156)) type |= 0x0003; if(Dlg->GetCheck(157)) type |= 0x0004;
if(Dlg->GetCheck(161)) type |= 0x0010; if(Dlg->GetCheck(162)) type |= 0x0020;
@@ -4285,43 +4524,75 @@ BoxPlot::PropertyDlg()
if(Dlg->GetCheck(151)) type |= 0x1000; if(Dlg->GetCheck(152)) type |= 0x2000;
if(Dlg->GetCheck(401)) type |= 0x4000; if(Dlg->GetCheck(402)) type |= 0x8000;
Dlg->GetValue(166, &ci_box); Dlg->GetValue(176, &ci_err);
- if(Dlg->GetText(404, TmpTxt) && TmpTxt[0]) case_prefix = strdup(TmpTxt);
+ if(Dlg->GetText(404, TmpTxt, TMP_TXT_SIZE)) case_prefix = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
CreateData();
if(curr_data && type) {
curr_data->GetSize(&width, &height);
- sprintf(text1, "a1:a%d", height); sprintf(text2, "b1:b%d", height);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt+100, 50, "a1:a%d", height); sprintf_s(TmpTxt+200, 50, "b1:b%d", height);
+#else
+ sprintf(TmpTxt+100, "a1:a%d", height); sprintf(TmpTxt+200, "b1:b%d", height);
+#endif
nPoints = height;
if(nPoints > 1 && (type & 0x1000)) {
- TheLine = new DataLine(this, curr_data, text1, text2);
+ TheLine = new DataLine(this, curr_data, TmpTxt+100, TmpTxt+200);
bRet = true;
}
if(nPoints > 0 && (type & 0x2000) && (Symbols = (Symbol**)calloc(nPoints, sizeof(Symbol*)))) {
+ switch(type & 0x000f) {
+ case 0x0001: cb = rlp_strcpy(symdesc, 40, "Mean"); break;
+ case 0x0002: cb = rlp_strcpy(symdesc, 40, "Geometric mean"); break;
+ case 0x0003: cb = rlp_strcpy(symdesc, 40, "Harmonic mean"); break;
+ case 0x0004: cb = rlp_strcpy(symdesc, 40, "Median"); break;
+ default: cb = rlp_strcpy(symdesc, 40, "n.a."); break;
+ }
for(i = 0; i < height; i++) {
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 1, &y1)
- && (Symbols[i] = new Symbol(this, curr_data, x, y1, SYM_PLUS, 0, i, 1, i)))
+ && (Symbols[i] = new Symbol(this, curr_data, x, y1, SYM_PLUS, 0, i, 1, i))){
Symbols[i]->idx = i;
+ Symbols[i]->name = (char*)memdup(symdesc, cb+1, 0);
+ }
}
bRet = true;
}
if(nPoints > 0 && (type & 0x00f0) && (Boxes = (Box**)calloc(nPoints, sizeof(Box*)))) {
+ switch(type & 0x00f0) {
+ case 0x0010: cb = rlp_strcpy(boxdesc, 40, "Std. Dev."); break;
+ case 0x0020: cb = rlp_strcpy(boxdesc, 40, "Std. Err."); break;
+ case 0x0030: cb = rlp_strcpy(boxdesc, 40, "25, 75% Perc."); break;
+ case 0x0040: cb = rlp_strcpy(boxdesc, 40, "Min./Max."); break;
+#ifdef USE_WIN_SECURE
+ case 0x0500: cb = sprintf_s(boxdesc, 40, "'%g%% CI", ci_err); break;
+#else
+ case 0x0500: cb = sprintf(boxdesc, "'%g%% CI", ci_err); break;
+#endif
+ default: cb = rlp_strcpy(boxdesc, 40, "n.a.");
+ }
for(i = 0; i < height; i++) {
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 2, &y1)
&& curr_data->GetValue(i, 3, &y2)) {
fp1.fy = y1; fp2.fy = y2; fp1.fx = fp2.fx = x;
Boxes[i] = new Box(this, curr_data, fp1, fp2, BAR_RELWIDTH, 0, i, 2, i, 0, i, 3, i);
- if(Boxes[i]) Boxes[i]->SetSize(SIZE_BOX, 60.0);
+ if(Boxes[i]){
+ Boxes[i]->SetSize(SIZE_BOX, 60.0);
+ Boxes[i]->name = (char*)memdup(boxdesc, cb+1, 0);
+ }
}
}
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");
+ switch(type & 0x0f00) {
+ case 0x0100: rlp_strcpy(errdesc, 40, "Std. Dev."); break;
+ case 0x0200: rlp_strcpy(errdesc, 40, "Std. Err."); break;
+ case 0x0300: rlp_strcpy(errdesc, 40, "25, 75% Perc."); break;
+ case 0x0400: rlp_strcpy(errdesc, 40, "Min./Max."); break;
+#ifdef USE_WIN_SECURE
+ case 0x0500: sprintf_s(errdesc, 40, "'%g%% CI", ci_err); break;
+#else
+ case 0x0500: sprintf(errdesc, "'%g%% CI", ci_err); break;
+#endif
+ default: rlp_strcpy(errdesc, 40, "error");
}
for(i = 0; i < height; i++) {
if(curr_data->GetValue(i, 0, &x) && curr_data->GetValue(i, 4, &y1)
@@ -4334,7 +4605,7 @@ BoxPlot::PropertyDlg()
bRet = true;
}
if(nPoints > 0 && (type & 0xc000) && (Labels = (Label**)calloc(nPoints, sizeof(Label*)))) {
- dy = -0.4 * defs.GetSize(SIZE_SYMBOL);
+ dy = -0.4 * DefSize(SIZE_SYMBOL);
if(type & 0x4000){
lbdef.Align = TXA_HCENTER | TXA_VBOTTOM;
dx = 0.0;
@@ -4402,8 +4673,7 @@ DensDisp::PropertyDlg()
OD_filldef(OD_SETLINE, 0L, 0L, 0L, (void *)defs.GetOutLine(), 0);
OD_filldef(OD_SETFILL, 0L, 0L, 0L, (void *)defs.GetFill(), 0);
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);
+ if(!(Dlg = new DlgRoot(PlotDlg, data)))return false;
hDlg = CreateDlgWnd("Density profile", 50, 50, 420, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -4432,16 +4702,16 @@ DensDisp::PropertyDlg()
case 1:
if(rX) delete rX; if(rY) delete rY;
rX = rY = 0L;
- if(Dlg->GetText(101, TmpTxt)) rX = new AccRange(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) rX = new AccRange(TmpTxt);
n = rX ? rX->CountItems() : 0;
if(!n) {
ErrorBox("direction range not specified\nor not valid.");
bContinue = true;
res = -1;
}
- if(n && Dlg->GetText(103, TmpTxt) && (rY = new AccRange(TmpTxt))){
+ if(n && Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE) && (rY = new AccRange(TmpTxt))){
if(n != rY->CountItems()) {
- ErrorBox("both ranges must be given\nand must have same size");
+ ErrorBox("both ranges must be given\nand must have the same size");
bContinue = true;
res = -1;
}
@@ -4449,9 +4719,15 @@ DensDisp::PropertyDlg()
}
}while (res < 0);
if(res == 1 && n && rX && rY) {
+ if(Dlg->GetCheck(104)) {
+ y_info = rX->RangeDesc(data, 0); x_info = rY->RangeDesc(data, 0);
+ }
+ else {
+ x_info = rX->RangeDesc(data, 0); y_info = rY->RangeDesc(data, 0);
+ }
type = (bVert = Dlg->GetCheck(104)) ? align | 0x10 : align;
- if(Dlg->GetText(101, TmpTxt)) xRange=strdup(TmpTxt);
- if(Dlg->GetText(103, TmpTxt)) yRange=strdup(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) xRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
+ if(Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE)) yRange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
OD_filldef(OD_GETLINE, 0L, 0L, 0L, (void *)&DefLine, 0);
OD_filldef(OD_GETFILL, 0L, 0L, 0L, (void *)&DefFill, 0);
if(DefFill.hatch) memcpy(&DefFillLine, DefFill.hatch, sizeof(LineDEF));
@@ -4475,23 +4751,22 @@ int com_StackDlg(int res, DlgRoot *Dlg, AccRange **rX, int *nx, char ***rd, int
switch (res) {
case 1:
- if(rX && nx && Dlg->GetText(101, TmpTxt) && TmpTxt[0] &&
+ if(rX && nx && Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0] &&
(*rX = new AccRange(TmpTxt))) *nx = rX[0]->CountItems();
else if(nx) *nx = 0;
- if(Dlg->GetText(154, TmpTxt) && TmpTxt[0]) {
+ if(Dlg->GetText(154, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0]) {
if(rd[0][*currYR]) free(rd[0][*currYR]);
- rd[0][*currYR] = strdup(TmpTxt);
+ rd[0][*currYR] = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);
}
break;
case 155:
res = -1;
*ny = 0;
if(rX) {
- if(!(*currYR) && Dlg->GetText(101, TmpTxt) && TmpTxt[0]) {
+ if(!(*currYR) && Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0]) {
if(*rX = new AccRange(TmpTxt)){
*nx = rX[0]->CountItems();
- delete *rX;
- *rX = 0L;
+ delete *rX; *rX = 0L;
}
}
if(!(*nx)) {
@@ -4501,7 +4776,7 @@ int com_StackDlg(int res, DlgRoot *Dlg, AccRange **rX, int *nx, char ***rd, int
break;
}
}
- if(Dlg->GetText(154, TmpTxt) && TmpTxt[0]) {
+ if(Dlg->GetText(154, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0]) {
if(*rY = new AccRange(TmpTxt)){
*ny = rY[0]->CountItems();
delete *rY;
@@ -4523,16 +4798,16 @@ int com_StackDlg(int res, DlgRoot *Dlg, AccRange **rX, int *nx, char ***rd, int
rd[0][(*currYR)+1] = 0L;
}
if(rd[0][*currYR]) free(rd[0][*currYR]);
- rd[0][*currYR] = strdup(TmpTxt); //store y-ranges
+ rd[0][*currYR] = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0); //store y-ranges
*updateYR = true;
(*currYR)++;
Dlg->SetText(154, rd[0][*currYR]);
Dlg->Activate(154, true);
break;
case 156:
- if(Dlg->GetText(154, TmpTxt)){
+ if(Dlg->GetText(154, TmpTxt, TMP_TXT_SIZE)){
if(rd[0][*currYR]) free(rd[0][*currYR]);
- rd[0][*currYR] = strdup(TmpTxt);
+ rd[0][*currYR] = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+2, 0);;
}
else if(*currYR == *maxYR) (*maxYR)--;
(*currYR)--;
@@ -4581,7 +4856,7 @@ StackBar::PropertyDlg()
void *hDlg;
int i, sc, j, res, currYR = 0, maxYR = 0, nx = 0, ny;
bool updateYR = true, bContinue = false, bSub, bRet = false, bHor;
- char **rd = 0L;
+ char **rd = 0L, *rname;
AccRange *rX = 0L, *rY = 0L;
if(!parent || !data) return false;
@@ -4589,12 +4864,12 @@ StackBar::PropertyDlg()
TmpTxt+500, TmpTxt+600, TmpTxt+700, TmpTxt+800, TmpTxt+900, TmpTxt+1000)) return false;
if(!(StackBarDlg = CompileDialog(StackBar_DlgTmpl, dyndata))) return false;
if(TmpTxt[0] && TmpTxt[100] && (rd = (char**)calloc(12, sizeof(char*)))) {
- for(i=100, j= 0; i <= 1000; i +=100) if(TmpTxt[i]) rd[j++] = strdup(TmpTxt+i); maxYR = j-1;
+ for(i=100, j= 0; i <= 1000; i +=100) if(TmpTxt[i])
+ rd[j++] = (char*)memdup(TmpTxt+i, ((int)strlen(TmpTxt+i))+2, 0); maxYR = j-1;
}
if(!rd && !(rd = (char**)calloc(1, sizeof(char*))))return false;
- if(!(Dlg = new DlgRoot(StackBarDlg))) return false;
+ if(!(Dlg = new DlgRoot(StackBarDlg, data))) return false;
if(rd && rd[currYR] && *(rd[currYR])) Dlg->SetText(154, rd[currYR]);
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(154, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd(Id == GO_STACKBAR ? (char*)"Stacked Bar Plot" :
(char*)"Stacked Polygons", 50, 50, 420, 260, Dlg, 0x0L);
do {
@@ -4605,7 +4880,11 @@ StackBar::PropertyDlg()
else {
Dlg->ShowItem(156, false); Dlg->Activate(101, true);
}
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "y-values # %d/%d", currYR+1, maxYR+1);
+#else
sprintf(TmpTxt,"y-values # %d/%d", currYR+1, maxYR+1);
+#endif
//SetText will also cause a redraw of the whole dialog
Dlg->SetText(153, TmpTxt);
updateYR = false;
@@ -4613,8 +4892,7 @@ StackBar::PropertyDlg()
LoopDlgWnd();
res = Dlg->GetResult();
ny = 0;
- if(rX) delete rX;
- rX = 0L;
+ if(rX) delete rX; rX = 0L;
switch(res) {
case 0:
if(bContinue || Dlg->GetCheck(20)) res = -1;
@@ -4634,39 +4912,55 @@ StackBar::PropertyDlg()
if(res == 1 && nx && rX && rd && rd[0] && rd[0][0]){ //accept settings and create plot
maxYR++;
for(i = j = 0; i < maxYR; i++) {
- if(i) j += sprintf(TmpTxt+j, "&");
- j += sprintf(TmpTxt+j, "%s", rd[i]);
+ if(i) TmpTxt[j++] = '&';
+ j+= rlp_strcpy(TmpTxt+j, TMP_TXT_SIZE-j, rd[i]);
}
- ssYrange = strdup(TmpTxt);
- if(Dlg->GetText(101, TmpTxt)) ssXrange = strdup(TmpTxt);
+ if(Dlg->GetCheck(204)) y_info = rX->RangeDesc(data, 0);
+ else x_info = rX->RangeDesc(data, 0);
+ ssYrange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+1, 0);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) ssXrange = (char*)memdup(TmpTxt, ((int)strlen(TmpTxt))+1, 0);;
cum_data_mode = Dlg->GetCheck(200) ? 1 : 2;
if(Id == GO_STACKPG) cum_data_mode += 2;
CumData = CreaCumData(ssXrange, ssYrange, cum_data_mode, StartVal);
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
//do stacked bar
+ if(rY)delete rY; rY = 0L;
if(Id == GO_STACKBAR){
numPlots = maxYR;
if(Boxes = (BoxPlot**)calloc(numPlots, sizeof(BoxPlot*)))
- for(i = sc = 0; i < (maxYR); i++) {
- if(Boxes[i]= new BoxPlot(this, CumData, Dlg->GetCheck(204)?2:1, 0, i+1, i+2)){
- Boxes[i]->Command(CMD_UPDATE, 0L, 0L);
- Boxes[i]->Command(CMD_AUTOSCALE, 0L, 0L);
+ for(i = sc = 0; i < (maxYR) && rd[i] && *rd[i]; i++) {
+ rY = new AccRange(rd[i]); rname = rY->RangeDesc(data, 1);
+ if(Boxes[i]= new BoxPlot(this, CumData, Dlg->GetCheck(204)? 2:1, 0, i+1, i+2, rname)){
+ 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);
+ if(rname) free(rname); delete rY; rY = 0L;
}
}
}
//do stacked polygon
else if(Id == GO_STACKPG){
- numPG = maxYR; sprintf(TmpTxt, "a1:a%d", nx*2);
- if(Polygons=(DataPolygon**)calloc(numPG,sizeof(DataPolygon*)))for(i=sc=0;i<maxYR;i++){
+ numPG = maxYR;
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, 20, "a1:a%d", nx*2);
+#else
+ sprintf(TmpTxt, "a1:a%d", nx*2);
+#endif
+ if(Polygons=(DataPolygon**)calloc(numPG,sizeof(DataPolygon*)))
+ for(i=sc=0; i < maxYR && rd[i] && *rd[i];i++){
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt+20, 20, "%c1:%c%d", 'c'+i, 'c'+i, nx*2);
+#else
sprintf(TmpTxt+20, "%c1:%c%d", 'c'+i, 'c'+i, nx*2);
- if(Dlg->GetCheck(204)) Polygons[i]=new DataPolygon(this,CumData,TmpTxt+20,TmpTxt);
- else Polygons[i] = new DataPolygon(this, CumData, TmpTxt, TmpTxt+20);
+#endif
+ rY = new AccRange(rd[i]); rname = rY->RangeDesc(data, 1);
+ if(Dlg->GetCheck(204)) Polygons[i]=new DataPolygon(this,CumData,TmpTxt+20,TmpTxt, rname);
+ else Polygons[i] = new DataPolygon(this, CumData, TmpTxt, TmpTxt+20, rname);
if(Polygons[i]) {
Polygons[i]->Command(CMD_AUTOSCALE, 0L, 0L);
Polygons[i]->Command(CMD_PG_FILL, GetSchemeFill(&sc), 0L);
}
+ if(rname) free(rname); delete rY; rY = 0L;
}
}
if(Bounds.Xmax >= Bounds.Xmin && Bounds.Ymax >= Bounds.Ymin) bRet = true;
@@ -4727,7 +5021,7 @@ GroupBars::PropertyDlg()
DlgRoot *Dlg;
void *hDlg;
bool bRet = false, updateYR = true, bContinue = false;
- char **rd = 0L;
+ char **rd = 0L, *desc;
Bar **bars = 0L;
AccRange *rY = 0L;
int i, j, ic, res, ix, iy, ny, sc = 0, currYR = 0, maxYR = 0;
@@ -4739,20 +5033,24 @@ GroupBars::PropertyDlg()
if(!(GBDlg = CompileDialog(GBDlg_Tmpl, dyndata)))return false;
if(TmpTxt[0] && TmpTxt[100] && (rd = (char**)calloc(12, sizeof(char*)))) {
for(i=0, j= 0; i <= 1000; i +=100)
- if(TmpTxt[i]) rd[j++] = strdup(TmpTxt+i); maxYR = j-1;
+ if(TmpTxt[i]) rd[j++] = (char*)memdup(TmpTxt+i, ((int)strlen(TmpTxt+i))+2, 0);
+ maxYR = j-1;
}
Id = GO_STACKBAR;
if(!rd && !(rd = (char**)calloc(1, sizeof(char*))))return false;
- if(!(Dlg = new DlgRoot(GBDlg)))return false;
+ if(!(Dlg = new DlgRoot(GBDlg, data)))return false;
if(rd && rd[currYR] && *(rd[currYR])) Dlg->SetText(154, rd[currYR]);
else Dlg->SetText(154, "");
- Dlg->ItemCmd(154, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd("Grouped bar chart", 50, 50, 370, 240, Dlg, 0x0L);
do {
if(updateYR) {
if(currYR >0) Dlg->ShowItem(156, true);
else Dlg->ShowItem(156, false);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, 20, "y-values # %d/%d", currYR+1, maxYR+1);
+#else
sprintf(TmpTxt,"y-values # %d/%d", currYR+1, maxYR+1);
+#endif
//SetText will also cause a redraw of the whole dialog
Dlg->SetText(153, TmpTxt);
updateYR = false;
@@ -4789,18 +5087,19 @@ GroupBars::PropertyDlg()
}
xinc = fabs(step / ((double)maxYR + gg/100.0));
start -= (xinc * ((double)maxYR-1))/2.0;
- for(i = 0; i < maxYR; i++) {
+ for(i = 0, desc = 0L; i < maxYR; i++) {
x = start + xinc * (double)i;
if(rd[i] && (rY = new AccRange(rd[i]))) ny = rY->CountItems();
else {
rY = 0L; ny = 0;
}
+ desc = rY->RangeDesc(data, 1);
rY->GetFirst(&ix, &iy); rY->GetNext(&ix, &iy);
if(ny && rY && (bars = (Bar **)calloc(ny, sizeof(Bar*)))){
for(ic = 0; ic < ny; ic++) {
if(data->GetValue(iy, ix, &y)){
bars[ic] = new Bar(0L, data, x, y, BAR_VERTB | BAR_RELWIDTH,
- -1, -1, ix, iy);
+ -1, -1, ix, iy, desc);
CheckBounds(x, y);
}
x += step;
@@ -4813,11 +5112,9 @@ GroupBars::PropertyDlg()
xyPlots[i]->Command(CMD_BAR_FILL, GetSchemeFill(&sc), 0L);
}
for(ic = 0; ic < ny; ic++) if(bars[ic]) delete(bars[ic]);
- free(bars);
- bRet = true;
+ free(bars); bRet = true;
}
- if(rY) delete(rY);
- rY = 0L;
+ if(rY) delete(rY); if(desc) free(desc); rY = 0L;
}
}
CloseDlgWnd(hDlg);
@@ -4865,16 +5162,16 @@ Waterfall::PropertyDlg()
{204, 205, 0, 0x0L, EDVAL1, &dspm.fy, 88, 45, 25, 10},
{205, 0, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 115, 45, 15, 8},
{300, 301, 0, CHECKED, RADIO1, (void*)" common color for lines:", 20, 35, 80, 9},
- {301, 302, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, (void*)defcol, 105, 35, 20, 10},
+ {301, 302, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&defcol, 105, 35, 20, 10},
{302, 303, 0, 0x0L, RADIO1, (void*)" increment color scheme:", 20, 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},
+ {303, 304, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[0], 25, 70, 10, 10},
+ {304, 305, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[1], 37, 70, 10, 10},
+ {305, 306, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[2], 49, 70, 10, 10},
+ {306, 307, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[3], 61, 70, 10, 10},
+ {307, 308, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[4], 73, 70, 10, 10},
+ {308, 309, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[5], 85, 70, 10, 10},
+ {309, 310, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[6], 97, 70, 10, 10},
+ {310, 0, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, (void*)&colarr[7], 109, 70, 10, 10},
{500, 0, 0, LASTOBJ, NONE, 0L, 0, 0, 0, 0}};
DlgRoot *Dlg;
void *hDlg;
@@ -4887,24 +5184,27 @@ Waterfall::PropertyDlg()
if(!UseRangeMark(data, 2, TmpTxt, TmpTxt+100, TmpTxt+200, TmpTxt+300, TmpTxt+400,
TmpTxt+500, TmpTxt+600, TmpTxt+700, TmpTxt+800, TmpTxt+900, TmpTxt+1000)) return false;
if(TmpTxt[0] && TmpTxt[100] && (rd = (char**)calloc(12, sizeof(char*)))) {
- for(i=100, j= 0; i <= 1000; i +=100) if(TmpTxt[i]) rd[j++] = strdup(TmpTxt+i); maxYR = j-1;
+ for(i=100, j= 0; i <= 1000; i +=100) if(TmpTxt[i])
+ rd[j++] = (char*)memdup(TmpTxt+i, ((int)strlen(TmpTxt+i))+2, 0);
+ maxYR = j-1;
}
if(!rd && !(rd = (char**)calloc(1, sizeof(char*))))return false;
- if(!(Dlg = new DlgRoot(StackBarDlg))) return false;
+ if(!(Dlg = new DlgRoot(StackBarDlg, data))) return false;
if(rd && rd[currYR] && *(rd[currYR])) Dlg->SetText(154, rd[currYR]);
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(154, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd("Create waterfall plot", 50, 50, 420, 260, Dlg, 0x0L);
do {
if(updateYR) {
if(currYR >0) {
- Dlg->ShowItem(156, true);
- Dlg->Activate(101, false);
+ Dlg->ShowItem(156, true); Dlg->Activate(101, false);
}
else {
- Dlg->ShowItem(156, false);
- Dlg->Activate(101, true);
+ Dlg->ShowItem(156, false); Dlg->Activate(101, true);
}
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, 20, "y-values # %d/%d", currYR+1, maxYR+1);
+#else
sprintf(TmpTxt,"y-values # %d/%d", currYR+1, maxYR+1);
+#endif
//SetText will also cause a redraw of the whole dialog
Dlg->SetText(153, TmpTxt);
updateYR = false;
@@ -4943,7 +5243,7 @@ Waterfall::PropertyDlg()
maxYR++;
numPL = maxYR;
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
- Dlg->GetText(101, text1);
+ Dlg->GetText(101, text1, 100);
if(Lines=(DataLine**)calloc(numPL,sizeof(DataLine*)))for(i=0;i<maxYR;i++){
if(rd[i] && rd[i][0]) Lines[i] = new DataLine(this, data, text1, rd[i]);
if(Lines[i]) {
@@ -5025,12 +5325,11 @@ MultiLines::PropertyDlg()
if(TmpTxt[0] && TmpTxt[100] && (rdx = (char**)calloc(12, sizeof(char*)))
&& (rdy = (char**)calloc(12, sizeof(char*))) && (rdc = (DWORD*)malloc(12*sizeof(DWORD)))) {
for(i=100, j= 0; i <= 1000; i +=100) if(TmpTxt[i]) {
- rdx[j] = strdup(TmpTxt); rdc[j] = colarr[j%8];
- rdy[j] = strdup(TmpTxt+i); maxYR = j++;
+ rdx[j] = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0); rdc[j] = colarr[j%8];
+ rdy[j] = (char*)memdup(TmpTxt+i, (int)strlen(TmpTxt+i)+1, 0); maxYR = j++;
}
}
- if(!(Dlg = new DlgRoot(StackBarDlg))) return false;
- Dlg->ItemCmd(102, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(104, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(StackBarDlg, data))) return false;
hDlg = CreateDlgWnd("Create Multi Line Plot", 50, 50, 420, 260, Dlg, 0x0L);
do {
if(updateYR) {
@@ -5040,10 +5339,18 @@ MultiLines::PropertyDlg()
else {
Dlg->ShowItem(106, false); Dlg->ShowItem(108, true);
}
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "x-range # %d/%d", currYR+1, maxYR+1);
+#else
sprintf(TmpTxt,"x-range # %d/%d", currYR+1, maxYR+1);
+#endif
//SetText will also cause a redraw of the whole dialog
Dlg->SetText(101, TmpTxt);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "y-range # %d/%d", currYR+1, maxYR+1);
+#else
sprintf(TmpTxt,"y-range # %d/%d", currYR+1, maxYR+1);
+#endif
Dlg->SetText(103, TmpTxt);
updateYR = false;
}
@@ -5059,7 +5366,7 @@ MultiLines::PropertyDlg()
case 1:
case 105: //next button
bError=false; s1 = s2 = 0;
- if(Dlg->GetText(102, x_txt)) {
+ if(Dlg->GetText(102, x_txt, 100)) {
if(rX = new AccRange(x_txt)) {
s1 = rX->CountItems();
if(s1 < 2) {
@@ -5072,7 +5379,7 @@ MultiLines::PropertyDlg()
else bError = true;
}
else bError = true;
- if(Dlg->GetText(104, y_txt) && !bError) {
+ if(Dlg->GetText(104, y_txt, 100) && !bError) {
if(rY = new AccRange(y_txt)) {
s2 = rY->CountItems();
if(s2 < 2) {
@@ -5103,10 +5410,10 @@ MultiLines::PropertyDlg()
maxYR = currYR+1;
rdc[currYR] = rdc[currYR+1] = Dlg->GetCheck(302) ? colarr[maxYR & 0x07] : defcol;
}
- if(rdx[currYR]) free(rdx[currYR]);
- rdx[currYR] = strdup(x_txt); //store x-range
- if(rdy[currYR]) free(rdy[currYR]);
- rdy[currYR] = strdup(y_txt); //store y-range
+ if(rdx[currYR]) free(rdx[currYR]); //store x-range
+ rdx[currYR] = (char*)memdup(x_txt, (int)strlen(x_txt)+1, 0);
+ if(rdy[currYR]) free(rdy[currYR]); //store y range
+ rdy[currYR] = (char*)memdup(y_txt, (int)strlen(y_txt)+1, 0);
Dlg->GetColor(107, &curr_col); rdc[currYR] = curr_col;
updateYR = true; currYR++;
Dlg->SetColor(107, rdc[currYR]); Dlg->SetText(102, rdx[currYR]);
@@ -5119,9 +5426,10 @@ MultiLines::PropertyDlg()
}
break;
case 106: //prev button
- if(Dlg->GetText(102, x_txt) && Dlg->GetText(104, y_txt)){
- if(rdx[currYR]) free(rdx[currYR]); rdx[currYR] = strdup(x_txt);
- if(rdy[currYR]) free(rdy[currYR]); rdy[currYR] = strdup(y_txt);
+ if(Dlg->GetText(102, x_txt, 100) && Dlg->GetText(104, y_txt, 100)){
+ if(rdx[currYR]) free(rdx[currYR]); if(rdy[currYR]) free(rdy[currYR]);
+ rdx[currYR] = (char*)memdup(x_txt, (int)strlen(x_txt)+1, 0);
+ rdy[currYR] = (char*)memdup(y_txt, (int)strlen(y_txt)+1, 0);
Dlg->GetColor(107, &curr_col); rdc[currYR] = curr_col;
}
else if(currYR == maxYR) maxYR--;
@@ -5196,12 +5504,12 @@ static char *PieDlgTmpl =
"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"
+ "101,105,,,RANGEINPUT,-15,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"
+ "200,201,,,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"
@@ -5220,7 +5528,7 @@ static char *PieDlgTmpl =
"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"
+ "502,503,,,RANGEINPUT,-16,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"
@@ -5237,15 +5545,15 @@ PieChart::PropertyDlg()
double fcx =10.0, fcy = 20.0, frad=40.0, firad = 30.0;
char txt2[80];
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,
+ 0L, (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",
+ 0L, (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, cf;
+ int i, ix, iy, rix, riy, ny, res, cf, cb;
bool bRet = false, bContinue = false;
double sum = 0.0, dang1, dang2;
double fv;
@@ -5254,13 +5562,13 @@ PieChart::PropertyDlg()
if(!parent || !data) return false;
UseRangeMark(data, 1, TmpTxt, TmpTxt+100);
- sprintf(txt2, "= [%s]", Units[defs.cUnits].display);
+ cb = rlp_strcpy(txt2, 80, "= ["); cb += rlp_strcpy(txt2+cb, 80-cb, Units[defs.cUnits].display);
+ rlp_strcpy(txt2+cb, 80-cb, "]");
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;
fcy = parent->GetSize(SIZE_GRECT_TOP) + parent->GetSize(SIZE_DRECT_TOP) + frad;
firad = frad-frad/10.0f;
- if(!(Dlg = new DlgRoot(PieDlg)))return false;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(502, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(PieDlg, data)))return false;
if(Id == GO_PIECHART) {
Dlg->ShowItem(105, true); Dlg->ShowItem(106, false);
Dlg->ShowItem(210, true); Dlg->ShowItem(211, false);
@@ -5270,7 +5578,7 @@ PieChart::PropertyDlg()
Dlg->ShowItem(210, false); Dlg->ShowItem(211, true);
}
hDlg = CreateDlgWnd(Id == GO_PIECHART ? (char*)"Create pie chart" :
- (char*)"Create ring chart", 50, 50, 370, 260, Dlg, 0x0L);
+ (char*)"Create ring chart", 50, 50, 370, 266, Dlg, 0x0L);
do {
LoopDlgWnd();
res = Dlg->GetResult();
@@ -5292,13 +5600,13 @@ PieChart::PropertyDlg()
CtDef.fy = 180.0; res = -1;
break;
case 1:
- if(Dlg->GetText(101, TmpTxt) && TmpTxt[0] && (rY = new AccRange(TmpTxt)))
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0] && (rY = new AccRange(TmpTxt)))
ny = rY->CountItems();
else ny = 0;
Dlg->GetValue(208, &CtDef.fx); Dlg->GetValue(202, &fcx);
Dlg->GetValue(205, &fcy); Dlg->GetValue(107, &frad);
Dlg->GetValue(602, &firad); Dlg->GetValue(504, &FacRad);
- if(Dlg->GetCheck(501) && ny && Dlg->GetText(502, TmpTxt) &&
+ if(Dlg->GetCheck(501) && ny && Dlg->GetText(502, TmpTxt, TMP_TXT_SIZE) &&
(rR = new AccRange(TmpTxt))){
if(rR->CountItems() != ny) {
delete rR;
@@ -5315,8 +5623,8 @@ PieChart::PropertyDlg()
if(res == 1 && rY && ny >1 && (Segments = (segment **)calloc(ny, sizeof(segment*)))) {
nPts = ny;
- if(Dlg->GetText(101, TmpTxt)) ssRefA = strdup(TmpTxt);
- if(rR && Dlg->GetText(502, TmpTxt)) ssRefR = strdup(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) ssRefA = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
+ if(rR && Dlg->GetText(502, TmpTxt, TMP_TXT_SIZE)) ssRefR = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
Bounds.Xmax = Bounds.Ymax = 100.0; Bounds.Xmin = Bounds.Ymin = -100.0;
fpCent.fx = fcx; fpCent.fy = fcy;
rY->GetFirst(&ix, &iy); rY->GetNext(&ix, &iy);
@@ -5359,7 +5667,7 @@ StarChart::PropertyDlg()
{
TabSHEET tab1 = {0, 25, 10, "Data"};
TabSHEET tab2 = {25, 55, 10, "Labels"};
- double sa = 90.0, factor = 1.0, lbdist = NiceValue(defs.GetSize(SIZE_TEXT)*1.2);
+ double sa = 90.0, factor = 1.0, lbdist = NiceValue(DefSize(SIZE_TEXT)*1.2);
char txt1[80], txt2[80];
DlgInfo StarDlg[] = {
{1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 130, 10, 45, 12},
@@ -5394,20 +5702,22 @@ StarChart::PropertyDlg()
double fx, fy, tmpval, frad;
double sia, csia;
polyline *plo;
- TextDEF td = {0x00000000L, 0x00ffffffL, defs.GetSize(SIZE_TEXT), 0.0, 0.0, 0,
+ TextDEF td = {0x00000000L, 0x00ffffffL, DefSize(SIZE_TEXT), 0.0, 0.0, 0,
TXA_HCENTER | TXA_VCENTER, TXM_TRANSPARENT, TXS_NORMAL, FONT_HELVETICA, 0L};
if(!parent || !data) return false;
data->GetSize(&width, &height);
- sprintf(txt1, "a1:a%d", height);
- sprintf(txt2, "= [%s]", Units[defs.cUnits].display);
+#ifdef USE_WIN_SECURE
+ sprintf_s(txt1, 80,"a1:a%d", height); sprintf_s(txt2, 80, "= [%s]", Units[defs.cUnits].display);
+#else
+ sprintf(txt1, "a1:a%d", height); sprintf(txt2, "= [%s]", Units[defs.cUnits].display);
+#endif
if(parent) {
frad = (parent->GetSize(SIZE_DRECT_BOTTOM) - parent->GetSize(SIZE_DRECT_TOP))/2.0f;
fPos.fx = parent->GetSize(SIZE_GRECT_LEFT) + parent->GetSize(SIZE_DRECT_LEFT) + frad;
fPos.fy = parent->GetSize(SIZE_GRECT_TOP) + parent->GetSize(SIZE_DRECT_TOP) + frad;
}
- if(!(Dlg = new DlgRoot(StarDlg)))return false;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(201, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(StarDlg, data)))return false;
hDlg = CreateDlgWnd("Create star chart", 50, 50, 370, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -5421,7 +5731,7 @@ StarChart::PropertyDlg()
bContinue = false;
break;
case 1:
- if(Dlg->GetText(101, TmpTxt) && TmpTxt[0] && (rY = new AccRange(TmpTxt)))
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0] && (rY = new AccRange(TmpTxt)))
ny = rY->CountItems();
else ny = 0;
Dlg->GetValue(106, &sa); Dlg->GetValue(103, &factor);
@@ -5461,7 +5771,7 @@ StarChart::PropertyDlg()
}
}
}
- if(Dlg->GetCheck(200) && Dlg->GetText(201, TmpTxt) && TmpTxt[0] && (rL = new AccRange(TmpTxt))){
+ if(Dlg->GetCheck(200) && Dlg->GetText(201, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0] && (rL = new AccRange(TmpTxt))){
rL->GetFirst(&ix, &iy);
td.text = TmpTxt;
for(i = 0; i < ny; i++) {
@@ -5509,13 +5819,13 @@ Grid3D::Configure()
{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},
+ {404, 405, 0, OWNDIALOG, COLBUTT, (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;
+ int res, cb, new_type, undo_level = *Undo.pcb;
bool bRet = false;
double tmp;
DWORD new_col;
@@ -5525,15 +5835,18 @@ Grid3D::Configure()
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(!(Dlg = new DlgRoot(GridDlg, data))) 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");
+ if(parent->name) {
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Grid of ");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, parent->name);
+ }
+ else rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "3D Grid");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 426, 260, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -5650,7 +5963,7 @@ Scatt3D::PropertyDlg()
DlgRoot *Dlg;
void *hDlg;
int res, n1, n2, n3, ic = 0;
- int i, j, k, l, m, n, i2, j2, k2, l2, m2;
+ int i, j, k, l, m, n, i2, j2, k2, l2, m2, cb;
double x, y, z, bar_w, bar_d, rad;
bool bRet = false, bContinue = false;
AccRange *rX, *rY, *rZ;
@@ -5658,16 +5971,14 @@ Scatt3D::PropertyDlg()
if(!data || !parent)return false;
UseRangeMark(data, 1, text1, text2, text3);
- if(!(Dlg = new DlgRoot(Dlg3D)))return false;
+ if(!(Dlg = new DlgRoot(Dlg3D, data)))return false;
Dlg->SetCheck(410 + AxisTempl3D, 0L, true);
- 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 || c_flags == 0x4000) {
Dlg->ShowItem(5, false); Dlg->ShowItem(6, false);
}
else Dlg->ShowItem(6, (c_flags & 0x1000) == 0x1000);
- rX = rY = rZ = 0L; rad = defs.GetSize(SIZE_SYMBOL);
+ rX = rY = rZ = 0L; rad = DefSize(SIZE_SYMBOL);
#ifdef _WINDOWS
for(i = 61; i <= 62; i++) Dlg->TextSize(i, 12);
#else
@@ -5700,9 +6011,9 @@ Scatt3D::PropertyDlg()
case 1:
if(rX) delete rX; if(rY) delete rY; if(rZ) delete rZ;
rX = rY = rZ = 0L; n1 = n2 = n3 = 0;
- if(Dlg->GetText(101, text1) && (rX = new AccRange(text1))) n1 = rX->CountItems();
- if(Dlg->GetText(103, text2) && (rY = new AccRange(text2))) n2 = rY->CountItems();
- if(Dlg->GetText(105, text3) && (rZ = new AccRange(text3))) n3 = rZ->CountItems();
+ if(Dlg->GetText(101, text1, 100) && (rX = new AccRange(text1))) n1 = rX->CountItems();
+ if(Dlg->GetText(103, text2, 100) && (rY = new AccRange(text2))) n2 = rY->CountItems();
+ if(Dlg->GetText(105, text3, 100) && (rZ = new AccRange(text3))) n3 = rZ->CountItems();
if(n1 && n2 && n3){
if(c_flags == 0x2000 || c_flags == 0x4000) {
//no more but a ribbon ore surface
@@ -5718,9 +6029,11 @@ Scatt3D::PropertyDlg()
}
}
else {
- sprintf(TmpTxt, "Ranges for\n%s%s%s\n\nnot given or not valid.",
- n1 == 0 ? "\n X Data" : "", n2 == 0 ? "\n Y Data" : "",
- n3 == 0 ? "\n Z Data" : "");
+ cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Ranges for ");
+ if(!n1) cb += rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, "\n- X Data");
+ if(!n2) cb += rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, "\n- Y Data");
+ if(!n3) cb += rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, "\n- Z Data");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE-cb, "\nnot given or not valid.");
InfoBox(TmpTxt);
res = -1; bContinue = true;
}
@@ -5731,7 +6044,7 @@ Scatt3D::PropertyDlg()
Bounds.Xmin = Bounds.Ymin = HUGE_VAL; Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
xBounds.fx = yBounds.fx = zBounds.fx = HUGE_VAL;
xBounds.fy = yBounds.fy = zBounds.fy = -HUGE_VAL;
- bar_w = bar_d = (defs.GetSize(SIZE_BAR)/2.0);
+ bar_w = bar_d = (DefSize(SIZE_BAR)/2.0);
if(c_flags & 0x01) (Balls = (Sphere**)calloc((nBalls = n1)+1, sizeof(Sphere*)));
if(c_flags & 0x02) (Columns = (Brick**)calloc((nColumns = n1)+1, sizeof(Brick*)));
if(c_flags & 0x04) Line = new Line3D(this, data, text1, text2, text3);
@@ -5743,11 +6056,10 @@ Scatt3D::PropertyDlg()
i2 = i; j2 = j; k2 = k; l2 = l; m2 = m; n2 = n;
if(c_flags == 0x2000){
Bounds.Ymin = 0.0;
- rib = new Ribbon(this, data, text1, text2, text3);
+ rib = new Ribbon(this, data, 2, text1, text2, text3);
}
else if(c_flags == 0x4000){
- Bounds.Ymin = 0.0;
- rib = SurfTria(this, data, text1, text2, text3);
+ rib = new Ribbon(this, data, 3, text1, text2, text3);
}
do {
if(data->GetValue(j, i, &x) && data->GetValue(l, k, &y) &&
@@ -5818,7 +6130,7 @@ Function::PropertyDlg()
if(!parent) return false;
if(parent->Id == GO_FITFUNC) return parent->PropertyDlg();
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
- if(!(Dlg = new DlgRoot(FuncDlg))) return false;
+ if(!(Dlg = new DlgRoot(FuncDlg, data))) return false;
if(!bNew) Dlg->ShowItem(10, false);
Dlg->GetValue(102, &o_x1); n_x1 = o_x1;
Dlg->GetValue(104, &o_x2); n_x2 = o_x2;
@@ -5840,9 +6152,9 @@ Function::PropertyDlg()
if(bNew) { //create function
OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&Line, 0);
Dlg->GetValue(102, &x1); Dlg->GetValue(104, &x2);
- Dlg->GetValue(106, &xstep); Dlg->GetText(200, TmpTxt);
- cmdxy = strdup(TmpTxt); ReshapeFormula(&cmdxy);
- bRet = Update(0L, 0L);
+ Dlg->GetValue(106, &xstep); Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE);
+ cmdxy = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
+ ReshapeFormula(&cmdxy); bRet = Update(0L, 0L);
}
else { //edit existing function
Dlg->GetValue(102, &n_x1); Dlg->GetValue(104, &n_x2);
@@ -5850,10 +6162,11 @@ Function::PropertyDlg()
undo_flags = CheckNewFloat(&x1, o_x1, n_x1, this, undo_flags);
undo_flags = CheckNewFloat(&x2, o_x2, n_x2, this, undo_flags);
undo_flags = CheckNewFloat(&xstep, o_xstep, n_xstep, this, undo_flags);
- Dlg->GetText(200, TmpTxt);
+ Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE);
if(cmdxy && strcmp(cmdxy, TmpTxt)) {
Undo.String(this, &cmdxy, undo_flags);
- free(cmdxy); cmdxy = strdup(TmpTxt); undo_flags |= UNDO_CONTINUE;
+ free(cmdxy); undo_flags |= UNDO_CONTINUE;
+ cmdxy = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
if(undo_flags & UNDO_CONTINUE){
Update(0L, UNDO_CONTINUE);
@@ -5920,6 +6233,7 @@ FitFunc::PropertyDlg()
DlgRoot *Dlg;
void *hDlg;
int res, undo_level = *Undo.pcb, i, j, k, l, cs;
+ size_t cb;
bool bRet = false, bContinue = false;
DWORD undo_flags = 0L;
LineDEF newLine;
@@ -5930,19 +6244,22 @@ FitFunc::PropertyDlg()
anyResult *ares;
if(!parent || !data) return false;
- if(!(o_cmdxy = strdup(cmdxy))) return false;
- if(!(o_parxy = strdup(parxy))) return false;
+ if(!(o_cmdxy = (char*)memdup(cmdxy, (int)strlen(cmdxy)+1, 0))) return false;;
+ if(!(o_parxy = (char*)memdup(parxy, (int)strlen(parxy)+1, 0))) 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;
- Dlg->ItemCmd(401, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(403, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(FuncDlg, data))) return false;
if(!bNew){
Dlg->ShowItem(10, false); Dlg->Activate(401, false);
Dlg->Activate(403, false); Dlg->SetCheck(6, 0L, true);
Dlg->SetCheck(4, 0L, false); Dlg->ShowItem(404, false);
if(chi2 > 0.0) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "Chi 2 = %g", chi2);
+#else
sprintf(TmpTxt, "Chi 2 = %g", chi2);
+#endif
Dlg->SetText(405,TmpTxt); Dlg->ShowItem(405, true);
}
}
@@ -5965,11 +6282,13 @@ FitFunc::PropertyDlg()
break;
case 1:
if(!bNew){
- if(Dlg->GetText(102, TmpTxt) && parxy) {
- free(parxy); parxy = strdup(TmpTxt);
+ if(Dlg->GetText(102, TmpTxt, TMP_TXT_SIZE)) {
+ if(parxy = (char*)realloc(parxy, (cb = strlen(TmpTxt)+2)))
+ rlp_strcpy(parxy, (int)cb, TmpTxt);
}
- if(Dlg->GetText(200, TmpTxt) && cmdxy) {
- free(cmdxy); cmdxy = strdup(TmpTxt);
+ if(Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE)) {
+ if(cmdxy = (char*)realloc(cmdxy, (cb = strlen(TmpTxt)+2)))
+ rlp_strcpy(cmdxy, (int)cb, TmpTxt);
}
ReshapeFormula(&parxy); ReshapeFormula(&cmdxy);
dirty = true;
@@ -5979,12 +6298,14 @@ FitFunc::PropertyDlg()
Undo.SetDisp(cdisp);
if(Dlg->GetCheck(5)) { // the function tab must be shown
if(Dlg->CurrDisp) Dlg->CurrDisp->MouseCursor(MC_WAIT, true);
- Dlg->GetText(401, text1); Dlg->GetText(403, text2);
- if(Dlg->GetText(102, TmpTxt) && parxy) {
- free(parxy); parxy = strdup(TmpTxt);
+ Dlg->GetText(401, text1, 100); Dlg->GetText(403, text2, 100);
+ if(Dlg->GetText(102, TmpTxt, TMP_TXT_SIZE)) {
+ if(parxy = (char*)realloc(parxy, (cb = strlen(TmpTxt)+2)))
+ rlp_strcpy(parxy, (int)cb, TmpTxt);
}
- if(Dlg->GetText(200, TmpTxt) && cmdxy) {
- free(cmdxy); cmdxy = strdup(TmpTxt);
+ if(Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE)) {
+ if(cmdxy = (char*)realloc(cmdxy, (cb = strlen(TmpTxt)+2)))
+ rlp_strcpy(cmdxy, (int)cb, TmpTxt);
}
Dlg->GetValue(153, &conv); Dlg->GetValue(155, &iter);
ReshapeFormula(&parxy); ReshapeFormula(&cmdxy);
@@ -6000,10 +6321,22 @@ FitFunc::PropertyDlg()
bContinue = true; res = -1;
break;
}
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE-2, parxy); i += rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, ";x=1;");
+ rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, cmdxy); yywarn(0L, true);
+ ares = do_formula(data, TmpTxt);
+ if(tmp_char = yywarn(0L, false)) {
+ ErrorBox(tmp_char);
+ 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) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "The Levenberg-Marquart algorithm\nexited after %d iterations.\n\nChi2 = %g", i, chi2);
+#else
sprintf(TmpTxt, "The Levenberg-Marquart algorithm\nexited after %d iterations.\n\nChi2 = %g", i, chi2);
+#endif
InfoBox(TmpTxt);
}
bContinue = true;
@@ -6022,9 +6355,10 @@ FitFunc::PropertyDlg()
if(res == 1){ //OK pressed
//get ranges for x- and y data (again).
chi2 = n_chi2;
- Dlg->GetText(401, text1); Dlg->GetText(403, text2);
- if(ssXref) free(ssXref); if(ssYref) free(ssYref);
- ssXref = strdup(text1); ssYref = strdup(text2);
+ if(Dlg->GetText(401, text1, 100) && (ssXref = (char*)realloc(ssXref, (cb = strlen(text1)+2))))
+ rlp_strcpy(ssXref, (int)cb, text1);
+ if(Dlg->GetText(403, text2, 100) && (ssYref = (char*)realloc(ssYref, (cb = strlen(text2)+2))))
+ rlp_strcpy(ssYref, (int)cb, text2);
if(bNew) { //create function
if(!(rX = new AccRange(text1)) || ! (rY = new AccRange(text2))) return false;
i = rX->CountItems(); maxiter = int(iter);
@@ -6042,7 +6376,7 @@ FitFunc::PropertyDlg()
}
}while(rX->GetNext(&i, &j) && rY->GetNext(&k, &l));
delete rX; delete rY;
- if(x1 >= x2 || !(dl = new Function(this, data))){
+ if(x1 >= x2 || !(dl = new Function(this, data, "Fitted function"))){
CloseDlgWnd(hDlg);
delete Dlg;
return false;
@@ -6127,7 +6461,7 @@ Plot3D::AddPlot(int family)
bool bRet = false;
Plot *p;
- if(!(Dlg = new DlgRoot(PlotsDlg)))return false;
+ if(!(Dlg = new DlgRoot(PlotsDlg, data)))return false;
hDlg = CreateDlgWnd("Add Plot", 50, 50, 410, 204, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -6249,12 +6583,14 @@ Chart25D::PropertyDlg()
if(!UseRangeMark(data, 2, TmpTxt, TmpTxt+100, TmpTxt+200, TmpTxt+300, TmpTxt+400,
TmpTxt+500, TmpTxt+600, TmpTxt+700, TmpTxt+800, TmpTxt+900, TmpTxt+1000)) return false;
if(TmpTxt[0] && TmpTxt[100] && (rd = (char**)calloc(12, sizeof(char*)))) {
- for(i=100, j= 0; i <= 1000; i +=100) if(TmpTxt[i]) rd[j++] = strdup(TmpTxt+i); maxYR = j-1;
+ for(i=100, j= 0; i <= 1000; i +=100){
+ if(TmpTxt[i]) rd[j++] = (char*)memdup(TmpTxt+i, (int)strlen(TmpTxt+i)+1, 0);
+ }
+ if(j) maxYR = j-1;
}
if(!rd && !(rd = (char**)calloc(1, sizeof(char*))))return false;
- if(!(Dlg = new DlgRoot(Bar3D_Dlg))) return false;
+ if(!(Dlg = new DlgRoot(Bar3D_Dlg, data))) return false;
if(rd && rd[currYR] && *(rd[currYR])) Dlg->SetText(154, rd[currYR]);
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(154, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd("Create 3D Bar Chart", 50, 50, 420, 260, Dlg, 0x0L);
do {
if(updateYR) {
@@ -6266,7 +6602,11 @@ Chart25D::PropertyDlg()
Dlg->ShowItem(156, false);
Dlg->Activate(101, true);
}
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "y-values # %d/%d", currYR+1, maxYR+1);
+#else
sprintf(TmpTxt,"y-values # %d/%d", currYR+1, maxYR+1);
+#endif
//SetText will also cause a redraw of the whole dialog
Dlg->SetText(153, TmpTxt);
updateYR = false;
@@ -6303,7 +6643,7 @@ Chart25D::PropertyDlg()
}while (res < 0);
if(res == 1 && nx && rX && rd && rd[0] && rd[0][0]) {
if(rd[maxYR]) maxYR++;
- fsz = defs.GetSize(SIZE_BAR)/2.0; fz = start_z;
+ fsz = DefSize(SIZE_BAR)/2.0; fz = start_z;
oax = AxisTempl3D; AxisTempl3D = 1; CreateAxes();
if(Axes && nAxes > 2 && Axes[2] && (ax = Axes[2]->GetAxis())){
ax->flags = AXIS_3D | AXIS_INVERT | AXIS_DEFRECT;
@@ -6376,7 +6716,7 @@ Ribbon25D::PropertyDlg()
DlgRoot *Dlg;
void *hDlg;
int i, j, res, currYR=0, maxYR=0, nx=0, ny, oax;
- char **rd = 0L;
+ char **rd = 0L, xrange[100];
double fz;
bool updateYR = true, bContinue = false, bRet = false, bUseSch;
AccRange *rX = 0L, *rY = 0L;
@@ -6391,12 +6731,14 @@ Ribbon25D::PropertyDlg()
if(!UseRangeMark(data, 2, TmpTxt, TmpTxt+100, TmpTxt+200, TmpTxt+300, TmpTxt+400,
TmpTxt+500, TmpTxt+600, TmpTxt+700, TmpTxt+800, TmpTxt+900, TmpTxt+1000)) return false;
if(TmpTxt[0] && TmpTxt[100] && (rd = (char**)calloc(12, sizeof(char*)))) {
- for(i=100, j= 0; i <= 1000; i +=100) if(TmpTxt[i]) rd[j++] = strdup(TmpTxt+i); maxYR = j-1;
+ for(i=100, j= 0; i <= 1000; i +=100){
+ if(TmpTxt[i]) rd[j++] = (char*)memdup(TmpTxt+i, (int)strlen(TmpTxt+i)+1, 0);
+ }
+ if(j) maxYR = j-1;
}
if(!rd && !(rd = (char**)calloc(1, sizeof(char*))))return false;
- if(!(Dlg = new DlgRoot(Bar3D_Dlg)))return false;
+ if(!(Dlg = new DlgRoot(Bar3D_Dlg, data)))return false;
if(rd && rd[currYR] && *(rd[currYR])) Dlg->SetText(154, rd[currYR]);
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(154, CMD_SET_DATAOBJ, data);
hDlg = CreateDlgWnd("Create 3D Ribbon Chart", 50, 50, 420, 260, Dlg, 0x0L);
do {
if(updateYR) {
@@ -6406,7 +6748,11 @@ Ribbon25D::PropertyDlg()
else {
Dlg->ShowItem(156, false); Dlg->Activate(101, true);
}
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "y-values # %d/%d", currYR+1, maxYR+1);
+#else
sprintf(TmpTxt,"y-values # %d/%d", currYR+1, maxYR+1);
+#endif
//SetText will also cause a redraw of the whole dialog
Dlg->SetText(153, TmpTxt);
updateYR = false;
@@ -6440,21 +6786,23 @@ Ribbon25D::PropertyDlg()
}while (res < 0);
if(res == 1 && nx && rX && rd && rd[0] && rd[0][0]) {
if(rd[maxYR]) maxYR++; fz = start_z;
+ Dlg->GetText(101, TmpTxt+100, 100);
oax = AxisTempl3D; AxisTempl3D = 1; CreateAxes();
- Dlg->GetText(101, TmpTxt+100);
if(Axes && nAxes > 2 && Axes[2] && (ax = Axes[2]->GetAxis())){
ax->flags = AXIS_3D | AXIS_INVERT | AXIS_DEFRECT;
ax->min = start_z-dspm.fz;
ax->max = start_z+dspm.fz*maxYR;
if(Axes[1] && (ax = Axes[1]->GetAxis())){
- ax->flags |= AXIS_GRIDLINE; i = 0x0c;
+ ax->flags |= AXIS_GRIDLINE;
+ i = 0x0c;
Axes[1]->Command(CMD_SET_GRIDTYPE, &i, 0L);
}
AxisTempl3D = oax;
}
if(plots = (GraphObj**)calloc(maxYR, sizeof(GraphObj*))) {
+ Dlg->GetText(101, xrange, 100);
for(i = 0; i < maxYR; i++, fz += dspm.fz) {
- if(plot = new Ribbon(this, data, fz, dspm.fz, TmpTxt+100, rd[i])){
+ if(plot = new Ribbon(this, data, fz, dspm.fz, xrange, rd[i])){
if(bUseSch) plot->SetColor(COL_POLYGON, colarr[(i & 0x07)]);
else plot->SetColor(COL_POLYGON, defcol);
plots[nPlots++] = plot;
@@ -6519,12 +6867,10 @@ BubblePlot3D::PropertyDlg()
Sphere **Balls;
AccRange *rX, *rY, *rZ, *rR;
Scatt3D *sc_plot;
- int etracc[] = {101, 103, 105, 151};
if(!data || !parent)return false;
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);
+ if(!(Dlg = new DlgRoot(BubDlg3D, data)))return false;
rX = rY = rZ = rR = 0L;
Dlg->SetCheck(410 + AxisTempl3D, 0L, true);
hDlg = CreateDlgWnd("Bubble Plot 3D", 50, 50, 388, 340, Dlg, 0x0L);
@@ -6553,10 +6899,10 @@ BubblePlot3D::PropertyDlg()
}
}while (res <0);
if(res == 1) {
- if(Dlg->GetText(101, TmpTxt)) rX = new AccRange(TmpTxt);
- if(Dlg->GetText(103, TmpTxt)) rY = new AccRange(TmpTxt);
- if(Dlg->GetText(105, TmpTxt)) rZ = new AccRange(TmpTxt);
- if(Dlg->GetText(151, TmpTxt)) rR = new AccRange(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) rX = new AccRange(TmpTxt);
+ if(Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE)) rY = new AccRange(TmpTxt);
+ if(Dlg->GetText(105, TmpTxt, TMP_TXT_SIZE)) rZ = new AccRange(TmpTxt);
+ if(Dlg->GetText(151, TmpTxt, TMP_TXT_SIZE)) rR = new AccRange(TmpTxt);
if(rX && rY && rZ && rR && (count = rX->CountItems())
&& (Balls = (Sphere**)calloc(count, sizeof(Sphere*)))) {
rX->GetFirst(&cx, &rx); rY->GetFirst(&cy, &ry);
@@ -6622,7 +6968,7 @@ Func3D::PropertyDlg()
{401, 402, 0, 0x0L, EDVAL1, &Line.width, 80, 50, 25, 10},
{402, 403, 0, 0x0L, LTEXT, (void*)Units[defs.cUnits].display, 107, 50, 20, 8},
{403, 404, 0, 0x0L, RTEXT, (void*)"grid line color", 38, 62, 40, 8},
- {404, 405, 0, OWNDIALOG, COLBUTTON, (void *)Line.color, 80, 62, 25, 10},
+ {404, 405, 0, OWNDIALOG, COLBUTT, (void *)&Line.color, 80, 62, 25, 10},
{405, 406, 0, 0x0L, RTEXT,(void*)"plane color" , 38, 74, 40, 8},
{406, 0, 0, OWNDIALOG, SHADE3D, &newFill, 80, 74, 25, 10},
{500, 0, 0, LASTOBJ | NOSELECT, ODBUTTON, (void*)OD_linedef, 15, 45, 130, 100}};
@@ -6640,7 +6986,7 @@ Func3D::PropertyDlg()
// if(parent->Id == GO_FITFUNC) return parent->PropertyDlg();
memcpy(&newFill, &Fill, sizeof(FillDEF));
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&Line, 0);
- if(!(Dlg = new DlgRoot(FuncDlg))) return false;
+ if(!(Dlg = new DlgRoot(FuncDlg, data))) return false;
if(!bNew) Dlg->ShowItem(10, false);
Dlg->GetValue(102, &o_x1); n_x1 = o_x1;
Dlg->GetValue(104, &o_x2); n_x2 = o_x2;
@@ -6648,7 +6994,7 @@ Func3D::PropertyDlg()
Dlg->GetValue(108, &o_z1); n_z1 = o_z1;
Dlg->GetValue(109, &o_z2); n_z2 = o_z2;
Dlg->GetValue(110, &o_zstep); n_zstep = o_zstep;
- hDlg = CreateDlgWnd("3D Function Plot", 50, 50, 426, 320, Dlg, 0x0L);
+ hDlg = CreateDlgWnd("3D Function Plot", 50, 50, 426, 328, Dlg, 0x0L);
if(bNew) Dlg->SetCheck(4, 0L, true);
do{
LoopDlgWnd();
@@ -6689,10 +7035,9 @@ Func3D::PropertyDlg()
Dlg->GetValue(106, &xstep);
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();
+ if(Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE)) {
+ if(cmdxy) free(cmdxy); cmdxy = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
+ ReshapeFormula(&cmdxy); bRet = Update();
}
}
else { //edit existing function
@@ -6701,10 +7046,11 @@ Func3D::PropertyDlg()
undo_flags = CheckNewFloat(&x1, o_x1, n_x1, this, undo_flags);
undo_flags = CheckNewFloat(&x2, o_x2, n_x2, this, undo_flags);
undo_flags = CheckNewFloat(&xstep, o_xstep, n_xstep, this, undo_flags);
- Dlg->GetText(200, TmpTxt);
+ Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE);
if(cmdxy && strcmp(cmdxy, TmpTxt)) {
Undo.String(this, &cmdxy, undo_flags);
- free(cmdxy); cmdxy = strdup(TmpTxt); undo_flags |= UNDO_CONTINUE;
+ if(cmdxy) free(cmdxy); cmdxy = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
+ undo_flags |= UNDO_CONTINUE;
}
// if(undo_flags & UNDO_CONTINUE) Update(0L, UNDO_CONTINUE);
OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&newLine, 0);
@@ -6721,7 +7067,7 @@ Func3D::PropertyDlg()
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Fit data to a 3D function
+// Fit a 3D function to data
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool
FitFunc3D::PropertyDlg()
@@ -6762,7 +7108,7 @@ FitFunc3D::PropertyDlg()
{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},
+ {354, 355, 0, OWNDIALOG, COLBUTT, (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},
@@ -6789,38 +7135,39 @@ FitFunc3D::PropertyDlg()
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;
+ char *o_cmdxy, *o_param, *tmp_char;
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;
+ if(!(o_cmdxy = (char*)memdup(cmdxy, (int)strlen(cmdxy)+1, 0)))return false;
+ if(!(o_param = (char*)memdup(param, (int)strlen(param)+1, 0)))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(!(Dlg = new DlgRoot(FuncDlg, data))) 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) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "Chi 2 = %g", chi2);
+#else
sprintf(TmpTxt, "Chi 2 = %g", chi2);
+#endif
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);
- }
+ else 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);
+ hDlg = CreateDlgWnd("Fit Function to Data in 3D Space", 50, 50, 426, 328, Dlg, 0x0L);
if(bNew) Dlg->SetCheck(4, 0L, true);
do{
LoopDlgWnd();
@@ -6843,11 +7190,13 @@ FitFunc3D::PropertyDlg()
break;
case 1:
if(!bNew){
- if(Dlg->GetText(102, TmpTxt) && param) {
- free(param); param = strdup(TmpTxt);
+ if(Dlg->GetText(102, TmpTxt, TMP_TXT_SIZE)) {
+ if(param) free(param);
+ param = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
- if(Dlg->GetText(200, TmpTxt) && cmdxy) {
- free(cmdxy); cmdxy = strdup(TmpTxt);
+ if(Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE)) {
+ if(cmdxy) free(cmdxy);
+ cmdxy = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
ReshapeFormula(¶m); ReshapeFormula(&cmdxy);
dirty = true;
@@ -6855,18 +7204,20 @@ FitFunc3D::PropertyDlg()
}
case 7: //Start: do nonlinear regression
Undo.SetDisp(cdisp);
- if(!Dlg->GetText(401, text1) || !Dlg->GetText(403, text2) || !Dlg->GetText(405, text3)) {
+ if(!Dlg->GetText(401, text1, 100) || !Dlg->GetText(403, text2, 100) || !Dlg->GetText(405, text3, 100)) {
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(102, TmpTxt, TMP_TXT_SIZE)) {
+ if(param) free(param);
+ param = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
- if(Dlg->GetText(200, TmpTxt) && cmdxy) {
- free(cmdxy); cmdxy = strdup(TmpTxt);
+ if(Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE)) {
+ if(cmdxy) free(cmdxy);
+ cmdxy = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
Dlg->GetValue(153, &conv); Dlg->GetValue(155, &iter);
ReshapeFormula(¶m); ReshapeFormula(&cmdxy);
@@ -6882,10 +7233,22 @@ FitFunc3D::PropertyDlg()
bContinue = true; res = -1;
break;
}
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE-2, param); i += rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, ";x=1;z=1;");
+ rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, cmdxy); yywarn(0L, true);
+ ares = do_formula(data, TmpTxt);
+ if(tmp_char = yywarn(0L, false)) {
+ ErrorBox(tmp_char);
+ 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) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "The Levenberg-Marquart algorithm\nexited after %d iterations.\n\nChi2 = %g", i, chi2);
+#else
sprintf(TmpTxt, "The Levenberg-Marquart algorithm\nexited after %d iterations.\n\nChi2 = %g", i, chi2);
+#endif
InfoBox(TmpTxt);
}
bContinue = true;
@@ -6924,17 +7287,20 @@ FitFunc3D::PropertyDlg()
}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(102, TmpTxt, TMP_TXT_SIZE)) {
+ if(param) free(param);
+ param = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
- if(Dlg->GetText(200, TmpTxt)) {
- if(cmdxy) free(cmdxy); cmdxy = strdup(TmpTxt); ReshapeFormula(&cmdxy);
+ if(Dlg->GetText(200, TmpTxt, TMP_TXT_SIZE)) {
+ if(cmdxy) free(cmdxy);
+ cmdxy = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
+ ReshapeFormula(¶m); 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);
+ rad = DefSize(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);
@@ -7004,7 +7370,7 @@ GridLine::PropertyDlg()
if(!parent || !parent->parent) return false;
OD_linedef(OD_SETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
- if(!(Dlg = new DlgRoot(LineDlg)))return false;
+ if(!(Dlg = new DlgRoot(LineDlg, data)))return false;
if ((flags & AXIS_ANGULAR) || (flags & AXIS_RADIAL)) {
//no checkboxes
}
@@ -7133,7 +7499,7 @@ Tick::PropertyDlg()
default: tick_rot = trig2deg(lsi, lcsi); break;
}
old_flags = flags;
- Dlg = new DlgRoot(TickDlg);
+ Dlg = new DlgRoot(TickDlg, data);
Dlg->SetCheck(301 + (type & 0x07), 0L, true);
if(flags & AXIS_ANGULAR) {
Dlg->SetText(105, "outside"); Dlg->SetText(106, "inside");
@@ -7162,11 +7528,9 @@ Tick::PropertyDlg()
}
}
if(label) {
- label->Command(CMD_GETTEXT, &TmpTxt, 0L);
- if(TmpTxt[0]) {
- old_label = strdup(TmpTxt);
+ if(label->Command(CMD_GETTEXT, &TmpTxt, 0L) && TmpTxt[0] &&
+ (old_label = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0)))
Dlg->SetText(203, old_label);
- }
if(label->Id != GO_LABEL) Dlg->Activate(203, false);
}
switch(flags &0x03) {
@@ -7212,7 +7576,7 @@ Tick::PropertyDlg()
undo_flags = CheckNewFloat(&value, old_value, new_value, parent, undo_flags);
if(label && label->Id == GO_LABEL) {
td = ((Label*)label)->GetTextDef();
- if(!Dlg->GetText(203, TmpTxt)) TmpTxt[0] = 0;
+ if(!Dlg->GetText(203, TmpTxt, TMP_TXT_SIZE)) TmpTxt[0] = 0;
if(td->text && strcmp(td->text, TmpTxt)) {
Undo.String(this, &td->text, undo_flags);
undo_flags |= UNDO_CONTINUE;
@@ -7264,9 +7628,7 @@ Axis::ssTicks()
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);
+ if(!(Dlg = new DlgRoot(TickDlg, data)))return false;
hDlg = CreateDlgWnd("choose ticks from spreadsheet", 50, 50, 330, 190, Dlg, 0x0L);
Dlg->Activate(4, true);
do{
@@ -7282,8 +7644,8 @@ Axis::ssTicks()
case 1:
if(rT) delete rT; if(rL) delete rL; if(rMT) delete rMT;
n = n1 = n2 = n3 = 0; rT = rL = rMT = 0L;
- if(Dlg->GetText(4,TmpTxt) && (rT=new AccRange(TmpTxt)) && (n1=rT->CountItems())){
- if(Dlg->GetText(6,TmpTxt) && (rL = new AccRange(TmpTxt)) &&
+ if(Dlg->GetText(4,TmpTxt, TMP_TXT_SIZE) && (rT=new AccRange(TmpTxt)) && (n1=rT->CountItems())){
+ if(Dlg->GetText(6, TmpTxt, TMP_TXT_SIZE) && (rL = new AccRange(TmpTxt)) &&
(n2 = rL->CountItems()) && n1 != n2){
ErrorBox("Ranges for tick values\nand tick labels must"
" have\nthe same size");
@@ -7291,7 +7653,7 @@ Axis::ssTicks()
break;
}
}
- if(Dlg->GetText(8,TmpTxt) && (rMT=new AccRange(TmpTxt)) && (n3=rMT->CountItems())){
+ if(Dlg->GetText(8,TmpTxt,TMP_TXT_SIZE) && (rMT=new AccRange(TmpTxt)) && (n3=rMT->CountItems())){
//minor ticks are valid
}
if(!(n = n1 + n3)) {
@@ -7304,9 +7666,12 @@ Axis::ssTicks()
if(n1) {
if(ssMATval) free(ssMATval); if(ssMATlbl) free(ssMATlbl);
if(ssMITval) free(ssMITval); ssMATval = ssMATlbl = ssMITval = 0L;
- if(Dlg->GetText(4, TmpTxt))ssMATval = strdup(TmpTxt);
- if(Dlg->GetText(6, TmpTxt))ssMATlbl = strdup(TmpTxt);
- if(Dlg->GetText(8, TmpTxt))ssMITval = strdup(TmpTxt);
+ if(Dlg->GetText(4, TmpTxt, TMP_TXT_SIZE))
+ ssMATval = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
+ if(Dlg->GetText(6, TmpTxt, TMP_TXT_SIZE))
+ ssMATlbl = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
+ if(Dlg->GetText(8, TmpTxt, TMP_TXT_SIZE))
+ ssMITval = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
UpdateTicks();
}
bRet = true;
@@ -7366,7 +7731,7 @@ Axis::PropertyDlg()
{122, 123, 0, 0x0L, EDVAL1, &sizAxLine, 37, 128, 25, 10},
{123, 124, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 63, 128, 10, 8},
{124, 125, 0, 0x0L, RTEXT, (void*)"color", 82, 128, 25, 8},
- {125, 130, 0, OWNDIALOG, COLBUTTON, (void *)colAxis, 109, 128, 25, 10},
+ {125, 130, 0, OWNDIALOG, COLBUTT, (void *)&colAxis, 109, 128, 25, 10},
{130, 0, 131, ISPARENT | CHECKED, GROUPBOX, (void*)" axis label ", 10, 149, 138, 20},
{131, 0, 0, 0x0L, EDTEXT, (void*)"abc", 15, 154, 128, 10},
{180, 0, 181, HIDDEN | ISPARENT | CHECKED, GROUPBOX, (void*)" placement ", 10, 72, 138, 45},
@@ -7445,20 +7810,20 @@ Axis::PropertyDlg()
if(!scp || !(names = (char**)calloc(res+2, sizeof(char*))) ||
!(somePlots = (GraphObj**)calloc(res+2, sizeof(GraphObj*))))
return false;
- names[j=0] = strdup("[unchanged]");
+ if(names[0] = (char*)malloc(15 * sizeof(char))) rlp_strcpy(names[0], 15, "[unchanged]");
for(i = 0, j = 1; i < res; i++) {
if(scp[i] && scp[i]->name){
- names[j] = strdup(scp[i]->name);
+ names[j] = (char*)memdup(scp[i]->name, (int)strlen(scp[i]->name)+1, 0);
somePlots[j++] = scp[i];
}
}
}
else {
- names = (char**)calloc(2, sizeof(char*));
- names[0] = strdup("n.a.");
+ names = (char**)calloc(2, sizeof(char*)); names[0] = (char*)malloc(10*sizeof(char));
+ rlp_strcpy(names[0], 10, "n.a.");
}
OD_axisplot(OD_ACCEPT, 0L, 0L, 0L, names, 0);
- if(!(Dlg = new DlgRoot(AxisDlg)))return false;
+ if(!(Dlg = new DlgRoot(AxisDlg, data)))return false;
if(names && somePlots) Dlg->ShowItem(8, true); //show tab
if(axis->breaks && axis->nBreaks) {
if(!(brks = (lfPOINT*)calloc(axis->nBreaks+2, sizeof(lfPOINT)))) return false;
@@ -7533,7 +7898,7 @@ Axis::PropertyDlg()
TmpTxt[0] = 0;
axisLabel->Command(CMD_GETTEXT, TmpTxt, 0L);
Dlg->SetText(131,TmpTxt);
- old_Label = strdup(TmpTxt);
+ old_Label = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
if(axisLabel->Id == GO_MLABEL) Dlg->Activate(131, false);
}
else Dlg->SetText(131, 0L);
@@ -7561,7 +7926,8 @@ Axis::PropertyDlg()
Dlg->GetValue(182, &old_a.Center.fx); Dlg->GetValue(185, &old_a.Center.fy);
Dlg->GetValue(188, &old_a.Radius);
memcpy(&new_a, &old_a, sizeof(AxisDEF));
- sprintf(TmpTxt, "%sxis properties", type_txt);
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, type_txt);
+ rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, "xis properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 436, 384, Dlg, 0x0L);
switch(axis->flags & 0x70) {
case AXIS_LEFT:
@@ -7576,7 +7942,11 @@ Axis::PropertyDlg()
do{
if(upd_brk) {
Dlg->ShowItem(453, cbrk > 0);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "break # %d/%d", cbrk+1, nbrk+1);
+#else
sprintf(TmpTxt,"break # %d/%d", cbrk+1, nbrk+1);
+#endif
Dlg->SetText(451, TmpTxt);
upd_brk = false;
}
@@ -7802,16 +8172,17 @@ Axis::PropertyDlg()
}
if(Dlg->GetValue(122, &tmp))
undo_flags = CheckNewFloat(&sizAxLine, sizAxLine, tmp, this, undo_flags);
- if(Dlg->GetText(131, TmpTxt) && TmpTxt[0]) {
+ if(Dlg->GetText(131, TmpTxt, TMP_TXT_SIZE) && TmpTxt[0]) {
if(old_Label && strcmp(old_Label,TmpTxt) && axisLabel->Id == GO_LABEL){
lb_def = ((Label*)axisLabel)->GetTextDef();
Undo.String(axisLabel, &lb_def->text, undo_flags);
if(lb_def->text) free(lb_def->text);
- lb_def->text = strdup(TmpTxt); undo_flags |= UNDO_CONTINUE;
+ lb_def->text = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
+ undo_flags |= UNDO_CONTINUE;
}
else if(!axisLabel) {
label_def.ColTxt = colAxis; label_def.ColBg = 0x00ffffffL;
- label_def.fSize = defs.GetSize(SIZE_TICK_LABELS)*1.2;
+ label_def.fSize = DefSize(SIZE_TICK_LABELS)*1.2;
label_def.RotBL = fabs(si)>0.80 ? 90.0 : 0.0;
label_def.RotCHAR = 0.0f; label_def.iSize = 0;
label_def.Align = TXA_VCENTER | TXA_HCENTER;
@@ -7914,7 +8285,7 @@ Graph::AddPlot(int family)
InfoBox("Don\'t know how to\nadd a plot to the\ncurrent graph.");
return false;
}
- Dlg = new DlgRoot(GraphDlg);
+ Dlg = new DlgRoot(GraphDlg, data);
hDlg = CreateDlgWnd("Add Plot", 50, 50, 410, 240, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -7938,7 +8309,7 @@ Graph::AddPlot(int family)
else if(Dlg->GetCheck(523)) p = new PlotScatt(this, data, 0x04);
else if(Dlg->GetCheck(526)) p = new Regression(this, data);
else if(Dlg->GetCheck(528)) p = new DensDisp(this, data);
- else if(Dlg->GetCheck(529)) p = new Function(this, data);
+ else if(Dlg->GetCheck(529)) p = new Function(this, data, "Function");
else if(Dlg->GetCheck(530)) p = new FitFunc(this, data);
else if(Dlg->GetCheck(531)) p = new MultiLines(this, data);
else if(Dlg->GetCheck(532)) p = new xyStat(this, data);
@@ -8067,7 +8438,7 @@ Graph::PropertyDlg()
ODtickstyle = tickstyle;
AxisTempl = 0;
if(!parent) return false;
- Dlg = new DlgRoot(GraphDlg);
+ Dlg = new DlgRoot(GraphDlg, data);
Dlg->SetCheck(410 + AxisTempl3D, 0L, true);
if(parent->Id != GO_PAGE) {
Dlg->Activate(202, false); Dlg->Activate(204, false);
@@ -8193,7 +8564,7 @@ Graph::PropertyDlg()
else if(Dlg->GetCheck(526)) p = new Regression(this, data);
else if(Dlg->GetCheck(527)) p = new PolarPlot(this, data);
else if(Dlg->GetCheck(528)) p = new DensDisp(this, data);
- else if(Dlg->GetCheck(529)) p = new Function(this, data);
+ else if(Dlg->GetCheck(529)) p = new Function(this, data, "Function");
else if(Dlg->GetCheck(530)) p = new FitFunc(this, data);
else if(Dlg->GetCheck(531)) p = new MultiLines(this, data);
else if(Dlg->GetCheck(532)) p = new xyStat(this, data);
@@ -8255,15 +8626,15 @@ Graph::Configure()
{50, 0, 600, ISPARENT | CHECKED | HIDDEN, GROUP, 0L, 0, 0, 0, 0},
{100, 101, 0, 0x0L, LTEXT, (void*)"bounding rectangle", 20, 30, 60, 8},
{101, 102, 0, 0x0L, RTEXT, (void*)"fill color", 15, 42, 58, 8},
- {102, 103, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)ColGR, 74, 42, 25, 10},
+ {102, 103, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&ColGR, 74, 42, 25, 10},
{103, 104, 0, 0x0L, RTEXT, (void*)"outline color", 15, 54, 58, 8},
- {104, 105, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)ColGRL, 74, 54, 25, 10},
+ {104, 105, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&ColGRL, 74, 54, 25, 10},
{105, 106, 0, 0x0L, LTEXT, (void*)"plotting rectangle", 20, 68, 60, 8},
{106, 107, 0, 0x0L, RTEXT, (void*)"fill color", 15, 80, 58, 8},
- {107, 108, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)ColDR, 74, 80, 25, 10},
+ {107, 108, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&ColDR, 74, 80, 25, 10},
{108, 109, 0, 0x0L, LTEXT, (void*)"axes, ticks, and axis labels", 20, 94, 60, 8},
{109, 110, 0, 0x0L, RTEXT, (void*)"axis color", 15, 106, 58, 8},
- {110, 0, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)ColAX, 74, 106, 25, 10},
+ {110, 0, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&ColAX, 74, 106, 25, 10},
{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},
@@ -8298,13 +8669,14 @@ Graph::Configure()
bool bRet = false, bContinue = false;
fRECT o_gr, n_gr, o_dr, n_dr;
- if(!(Dlg = new DlgRoot(GraphDlg)))return false;
+ if(!(Dlg = new DlgRoot(GraphDlg, data)))return false;
Dlg->GetValue(202, &o_gr.Xmin); Dlg->GetValue(204, &o_gr.Ymin);
Dlg->GetValue(207, &o_gr.Xmax); Dlg->GetValue(209, &o_gr.Ymax);
Dlg->GetValue(213, &o_dr.Xmin); Dlg->GetValue(215, &o_dr.Ymin);
Dlg->GetValue(218, &o_dr.Xmax); Dlg->GetValue(220, &o_dr.Ymax);
if(parent && parent->Id == GO_PAGE) Dlg->ShowItem(50, true);
- sprintf(TmpTxt, "%s properties", name ? name : "Graph");
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, name ? name : (char*)"Graph");
+ rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, (char*)" properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 450, 300, Dlg, 0x0L);
do{
LoopDlgWnd(); res = Dlg->GetResult();
@@ -8433,7 +8805,7 @@ static char *AddAxisTmpl =
"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"
+ "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"
@@ -8454,7 +8826,7 @@ Graph::AddAxis()
TabSHEET tab2 = {25, 52, 10, "Style"};
TabSHEET tab3 = {52, 78, 10, "Plots"};
AxisDEF axis;
- double sizAxLine = defs.GetSize(SIZE_AXIS_LINE);
+ double sizAxLine = DefSize(SIZE_AXIS_LINE);
DWORD colAxis = ColAX;
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",
@@ -8479,10 +8851,10 @@ Graph::AddAxis()
if(!(names = (char**)calloc(nscp+2, sizeof(char*))))return false;
if(!(somePlots = (GraphObj**)calloc(nscp+2, sizeof(GraphObj*))))return false;
if(!Axes) Axes = (Axis**)calloc(2, sizeof(Axis*));
- names[j=0] = strdup("[none]");
+ if(names[0] = (char*)malloc(10)) rlp_strcpy(names[0], 10, "[none]");
for(i = 0, j = 1; i < nscp; i++) {
if(Sc_Plots[i] && Sc_Plots[i]->name){
- names[j] = strdup(Sc_Plots[i]->name);
+ names[j] = (char*)memdup(Sc_Plots[i]->name, (int)strlen(Sc_Plots[i]->name)+1, 0);
somePlots[j++] = Sc_Plots[i];
}
}
@@ -8493,11 +8865,11 @@ Graph::AddAxis()
axis.min = y_axis.min; axis.max = y_axis.max;
hy1 = hy2 = (DRect.Ymax + DRect.Ymin)/2.0;
hx1 = DRect.Xmin; hx2 = DRect.Xmax;
- if(!(Dlg = new DlgRoot(NewAxisDlg)))return false;
+ if(!(Dlg = new DlgRoot(NewAxisDlg, data)))return false;
if(type != 1 || !nscp){ //must be standard graph to link to plot
Dlg->ShowItem(6, false);
}
- hDlg = CreateDlgWnd("New axis properties", 50, 50, 400, 314, Dlg, 0x0L);
+ hDlg = CreateDlgWnd("New axis properties", 50, 50, 400, 318, Dlg, 0x0L);
do{
LoopDlgWnd();
res = Dlg->GetResult();
@@ -8509,31 +8881,25 @@ Graph::AddAxis()
case 201: case 202: case 203: case 204: //axis templates
case 205: case 206: case 207: case 208:
if(currTempl > 204) {
- Dlg->GetValue(221, &hx1); Dlg->GetValue(223, &hx2);
- Dlg->GetValue(226, &hy1); Dlg->GetValue(228, &hy2);
+ Dlg->GetValue(221, &hx1); Dlg->GetValue(223, &hx2);
+ Dlg->GetValue(226, &hy1); Dlg->GetValue(228, &hy2);
}
else {
- Dlg->GetValue(221, &vx1); Dlg->GetValue(223, &vx2);
- Dlg->GetValue(226, &vy1); Dlg->GetValue(228, &vy2);
+ Dlg->GetValue(221, &vx1); Dlg->GetValue(223, &vx2);
+ Dlg->GetValue(226, &vy1); Dlg->GetValue(228, &vy2);
}
if(res > 204) {
- WriteFloatToBuff(TmpTxt, hx1); Dlg->SetText(221, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, hx2); Dlg->SetText(223, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, hy1); Dlg->SetText(226, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, hy2); Dlg->SetText(228, TmpTxt+1);
+ Dlg->SetValue(221, hx1); Dlg->SetValue(223, hx2);
+ Dlg->SetValue(226, hy1); Dlg->SetValue(228, hy2);
if(! bAxis) {
- WriteFloatToBuff(TmpTxt, x_axis.min); Dlg->SetText(101, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, x_axis.max); Dlg->SetText(103, TmpTxt+1);
+ Dlg->SetValue(101, x_axis.min); Dlg->SetValue(103, x_axis.max);
}
}
else {
- WriteFloatToBuff(TmpTxt, vx1); Dlg->SetText(221, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, vx2); Dlg->SetText(223, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, vy1); Dlg->SetText(226, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, vy2); Dlg->SetText(228, TmpTxt+1);
+ Dlg->SetValue(221, vx1); Dlg->SetValue(223, vx2);
+ Dlg->SetValue(226, vy1); Dlg->SetValue(228, vy2);
if(! bAxis) {
- WriteFloatToBuff(TmpTxt, y_axis.min); Dlg->SetText(101, TmpTxt+1);
- WriteFloatToBuff(TmpTxt, y_axis.max); Dlg->SetText(103, TmpTxt+1);
+ Dlg->SetValue(101, y_axis.min); Dlg->SetValue(103, y_axis.max);
}
}
currTempl = res;
@@ -8551,15 +8917,15 @@ Graph::AddAxis()
Dlg->GetValue(101, &axis.min); Dlg->GetValue(103, &axis.max);
axis.Start = axis.min; axis.Center.fx = axis.Center.fy = 0.0;
axis.nBreaks = 0; axis.breaks = 0L; axis.Radius = 0.0;
- tlb_dist = NiceValue(defs.GetSize(SIZE_AXIS_TICKS));
+ tlb_dist = NiceValue(DefSize(SIZE_AXIS_TICKS));
tlb_dx = tlb_dy = 0.0;
tlbdef.ColTxt = colAxis; tlbdef.ColBg = 0x00ffffffL;
- tlbdef.RotBL = tlbdef.RotCHAR = 0.0f; tlbdef.fSize = defs.GetSize(SIZE_TICK_LABELS);
+ tlbdef.RotBL = tlbdef.RotCHAR = 0.0f; tlbdef.fSize = DefSize(SIZE_TICK_LABELS);
tlbdef.Align = TXA_VCENTER | TXA_HCENTER;
tlbdef.Style = TXS_NORMAL; tlbdef.Mode = TXM_TRANSPARENT;
tlbdef.Font = FONT_HELVETICA; tlbdef.text = 0L;
label_def.ColTxt = colAxis; label_def.ColBg = 0x00ffffffL;
- label_def.fSize = defs.GetSize(SIZE_TICK_LABELS)*1.2f; label_def.RotBL = 0.0f;
+ label_def.fSize = DefSize(SIZE_TICK_LABELS)*1.2f; label_def.RotBL = 0.0f;
label_def.RotCHAR = 0.0f; label_def.iSize = 0;
label_def.Align = TXA_VTOP | TXA_HCENTER; label_def.Mode = TXM_TRANSPARENT;
label_def.Style = TXS_NORMAL; label_def.Font = FONT_HELVETICA;
@@ -8609,7 +8975,7 @@ Graph::AddAxis()
the_new->SetColor(COL_AXIS, colAxis);
the_new->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
the_new->SetSize(SIZE_LB_XDIST, lb_x); the_new->SetSize(SIZE_LB_YDIST, lb_y);
- if(Dlg->GetText(131, TmpTxt)) label_def.text = TmpTxt;
+ if(Dlg->GetText(131, TmpTxt, TMP_TXT_SIZE)) label_def.text = TmpTxt;
else label_def.text = 0L;
if(label = new Label(Axes[0], data, (axis.loc[0].fx + axis.loc[1].fx)/2.0,
(axis.loc[0].fy + axis.loc[1].fy)/2.0, &label_def,
@@ -8662,12 +9028,14 @@ Page::Configure()
{100, 0, 0, LASTOBJ | NOSELECT, ODBUTTON, (void*)OD_paperdef, 15, 30, 110, 140}};
DlgRoot *Dlg;
void *hDlg;
- int res;
+ int res, cb;
bool bRet = false, bContinue = false;
FindPaper(GRect.Xmax - GRect.Xmin, GRect.Ymax -GRect.Ymin, .0001);
- if(!(Dlg = new DlgRoot(PageDlg)))return false;
- sprintf(TmpTxt, "%s properties", name ? name : "Page");
+ if(!(Dlg = new DlgRoot(PageDlg, data)))return false;
+ if(name)cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, name);
+ else cb = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Page");
+ rlp_strcpy(TmpTxt+cb, TMP_TXT_SIZE - cb, " properties");
hDlg = CreateDlgWnd(TmpTxt, 50, 50, 380, 300, Dlg, 0x0L);
do{
LoopDlgWnd();
@@ -8749,7 +9117,7 @@ Default::PropertyDlg()
{422, 0, 0, LASTOBJ, RADIO1, (void*)Units[2].display, 75, 91, 20, 8}};
DlgRoot *Dlg;
void *hDlg;
- int i, res, tmpUnits = cUnits;
+ int i, cb, res, tmpUnits = cUnits;
bool bRet = false, bContinue = false;
double dt;
LineDEF LineDef;
@@ -8758,13 +9126,18 @@ Default::PropertyDlg()
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;
+ cb = rlp_strcpy(dt_info, 20, "today is ");
+#ifdef USE_WIN_SECURE
+ ctime_s(dt_info+cb, 50-cb, &ti);
+#else
+ rlp_strcpy(dt_info+cb, 50-cb, ctime(&ti));
+#endif
+ dt_info[cb+24] = 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);
+ rlp_strcpy(date_info, 50, value_date(dt, defs.fmt_date));
+ rlp_strcpy(datetime_info, 50, value_date(dt, defs.fmt_datetime));
+ rlp_strcpy(time_info, 50, value_date(dt, defs.fmt_time));
+ Dlg = new DlgRoot(DefsDlg, 0L);
switch(dUnits) {
case 1: Dlg->SetCheck(421, 0L, true); break;
case 2: Dlg->SetCheck(422, 0L, true); break;
@@ -8783,17 +9156,21 @@ Default::PropertyDlg()
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);
+ case 362: //update date/time display
+ ti = time(0L); cb = rlp_strcpy(dt_info, 20, "today is ");
+#ifdef USE_WIN_SECURE
+ ctime_s(dt_info+cb, 50-cb, &ti);
+#else
+ rlp_strcpy(dt_info+cb, 50-cb, ctime(&ti));
+#endif
+ dt_info[cb+24] = 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);
+ if(!(Dlg->GetText(352, date_info, 50))) rlp_strcpy(date_info, 50, defs.fmt_date);
+ rlp_strcpy(date_info, 50, value_date(dt, date_info)); Dlg->SetText(353, date_info);
+ if(!(Dlg->GetText(355, datetime_info, 50))) rlp_strcpy(datetime_info, 50, defs.fmt_datetime);
+ rlp_strcpy(datetime_info, 50, value_date(dt, datetime_info)); Dlg->SetText(356, datetime_info);
+ if(!(Dlg->GetText(358, time_info, 50))) rlp_strcpy(time_info, 50, defs.fmt_time);
+ rlp_strcpy(time_info, 50, value_date(dt, time_info)); Dlg->SetText(359, time_info);
bContinue = false; res = -1;
break;
case 361: //call browser
@@ -8812,8 +9189,8 @@ Default::PropertyDlg()
}
}while (res < 0);
if(res == 1) {
- if(Dlg->GetText(402, TmpTxt)) DecPoint[0] = TmpTxt[0];
- if(Dlg->GetText(404, TmpTxt)) ColSep[0] = TmpTxt[0];
+ if(Dlg->GetText(402, TmpTxt, TMP_TXT_SIZE)) DecPoint[0] = TmpTxt[0];
+ if(Dlg->GetText(404, TmpTxt, TMP_TXT_SIZE)) ColSep[0] = TmpTxt[0];
OD_linedef(OD_GETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
SetLine(tmpUnits, &LineDef, 0);
OD_filldef(OD_GETLINE, 0L, 0L, 0L, (void *)&LineDef, 0);
@@ -8821,17 +9198,17 @@ 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(352, date_info, 50) && date_info[0] && strcmp(date_info, defs.fmt_date)) {
+ if(defs.fmt_date = (char*)realloc(defs.fmt_date, (cb = (int)strlen(date_info) +2)))
+ rlp_strcpy(defs.fmt_date, cb, 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(355, datetime_info, 50) && datetime_info[0] && strcmp(datetime_info, defs.fmt_datetime)) {
+ if(defs.fmt_datetime = (char*)realloc(defs.fmt_datetime, (cb = (int)strlen(datetime_info) +2)))
+ rlp_strcpy(defs.fmt_datetime, cb, 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);
+ if(Dlg->GetText(358, time_info, 50) && time_info[0] && strcmp(time_info, defs.fmt_time)) {
+ if(defs.fmt_time = (char*)realloc(defs.fmt_time, (cb = (int)strlen(time_info) +2)))
+ rlp_strcpy(defs.fmt_time, cb, time_info);
}
bRet = true;
}
diff --git a/QT_Spec.cpp b/QT_Spec.cpp
index c3eb457..8623c1c 100755
--- a/QT_Spec.cpp
+++ b/QT_Spec.cpp
@@ -1,183 +1,195 @@
-//QT_Spec.cpp, Copyright (c) 2001-2006 R.Lackner
-//
-// This file is part of RLPlot.
-//
-// RLPlot is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// RLPlot is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with RLPlot; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-#include <qmessagebox.h>
-#include <qpixmap.h>
-#include <qapplication.h>
-#include <qnamespace.h>
-#include <qfiledialog.h>
-#include <qpaintdevicemetrics.h>
-#include <qimage.h>
-#include <qcursor.h>
-#include <qcstring.h>
-#include <qclipboard.h>
-#include <qbuffer.h>
+//QT_Spec.cpp, Copyright (c) 2001-2006 R.Lackner
+//
+// This file is part of RLPlot.
+//
+// RLPlot is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// RLPlot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RLPlot; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#include <qmessagebox.h>
+#include <qpixmap.h>
+#include <qapplication.h>
+#include <qnamespace.h>
+#include <qfiledialog.h>
+#include <qpaintdevicemetrics.h>
+#include <qimage.h>
+#include <qcursor.h>
+#include <qcstring.h>
+#include <qclipboard.h>
+#include <qbuffer.h>
#include <qbitmap.h>
-#include <qtextstream.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
+#include <qtextstream.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
#include "QT_Spec.h"
#include "menu.h"
-extern tag_Units Units[];
-extern GraphObj *CurrGO; //Selected Graphic Objects
-extern Graph *CurrGraph;
-extern char *WWWbrowser;
-extern char *LoadFile; //command line argument
-extern char TmpTxt[];
-extern Default defs;
+extern tag_Units Units[];
+extern GraphObj *CurrGO; //Selected Graphic Objects
+extern Graph *CurrGraph;
+extern char *WWWbrowser;
+extern char *LoadFile; //command line argument
+extern char TmpTxt[];
+extern Default defs;
extern UndoObj Undo;
-
-QApplication *QAppl;
-QWidget *MainWidget =0L;
-POINT CurrWidgetPos = {0,0};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Exute a file open dialog for the different situations
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-static char UserFileName[600];
-// Get a new file name to store data in
-char *SaveDataAsName(char *oldname)
+
+QApplication *QAppl;
+QWidget *MainWidget =0L;
+POINT CurrWidgetPos = {0,0};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Exute a file open dialog for the different situations
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char UserFileName[600];
+// Get a new file name to store data in
+char *SaveDataAsName(char *oldname)
{
QFileDialog qf(0,0,true);
QString filters("RLPlot workbook (*.rlw);;data files (*.csv);;"
"tab separated (*.tsv);;XML (*.xml)");
+ int i, cb;
+ char *ext;
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());
+ cb = rlp_strcpy(UserFileName, 600, (char*)qf.selectedFile().ascii());
+ if(cb < 4 || UserFileName[cb-4] != '.'){
+ ext = (char*)qf.selectedFilter().ascii();
+ for(i = 0; ext[i] && ext[i] != '*'; i++);
+ rlp_strcpy(UserFileName+cb, 5, ext+i+1);
+ }
defs.FileHistory(UserFileName);
return UserFileName;
}
}
return 0L;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Get a new file name to store graph
-char *SaveGraphAsName(char *oldname)
-{
- QString fileName = QFileDialog::getSaveFileName(oldname?oldname:defs.currPath,
- "RLPlot files (*.rlp)", QAppl->focusWidget());
- if(!fileName.isEmpty()){
- strcpy(UserFileName, fileName);
- defs.FileHistory(UserFileName);
- return UserFileName;
- }
- return 0L;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Get file name to read graph
-char *OpenGraphName(char *oldname)
-{
- QString fileName = QFileDialog::getOpenFileName(oldname?oldname:defs.currPath,
- "RLPlot files (*.rlp)", QAppl->focusWidget());
- if(!fileName.isEmpty()){
- strcpy(UserFileName, fileName);
- defs.FileHistory(UserFileName);
- return UserFileName;
- }
- return 0L;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Get a file name to load data
-char *OpenDataName(char *oldname)
-{
- QString fileName = QFileDialog::getOpenFileName(oldname?oldname:defs.currPath,
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Get a new file name to store graph
+char *SaveGraphAsName(char *oldname)
+{
+ QString fileName = QFileDialog::getSaveFileName(oldname?oldname:defs.currPath,
+ "RLPlot files (*.rlp)", QAppl->focusWidget());
+ if(!fileName.isEmpty()){
+ strcpy(UserFileName, fileName);
+ defs.FileHistory(UserFileName);
+ return UserFileName;
+ }
+ return 0L;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Get file name to read graph
+char *OpenGraphName(char *oldname)
+{
+ QString fileName = QFileDialog::getOpenFileName(oldname?oldname:defs.currPath,
+ "RLPlot files (*.rlp)", QAppl->focusWidget());
+ if(!fileName.isEmpty()){
+ strcpy(UserFileName, fileName);
+ defs.FileHistory(UserFileName);
+ return UserFileName;
+ }
+ return 0L;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Get a file name to load data
+char *OpenDataName(char *oldname)
+{
+ QString fileName = QFileDialog::getOpenFileName(oldname?oldname:defs.currPath,
"RLPlot workbook (*.rlw)\ndata files (*.csv)\ntab separated file (*.tsv)\n"
- "RLPlot files (*.rlp)\nall files (*.*)", QAppl->focusWidget());
- if(!fileName.isEmpty()){
- strcpy(UserFileName, fileName);
- defs.FileHistory(UserFileName);
- return UserFileName;
- }
- return 0L;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Get a file name to export graph
-void OpenExportName(GraphObj *g, char *oldname)
-{
- int i;
- PrintQT *out=0L;
-
- if (!g) return;
- QString fileName = QFileDialog::getSaveFileName(oldname?oldname:defs.currPath,
- "Scalable Vector Graphics (*.svg)\nEncapsulated Post Script (*.eps)\n"
- "MSWindows MetaFile (*.wmf)\nTag Image File Format(*.tif *.tiff)",
- QAppl->focusWidget());
- if(!fileName.isEmpty()){
- strcpy(UserFileName, fileName);
- i = strlen(UserFileName);
- g->Command(CMD_BUSY, 0L, 0L);
- if(0==strcasecmp(".svg", UserFileName+i-4)) {
- DoExportSvg(g, UserFileName, 0L);
- }
- else if(0==strcasecmp(".wmf", UserFileName+i-4)) {
- DoExportWmf(g, UserFileName, 600.0f, 0L);
- }
- else if(0==strcasecmp(".eps", UserFileName+i-4)) {
- DoExportEps(g, UserFileName, 0L);
- }
- else if(0==strcasecmp(".tif", UserFileName+i-4)) {
- DoExportTif(g, UserFileName, 0L);
- }
- else if(0==strcasecmp(".tiff", UserFileName+i-5)) {
- DoExportTif(g, UserFileName, 0L);
- }
- else ErrorBox("Unknown file extension or format");
- g->Command(CMD_MOUSECURSOR, 0L, 0L);
- }
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Common alert boxes
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-void InfoBox(char *Msg)
+ "RLPlot files (*.rlp)\nall files (*.*)", QAppl->focusWidget());
+ if(!fileName.isEmpty()){
+ strcpy(UserFileName, fileName);
+ defs.FileHistory(UserFileName);
+ return UserFileName;
+ }
+ return 0L;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Get a file name to export graph
+void OpenExportName(GraphObj *g, char *oldname)
+{
+ int i;
+ PrintQT *out=0L;
+
+ if (!g) return;
+ QString fileName = QFileDialog::getSaveFileName(oldname?oldname:defs.currPath,
+ "Scalable Vector Graphics (*.svg)\nEncapsulated Post Script (*.eps)\n"
+ "MSWindows MetaFile (*.wmf)\nTag Image File Format(*.tif *.tiff)",
+ QAppl->focusWidget());
+ if(!fileName.isEmpty()){
+ strcpy(UserFileName, fileName);
+ i = strlen(UserFileName);
+ g->Command(CMD_BUSY, 0L, 0L);
+ if(0==strcasecmp(".svg", UserFileName+i-4)) {
+ DoExportSvg(g, UserFileName, 0L);
+ }
+ else if(0==strcasecmp(".wmf", UserFileName+i-4)) {
+ DoExportWmf(g, UserFileName, 600.0f, 0L);
+ }
+ else if(0==strcasecmp(".eps", UserFileName+i-4)) {
+ DoExportEps(g, UserFileName, 0L);
+ }
+ else if(0==strcasecmp(".tif", UserFileName+i-4)) {
+ DoExportTif(g, UserFileName, 0L);
+ }
+ else if(0==strcasecmp(".tiff", UserFileName+i-5)) {
+ DoExportTif(g, UserFileName, 0L);
+ }
+ else ErrorBox("Unknown file extension or format");
+ g->Command(CMD_MOUSECURSOR, 0L, 0L);
+ }
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Common alert boxes
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char the_message[500];
+void InfoBox(char *Msg)
{
QMessageBox::information(QAppl->focusWidget(), "Info", Msg);
}
-
-void ErrorBox(char *Msg)
-{
- QMessageBox::critical(QAppl->focusWidget(), "ERROR", Msg);
-}
-
-bool YesNoBox(char *Msg)
-{
- if(QMessageBox::information(QAppl->focusWidget(), "RLPlot", Msg,
- "&Yes", "&No", 0L, 0, -1)) return false;
- return true;
-}
-
+
+void ErrorBox(char *Msg)
+{
+ QMessageBox::critical(QAppl->focusWidget(), "ERROR", Msg);
+}
+
+bool YesNoBox(char *Msg)
+{
+ int cb;
+
+ cb = rlp_strcpy(the_message, 450, Msg);
+ rlp_strcpy(the_message+cb, 500-cb, "\n");
+ if(QMessageBox::information(QAppl->focusWidget(), "RLPlot", the_message,
+ "&Yes", "&No", 0L, 0, -1)) return false;
+ return true;
+}
+
int YesNoCancelBox(char *Msg)
{
- int res;
+ int res, cb;
- res = QMessageBox::information(QAppl->focusWidget(), "RLPlot", Msg,
+ cb = rlp_strcpy(the_message, 450, Msg);
+ rlp_strcpy(the_message+cb, 500-cb, "\n");
+ res = QMessageBox::information(QAppl->focusWidget(), "RLPlot", the_message,
"&Yes", "&No", "&Cancel", 0, -1);
switch(res) {
case 0: return 1;
@@ -186,148 +198,148 @@ int YesNoCancelBox(char *Msg)
}
return 0;
}
-
-void Qt_Box()
-{
- QMessageBox::aboutQt(QAppl->focusWidget(), "RLPlot uses Qt");
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Display blinking text cursor
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-anyOutput *oTxtCur = 0L;
-RECT rTxtCur, rCopyMark;
-bool bTxtCur = false;
-DWORD coTxtCur = 0x0L;
-TxtCurBlink *cTxtCur = 0L;
-POINT ptTxtCurLine[2];
-
-void HideTextCursor()
-{
- if(oTxtCur) {
- bTxtCur = false;
- oTxtCur->UpdateRect(&rTxtCur, false);
- }
- oTxtCur = 0L;
-}
-
-void HideTextCursorObj(anyOutput *out)
-{
- if(oTxtCur && oTxtCur == out) HideTextCursor();
-}
-
-void ShowTextCursor(anyOutput *out, RECT *disp, DWORD color)
-{
- coTxtCur = color;
- HideTextCursor();
- oTxtCur = out;
- memcpy(&rTxtCur, disp, sizeof(RECT));
- ptTxtCurLine[0].x = rTxtCur.left; ptTxtCurLine[0].y = rTxtCur.top;
- ptTxtCurLine[1].x = rTxtCur.right; ptTxtCurLine[1].y = rTxtCur.bottom;
- rTxtCur.bottom++; rTxtCur.right++;
- bTxtCur = true;
- if(cTxtCur) cTxtCur->Show();
-}
-
-void InitTextCursor(bool init)
-{
- if(init && !cTxtCur) cTxtCur = new TxtCurBlink();
- else if(!init && cTxtCur) {
- delete cTxtCur;
- cTxtCur = 0L;
- }
-}
-
-void HideCopyMark()
-{
- if(cTxtCur && cTxtCur->bmCopyMark && cTxtCur->oCopyMark) {
- cTxtCur->oCopyMark->UpdateRect(&rCopyMark, false);
- delete cTxtCur->bmCopyMark;
- }
- cTxtCur->bmCopyMark = 0L; cTxtCur->oCopyMark = 0L;
-}
-
-void ShowCopyMark(anyOutput *out, RECT *mrk, int nRec)
-{
- int i;
-
- if(!out || !mrk || !nRec || !cTxtCur) return;
- cTxtCur->oCopyMark = out;
- rCopyMark.left = mrk[0].left; rCopyMark.right = mrk[0].right;
- rCopyMark.top = mrk[0].top; rCopyMark.bottom = mrk[0].bottom;
- for(i = 1; i < nRec; i++) {
- UpdateMinMaxRect(&rCopyMark, mrk[i].left, mrk[i].top);
- UpdateMinMaxRect(&rCopyMark, mrk[i].right, mrk[i].bottom);
- }
- cTxtCur->bmCopyMark = new BitMapQT(rCopyMark.right - rCopyMark.left+1,
- rCopyMark.bottom - rCopyMark.top+1, out->hres, out->vres);
-}
-
-LineDEF liCopyMark1 = {0.0f, 1.0f, 0x00ffffffL, 0L};
-LineDEF liCopyMark2 = {0.0f, 6.0f, 0x0L, 0xf0f0f0f0L};
-
-TxtCurBlink::TxtCurBlink():QObject(MainWidget, 0)
-{
- isVis = false;
- oCopyMark = 0L; bmCopyMark = 0L;
- count = cp_mark = 0;
- startTimer(60);
-}
-
-void
-TxtCurBlink::Show()
-{
- count = -4;
- isVis = true;
- if(bTxtCur && oTxtCur)oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
-
-}
-
-void
-TxtCurBlink::showCopyMark()
-{
- if(bmCopyMark && oCopyMark) {
- bmCopyMark->CopyBitmap(0, 0, oCopyMark, rCopyMark.left, rCopyMark.top,
- rCopyMark.right - rCopyMark.left, rCopyMark.bottom - rCopyMark.top, false);
- bmCopyMark->SetLine(&liCopyMark1);
- line[0].x = line[1].x = line[4].x = 0;
- line[0].y = line[3].y = line[4].y = 0;
- line[1].y = line[2].y = rCopyMark.bottom-rCopyMark.top-1;
- line[2].x = line[3].x = rCopyMark.right-rCopyMark.left-1;
- bmCopyMark->oPolyline(line, 5);
- bmCopyMark->SetLine(&liCopyMark2);
- bmCopyMark->RLP.finc = 1.0; bmCopyMark->RLP.fp = (cp_mark & 0x7);
- bmCopyMark->oPolyline(line, 5);
- oCopyMark->ShowBitmap(rCopyMark.left, rCopyMark.top, bmCopyMark);
- cp_mark++;
- if(isVis && oTxtCur && ptTxtCurLine[0].y != ptTxtCurLine[1].y &&
- oTxtCur == oCopyMark && OverlapRect(&rCopyMark, &rTxtCur)){
- oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
- }
- }
-}
-
-void
-TxtCurBlink::timerEvent(QTimerEvent *ev)
-{
- showCopyMark();
- if(!oTxtCur || (ptTxtCurLine[0].x == ptTxtCurLine[1].x &&
- ptTxtCurLine[0].y == ptTxtCurLine[1].y)) return;
- count++;
- if(count<0) oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
- if(count < 8) return;
- count = 0;
- if(bTxtCur && oTxtCur) {
- if(isVis) {
- oTxtCur->UpdateRect(&rTxtCur, false);
- isVis = false;
- }
- else {
- oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
- isVis = true;
- }
- }
-}
+
+void Qt_Box()
+{
+ QMessageBox::aboutQt(QAppl->focusWidget(), "RLPlot uses Qt");
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Display blinking text cursor
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+anyOutput *oTxtCur = 0L;
+RECT rTxtCur, rCopyMark;
+bool bTxtCur = false;
+DWORD coTxtCur = 0x0L;
+TxtCurBlink *cTxtCur = 0L;
+POINT ptTxtCurLine[2];
+
+void HideTextCursor()
+{
+ if(oTxtCur) {
+ bTxtCur = false;
+ oTxtCur->UpdateRect(&rTxtCur, false);
+ }
+ oTxtCur = 0L;
+}
+
+void HideTextCursorObj(anyOutput *out)
+{
+ if(oTxtCur && oTxtCur == out) HideTextCursor();
+}
+
+void ShowTextCursor(anyOutput *out, RECT *disp, DWORD color)
+{
+ coTxtCur = color;
+ HideTextCursor();
+ oTxtCur = out;
+ memcpy(&rTxtCur, disp, sizeof(RECT));
+ ptTxtCurLine[0].x = rTxtCur.left; ptTxtCurLine[0].y = rTxtCur.top;
+ ptTxtCurLine[1].x = rTxtCur.right; ptTxtCurLine[1].y = rTxtCur.bottom;
+ rTxtCur.bottom++; rTxtCur.right++;
+ bTxtCur = true;
+ if(cTxtCur) cTxtCur->Show();
+}
+
+void InitTextCursor(bool init)
+{
+ if(init && !cTxtCur) cTxtCur = new TxtCurBlink();
+ else if(!init && cTxtCur) {
+ delete cTxtCur;
+ cTxtCur = 0L;
+ }
+}
+
+void HideCopyMark()
+{
+ if(cTxtCur && cTxtCur->bmCopyMark && cTxtCur->oCopyMark) {
+ cTxtCur->oCopyMark->UpdateRect(&rCopyMark, false);
+ delete cTxtCur->bmCopyMark;
+ }
+ cTxtCur->bmCopyMark = 0L; cTxtCur->oCopyMark = 0L;
+}
+
+void ShowCopyMark(anyOutput *out, RECT *mrk, int nRec)
+{
+ int i;
+
+ if(!out || !mrk || !nRec || !cTxtCur) return;
+ cTxtCur->oCopyMark = out;
+ rCopyMark.left = mrk[0].left; rCopyMark.right = mrk[0].right;
+ rCopyMark.top = mrk[0].top; rCopyMark.bottom = mrk[0].bottom;
+ for(i = 1; i < nRec; i++) {
+ UpdateMinMaxRect(&rCopyMark, mrk[i].left, mrk[i].top);
+ UpdateMinMaxRect(&rCopyMark, mrk[i].right, mrk[i].bottom);
+ }
+ cTxtCur->bmCopyMark = new BitMapQT(rCopyMark.right - rCopyMark.left+1,
+ rCopyMark.bottom - rCopyMark.top+1, out->hres, out->vres);
+}
+
+LineDEF liCopyMark1 = {0.0f, 1.0f, 0x00ffffffL, 0L};
+LineDEF liCopyMark2 = {0.0f, 6.0f, 0x0L, 0xf0f0f0f0L};
+
+TxtCurBlink::TxtCurBlink():QObject(MainWidget, 0)
+{
+ isVis = false;
+ oCopyMark = 0L; bmCopyMark = 0L;
+ count = cp_mark = 0;
+ startTimer(60);
+}
+
+void
+TxtCurBlink::Show()
+{
+ count = -4;
+ isVis = true;
+ if(bTxtCur && oTxtCur)oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
+
+}
+
+void
+TxtCurBlink::showCopyMark()
+{
+ if(bmCopyMark && oCopyMark) {
+ bmCopyMark->CopyBitmap(0, 0, oCopyMark, rCopyMark.left, rCopyMark.top,
+ rCopyMark.right - rCopyMark.left, rCopyMark.bottom - rCopyMark.top, false);
+ bmCopyMark->SetLine(&liCopyMark1);
+ line[0].x = line[1].x = line[4].x = 0;
+ line[0].y = line[3].y = line[4].y = 0;
+ line[1].y = line[2].y = rCopyMark.bottom-rCopyMark.top-1;
+ line[2].x = line[3].x = rCopyMark.right-rCopyMark.left-1;
+ bmCopyMark->oPolyline(line, 5);
+ bmCopyMark->SetLine(&liCopyMark2);
+ bmCopyMark->RLP.finc = 1.0; bmCopyMark->RLP.fp = (cp_mark & 0x7);
+ bmCopyMark->oPolyline(line, 5);
+ oCopyMark->ShowBitmap(rCopyMark.left, rCopyMark.top, bmCopyMark);
+ cp_mark++;
+ if(isVis && oTxtCur && ptTxtCurLine[0].y != ptTxtCurLine[1].y &&
+ oTxtCur == oCopyMark && OverlapRect(&rCopyMark, &rTxtCur)){
+ oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
+ }
+ }
+}
+
+void
+TxtCurBlink::timerEvent(QTimerEvent *ev)
+{
+ showCopyMark();
+ if(!oTxtCur || (ptTxtCurLine[0].x == ptTxtCurLine[1].x &&
+ ptTxtCurLine[0].y == ptTxtCurLine[1].y)) return;
+ count++;
+ if(count<0) oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
+ if(count < 8) return;
+ count = 0;
+ if(bTxtCur && oTxtCur) {
+ if(isVis) {
+ oTxtCur->UpdateRect(&rTxtCur, false);
+ isVis = false;
+ }
+ else {
+ oTxtCur->ShowLine(ptTxtCurLine, 2, coTxtCur);
+ isVis = true;
+ }
+ }
+}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Clipboard support: the clipboard server uses sockets
@@ -550,11 +562,11 @@ RLPserver::GetRLP()
#endif //RLP_PORT
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Process paste command: check for clipboard contents
-void TestClipboard(GraphObj *g)
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Process paste command: check for clipboard contents
+void TestClipboard(GraphObj *g)
{
- if(!g) return;
+ if(!g) return;
#ifdef RLP_PORT
if(rlpsrv && rlpsrv->SourceGO) {
if(rlpsrv->SourceGO->Id == GO_GRAPH || rlpsrv->SourceGO->Id == GO_PAGE)
@@ -564,11 +576,11 @@ void TestClipboard(GraphObj *g)
}
else new ReadCB(0, 0, g);
#endif //RLP_PORT
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Copy spreadsheet or graph to clipboard
-void CopyData(GraphObj *g)
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Copy spreadsheet or graph to clipboard
+void CopyData(GraphObj *g)
{
HideCopyMark();
QAppl->clipboard()->clear();
@@ -582,31 +594,31 @@ void CopyData(GraphObj *g)
}
else rlpsrv = new RLPserver(0, g);
#endif //RLP_PORT
-}
-
-void CopyGraph(GraphObj *g)
+}
+
+void CopyGraph(GraphObj *g)
{
if(g->Id == GO_PAGE && CurrGraph) CopyData(CurrGraph);
else CopyData(g);
-}
-
-void EmptyClip()
+}
+
+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();
- }
+// 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();
-}
+ HideCopyMark();
+ QAppl->clipboard()->clear();
+}
void CopyText(char *txt, int len)
{
@@ -645,29 +657,29 @@ unsigned char* PasteText()
}
return tmp_txt;
}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Get display (desktop) size
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-void GetDesktopSize(int *width, int *height)
-{
- QWidget *d = QApplication::desktop();
- *width = d->width();
- *height = d->height();
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Swap red and blue in RGB value
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-DWORD SwapRB(DWORD col)
-{
- DWORD nc = col & 0x0000ff00L;
-
- nc |= (col>>16)&0x000000ffL;
- nc |= (col<<16)&0x00ff0000L;
- return nc;
-}
-
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Get display (desktop) size
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void GetDesktopSize(int *width, int *height)
+{
+ QWidget *d = QApplication::desktop();
+ *width = d->width();
+ *height = d->height();
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Swap red and blue in RGB value
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+DWORD SwapRB(DWORD col)
+{
+ DWORD nc = col & 0x0000ff00L;
+
+ nc |= (col>>16)&0x000000ffL;
+ nc |= (col<<16)&0x00ff0000L;
+ return nc;
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Common code for all QT output classes
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -688,12 +700,9 @@ bool com_TextOut(int x, int y, char *ctxt, TextDEF *TxtSet, QPainter *qP, anyOut
else txt.append(QChar(ctxt[i]));
}
}
- oldBrush = qP->brush(); dxf = qP->worldMatrix();
+ oldBrush = qP->brush(); dxf = qP->worldMatrix();
oldPen = currPen = qP->pen();
- o->oGetTextExtent(ctxt, -1, &w, &h);
- if(TxtSet->Align & TXA_VCENTER) iy = y + iround(TxtSet->iSize *0.4);
- else if(TxtSet->Align & TXA_VBOTTOM) iy = y;
- else iy = y + TxtSet->iSize + 1;
+ o->oGetTextExtent(ctxt, -1, &w, &h); iy = y;
if(TxtSet->Align & TXA_HCENTER) ix = x - (w >> 1);
else if(TxtSet->Align & TXA_HRIGHT) ix = x - w;
else ix = x;
@@ -711,8 +720,8 @@ bool com_TextOut(int x, int y, char *ctxt, TextDEF *TxtSet, QPainter *qP, anyOut
currPen.setColor(SwapRB(TxtSet->ColTxt));
qP->setPen(currPen);
}
- if(TxtSet->Style & TXS_SUB) iy += o->un2iy(TxtSet->fSize*0.4);
- else if(TxtSet->Style & TXS_SUPER) iy -= o->un2iy(TxtSet->fSize*0.4);
+ if(TxtSet->Style & TXS_SUB) iy += ((TxtSet->iSize <<2)/10);
+ else if(TxtSet->Style & TXS_SUPER) iy -= ((TxtSet->iSize <<2)/10);
qP->drawText(ix-x, iy-y, txt, -1);
}
else {
@@ -728,6 +737,8 @@ bool com_TextOut(int x, int y, char *ctxt, TextDEF *TxtSet, QPainter *qP, anyOut
else if(TxtSet->Style & TXS_SUPER) iy -= o->un2iy(TxtSet->fSize*0.4);
qP->drawText(ix, iy, txt, -1);
}
+ oldPen.setCapStyle(Qt::RoundCap);
+ oldPen.setJoinStyle(Qt::RoundJoin);
qP->setPen(oldPen);
qP->setBrush(oldBrush);
qP->setWorldMatrix(dxf, FALSE);
@@ -736,23 +747,18 @@ bool com_TextOut(int x, int y, char *ctxt, TextDEF *TxtSet, QPainter *qP, anyOut
bool com_SetTextSpec(TextDEF *set, TextDEF *TxtSet, anyOutput *o, QFont qF, QPainter *qP)
{
- bool IsModified, RetVal;
+ bool RetVal;
if(!set->iSize && set->fSize > 0.0) set->iSize = o->un2iy(set->fSize);
if(!set->iSize) return false;
- if(TxtSet->iSize != set->iSize || TxtSet->Style != set->Style ||
- TxtSet->RotBL != set->RotBL || TxtSet->RotCHAR != set->RotCHAR ||
- TxtSet->Font != set->Font || TxtSet->Mode != set->Mode)
- IsModified = true;
- else IsModified = false;
RetVal = o->anyOutput::SetTextSpec(set);
- if(IsModified) {
+ if(true) {
qF.setBold((TxtSet->Style & TXS_BOLD) ? true : false);
qF.setItalic((TxtSet->Style & TXS_ITALIC) ? true : false);
qF.setUnderline((TxtSet->Style &TXS_UNDERLINE) ? true : false);
if((TxtSet->Style & TXS_SUPER) || (TxtSet->Style & TXS_SUB))
- qF.setPointSize(o->un2iy(set->fSize*0.71));
- else qF.setPointSize((TxtSet->iSize > 8) ? TxtSet->iSize : 8);
+ qF.setPointSize((int)(TxtSet->iSize*0.71));
+ else qF.setPointSize((TxtSet->iSize > 2) ? TxtSet->iSize : 2);
switch(TxtSet->Font){
case FONT_HELVETICA:
default: qF.setFamily("Helvetica"); break;
@@ -761,96 +767,97 @@ bool com_SetTextSpec(TextDEF *set, TextDEF *TxtSet, anyOutput *o, QFont qF, QPai
case FONT_COURIER: qF.setFamily("Courier"); break;
}
qP->setFont(qF);
+ if(TxtSet->fSize >0.0) TxtSet->iSize = o->un2iy(TxtSet->fSize); //correct for printer
}
return RetVal;
}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Icon definitions
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//this icon has been taken from trolltech's Qt: qmessagebox.cpp
-static char *information_xpm[]={
-"32 32 5 1",
-". c None",
-"c c #000000",
-"* c #999999",
-"a c #ffffff",
-"b c #0000ff",
-"...........********.............",
-"........***aaaaaaaa***..........",
-"......**aaaaaaaaaaaaaa**........",
-".....*aaaaaaaaaaaaaaaaaa*.......",
-"....*aaaaaaaabbbbaaaaaaaac......",
-"...*aaaaaaaabbbbbbaaaaaaaac.....",
-"..*aaaaaaaaabbbbbbaaaaaaaaac....",
-".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
-".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
-"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
-"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
-".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
-".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
-"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
-"...caaaaaaabbbbbbbbbaaaaaac****.",
-"....caaaaaaaaaaaaaaaaaaaac****..",
-".....caaaaaaaaaaaaaaaaaac****...",
-"......ccaaaaaaaaaaaaaacc****....",
-".......*cccaaaaaaaaccc*****.....",
-"........***cccaaaac*******......",
-"..........****caaac*****........",
-".............*caaac**...........",
-"...............caac**...........",
-"................cac**...........",
-".................cc**...........",
-"..................***...........",
-"...................**..........."};
-
-//this icon has been taken from trolltech's Qt: qmessagebox.cpp
-static char *critical_xpm[]={
-"32 32 4 1",
-". c None",
-"a c #999999",
-"* c #ff0000",
-"b c #ffffff",
-"...........********.............",
-".........************...........",
-".......****************.........",
-"......******************........",
-".....********************a......",
-"....**********************a.....",
-"...************************a....",
-"..*******b**********b*******a...",
-"..******bbb********bbb******a...",
-".******bbbbb******bbbbb******a..",
-".*******bbbbb****bbbbb*******a..",
-"*********bbbbb**bbbbb*********a.",
-"**********bbbbbbbbbb**********a.",
-"***********bbbbbbbb***********aa",
-"************bbbbbb************aa",
-"************bbbbbb************aa",
-"***********bbbbbbbb***********aa",
-"**********bbbbbbbbbb**********aa",
-"*********bbbbb**bbbbb*********aa",
-".*******bbbbb****bbbbb*******aa.",
-".******bbbbb******bbbbb******aa.",
-"..******bbb********bbb******aaa.",
-"..*******b**********b*******aa..",
-"...************************aaa..",
-"....**********************aaa...",
-"....a********************aaa....",
-".....a******************aaa.....",
-"......a****************aaa......",
-".......aa************aaaa.......",
-".........aa********aaaaa........",
-"...........aaaaaaaaaaa..........",
-".............aaaaaaa............"};
-
-//thanks to Markus Bongard for the following icon
-static char *RLPlot_xpm[]={
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Icon definitions
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//this icon has been taken from trolltech's Qt: qmessagebox.cpp
+static char *information_xpm[]={
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaabbbbaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaaabbbbbbaaaaaaaaac....",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
+".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
+"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
+"...caaaaaaabbbbbbbbbaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**..........."};
+
+//this icon has been taken from trolltech's Qt: qmessagebox.cpp
+static char *critical_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #999999",
+"* c #ff0000",
+"b c #ffffff",
+"...........********.............",
+".........************...........",
+".......****************.........",
+"......******************........",
+".....********************a......",
+"....**********************a.....",
+"...************************a....",
+"..*******b**********b*******a...",
+"..******bbb********bbb******a...",
+".******bbbbb******bbbbb******a..",
+".*******bbbbb****bbbbb*******a..",
+"*********bbbbb**bbbbb*********a.",
+"**********bbbbbbbbbb**********a.",
+"***********bbbbbbbb***********aa",
+"************bbbbbb************aa",
+"************bbbbbb************aa",
+"***********bbbbbbbb***********aa",
+"**********bbbbbbbbbb**********aa",
+"*********bbbbb**bbbbb*********aa",
+".*******bbbbb****bbbbb*******aa.",
+".******bbbbb******bbbbb******aa.",
+"..******bbb********bbb******aaa.",
+"..*******b**********b*******aa..",
+"...************************aaa..",
+"....**********************aaa...",
+"....a********************aaa....",
+".....a******************aaa.....",
+"......a****************aaa......",
+".......aa************aaaa.......",
+".........aa********aaaaa........",
+"...........aaaaaaaaaaa..........",
+".............aaaaaaa............"};
+
+//thanks to Markus Bongard for the following icon
+static char *RLPlot_xpm[]={
/* width height ncolors chars_per_pixel */
"32 32 169 2",
/* colors */
@@ -1057,553 +1064,565 @@ static char *RLPlot_xpm[]={
"EGDDKEKEMEBFBFBFBFMEBFBFFEKEMEMEMEGEBFMEBFBFBFKEMEBFMEBFBFKEKEGI",
"KJLHGINHGINHNHNHNHGINHNHGINHGINHNHGIGINHGINHNHGINHNHGIGINHNHGICJ"};
-//this icon has been taken from trolltech's Qt: qmessagebox.cpp
-static char *qtlogo_xpm[] = {
-/* width height ncolors chars_per_pixel */
-"50 50 17 1",
-/* colors */
-" c #000000",
-". c #495808",
-"X c #2A3304",
-"o c #242B04",
-"O c #030401",
-"+ c #9EC011",
-"@ c #93B310",
-"# c #748E0C",
-"$ c #A2C511",
-"% c #8BA90E",
-"& c #99BA10",
-"* c #060701",
-"= c #181D02",
-"- c #212804",
-"; c #61770A",
-": c #0B0D01",
-"/ c None",
-/* pixels */
-"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$@;.o=::=o.;@$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$+#X* **X#+$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$#oO* O **o#+$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$&.* OO O*.&$$$$$$$$$$$$$",
-"$$$$$$$$$$$$@XOO * OO X&$$$$$$$$$$$$",
-"$$$$$$$$$$$@XO OO O **:::OOO OOO X@$$$$$$$$$$$",
-"$$$$$$$$$$&XO O-;#@++@%.oOO X&$$$$$$$$$$",
-"$$$$$$$$$$.O : *-#+$$$$$$$$+#- : O O*.$$$$$$$$$$",
-"$$$$$$$$$#*OO O*.&$$$$$$$$$$$$+.OOOO **#$$$$$$$$$",
-"$$$$$$$$+-OO O *;$$$$$$$$$$$&$$$$;* o+$$$$$$$$",
-"$$$$$$$$#O* O .+$$$$$$$$$$@X;$$$+.O *#$$$$$$$$",
-"$$$$$$$$X* -&$$$$$$$$$$@- :;$$$&- OX$$$$$$$$",
-"$$$$$$$@*O *O#$$$$$$$$$$@oOO**;$$$# O*%$$$$$$$",
-"$$$$$$$; -+$$$$$$$$$@o O OO ;+$$-O *;$$$$$$$",
-"$$$$$$$. ;$$$$$$$$$@-OO OO X&$$;O .$$$$$$$",
-"$$$$$$$o *#$$$$$$$$@o O O O-@$$$#O *o$$$$$$$",
-"$$$$$$+= *@$$$$$$$@o* OO -@$$$$&: =$$$$$$$",
-"$$$$$$+: :+$$$$$$@- *-@$$$$$$: :+$$$$$$",
-"$$$$$$+: :+$$$$$@o* O *-@$$$$$$: :+$$$$$$",
-"$$$$$$$= :@$$$$@o*OOO -@$$$$@: =+$$$$$$",
-"$$$$$$$- O%$$$@o* O O O O-@$$$#* OX$$$$$$$",
-"$$$$$$$. O *O;$$&o O*O* *O -@$$; O.$$$$$$$",
-"$$$$$$$;* Oo+$$;O*O:OO-- Oo at += *;$$$$$$$",
-"$$$$$$$@* O O#$$$;*OOOo@@-O Oo;O* **@$$$$$$$",
-"$$$$$$$$X* OOO-+$$$;O o@$$@- O O OX$$$$$$$$",
-"$$$$$$$$#* * O.$$$$;X@$$$$@-O O O#$$$$$$$$",
-"$$$$$$$$+oO O OO.+$$+&$$$$$$@-O o+$$$$$$$$",
-"$$$$$$$$$#* **.&$$$$$$$$$$@o OO:#$$$$$$$$$",
-"$$$$$$$$$+. O* O-#+$$$$$$$$+;O OOO:@$$$$$$$$$",
-"$$$$$$$$$$&X *O -;#@++@#;=O O -@$$$$$$$$",
-"$$$$$$$$$$$&X O O*O::::O OO Oo@$$$$$$$",
-"$$$$$$$$$$$$@XOO OO O*X+$$$$$$",
-"$$$$$$$$$$$$$&.* ** O :: *:#$$$$$$$",
-"$$$$$$$$$$$$$$$#o*OO O Oo#@-OOO=#$$$$$$$$",
-"$$$$$$$$$$$$$$$$+#X:* * O**X#+$$@-*:#$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$%;.o=::=o.#@$$$$$$@X#$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$+$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
-"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/"};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Bitmap class for display export etc.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-BitMapQT::BitMapQT(GraphObj *g, QWidget *wi, int vr, int hr):anyOutput()
-{
- int w, h;
-
- hres = (double)hr; vres = (double)vr;
+//this icon has been taken from trolltech's Qt: qmessagebox.cpp
+static char *qtlogo_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"50 50 17 1",
+/* colors */
+" c #000000",
+". c #495808",
+"X c #2A3304",
+"o c #242B04",
+"O c #030401",
+"+ c #9EC011",
+"@ c #93B310",
+"# c #748E0C",
+"$ c #A2C511",
+"% c #8BA90E",
+"& c #99BA10",
+"* c #060701",
+"= c #181D02",
+"- c #212804",
+"; c #61770A",
+": c #0B0D01",
+"/ c None",
+/* pixels */
+"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$@;.o=::=o.;@$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$+#X* **X#+$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$#oO* O **o#+$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$&.* OO O*.&$$$$$$$$$$$$$",
+"$$$$$$$$$$$$@XOO * OO X&$$$$$$$$$$$$",
+"$$$$$$$$$$$@XO OO O **:::OOO OOO X@$$$$$$$$$$$",
+"$$$$$$$$$$&XO O-;#@++@%.oOO X&$$$$$$$$$$",
+"$$$$$$$$$$.O : *-#+$$$$$$$$+#- : O O*.$$$$$$$$$$",
+"$$$$$$$$$#*OO O*.&$$$$$$$$$$$$+.OOOO **#$$$$$$$$$",
+"$$$$$$$$+-OO O *;$$$$$$$$$$$&$$$$;* o+$$$$$$$$",
+"$$$$$$$$#O* O .+$$$$$$$$$$@X;$$$+.O *#$$$$$$$$",
+"$$$$$$$$X* -&$$$$$$$$$$@- :;$$$&- OX$$$$$$$$",
+"$$$$$$$@*O *O#$$$$$$$$$$@oOO**;$$$# O*%$$$$$$$",
+"$$$$$$$; -+$$$$$$$$$@o O OO ;+$$-O *;$$$$$$$",
+"$$$$$$$. ;$$$$$$$$$@-OO OO X&$$;O .$$$$$$$",
+"$$$$$$$o *#$$$$$$$$@o O O O-@$$$#O *o$$$$$$$",
+"$$$$$$+= *@$$$$$$$@o* OO -@$$$$&: =$$$$$$$",
+"$$$$$$+: :+$$$$$$@- *-@$$$$$$: :+$$$$$$",
+"$$$$$$+: :+$$$$$@o* O *-@$$$$$$: :+$$$$$$",
+"$$$$$$$= :@$$$$@o*OOO -@$$$$@: =+$$$$$$",
+"$$$$$$$- O%$$$@o* O O O O-@$$$#* OX$$$$$$$",
+"$$$$$$$. O *O;$$&o O*O* *O -@$$; O.$$$$$$$",
+"$$$$$$$;* Oo+$$;O*O:OO-- Oo at += *;$$$$$$$",
+"$$$$$$$@* O O#$$$;*OOOo@@-O Oo;O* **@$$$$$$$",
+"$$$$$$$$X* OOO-+$$$;O o@$$@- O O OX$$$$$$$$",
+"$$$$$$$$#* * O.$$$$;X@$$$$@-O O O#$$$$$$$$",
+"$$$$$$$$+oO O OO.+$$+&$$$$$$@-O o+$$$$$$$$",
+"$$$$$$$$$#* **.&$$$$$$$$$$@o OO:#$$$$$$$$$",
+"$$$$$$$$$+. O* O-#+$$$$$$$$+;O OOO:@$$$$$$$$$",
+"$$$$$$$$$$&X *O -;#@++@#;=O O -@$$$$$$$$",
+"$$$$$$$$$$$&X O O*O::::O OO Oo@$$$$$$$",
+"$$$$$$$$$$$$@XOO OO O*X+$$$$$$",
+"$$$$$$$$$$$$$&.* ** O :: *:#$$$$$$$",
+"$$$$$$$$$$$$$$$#o*OO O Oo#@-OOO=#$$$$$$$$",
+"$$$$$$$$$$$$$$$$+#X:* * O**X#+$$@-*:#$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$%;.o=::=o.#@$$$$$$@X#$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$+$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
+"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/"};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Bitmap class for display export etc.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+BitMapQT::BitMapQT(GraphObj *g, QWidget *wi, int vr, int hr):anyOutput()
+{
+ int w, h;
+
+ hres = (double)hr; vres = (double)vr;
image = 0L; hgo = 0L;
- if(wi) {
- w = wi->width(); h = wi->height();
- }
- else {
- GetDesktopSize(&w, &h);
- }
- Box1.Xmin = Box1.Ymin = 0.0;
- Box1.Xmax = w; Box1.Ymax = h;
- DeskRect.left = DeskRect.top = 0;
- GetDesktopSize(&w, &h);
- DeskRect.right = w; DeskRect.bottom = h;
- mempic = new QPixmap(w, h);
- mempic->fill(0x00ffffffL);
- qPainter.begin(mempic);
- qPen.setCapStyle(Qt::RoundCap);
- qPainter.setPen(qPen);
- qFont = qPainter.font();
-}
-
-BitMapQT::BitMapQT(int w, int h, double hr, double vr):anyOutput()
-{
- hres = hr; vres = vr;
+ if(wi) {
+ w = wi->width(); h = wi->height();
+ }
+ else {
+ GetDesktopSize(&w, &h);
+ }
+ Box1.Xmin = Box1.Ymin = 0.0;
+ Box1.Xmax = w; Box1.Ymax = h;
+ DeskRect.left = DeskRect.top = 0;
+ GetDesktopSize(&w, &h);
+ DeskRect.right = w; DeskRect.bottom = h;
+ mempic = new QPixmap(w, h);
+ mempic->fill(0x00ffffffL);
+ qPainter.begin(mempic);
+ qPen.setCapStyle(Qt::RoundCap);
+ qPen.setJoinStyle(Qt::RoundJoin);
+ qPainter.setPen(qPen);
+ qFont = qPainter.font();
+}
+
+BitMapQT::BitMapQT(int w, int h, double hr, double vr):anyOutput()
+{
+ hres = hr; vres = vr;
image = 0L; hgo = 0L;
- w = abs(w); h = abs(h);
- Box1.Xmin = Box1.Ymin = 0.0;
- Box1.Xmax = w; Box1.Ymax = h;
- DeskRect.right = w; DeskRect.bottom = h;
- DeskRect.left = DeskRect.top = 0;
- mempic = new QPixmap(w, h);
- mempic->fill(0x00ffffffL);
- qPainter.begin(mempic);
- qPen.setCapStyle(Qt::RoundCap);
- qPainter.setPen(qPen);
- qFont = qPainter.font();
-}
-
-BitMapQT::~BitMapQT()
-{
+ w = abs(w); h = abs(h);
+ Box1.Xmin = Box1.Ymin = 0.0;
+ Box1.Xmax = w; Box1.Ymax = h;
+ DeskRect.right = w; DeskRect.bottom = h;
+ DeskRect.left = DeskRect.top = 0;
+ mempic = new QPixmap(w, h);
+ mempic->fill(0x00ffffffL);
+ qPainter.begin(mempic);
+ qPen.setCapStyle(Qt::RoundCap);
+ qPen.setJoinStyle(Qt::RoundJoin);
+ qPainter.setPen(qPen);
+ qFont = qPainter.font();
+}
+
+BitMapQT::~BitMapQT()
+{
Undo.KillDisp(this);
- if(qPainter.isActive()) qPainter.end();
- HideTextCursorObj(this);
- if(mempic) delete mempic;
- if(hgo) delete hgo;
- if(image) delete image;
- mempic = 0L; hgo = 0L; image = 0L;
-}
-
-bool
-BitMapQT::SetLine(LineDEF *lDef)
-{
- int iw;
-
- if(lDef->width != LineWidth || lDef->width != LineWidth ||
- lDef->pattern != dPattern || lDef->color != dLineCol) {
- LineWidth = lDef->width;
- iw = iround(un2ix(lDef->width));
- dPattern = lDef->pattern;
- RLP.finc = 256.0/un2fix(lDef->patlength*8.0);
- RLP.fp = 0.0;
- if(iLine == iw && dLineCol == lDef->color) return true;
- iLine = iw;
- dLineCol = lDef->color;
- qPen.setColor(SwapRB(dLineCol));
- qPen.setWidth(iw);
- qPen.setStyle(Qt::SolidLine);
- qPen.setCapStyle(Qt::RoundCap);
- qPen.setJoinStyle(Qt::RoundJoin);
- qPainter.setPen(qPen);
- }
- return true;
-}
-
-bool
-BitMapQT::SetFill(FillDEF *fill)
-{
- if(!fill) return false;
- if((fill->type & 0xff) != FILL_NONE) {
- if(!hgo) hgo = new HatchOut(this);
- if(hgo) hgo->SetFill(fill);
- }
- else {
- if(hgo) delete hgo;
- hgo = 0L;
- }
- qPainter.setBrush(QColor(SwapRB(fill->color)));
- dFillCol = fill->color;
- dFillCol2 = fill->color2;
- return true;
-}
-
-bool
-BitMapQT::SetTextSpec(TextDEF *set)
+ if(qPainter.isActive()) qPainter.end();
+ HideTextCursorObj(this);
+ if(mempic) delete mempic;
+ if(hgo) delete hgo;
+ if(image) delete image;
+ mempic = 0L; hgo = 0L; image = 0L;
+}
+
+bool
+BitMapQT::SetLine(LineDEF *lDef)
{
- return com_SetTextSpec(set, &TxtSet, this, qFont, &qPainter);
-}
-
-bool
-BitMapQT::Erase(DWORD color)
-{
- if(!mempic) return false;
- mempic->fill(color);
- if(image) delete image;
- image = 0L;
- return true;
-}
-
-bool
-BitMapQT::CopyBitmap(int x, int y, anyOutput* sr, int sx, int sy,
- int sw, int sh, bool invert)
-{
- BitMapQT *src = (BitMapQT*)sr;
-
- if(!mempic) return false;
- bitBlt(mempic, x, y, src->mempic, sx, sy, sw, sh,
- invert ? Qt::NotCopyROP : Qt::CopyROP);
- return true;
-
-
-}
-
-bool
-BitMapQT::oGetTextExtent(char *text, int cb, int *width, int *height)
-{
- if(!text) return false;
- QRect rc = qPainter.boundingRect(0, 0, 10000, 1000, Qt::AlignLeft | Qt::AlignTop,
- text, cb > 0 ? cb : strlen(text));
- *width = rc.rRight() - rc.rLeft(); *height = TxtSet.iSize +2;
- return true;
-}
-
-bool
-BitMapQT::oGetPix(int x, int y, DWORD *col)
-{
- DWORD pix;
-
- if(!image && !(image = new QImage(mempic->convertToImage())))return false;
- if(x >= DeskRect.left && x < DeskRect.right &&
- y >= DeskRect.top && y < DeskRect.bottom){
- pix = SwapRB(image->pixel(x, y));
- *col = pix;
- return true;
- }
- return false;
-}
-
-bool
-BitMapQT::oDrawIcon(int type, int x, int y)
-{
- char** xpm_data;
- QPixmap pm;
-
- switch (type) {
- case ICO_INFO:
- xpm_data = information_xpm;
- break;
- case ICO_ERROR:
- xpm_data = critical_xpm;
- break;
- case ICO_RLPLOT:
- xpm_data = RLPlot_xpm;
- break;
- case ICO_QT:
- xpm_data = qtlogo_xpm;
- break;
- default:
- return false;
- }
- if (xpm_data) {
- QImage image((const char **)xpm_data);
- pm.convertFromImage(image);
- bitBlt(mempic, x, y, &pm, 0, 0, -1, -1, Qt::CopyROP);
- return true;
- }
- return false;
-}
-
-bool
-BitMapQT::oCircle(int x1, int y1, int x2, int y2, char* nam)
-{
- qPainter.drawEllipse(x1, y1, x2-x1, y2-y1);
- if(hgo) return hgo->oCircle(x1, y1, x2, y2);
- return true;
-}
-
-bool
-BitMapQT::oPolyline(POINT * pts, int cp, char *nam)
-{
- int i;
-
- if(cp < 1) return false;
- if (dPattern) {
- for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
- }
- else {
- qPainter.moveTo(pts[0].x, pts[0].y);
- for (i = 1; i < cp; i++) qPainter.lineTo(pts[i].x, pts[i].y);
- }
- return true;
-}
-
-bool
-BitMapQT::oRectangle(int x1, int y1, int x2, int y2, char *nam)
-{
- qPainter.drawRect(x1, y1, x2-x1, y2-y1);
- if(hgo) hgo->oRectangle(x1, y1, x2, y2, 0L);
- return true;
-}
-
-bool
-BitMapQT::oSolidLine(POINT *p)
-{
- qPainter.drawLine(p[0].x, p[0].y, p[1].x, p[1].y);
- return true;
-}
-
-bool
-BitMapQT::oTextOut(int x, int y, char *txt, int cb)
-{
- return com_TextOut(x, y, txt, &TxtSet, &qPainter, this);
-}
-
-bool
-BitMapQT::oPolygon(POINT *pts, int cp, char *nam)
-{
- int i;
-
- QPointArray *a;
-
- if(!pts || cp <2) return false;
- a = new QPointArray(cp);
- if (a) {
- for(i = 0; i < cp; i++) a->setPoint(i, pts[i].x, pts[i].y);
- qPainter.drawPolygon(*a);
- delete a;
- }
- if(hgo) hgo->oPolygon(pts, cp);
-}
-
-bool
-BitMapQT::oArc(int x1, int y1, int x2, int y2, int quads)
-{
- int i, j;
-
- if(x1 > x2) Swap(x1, x2); if(y1 > y2) Swap(y1, y2);
- switch(quads) {
- case 1: i = 270*16; j = 90*16; break;
- case 2: i = 180*16; j = 180*16; break;
- case 3: i = 90*16; j = 270*16; break;
- case 4: i = 0; j = 360*16; break;
- default: return false;
- }
- qPainter.drawArc(x1, y1, x2-x1, y2-y1, i, j);
- return true;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// The display output class
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-OutputQT::OutputQT(GraphObj *g):BitMapQT(g, 0L)
-{
- int w, h;
- RLPwidget *rw;
-
- HScroll = VScroll = 0L;
- CreateNewWindow(BaseObj = g);
- if(rw = (RLPwidget*)widget) {
- rw->move(CurrWidgetPos.x+50, CurrWidgetPos.y+50);
- rw->show();
- rw->mempic = mempic;
- rw->setBackgroundMode(QWidget::NoBackground);
- }
-}
-
-OutputQT::OutputQT(DlgWidget *wi):BitMapQT(0L, wi)
-{
- //assume fixed size (dialog) widget
- widget = wi;
- HScroll = VScroll = 0L;
- BaseObj = 0L;
- wi->OutputClass = this;
- wi->mempic = mempic;
- wi->setBackgroundMode(QWidget::NoBackground);
- xAxis.flags = 0L;
- yAxis.flags = AXIS_INVERT; //drawing origin upper left corner
-}
-
-OutputQT::~OutputQT()
-{
- if(qPainter.isActive()) qPainter.end();
- if(widget) delete widget; widget = 0L;
- HideTextCursorObj(this);
- if(mempic) delete mempic; mempic = 0L;
- if(hgo) delete hgo; hgo = 0L;
- if(image) delete image; image = 0L;
-}
-
-bool
-OutputQT::ActualSize(RECT *rc)
-{
- if(rc) {
- rc->left = rc->top = 0;
- rc->bottom = widget->height() - MenuHeight-6;
- rc->right = widget->width();
- return true;
- }
- return false;
-}
-
-void
-OutputQT::Caption(char *txt)
-{
- QString cap(txt);
- widget->setCaption(cap);
-}
-
-unsigned char hand_bits[] = { //hand cursor bitmap
- 0x80, 0x01, 0x58, 0x0e, 0x64, 0x12, 0x64, 0x52,
- 0x48, 0xb2, 0x48, 0x92, 0x16, 0x90, 0x19, 0x80,
- 0x11, 0x40, 0x02, 0x40, 0x02, 0x40, 0x04, 0x20,
- 0x08, 0x20, 0x10, 0x10, 0x20, 0x10, 0x20, 0x10};
-
-unsigned char hand_mask[] = { //hand cursor mask
- 0x80, 0x01, 0xd8, 0x0f, 0xfc, 0x1f, 0xfc, 0x5f,
- 0xf8, 0xbf, 0xf8, 0xff, 0xfe, 0xff, 0xff, 0xff,
- 0xff, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfc, 0x3f,
- 0xf8, 0x3f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0, 0x1f};
-
-unsigned char zoom_bits[] = { //zoom cursor bitmap
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x60, 0x0a,
- 0x10, 0x10, 0x08, 0x21, 0x08, 0x21, 0x04, 0x40,
- 0x64, 0x4c, 0x04, 0x40, 0x08, 0x21, 0x08, 0x21,
- 0x10, 0x10, 0x60, 0x0a, 0x80, 0x03, 0x00, 0x00};
-
-unsigned char zoom_mask[] = { //zoom cursor mask
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xe0, 0x0f,
- 0xf0, 0x1f, 0xf8, 0x3f, 0xf8, 0x3f, 0xf4, 0x7e,
- 0x7c, 0x7c, 0xfc, 0x7e, 0xf8, 0x3f, 0xf8, 0x3f,
- 0xf0, 0x1f, 0xe0, 0x0f, 0x80, 0x03, 0x00, 0x00};
+ int iw;
-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};
+ if(lDef->width != LineWidth || lDef->width != LineWidth ||
+ lDef->pattern != dPattern || lDef->color != dLineCol) {
+ LineWidth = lDef->width;
+ iw = iround(un2ix(lDef->width));
+ dPattern = lDef->pattern;
+ RLP.finc = 256.0/un2fix(lDef->patlength*8.0);
+ RLP.fp = 0.0;
+ if(iLine == iw && dLineCol == lDef->color) return true;
+ iLine = iw;
+ dLineCol = lDef->color;
+ qPen.setColor(SwapRB(dLineCol));
+ qPen.setWidth(iw);
+ qPen.setStyle(Qt::SolidLine);
+ qPen.setCapStyle(Qt::RoundCap);
+ qPen.setJoinStyle(Qt::RoundJoin);
+ qPainter.setPen(qPen);
+ }
+ return true;
+}
-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};
+bool
+BitMapQT::SetFill(FillDEF *fill)
+{
+ if(!fill) return false;
+ if((fill->type & 0xff) != FILL_NONE) {
+ if(!hgo) hgo = new HatchOut(this);
+ if(hgo) hgo->SetFill(fill);
+ }
+ else {
+ if(hgo) delete hgo;
+ hgo = 0L;
+ }
+ qPainter.setBrush(QColor(SwapRB(fill->color)));
+ dFillCol = fill->color;
+ dFillCol2 = fill->color2;
+ return true;
+}
-unsigned char drawpen_bits[] = { //draw cursor bitmap
- 0x03, 0x00, 0x0f, 0x00, 0x3e, 0x00, 0xce, 0x00,
- 0x04, 0x01, 0x44, 0x02, 0x88, 0x04, 0x08, 0x09,
- 0x10, 0x12, 0x20, 0x24, 0x40, 0x48, 0x80, 0xd0,
- 0x00, 0xe1, 0x00, 0x72, 0x00, 0x3c, 0x00, 0x18};
+bool
+BitMapQT::SetTextSpec(TextDEF *set)
+{
+ return com_SetTextSpec(set, &TxtSet, this, qFont, &qPainter);
+}
-unsigned char drawpen_mask[] = { //draw cursor mask
- 0x03, 0x00, 0x0f, 0x00, 0x3e, 0x00, 0xfe, 0x00,
- 0xfc, 0x01, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x0f,
- 0xf0, 0x1f, 0xe0, 0x3f, 0xc0, 0x7f, 0x80, 0xff,
- 0x00, 0xff, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x18};
+bool
+BitMapQT::Erase(DWORD color)
+{
+ if(!mempic) return false;
+ mempic->fill(color);
+ if(image) delete image;
+ image = 0L;
+ return true;
+}
-unsigned char drect_bits[] = { //draw rectangle bitmap
- 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x08, 0x80,
- 0x08, 0x80, 0x08, 0x80, 0x08, 0x80, 0x08, 0x80,
- 0x08, 0x80, 0x08, 0x80, 0xf8, 0xff, 0x00, 0x00};
+bool
+BitMapQT::CopyBitmap(int x, int y, anyOutput* sr, int sx, int sy,
+ int sw, int sh, bool invert)
+{
+ BitMapQT *src = (BitMapQT*)sr;
-unsigned char drect_mask[] = { //draw rectangle mask
- 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xf8, 0xff,
- 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff,
- 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x00, 0x00};
+ if(!mempic) return false;
+ bitBlt(mempic, x, y, src->mempic, sx, sy, sw, sh,
+ invert ? Qt::NotCopyROP : Qt::CopyROP);
+ return true;
-unsigned char drrect_bits[] = { //draw rounded rectangle bitmap
- 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x10, 0x40,
- 0x08, 0x80, 0x08, 0x80, 0x08, 0x80, 0x08, 0x80,
- 0x08, 0x80, 0x10, 0x40, 0xe0, 0x3f, 0x00, 0x00};
-unsigned char drrect_mask[] = { //draw rounded rectangle mask
- 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0xf0, 0x7f,
- 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff,
- 0xf8, 0xff, 0xf0, 0x7f, 0xe0, 0x3f, 0x00, 0x00};
+}
-unsigned char delly_bits[] = { //draw ellipse bitmap
- 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x60, 0x30,
- 0x10, 0x40, 0x08, 0x80, 0x08, 0x80, 0x08, 0x80,
- 0x10, 0x40, 0x60, 0x30, 0x80, 0x0f, 0x00, 0x00};
+bool
+BitMapQT::oGetTextExtent(char *text, int cb, int *width, int *height)
+{
+ if(!text || !text[0]){
+ QRect rc = qPainter.boundingRect(0, 0, 10000, 1000, Qt::AlignLeft | Qt::AlignTop, "A", 1);
+ *width = rc.rLeft();
+ }
+ else {
+ QRect rc = qPainter.boundingRect(0, 0, 10000, 1000, Qt::AlignLeft | Qt::AlignTop,
+ text, cb > 0 ? cb : strlen(text));
+ *width = rc.rRight() - rc.rLeft();
+ }
+ *height = TxtSet.iSize +2;
+ return true;
+}
-unsigned char delly_mask[] = { //draw ellipse mask
- 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xe0, 0x3f,
- 0xf0, 0x7f, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff,
- 0xf0, 0x7f, 0xe0, 0x3f, 0x80, 0x0f, 0x00, 0x00};
-
-//display 16x16 cursor data: developers utility
-/*
-void disp_bm(unsigned char *tb)
+bool
+BitMapQT::oGetPix(int x, int y, DWORD *col)
{
- char txt[512];
- unsigned char currbyte;
- int i, j, pos;
+ DWORD pix;
- 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");
+ if(!image && !(image = new QImage(mempic->convertToImage())))return false;
+ if(x >= DeskRect.left && x < DeskRect.right &&
+ y >= DeskRect.top && y < DeskRect.bottom){
+ pix = SwapRB(image->pixel(x, y));
+ *col = pix;
+ return true;
}
- InfoBox(txt);
+ return false;
}
-*/
-void
-OutputQT::MouseCursor(int cid, bool force)
-{
- if(cid == cCursor && !force) return;
- if(cid == MC_LAST) cid = cCursor;
- QBitmap *bits, *mask;
- bits = mask = 0L;
+bool
+BitMapQT::oDrawIcon(int type, int x, int y)
+{
+ char** xpm_data;
+ QPixmap pm;
- switch(cid) {
-#ifdef Q_CHECK_PTR //Qt version 3
- case MC_ARROW: widget->setCursor(QCursor(Qt::ArrowCursor)); break;
- case MC_CROSS: widget->setCursor(QCursor(Qt::CrossCursor)); break;
- case MC_WAIT: widget->setCursor(QCursor(Qt::WaitCursor)); break;
- case MC_TEXT: widget->setCursor(QCursor(Qt::IbeamCursor)); break;
- case MC_NORTH: widget->setCursor(QCursor(Qt::SizeVerCursor)); break;
- case MC_NE: widget->setCursor(QCursor(Qt::SizeBDiagCursor));break;
- case MC_EAST: widget->setCursor(QCursor(Qt::SizeHorCursor)); break;
- case MC_SE: widget->setCursor(QCursor(Qt::SizeFDiagCursor));break;
- case MC_SALL: widget->setCursor(QCursor(Qt::SizeAllCursor)); break;
-#else //Qt version 2
- case MC_ARROW: widget->setCursor(QCursor(ArrowCursor)); break;
- case MC_CROSS: widget->setCursor(QCursor(CrossCursor)); break;
- case MC_WAIT: widget->setCursor(QCursor(WaitCursor)); break;
- case MC_TEXT: widget->setCursor(QCursor(IbeamCursor)); break;
- case MC_NORTH: widget->setCursor(QCursor(SizeVerCursor)); break;
- case MC_NE: widget->setCursor(QCursor(SizeBDiagCursor));break;
- case MC_EAST: widget->setCursor(QCursor(SizeHorCursor)); break;
- case MC_SE: widget->setCursor(QCursor(SizeFDiagCursor));break;
- case MC_SALL: widget->setCursor(QCursor(SizeAllCursor)); break;
-#endif
- case MC_MOVE:
- bits = new QBitmap(16, 16, hand_bits, TRUE);
- mask = new QBitmap(16, 16, hand_mask, TRUE);
- widget->setCursor(QCursor(*bits, *mask, 7, 7));
- break;
- case MC_ZOOM:
- bits = new QBitmap(16, 16, zoom_bits, TRUE);
- mask = new QBitmap(16, 16, zoom_mask, TRUE);
- widget->setCursor(QCursor(*bits, *mask, 7, 7));
- break;
- case MC_PASTE:
- bits = new QBitmap(16, 16, paste_bits, TRUE);
- mask = new QBitmap(16, 16, paste_mask, TRUE);
- widget->setCursor(QCursor(*bits, *mask, 2, 2));
+ switch (type) {
+ case ICO_INFO:
+ xpm_data = information_xpm;
+ break;
+ case ICO_ERROR:
+ xpm_data = critical_xpm;
+ break;
+ case ICO_RLPLOT:
+ xpm_data = RLPlot_xpm;
+ break;
+ case ICO_QT:
+ xpm_data = qtlogo_xpm;
+ break;
+ default:
+ return false;
+ }
+ if (xpm_data) {
+ QImage image((const char **)xpm_data);
+ pm.convertFromImage(image);
+ bitBlt(mempic, x, y, &pm, 0, 0, -1, -1, Qt::CopyROP);
+ return true;
+ }
+ return false;
+}
+
+bool
+BitMapQT::oCircle(int x1, int y1, int x2, int y2, char* nam)
+{
+ qPainter.drawEllipse(x1, y1, x2-x1, y2-y1);
+ if(hgo) return hgo->oCircle(x1, y1, x2, y2);
+ return true;
+}
+
+bool
+BitMapQT::oPolyline(POINT * pts, int cp, char *nam)
+{
+ int i;
+
+ if(cp < 1) return false;
+ if (dPattern) {
+ for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
+ }
+ else {
+ qPainter.moveTo(pts[0].x, pts[0].y);
+ for (i = 1; i < cp; i++) qPainter.lineTo(pts[i].x, pts[i].y);
+ }
+ return true;
+}
+
+bool
+BitMapQT::oRectangle(int x1, int y1, int x2, int y2, char *nam)
+{
+ qPainter.drawRect(x1, y1, x2-x1, y2-y1);
+ if(hgo) hgo->oRectangle(x1, y1, x2, y2, 0L);
+ return true;
+}
+
+bool
+BitMapQT::oSolidLine(POINT *p)
+{
+ qPainter.drawLine(p[0].x, p[0].y, p[1].x, p[1].y);
+ return true;
+}
+
+bool
+BitMapQT::oTextOut(int x, int y, char *txt, int cb)
+{
+ if(!txt || !txt[0]) return false;
+ if(TxtSet.Align & TXA_VCENTER) y += iround(TxtSet.iSize * 0.4);
+ else if(TxtSet.Align & TXA_VBOTTOM) y -= iround(TxtSet.iSize * 0.1);
+ else y += iround(TxtSet.iSize * 1.0);
+ return com_TextOut(x, y, txt, &TxtSet, &qPainter, this);
+}
+
+bool
+BitMapQT::oPolygon(POINT *pts, int cp, char *nam)
+{
+ int i;
+
+ QPointArray *a;
+
+ if(!pts || cp <2) return false;
+ a = new QPointArray(cp);
+ if (a) {
+ for(i = 0; i < cp; i++) a->setPoint(i, pts[i].x, pts[i].y);
+ qPainter.drawPolygon(*a);
+ delete a;
+ }
+ if(hgo) hgo->oPolygon(pts, cp);
+}
+
+bool
+BitMapQT::oArc(int x1, int y1, int x2, int y2, int quads)
+{
+ int i, j;
+
+ if(x1 > x2) Swap(x1, x2); if(y1 > y2) Swap(y1, y2);
+ switch(quads) {
+ case 1: i = 270*16; j = 90*16; break;
+ case 2: i = 180*16; j = 180*16; break;
+ case 3: i = 90*16; j = 270*16; break;
+ case 4: i = 0; j = 360*16; break;
+ default: return false;
+ }
+ qPainter.drawArc(x1, y1, x2-x1, y2-y1, i, j);
+ return true;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The display output class
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+OutputQT::OutputQT(GraphObj *g):BitMapQT(g, 0L)
+{
+ int w, h;
+ RLPwidget *rw;
+
+ HScroll = VScroll = 0L;
+ CreateNewWindow(BaseObj = g);
+ if(rw = (RLPwidget*)widget) {
+ rw->move(CurrWidgetPos.x+50, CurrWidgetPos.y+50);
+ rw->show();
+ rw->mempic = mempic;
+ rw->setBackgroundMode(QWidget::NoBackground);
+ }
+}
+
+OutputQT::OutputQT(DlgWidget *wi):BitMapQT(0L, wi)
+{
+ //assume fixed size (dialog) widget
+ widget = wi;
+ HScroll = VScroll = 0L;
+ BaseObj = 0L;
+ wi->OutputClass = this;
+ wi->mempic = mempic;
+ wi->setBackgroundMode(QWidget::NoBackground);
+ xAxis.flags = 0L;
+ yAxis.flags = AXIS_INVERT; //drawing origin upper left corner
+}
+
+OutputQT::~OutputQT()
+{
+ if(qPainter.isActive()) qPainter.end();
+ if(widget) delete widget; widget = 0L;
+ HideTextCursorObj(this);
+ if(mempic) delete mempic; mempic = 0L;
+ if(hgo) delete hgo; hgo = 0L;
+ if(image) delete image; image = 0L;
+}
+
+bool
+OutputQT::ActualSize(RECT *rc)
+{
+ if(rc) {
+ rc->left = rc->top = 0;
+ rc->bottom = widget->height() - MenuHeight-6;
+ rc->right = widget->width();
+ return true;
+ }
+ return false;
+}
+
+void
+OutputQT::Caption(char *txt)
+{
+ QString cap(txt);
+ widget->setCaption(cap);
+}
+
+unsigned char hand_bits[] = { //hand cursor bitmap
+ 0x80, 0x01, 0x58, 0x0e, 0x64, 0x12, 0x64, 0x52,
+ 0x48, 0xb2, 0x48, 0x92, 0x16, 0x90, 0x19, 0x80,
+ 0x11, 0x40, 0x02, 0x40, 0x02, 0x40, 0x04, 0x20,
+ 0x08, 0x20, 0x10, 0x10, 0x20, 0x10, 0x20, 0x10};
+
+unsigned char hand_mask[] = { //hand cursor mask
+ 0x80, 0x01, 0xd8, 0x0f, 0xfc, 0x1f, 0xfc, 0x5f,
+ 0xf8, 0xbf, 0xf8, 0xff, 0xfe, 0xff, 0xff, 0xff,
+ 0xff, 0x7f, 0xfe, 0x7f, 0xfe, 0x7f, 0xfc, 0x3f,
+ 0xf8, 0x3f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0, 0x1f};
+
+unsigned char zoom_bits[] = { //zoom cursor bitmap
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x60, 0x0a,
+ 0x10, 0x10, 0x08, 0x21, 0x08, 0x21, 0x04, 0x40,
+ 0x64, 0x4c, 0x04, 0x40, 0x08, 0x21, 0x08, 0x21,
+ 0x10, 0x10, 0x60, 0x0a, 0x80, 0x03, 0x00, 0x00};
+
+unsigned char zoom_mask[] = { //zoom cursor mask
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xe0, 0x0f,
+ 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};
+
+unsigned char drawpen_bits[] = { //draw cursor bitmap
+ 0x03, 0x00, 0x0f, 0x00, 0x3e, 0x00, 0xce, 0x00,
+ 0x04, 0x01, 0x44, 0x02, 0x88, 0x04, 0x08, 0x09,
+ 0x10, 0x12, 0x20, 0x24, 0x40, 0x48, 0x80, 0xd0,
+ 0x00, 0xe1, 0x00, 0x72, 0x00, 0x3c, 0x00, 0x18};
+
+unsigned char drawpen_mask[] = { //draw cursor mask
+ 0x03, 0x00, 0x0f, 0x00, 0x3e, 0x00, 0xfe, 0x00,
+ 0xfc, 0x01, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x0f,
+ 0xf0, 0x1f, 0xe0, 0x3f, 0xc0, 0x7f, 0x80, 0xff,
+ 0x00, 0xff, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x18};
+
+unsigned char drect_bits[] = { //draw rectangle bitmap
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x08, 0x80,
+ 0x08, 0x80, 0x08, 0x80, 0x08, 0x80, 0x08, 0x80,
+ 0x08, 0x80, 0x08, 0x80, 0xf8, 0xff, 0x00, 0x00};
+
+unsigned char drect_mask[] = { //draw rectangle mask
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xf8, 0xff,
+ 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff,
+ 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x00, 0x00};
+
+unsigned char drrect_bits[] = { //draw rounded rectangle bitmap
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x10, 0x40,
+ 0x08, 0x80, 0x08, 0x80, 0x08, 0x80, 0x08, 0x80,
+ 0x08, 0x80, 0x10, 0x40, 0xe0, 0x3f, 0x00, 0x00};
+
+unsigned char drrect_mask[] = { //draw rounded rectangle mask
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0xf0, 0x7f,
+ 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff,
+ 0xf8, 0xff, 0xf0, 0x7f, 0xe0, 0x3f, 0x00, 0x00};
+
+unsigned char delly_bits[] = { //draw ellipse bitmap
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x60, 0x30,
+ 0x10, 0x40, 0x08, 0x80, 0x08, 0x80, 0x08, 0x80,
+ 0x10, 0x40, 0x60, 0x30, 0x80, 0x0f, 0x00, 0x00};
+
+unsigned char delly_mask[] = { //draw ellipse mask
+ 0x04, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x04, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xe0, 0x3f,
+ 0xf0, 0x7f, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff,
+ 0xf0, 0x7f, 0xe0, 0x3f, 0x80, 0x0f, 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)
+{
+ if(cid == cCursor && !force) return;
+ if(cid == MC_LAST) cid = cCursor;
+ QBitmap *bits, *mask;
+ bits = mask = 0L;
+
+ switch(cid) {
+#ifdef Q_CHECK_PTR //Qt version 3
+ case MC_ARROW: widget->setCursor(QCursor(Qt::ArrowCursor)); break;
+ case MC_CROSS: widget->setCursor(QCursor(Qt::CrossCursor)); break;
+ case MC_WAIT: widget->setCursor(QCursor(Qt::WaitCursor)); break;
+ case MC_TEXT: widget->setCursor(QCursor(Qt::IbeamCursor)); break;
+ case MC_NORTH: widget->setCursor(QCursor(Qt::SizeVerCursor)); break;
+ case MC_NE: widget->setCursor(QCursor(Qt::SizeBDiagCursor));break;
+ case MC_EAST: widget->setCursor(QCursor(Qt::SizeHorCursor)); break;
+ case MC_SE: widget->setCursor(QCursor(Qt::SizeFDiagCursor));break;
+ case MC_SALL: widget->setCursor(QCursor(Qt::SizeAllCursor)); break;
+#else //Qt version 2
+ case MC_ARROW: widget->setCursor(QCursor(ArrowCursor)); break;
+ case MC_CROSS: widget->setCursor(QCursor(CrossCursor)); break;
+ case MC_WAIT: widget->setCursor(QCursor(WaitCursor)); break;
+ case MC_TEXT: widget->setCursor(QCursor(IbeamCursor)); break;
+ case MC_NORTH: widget->setCursor(QCursor(SizeVerCursor)); break;
+ case MC_NE: widget->setCursor(QCursor(SizeBDiagCursor));break;
+ case MC_EAST: widget->setCursor(QCursor(SizeHorCursor)); break;
+ case MC_SE: widget->setCursor(QCursor(SizeFDiagCursor));break;
+ case MC_SALL: widget->setCursor(QCursor(SizeAllCursor)); break;
+#endif
+ case MC_MOVE:
+ bits = new QBitmap(16, 16, hand_bits, TRUE);
+ mask = new QBitmap(16, 16, hand_mask, TRUE);
+ widget->setCursor(QCursor(*bits, *mask, 7, 7));
+ break;
+ case MC_ZOOM:
+ bits = new QBitmap(16, 16, zoom_bits, TRUE);
+ mask = new QBitmap(16, 16, zoom_mask, TRUE);
+ widget->setCursor(QCursor(*bits, *mask, 7, 7));
+ break;
+ case MC_PASTE:
+ bits = new QBitmap(16, 16, paste_bits, TRUE);
+ mask = new QBitmap(16, 16, paste_mask, TRUE);
+ widget->setCursor(QCursor(*bits, *mask, 2, 2));
break;
case MC_DRAWPEN:
bits = new QBitmap(16, 16, drawpen_bits, TRUE);
@@ -1625,447 +1644,453 @@ OutputQT::MouseCursor(int cid, bool force)
mask = new QBitmap(16, 16, delly_mask, TRUE);
widget->setCursor(QCursor(*bits, *mask, 2, 2));
break;
- default: return;
- }
- if(bits) delete bits; if(mask) delete mask;
- cCursor = cid;
-}
-
-bool
-OutputQT::SetScroll(bool isVert, int iMin, int iMax, int iPSize, int iPos)
-{
- QScrollBar *sb;
-
- if(isVert) {
- if(!(sb = VScroll))return false;
- }
- else if(!(sb = HScroll)) return false;
- if(iPos < sb->minValue()) return false;
- sb->setRange(iMin, iMax);
- sb->setPageStep(iPSize);
- if(BaseObj && BaseObj->Id == GO_GRAPH) sb->setLineStep(8);
- else sb->setLineStep(1);
- sb->setValue(iPos);
- return true;
-}
-
-bool
-OutputQT::EndPage()
-{
- if(widget)widget->repaint();
- return true;
-}
-
-bool
-OutputQT::UpdateRect(RECT *rc, bool invert)
-{
- int x1, x2, y1, y2;
-
- if(!widget || !mempic)return false;
- if(rc->right > rc->left) {
- x1 = rc->left; x2 = rc->right;
- }
- else {
- x1 = rc->right; x2 = rc->left;
- }
- if(rc->bottom > rc->top) {
- y1 = rc->top; y2 = rc->bottom;
- }
- else {
- y1 = rc->bottom; y2 = rc->top;
- }
- if(x2 > DeskRect.right) x2 = DeskRect.right;
+ default: return;
+ }
+ if(bits) delete bits; if(mask) delete mask;
+ cCursor = cid;
+}
+
+bool
+OutputQT::SetScroll(bool isVert, int iMin, int iMax, int iPSize, int iPos)
+{
+ QScrollBar *sb;
+
+ if(isVert) {
+ if(!(sb = VScroll))return false;
+ }
+ else if(!(sb = HScroll)) return false;
+ if(iPos < sb->minValue()) return false;
+ sb->setRange(iMin, iMax);
+ sb->setPageStep(iPSize);
+ if(BaseObj && BaseObj->Id == GO_GRAPH) sb->setLineStep(8);
+ else sb->setLineStep(1);
+ sb->setValue(iPos);
+ return true;
+}
+
+bool
+OutputQT::EndPage()
+{
+ if(widget)widget->repaint();
+ return true;
+}
+
+bool
+OutputQT::UpdateRect(RECT *rc, bool invert)
+{
+ int x1, x2, y1, y2;
+
+ if(!widget || !mempic)return false;
+ if(rc->right > rc->left) {
+ x1 = rc->left; x2 = rc->right;
+ }
+ else {
+ x1 = rc->right; x2 = rc->left;
+ }
+ if(rc->bottom > rc->top) {
+ y1 = rc->top; y2 = rc->bottom;
+ }
+ else {
+ y1 = rc->bottom; y2 = rc->top;
+ }
+ if(x2 > DeskRect.right) x2 = DeskRect.right;
if(y2 > DeskRect.bottom) y2 = DeskRect.right;
- bitBlt(widget, x1, y1, mempic, x1, y1,
- x2 - x1, y2 - y1, invert ? Qt::NotCopyROP : Qt::CopyROP);
- return true;
-}
-
-void
-OutputQT::ShowBitmap(int x, int y, anyOutput* src)
-{
- BitMapQT *sr;
- RECT *rc;
-
- if(!widget || !mempic || !src)return;
- sr = (BitMapQT*) src; rc = &sr->DeskRect;
- bitBlt(widget, x, y, sr->mempic, 0, 0, abs(rc->right-rc->left),
- abs(rc->bottom-rc->top), Qt::CopyROP);
-}
-
-void
-OutputQT::ShowLine(POINT * pts, int cp, DWORD color)
-{
- int i;
- QPen qp;
- QPainter paint(widget);
-
- qp.setColor(SwapRB(color));
- qp.setWidth(1);
- qp.setStyle(Qt::SolidLine);
- paint.setPen(qp);
- paint.moveTo(pts[0].x, pts[0].y);
- for (i = 1; i < cp; i++) paint.lineTo(pts[i].x, pts[i].y);
- paint.flush();
-}
-
-void
-OutputQT::ShowEllipse(POINT p1, POINT p2, DWORD color)
-{
- int i;
- QPen qp;
- QPainter paint(widget);
-
- qp.setColor(SwapRB(color));
- qp.setWidth(1);
- qp.setStyle(Qt::SolidLine);
- paint.setPen(qp);
- paint.drawArc(p1.x, p1.y, p2.x-p1.x, p2.y-p1.y, 0, 5760);
- paint.flush();
-}
-
-bool
-OutputQT::SetMenu(int type)
-{
- if(type == MENU_SPREAD){
- QPopupMenu *file = new QPopupMenu(widget);
- file->insertItem("&Open", widget, SLOT(cmOpen()));
+ bitBlt(widget, x1, y1, mempic, x1, y1,
+ x2 - x1, y2 - y1, invert ? Qt::NotCopyROP : Qt::CopyROP);
+ return true;
+}
+
+void
+OutputQT::ShowBitmap(int x, int y, anyOutput* src)
+{
+ BitMapQT *sr;
+ RECT *rc;
+
+ if(!widget || !mempic || !src)return;
+ sr = (BitMapQT*) src; rc = &sr->DeskRect;
+ bitBlt(widget, x, y, sr->mempic, 0, 0, abs(rc->right-rc->left),
+ abs(rc->bottom-rc->top), Qt::CopyROP);
+}
+
+void
+OutputQT::ShowLine(POINT * pts, int cp, DWORD color)
+{
+ int i;
+ QPen qp;
+ QPainter paint(widget);
+
+ qp.setColor(SwapRB(color));
+ qp.setWidth(1);
+ qp.setStyle(Qt::SolidLine);
+ qp.setCapStyle(Qt::RoundCap);
+ qp.setJoinStyle(Qt::RoundJoin);
+ paint.setPen(qp);
+ paint.moveTo(pts[0].x, pts[0].y);
+ for (i = 1; i < cp; i++) paint.lineTo(pts[i].x, pts[i].y);
+ paint.flush();
+}
+
+void
+OutputQT::ShowEllipse(POINT p1, POINT p2, DWORD color)
+{
+ int i;
+ QPen qp;
+ QPainter paint(widget);
+
+ qp.setColor(SwapRB(color));
+ qp.setWidth(1);
+ qp.setStyle(Qt::SolidLine);
+ qp.setCapStyle(Qt::RoundCap);
+ qp.setJoinStyle(Qt::RoundJoin);
+ paint.setPen(qp);
+ paint.drawArc(p1.x, p1.y, p2.x-p1.x, p2.y-p1.y, 0, 5760);
+ paint.flush();
+}
+
+bool
+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(cmExitRLP()));
- file->insertSeparator();
- file->insertItem("n.a.", widget, SLOT(cmFile1()), 0, CM_FILE1);
- file->insertItem("n.a.", widget, SLOT(cmFile2()), 0, CM_FILE2);
- file->insertItem("n.a.", widget, SLOT(cmFile3()), 0, CM_FILE3);
- file->insertItem("n.a.", widget, SLOT(cmFile4()), 0, CM_FILE4);
- file->insertItem("n.a.", widget, SLOT(cmFile5()), 0, CM_FILE5);
- file->insertItem("n.a.", widget, SLOT(cmFile6()), 0, CM_FILE6);
+ file->insertItem("Save &as", widget, SLOT(cmSaveDataAs()));
+ file->insertSeparator();
+ file->insertItem("&Print", widget, SLOT(cmPrint()));
+ file->insertSeparator();
+ 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);
+ file->insertItem("n.a.", widget, SLOT(cmFile3()), 0, CM_FILE3);
+ file->insertItem("n.a.", widget, SLOT(cmFile4()), 0, CM_FILE4);
+ file->insertItem("n.a.", widget, SLOT(cmFile5()), 0, CM_FILE5);
+ file->insertItem("n.a.", widget, SLOT(cmFile6()), 0, CM_FILE6);
QPopupMenu *insert = new QPopupMenu(widget);
insert->insertItem("&Rows", widget, SLOT(cmInsRow()));
insert->insertItem("&Columns", widget, SLOT(cmInsCol()));
-
+
QPopupMenu *Delete = new QPopupMenu(widget);
Delete->insertItem("&Rows", widget, SLOT(cmDelRow()));
Delete->insertItem("&Columns", widget, SLOT(cmDelCol()));
- QPopupMenu *edit = new QPopupMenu(widget);
+ QPopupMenu *edit = new QPopupMenu(widget);
edit->insertItem("&Undo", widget, SLOT(cmUndo()), Qt::CTRL + Qt::Key_Z);
edit->insertSeparator();
- edit->insertItem("&Rows/Cols", widget, SLOT(cmAddRowCol()));
+ edit->insertItem("&Rows/Cols", widget, SLOT(cmAddRowCol()));
edit->insertItem("&Insert", insert);
edit->insertItem("&Delete", Delete);
- edit->insertSeparator();
- edit->insertItem("&Copy", widget, SLOT(cmCopy()), Qt::CTRL + Qt::Key_C);
- edit->insertItem("C&ut", widget, SLOT(cmCut()), Qt::CTRL + Qt::Key_X);
- edit->insertItem("&Paste", widget, SLOT(cmPaste()), Qt::CTRL + Qt::Key_V);
- edit->insertSeparator();
- edit->insertItem("&Fill Range", widget, SLOT(cmFillRange()));
-
- QPopupMenu *graph = new QPopupMenu(widget);
- graph->insertItem("Create &Graph", widget, SLOT(cmNewGraph()));
- graph->insertItem("Create &Page", widget, SLOT(cmNewPage()));
- graph->insertItem("&Flush Graph(s)", widget, SLOT(cmDelGraph()));
- graph->insertSeparator();
- graph->insertItem("&Settings", widget, SLOT(cmDefaults()));
+ edit->insertSeparator();
+ edit->insertItem("&Copy", widget, SLOT(cmCopy()), Qt::CTRL + Qt::Key_C);
+ edit->insertItem("C&ut", widget, SLOT(cmCut()), Qt::CTRL + Qt::Key_X);
+ edit->insertItem("&Paste", widget, SLOT(cmPaste()), Qt::CTRL + Qt::Key_V);
+ edit->insertSeparator();
+ edit->insertItem("&Fill Range", widget, SLOT(cmFillRange()));
+
+ QPopupMenu *graph = new QPopupMenu(widget);
+ graph->insertItem("Create &Graph", widget, SLOT(cmNewGraph()));
+ graph->insertItem("Create &Page", widget, SLOT(cmNewPage()));
+ graph->insertItem("&Flush Graph(s)", widget, SLOT(cmDelGraph()));
+ graph->insertSeparator();
+ graph->insertItem("&Settings", widget, SLOT(cmDefaults()));
QPopupMenu *stats = new QPopupMenu(widget);
+ stats->insertItem("&Comp. Means", widget, SLOT(cmRepCmeans()));
stats->insertItem("&Anova", widget, SLOT(cmRepanov()));
stats->insertItem("&Regression", widget, SLOT(cmRepregr()));
-
- QPopupMenu *about = new QPopupMenu(widget);
- about->insertItem("&About ...", widget, SLOT(cmAbout()));
-
- menu = new QMenuBar(widget);
+ stats->insertItem("&2x2 Table", widget, SLOT(cmReptwoway()));
+
+ QPopupMenu *about = new QPopupMenu(widget);
+ about->insertItem("&About ...", widget, SLOT(cmAbout()));
+
+ menu = new QMenuBar(widget);
menu->insertItem("&File", file); menu->insertItem("&Edit", edit);
menu->insertItem("&Statistics", stats); menu->insertItem("&Graph", graph);
- menu->insertItem("&?", about);
-#ifdef Q_CHECK_PTR //Qt version 3, n.a. in version 2
- menu->setItemVisible(CM_FILE1, false); menu->setItemVisible(CM_FILE2, false);
- menu->setItemVisible(CM_FILE3, false); menu->setItemVisible(CM_FILE4, false);
- menu->setItemVisible(CM_FILE5, false); menu->setItemVisible(CM_FILE6, false);
-#endif
- }
- else if(type == MENU_GRAPH) {
- QPopupMenu *file = new QPopupMenu(widget);
- file->insertItem("&Open", widget, SLOT(cmOpen()));
- file->insertItem("Save &as", widget, SLOT(cmSaveGraphAs()));
- file->insertItem("&Copy", widget, SLOT(cmCopyGraph()));
- file->insertSeparator();
- file->insertItem("&Print", widget, SLOT(cmPrint()));
- file->insertItem("&Export", widget, SLOT(cmExport()));
- file->insertSeparator();
- file->insertItem(widget == MainWidget ? "E&xit" : "&Close", widget, SLOT(cmExit()));
-
- QPopupMenu *edit = new QPopupMenu(widget);
- edit->insertItem("&Undo", widget, SLOT(cmUndo()), Qt::CTRL + Qt::Key_Z);
- edit->insertSeparator();
- edit->insertItem("&Copy", widget, SLOT(cmCopyGraph()), Qt::CTRL + Qt::Key_C);
- edit->insertItem("&Paste", widget, SLOT(cmPaste()), Qt::CTRL + Qt::Key_V);
- edit->insertSeparator();
- edit->insertItem("&UpdateValues", widget, SLOT(cmUpdate()));
- edit->insertSeparator();
- edit->insertItem("&Delete Object", widget, SLOT(cmDelObj()));
-
- QPopupMenu *zoom = new QPopupMenu(widget);
- zoom->insertTearOffHandle();
- zoom->insertItem("zoom &in", widget, SLOT(cmZoomIn()), Qt::CTRL + Qt::Key_Plus);
- zoom->insertItem("zoom &out", widget, SLOT(cmZoomOut()), Qt::CTRL + Qt::Key_Minus);
- zoom->insertItem("&fit to widget", widget, SLOT(cmZoomFit()), Qt::CTRL + Qt::Key_F);
- zoom->insertSeparator();
- zoom->insertItem("25%", widget, SLOT(cmZoom25()));
- zoom->insertItem("50%", widget, SLOT(cmZoom50()));
- zoom->insertItem("100%", widget, SLOT(cmZoom100()));
- zoom->insertItem("200%", widget, SLOT(cmZoom200()));
- zoom->insertItem("400%", widget, SLOT(cmZoom400()));
-
- QPopupMenu *displ = new QPopupMenu(widget);
- displ->insertItem("&Redraw", widget, SLOT(cmRedraw()));
- displ->insertItem("&Zoom", zoom);
+ menu->insertItem("&?", about);
+#ifdef Q_CHECK_PTR //Qt version 3, n.a. in version 2
+ menu->setItemVisible(CM_FILE1, false); menu->setItemVisible(CM_FILE2, false);
+ menu->setItemVisible(CM_FILE3, false); menu->setItemVisible(CM_FILE4, false);
+ menu->setItemVisible(CM_FILE5, false); menu->setItemVisible(CM_FILE6, false);
+#endif
+ }
+ else if(type == MENU_GRAPH) {
+ QPopupMenu *file = new QPopupMenu(widget);
+ file->insertItem("&Open", widget, SLOT(cmOpen()));
+ file->insertItem("Save &as", widget, SLOT(cmSaveGraphAs()));
+ file->insertItem("&Copy", widget, SLOT(cmCopyGraph()));
+ file->insertSeparator();
+ file->insertItem("&Print", widget, SLOT(cmPrint()));
+ file->insertItem("&Export", widget, SLOT(cmExport()));
+ file->insertSeparator();
+ file->insertItem(widget == MainWidget ? "E&xit" : "&Close", widget, SLOT(cmExit()));
+
+ QPopupMenu *edit = new QPopupMenu(widget);
+ edit->insertItem("&Undo", widget, SLOT(cmUndo()), Qt::CTRL + Qt::Key_Z);
+ edit->insertSeparator();
+ edit->insertItem("&Copy", widget, SLOT(cmCopyGraph()), Qt::CTRL + Qt::Key_C);
+ edit->insertItem("&Paste", widget, SLOT(cmPaste()), Qt::CTRL + Qt::Key_V);
+ edit->insertSeparator();
+ edit->insertItem("&UpdateValues", widget, SLOT(cmUpdate()));
+ edit->insertSeparator();
+ edit->insertItem("&Delete Object", widget, SLOT(cmDelObj()));
+
+ QPopupMenu *zoom = new QPopupMenu(widget);
+ zoom->insertTearOffHandle();
+ zoom->insertItem("zoom &in", widget, SLOT(cmZoomIn()), Qt::CTRL + Qt::Key_Plus);
+ zoom->insertItem("zoom &out", widget, SLOT(cmZoomOut()), Qt::CTRL + Qt::Key_Minus);
+ zoom->insertItem("&fit to widget", widget, SLOT(cmZoomFit()), Qt::CTRL + Qt::Key_F);
+ zoom->insertSeparator();
+ zoom->insertItem("25%", widget, SLOT(cmZoom25()));
+ zoom->insertItem("50%", widget, SLOT(cmZoom50()));
+ zoom->insertItem("100%", widget, SLOT(cmZoom100()));
+ zoom->insertItem("200%", widget, SLOT(cmZoom200()));
+ zoom->insertItem("400%", widget, SLOT(cmZoom400()));
+
+ QPopupMenu *displ = new QPopupMenu(widget);
+ displ->insertItem("&Redraw", widget, SLOT(cmRedraw()));
+ displ->insertItem("&Zoom", zoom);
displ->insertItem("&Layers", widget, SLOT(cmLayers()));
-
- QPopupMenu *tools = new QPopupMenu(widget);
- tools->insertTearOffHandle();
- tools->insertItem("&Standard", widget, SLOT(cmtStandard()), Qt::Key_Escape, CM_T_STANDARD);
- tools->insertSeparator();
- tools->insertItem("&Draw", widget, SLOT(cmtDraw()), 0, CM_T_DRAW);
- tools->insertItem("Poly&line", widget, SLOT(cmtPolyline()), 0, CM_T_POLYLINE);
- tools->insertItem("Poly&gon", widget, SLOT(cmtPolygon()), 0, CM_T_POLYGON);
- tools->insertItem("&Rectangle", widget, SLOT(cmtRectangle()), 0, CM_T_RECTANGLE);
- tools->insertItem("&r&ound Rect.", widget, SLOT(cmtRoundrect()), 0, CM_T_ROUNDREC);
- tools->insertItem("&Ellipse", widget, SLOT(cmtEllipse()), 0, CM_T_ELLIPSE);
- tools->insertItem("&Arrow", widget, SLOT(cmtArrow()), 0, CM_T_ARROW);
- tools->insertItem("&Text", widget, SLOT(cmtText()), 0, CM_T_TEXT);
- tools->setCheckable(true);
-
- QPopupMenu *plots = new QPopupMenu(widget);
- plots->insertItem("Add &Plot", widget, SLOT(cmAddPlot()));
- plots->insertItem("Add &Axis", widget, SLOT(cmAddAxis()));
- plots->insertItem("Add &Legend", widget, SLOT(cmAddLegend()));
- plots->insertSeparator();
- plots->insertItem("&Configure", widget, SLOT(cmDefaults()));
-
- QPopupMenu *about = new QPopupMenu(widget);
- about->insertItem("&About ...", widget, SLOT(cmAbout()));
-
- menu = new QMenuBar(widget);
- menu->insertItem("&File", file);
- menu->insertItem("&Edit", edit);
- menu->insertItem("&Display", displ);
- menu->insertItem("&Tools", tools);
- menu->insertItem("&Plots", plots);
- menu->insertItem("&?", about);
- }
- else if(type == MENU_PAGE) {
- QPopupMenu *file = new QPopupMenu(widget);
- file->insertItem("&Open", widget, SLOT(cmOpen()));
- file->insertItem("Save &as", widget, SLOT(cmSaveGraphAs()));
- file->insertSeparator();
- file->insertItem("&Print", widget, SLOT(cmPrint()));
- file->insertItem("&Export", widget, SLOT(cmExport()));
- file->insertSeparator();
- file->insertItem(widget == MainWidget ? "E&xit" : "&Close", widget, SLOT(cmExit()));
-
- QPopupMenu *edit = new QPopupMenu(widget);
- edit->insertItem("&Undo", widget, SLOT(cmUndo()), Qt::CTRL + Qt::Key_Z);
- edit->insertSeparator();
- edit->insertItem("&Copy", widget, SLOT(cmCopyGraph()), Qt::CTRL + Qt::Key_C);
- edit->insertItem("&Paste", widget, SLOT(cmPaste()), Qt::CTRL + Qt::Key_V);
- edit->insertSeparator();
- edit->insertItem("&UpdateValues", widget, SLOT(cmUpdate()));
- edit->insertSeparator();
- edit->insertItem("&Delete Object", widget, SLOT(cmDelObj()));
-
- QPopupMenu *zoom = new QPopupMenu(widget);
- zoom->insertTearOffHandle();
- zoom->insertItem("zoom &in", widget, SLOT(cmZoomIn()), Qt::CTRL + Qt::Key_Plus);
- zoom->insertItem("zoom &out", widget, SLOT(cmZoomOut()), Qt::CTRL + Qt::Key_Minus);
- zoom->insertItem("&fit to widget", widget, SLOT(cmZoomFit()), Qt::CTRL + Qt::Key_F);
- zoom->insertSeparator();
- zoom->insertItem("25%", widget, SLOT(cmZoom25()));
- zoom->insertItem("50%", widget, SLOT(cmZoom50()));
- zoom->insertItem("100%", widget, SLOT(cmZoom100()));
- zoom->insertItem("200%", widget, SLOT(cmZoom200()));
- zoom->insertItem("400%", widget, SLOT(cmZoom400()));
-
- QPopupMenu *displ = new QPopupMenu(widget);
- displ->insertItem("&Redraw", widget, SLOT(cmRedraw()));
+
+ QPopupMenu *tools = new QPopupMenu(widget);
+ tools->insertTearOffHandle();
+ tools->insertItem("&Standard", widget, SLOT(cmtStandard()), Qt::Key_Escape, CM_T_STANDARD);
+ tools->insertSeparator();
+ tools->insertItem("&Draw", widget, SLOT(cmtDraw()), 0, CM_T_DRAW);
+ tools->insertItem("Poly&line", widget, SLOT(cmtPolyline()), 0, CM_T_POLYLINE);
+ tools->insertItem("Poly&gon", widget, SLOT(cmtPolygon()), 0, CM_T_POLYGON);
+ tools->insertItem("&Rectangle", widget, SLOT(cmtRectangle()), 0, CM_T_RECTANGLE);
+ tools->insertItem("&r&ound Rect.", widget, SLOT(cmtRoundrect()), 0, CM_T_ROUNDREC);
+ tools->insertItem("&Ellipse", widget, SLOT(cmtEllipse()), 0, CM_T_ELLIPSE);
+ tools->insertItem("&Arrow", widget, SLOT(cmtArrow()), 0, CM_T_ARROW);
+ tools->insertItem("&Text", widget, SLOT(cmtText()), 0, CM_T_TEXT);
+ tools->setCheckable(true);
+
+ QPopupMenu *plots = new QPopupMenu(widget);
+ plots->insertItem("Add &Plot", widget, SLOT(cmAddPlot()));
+ plots->insertItem("Add &Axis", widget, SLOT(cmAddAxis()));
+ plots->insertItem("Add &Legend", widget, SLOT(cmAddLegend()));
+ plots->insertSeparator();
+ plots->insertItem("&Configure", widget, SLOT(cmDefaults()));
+
+ QPopupMenu *about = new QPopupMenu(widget);
+ about->insertItem("&About ...", widget, SLOT(cmAbout()));
+
+ menu = new QMenuBar(widget);
+ menu->insertItem("&File", file);
+ menu->insertItem("&Edit", edit);
+ menu->insertItem("&Display", displ);
+ menu->insertItem("&Tools", tools);
+ menu->insertItem("&Plots", plots);
+ menu->insertItem("&?", about);
+ }
+ else if(type == MENU_PAGE) {
+ QPopupMenu *file = new QPopupMenu(widget);
+ file->insertItem("&Open", widget, SLOT(cmOpen()));
+ file->insertItem("Save &as", widget, SLOT(cmSaveGraphAs()));
+ file->insertSeparator();
+ file->insertItem("&Print", widget, SLOT(cmPrint()));
+ file->insertItem("&Export", widget, SLOT(cmExport()));
+ file->insertSeparator();
+ file->insertItem(widget == MainWidget ? "E&xit" : "&Close", widget, SLOT(cmExit()));
+
+ QPopupMenu *edit = new QPopupMenu(widget);
+ edit->insertItem("&Undo", widget, SLOT(cmUndo()), Qt::CTRL + Qt::Key_Z);
+ edit->insertSeparator();
+ edit->insertItem("&Copy", widget, SLOT(cmCopyGraph()), Qt::CTRL + Qt::Key_C);
+ edit->insertItem("&Paste", widget, SLOT(cmPaste()), Qt::CTRL + Qt::Key_V);
+ edit->insertSeparator();
+ edit->insertItem("&UpdateValues", widget, SLOT(cmUpdate()));
+ edit->insertSeparator();
+ edit->insertItem("&Delete Object", widget, SLOT(cmDelObj()));
+
+ QPopupMenu *zoom = new QPopupMenu(widget);
+ zoom->insertTearOffHandle();
+ zoom->insertItem("zoom &in", widget, SLOT(cmZoomIn()), Qt::CTRL + Qt::Key_Plus);
+ zoom->insertItem("zoom &out", widget, SLOT(cmZoomOut()), Qt::CTRL + Qt::Key_Minus);
+ zoom->insertItem("&fit to widget", widget, SLOT(cmZoomFit()), Qt::CTRL + Qt::Key_F);
+ zoom->insertSeparator();
+ zoom->insertItem("25%", widget, SLOT(cmZoom25()));
+ zoom->insertItem("50%", widget, SLOT(cmZoom50()));
+ zoom->insertItem("100%", widget, SLOT(cmZoom100()));
+ zoom->insertItem("200%", widget, SLOT(cmZoom200()));
+ zoom->insertItem("400%", widget, SLOT(cmZoom400()));
+
+ QPopupMenu *displ = new QPopupMenu(widget);
+ displ->insertItem("&Redraw", widget, SLOT(cmRedraw()));
displ->insertItem("&Zoom", zoom);
- displ->insertItem("&Layers", widget, SLOT(cmLayers()));
-
- QPopupMenu *tools = new QPopupMenu(widget);
- tools->insertTearOffHandle();
- tools->insertItem("&Standard", widget, SLOT(cmtStandard()), Qt::Key_Escape, CM_T_STANDARD);
- tools->insertSeparator();
- tools->insertItem("&Draw", widget, SLOT(cmtDraw()), 0, CM_T_DRAW);
- tools->insertItem("Poly&line", widget, SLOT(cmtPolyline()), 0, CM_T_POLYLINE);
- tools->insertItem("Poly&gon", widget, SLOT(cmtPolygon()), 0, CM_T_POLYGON);
- tools->insertItem("&Rectangle", widget, SLOT(cmtRectangle()), 0, CM_T_RECTANGLE);
- tools->insertItem("&r&ound Rect.", widget, SLOT(cmtRoundrect()), 0, CM_T_ROUNDREC);
- tools->insertItem("&Ellipse", widget, SLOT(cmtEllipse()), 0, CM_T_ELLIPSE);
- tools->insertItem("&Arrow", widget, SLOT(cmtArrow()), 0, CM_T_ARROW);
- tools->insertItem("&Text", widget, SLOT(cmtText()), 0, CM_T_TEXT);
- tools->setCheckable(true);
-
- QPopupMenu *plots = new QPopupMenu(widget);
- plots->insertItem("Add &Graph", widget, SLOT(cmNewGraph()));
- plots->insertItem("Add &Plot", widget, SLOT(cmAddPlot()));
+ displ->insertItem("&Layers", widget, SLOT(cmLayers()));
+
+ QPopupMenu *tools = new QPopupMenu(widget);
+ tools->insertTearOffHandle();
+ tools->insertItem("&Standard", widget, SLOT(cmtStandard()), Qt::Key_Escape, CM_T_STANDARD);
+ tools->insertSeparator();
+ tools->insertItem("&Draw", widget, SLOT(cmtDraw()), 0, CM_T_DRAW);
+ tools->insertItem("Poly&line", widget, SLOT(cmtPolyline()), 0, CM_T_POLYLINE);
+ tools->insertItem("Poly&gon", widget, SLOT(cmtPolygon()), 0, CM_T_POLYGON);
+ tools->insertItem("&Rectangle", widget, SLOT(cmtRectangle()), 0, CM_T_RECTANGLE);
+ tools->insertItem("&r&ound Rect.", widget, SLOT(cmtRoundrect()), 0, CM_T_ROUNDREC);
+ tools->insertItem("&Ellipse", widget, SLOT(cmtEllipse()), 0, CM_T_ELLIPSE);
+ tools->insertItem("&Arrow", widget, SLOT(cmtArrow()), 0, CM_T_ARROW);
+ tools->insertItem("&Text", widget, SLOT(cmtText()), 0, CM_T_TEXT);
+ tools->setCheckable(true);
+
+ QPopupMenu *plots = new QPopupMenu(widget);
+ plots->insertItem("Add &Graph", widget, SLOT(cmNewGraph()));
+ plots->insertItem("Add &Plot", widget, SLOT(cmAddPlot()));
plots->insertItem("Add &Axis", widget, SLOT(cmAddAxis()));
- plots->insertItem("Add &Legend", widget, SLOT(cmAddLegend()));
- plots->insertSeparator();
- plots->insertItem("Page &Settings", widget, SLOT(cmDefaults()));
-
- QPopupMenu *about = new QPopupMenu(widget);
- about->insertItem("&About ...", widget, SLOT(cmAbout()));
-
- menu = new QMenuBar(widget);
- menu->insertItem("&File", file);
- menu->insertItem("&Edit", edit);
- menu->insertItem("&Display", displ);
- menu->insertItem("&Tools", tools);
- menu->insertItem("&Plots", plots);
- menu->insertItem("&?", about);
- }
- else return false;
- menu->show();
- MenuHeight = menu->height();
- widget->resize(widget->width()+8, widget->height()+8);
- return true;
-}
-
-void
-OutputQT::CheckMenu(int mid, bool check)
-{
- if(mid < CM_T_STANDARD) switch(mid){ //tool mode identifier
- case TM_STANDARD: mid = CM_T_STANDARD; break;
- case TM_DRAW: mid = CM_T_DRAW; break;
- case TM_POLYLINE: mid = CM_T_POLYLINE; break;
- case TM_POLYGON: mid = CM_T_POLYGON; break;
- case TM_RECTANGLE: mid = CM_T_RECTANGLE; break;
- case TM_ROUNDREC: mid = CM_T_ROUNDREC; break;
- case TM_ELLIPSE: mid = CM_T_ELLIPSE; break;
- case TM_ARROW: mid = CM_T_ARROW; break;
- case TM_TEXT: mid = CM_T_TEXT; break;
- default: return;
- }
- if(menu) menu->setItemChecked(mid, check);
-}
-
-void
-OutputQT::FileHistory()
-{
- char **history[] = {&defs.File1, &defs.File2, &defs.File3, &defs.File4, &defs.File5, &defs.File6};
- int i, j, k;
-
- if(!hasHistMenu || !defs.File1 || !menu) return;
- for(i = 0; i < 6 && *history[i]; i++) {
- k = strlen(*history[i]);
- for (j = 0; j < k && defs.currPath[j] == (*history[i])[j]; j++);
- if((*history[i])[j] == '\\' || (*history[i])[j] == '/') j++;
- menu->changeItem(CM_FILE1+i, *history[i]+j);
-#ifdef Q_CHECK_PTR //Qt version 3, n.a. in version 2
- menu->setItemVisible(CM_FILE1+i, true);
-#endif
- }
- HistMenuSize = i;
-}
-
-void
-OutputQT::CreateNewWindow(GraphObj *g)
-{
- int w, h;
-
- GetDesktopSize(&w, &h);
- if(widget = new RLPwidget(0, 0, this, g)) {
- widget->setCaption("OutputQT::CreateNewWindow");
- widget->setGeometry(0, 0, (int)(w*.7f), (int)(h*.7f));
- HScroll = ((RLPwidget*)widget)->HScroll;
- VScroll = ((RLPwidget*)widget)->VScroll;
- }
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Common widget support
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-RLPwidget::RLPwidget(QWidget *par, const char *name, anyOutput *o, GraphObj *g)
- : QWidget(par, name)
-{
- int w, h;
-
- GetDesktopSize(&w, &h);
- mempic = new QPixmap(w, h);
- parent = par;
- OutputClass = o;
- BaseObj = g;
- setMinimumSize(100, 80);
- setBackgroundMode(NoBackground);
- HScroll = new QScrollBar(QScrollBar::Horizontal, this, 0);
- HScroll->setRange(0, 1000);
- HScroll->setSteps(1, 16);
- connect(HScroll, SIGNAL(valueChanged(int)), SLOT(hScrollEvent(int)));
- VScroll = new QScrollBar(QScrollBar::Vertical, this, 0);
- VScroll->setRange(0, 1000);
- VScroll->setSteps(1, 16);
- connect(VScroll, SIGNAL(valueChanged(int)), SLOT(vScrollEvent(int)));
- if(!MainWidget) QAppl->setMainWidget(MainWidget = this);
- setMouseTracking(true);
- setFocusPolicy(StrongFocus);
-}
-
-RLPwidget::~RLPwidget()
-{
- if(OutputClass)((OutputQT*)OutputClass)->widget = 0L;
- OutputClass = 0L; BaseObj = 0L;
-}
-
-//public slots: menu items, events
-void
-RLPwidget::hScrollEvent(int pos)
-{
- if(BaseObj){
- BaseObj->Command(CMD_SETHPOS, (void*)(&pos), OutputClass);
- repaint();
- }
-}
-
-void
-RLPwidget::vScrollEvent(int pos)
-{
- if(BaseObj){
- BaseObj->Command(CMD_SETVPOS, (void*)(&pos), OutputClass);
- repaint();
- }
-}
-
-
-void
-RLPwidget::cmOpen()
-{
- if(BaseObj)BaseObj->Command(CMD_OPEN, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmSaveData()
-{
- if(BaseObj)BaseObj->Command(CMD_SAVEDATA, (void *)NULL, OutputClass);
-}
+ plots->insertItem("Add &Legend", widget, SLOT(cmAddLegend()));
+ plots->insertSeparator();
+ plots->insertItem("Page &Settings", widget, SLOT(cmDefaults()));
-void
-RLPwidget::cmSaveDataAs()
-{
- if(BaseObj)BaseObj->Command(CMD_SAVEDATAAS, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmExit()
-{
- if(BaseObj && BaseObj->Command(CMD_CAN_CLOSE, 0L, 0L)){
- if(BaseObj->parent) BaseObj->parent->Command(CMD_DELOBJ, BaseObj, 0L);
+ QPopupMenu *about = new QPopupMenu(widget);
+ about->insertItem("&About ...", widget, SLOT(cmAbout()));
+
+ menu = new QMenuBar(widget);
+ menu->insertItem("&File", file);
+ menu->insertItem("&Edit", edit);
+ menu->insertItem("&Display", displ);
+ menu->insertItem("&Tools", tools);
+ menu->insertItem("&Plots", plots);
+ menu->insertItem("&?", about);
}
-}
+ else return false;
+ menu->show();
+ MenuHeight = menu->height();
+ widget->resize(widget->width()+8, widget->height()+8);
+ return true;
+}
+
+void
+OutputQT::CheckMenu(int mid, bool check)
+{
+ if(mid < CM_T_STANDARD) switch(mid){ //tool mode identifier
+ case TM_STANDARD: mid = CM_T_STANDARD; break;
+ case TM_DRAW: mid = CM_T_DRAW; break;
+ case TM_POLYLINE: mid = CM_T_POLYLINE; break;
+ case TM_POLYGON: mid = CM_T_POLYGON; break;
+ case TM_RECTANGLE: mid = CM_T_RECTANGLE; break;
+ case TM_ROUNDREC: mid = CM_T_ROUNDREC; break;
+ case TM_ELLIPSE: mid = CM_T_ELLIPSE; break;
+ case TM_ARROW: mid = CM_T_ARROW; break;
+ case TM_TEXT: mid = CM_T_TEXT; break;
+ default: return;
+ }
+ if(menu) menu->setItemChecked(mid, check);
+}
+
+void
+OutputQT::FileHistory()
+{
+ char **history[] = {&defs.File1, &defs.File2, &defs.File3, &defs.File4, &defs.File5, &defs.File6};
+ int i, j, k;
+
+ if(!hasHistMenu || !defs.File1 || !menu) return;
+ for(i = 0; i < 6 && *history[i]; i++) {
+ k = strlen(*history[i]);
+ for (j = 0; j < k && defs.currPath[j] == (*history[i])[j]; j++);
+ if((*history[i])[j] == '\\' || (*history[i])[j] == '/') j++;
+ menu->changeItem(CM_FILE1+i, *history[i]+j);
+#ifdef Q_CHECK_PTR //Qt version 3, n.a. in version 2
+ menu->setItemVisible(CM_FILE1+i, true);
+#endif
+ }
+ HistMenuSize = i;
+}
+
+void
+OutputQT::CreateNewWindow(GraphObj *g)
+{
+ int w, h;
+
+ GetDesktopSize(&w, &h);
+ if(widget = new RLPwidget(0, 0, this, g)) {
+ widget->setCaption("OutputQT::CreateNewWindow");
+ widget->setGeometry(0, 0, (int)(w*.7f), (int)(h*.7f));
+ HScroll = ((RLPwidget*)widget)->HScroll;
+ VScroll = ((RLPwidget*)widget)->VScroll;
+ }
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Common widget support
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+RLPwidget::RLPwidget(QWidget *par, const char *name, anyOutput *o, GraphObj *g)
+ : QWidget(par, name)
+{
+ int w, h;
+
+ GetDesktopSize(&w, &h);
+ mempic = new QPixmap(w, h);
+ parent = par;
+ OutputClass = o;
+ BaseObj = g;
+ setMinimumSize(100, 80);
+ setBackgroundMode(NoBackground);
+ HScroll = new QScrollBar(QScrollBar::Horizontal, this, 0);
+ HScroll->setRange(0, 1000);
+ HScroll->setSteps(1, 16);
+ connect(HScroll, SIGNAL(valueChanged(int)), SLOT(hScrollEvent(int)));
+ VScroll = new QScrollBar(QScrollBar::Vertical, this, 0);
+ VScroll->setRange(0, 1000);
+ VScroll->setSteps(1, 16);
+ connect(VScroll, SIGNAL(valueChanged(int)), SLOT(vScrollEvent(int)));
+ if(!MainWidget) QAppl->setMainWidget(MainWidget = this);
+ setMouseTracking(true);
+ setFocusPolicy(StrongFocus);
+}
+
+RLPwidget::~RLPwidget()
+{
+ if(OutputClass)((OutputQT*)OutputClass)->widget = 0L;
+ OutputClass = 0L; BaseObj = 0L;
+}
+
+//public slots: menu items, events
+void
+RLPwidget::hScrollEvent(int pos)
+{
+ if(BaseObj){
+ BaseObj->Command(CMD_SETHPOS, (void*)(&pos), OutputClass);
+ repaint();
+ }
+}
+
+void
+RLPwidget::vScrollEvent(int pos)
+{
+ if(BaseObj){
+ BaseObj->Command(CMD_SETVPOS, (void*)(&pos), OutputClass);
+ repaint();
+ }
+}
+
+
+void
+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()
+{
+ if(BaseObj)BaseObj->Command(CMD_SAVEDATAAS, (void *)NULL, OutputClass);
+}
+
+void
+RLPwidget::cmExit()
+{
+ if(BaseObj && BaseObj->Command(CMD_CAN_CLOSE, 0L, 0L)){
+ if(BaseObj->parent) BaseObj->parent->Command(CMD_DELOBJ, BaseObj, 0L);
+ }
+}
void
RLPwidget::cmExitRLP()
@@ -2075,227 +2100,233 @@ RLPwidget::cmExitRLP()
}
QAppl->exit(0);
}
-
-void
-RLPwidget::cmNewGraph()
-{
- if(BaseObj)BaseObj->Command(CMD_NEWGRAPH, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmNewPage()
-{
- if(BaseObj)BaseObj->Command(CMD_NEWPAGE, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmDelGraph()
-{
- if(BaseObj)BaseObj->Command(CMD_DELGRAPH, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmAddPlot()
-{
- if(BaseObj)BaseObj->Command(CMD_ADDPLOT, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmAddLegend()
-{
- if(BaseObj)BaseObj->Command(CMD_LEGEND, (void *)NULL, OutputClass);
+
+void
+RLPwidget::cmNewGraph()
+{
+ if(BaseObj)BaseObj->Command(CMD_NEWGRAPH, (void *)NULL, OutputClass);
+}
+
+void
+RLPwidget::cmNewPage()
+{
+ if(BaseObj)BaseObj->Command(CMD_NEWPAGE, (void *)NULL, OutputClass);
+}
+
+void
+RLPwidget::cmDelGraph()
+{
+ if(BaseObj)BaseObj->Command(CMD_DELGRAPH, (void *)NULL, OutputClass);
+}
+
+void
+RLPwidget::cmAddPlot()
+{
+ if(BaseObj)BaseObj->Command(CMD_ADDPLOT, (void *)NULL, OutputClass);
+}
+
+void
+RLPwidget::cmAddLegend()
+{
+ if(BaseObj)BaseObj->Command(CMD_LEGEND, (void *)NULL, OutputClass);
}
void
RLPwidget::cmLayers()
{
if(BaseObj)BaseObj->Command(CMD_LAYERS, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmAbout()
-{
- RLPlotInfo();
-}
-
-void
-RLPwidget::cmAddRowCol()
-{
- if(BaseObj)BaseObj->Command(CMD_ADDROWCOL, (void *)NULL, OutputClass);
-}
-
-void
-RLPwidget::cmCopy()
-{
- if(BaseObj && BaseObj->Id == GO_SPREADDATA) {
- if(BaseObj->Command(CMD_QUERY_COPY, 0L, OutputClass))
- CopyData(BaseObj);
- }
-}
-
-void
-RLPwidget::cmCut()
-{
- if(BaseObj && BaseObj->Id == GO_SPREADDATA) {
- BaseObj->Command(CMD_CUT, 0L, OutputClass);
- CopyData(BaseObj);
- }
-}
-
-void
-RLPwidget::cmPaste()
-{
- if(BaseObj) {
- OutputClass->MouseCursor(MC_WAIT, true);
- TestClipboard(BaseObj);
- BaseObj->Command(CMD_MOUSECURSOR, 0L, OutputClass);
- }
-}
-
-void
-RLPwidget::cmCopyGraph()
-{
- if(BaseObj) CopyGraph(BaseObj);
-}
-
-void
-RLPwidget::cmSaveGraphAs()
-{
- SaveGraphAs(BaseObj);
-}
-
-void
-RLPwidget::cmRedraw()
-{
- if(OutputClass && BaseObj && OutputClass->Erase(defs.Color(COL_BG))) {
- BaseObj->Command(CMD_SETSCROLL, 0L, OutputClass);
- repaint();
- }
-}
-
-void
-RLPwidget::cmZoom25()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"25"), OutputClass);
-}
-
-void
-RLPwidget::cmZoom50()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"50"), OutputClass);
-}
-
-void
-RLPwidget::cmZoom100()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"100"), OutputClass);
-}
-
-void
-RLPwidget::cmZoom200()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"200"), OutputClass);
-}
-
-void
-RLPwidget::cmZoom400()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"400"), OutputClass);
-}
-
-void
-RLPwidget::cmZoomIn()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"+"), OutputClass);
-}
-
-void
-RLPwidget::cmZoomOut()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"-"), OutputClass);
-}
-
-void
-RLPwidget::cmZoomFit()
-{
- BaseObj->Command(CMD_ZOOM, (void*)(&"fit"), OutputClass);
-}
-
-void
-RLPwidget::cmPrint()
-{
- int m;
- PrintQT out(0L, 0L);
-
- if(!BaseObj) return;
- if(BaseObj->Id == GO_SPREADDATA) {
- m = iround(out.hres/60.0);
-#ifdef Q_CHECK_PTR //Qt version 3, n.a. in version 2
- out.printer->setMargins(m, m, m, m);
-#endif
- BaseObj->Command(CMD_PRINT, 0L, &out);
- }
- else if(out.StartPage()){
- BaseObj->DoPlot(&out);
- out.EndPage();
- }
- BaseObj->DoPlot(OutputClass);
-}
-
-void
-RLPwidget::cmExport()
-{
- OpenExportName(BaseObj, 0L);
- BaseObj->DoPlot(0L);
-}
-
-void
-RLPwidget::cmDelObj()
-{
- if(CurrGO && CurrGO->parent && CurrGO->parent->
- Command(CMD_DELOBJ, (void*)CurrGO, OutputClass)) {
- CurrGO = 0L;
- OutputClass->Erase(defs.Color(COL_BG));
- BaseObj->DoPlot(OutputClass);
- }
- else if(!CurrGO) InfoBox("No object selected!");
-}
-
-void
-RLPwidget::cmUpdate()
-{
- if(BaseObj) BaseObj->Command(CMD_UPDATE, 0L, OutputClass);
-}
-
-void
-RLPwidget::cmDefaults()
-{
- BaseObj->Command(CMD_CONFIG, 0L, OutputClass);
-}
-
-void
-RLPwidget::cmAddAxis()
-{
- BaseObj->Command(CMD_ADDAXIS, 0L, OutputClass);
-}
-
-void
-RLPwidget::cmUndo()
-{
- BaseObj->Command(CMD_UNDO, 0L, OutputClass);
-}
-
-void
-RLPwidget::cmFillRange()
-{
- BaseObj->Command(CMD_FILLRANGE, 0L, OutputClass);
+}
+
+void
+RLPwidget::cmAbout()
+{
+ RLPlotInfo();
+}
+
+void
+RLPwidget::cmAddRowCol()
+{
+ if(BaseObj)BaseObj->Command(CMD_ADDROWCOL, (void *)NULL, OutputClass);
+}
+
+void
+RLPwidget::cmCopy()
+{
+ if(BaseObj && BaseObj->Id == GO_SPREADDATA) {
+ if(BaseObj->Command(CMD_QUERY_COPY, 0L, OutputClass))
+ CopyData(BaseObj);
+ }
+}
+
+void
+RLPwidget::cmCut()
+{
+ if(BaseObj && BaseObj->Id == GO_SPREADDATA) {
+ BaseObj->Command(CMD_CUT, 0L, OutputClass);
+ CopyData(BaseObj);
+ }
+}
+
+void
+RLPwidget::cmPaste()
+{
+ if(BaseObj) {
+ OutputClass->MouseCursor(MC_WAIT, true);
+ if(BaseObj->Id == GO_SPREADDATA) TestClipboard(BaseObj);
+ else if(BaseObj->Id == GO_PAGE || BaseObj->Id == GO_GRAPH){
+ if(CurrGO && CurrGO->Id == GO_TEXTFRAME && CurrGO->Command(CMD_PASTE, 0L, OutputClass));
+ else TestClipboard(BaseObj);
+ }
+ BaseObj->Command(CMD_MOUSECURSOR, 0L, OutputClass);
+ }
+}
+
+void
+RLPwidget::cmCopyGraph()
+{
+ EmptyClip();
+ if(CurrGO && CurrGO->Id == GO_TEXTFRAME) if(CurrGO->Command(CMD_COPY, 0L, OutputClass))return;
+ if(BaseObj) CopyGraph(BaseObj);
+}
+
+void
+RLPwidget::cmSaveGraphAs()
+{
+ SaveGraphAs(BaseObj);
+}
+
+void
+RLPwidget::cmRedraw()
+{
+ if(OutputClass && BaseObj && OutputClass->Erase(defs.Color(COL_BG))) {
+ BaseObj->Command(CMD_SETSCROLL, 0L, OutputClass);
+ repaint();
+ }
+}
+
+void
+RLPwidget::cmZoom25()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"25"), OutputClass);
+}
+
+void
+RLPwidget::cmZoom50()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"50"), OutputClass);
+}
+
+void
+RLPwidget::cmZoom100()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"100"), OutputClass);
+}
+
+void
+RLPwidget::cmZoom200()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"200"), OutputClass);
+}
+
+void
+RLPwidget::cmZoom400()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"400"), OutputClass);
+}
+
+void
+RLPwidget::cmZoomIn()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"+"), OutputClass);
+}
+
+void
+RLPwidget::cmZoomOut()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"-"), OutputClass);
+}
+
+void
+RLPwidget::cmZoomFit()
+{
+ BaseObj->Command(CMD_ZOOM, (void*)(&"fit"), OutputClass);
+}
+
+void
+RLPwidget::cmPrint()
+{
+ int m;
+ PrintQT out(0L, 0L);
+
+ if(!BaseObj) return;
+ if(BaseObj->Id == GO_SPREADDATA) {
+ m = iround(out.hres/60.0);
+#ifdef Q_CHECK_PTR //Qt version 3, n.a. in version 2
+ out.printer->setMargins(m, m, m, m);
+#endif
+ BaseObj->Command(CMD_PRINT, 0L, &out);
+ }
+ else if(out.StartPage()){
+ BaseObj->DoPlot(&out);
+ out.EndPage();
+ }
+ BaseObj->DoPlot(OutputClass);
+}
+
+void
+RLPwidget::cmExport()
+{
+ OpenExportName(BaseObj, 0L);
+ BaseObj->DoPlot(0L);
+}
+
+void
+RLPwidget::cmDelObj()
+{
+ if(CurrGO && CurrGO->parent && CurrGO->parent->
+ Command(CMD_DELOBJ, (void*)CurrGO, OutputClass)) {
+ CurrGO = 0L;
+ OutputClass->Erase(defs.Color(COL_BG));
+ BaseObj->DoPlot(OutputClass);
+ }
+ else if(!CurrGO) InfoBox("No object selected!");
+}
+
+void
+RLPwidget::cmUpdate()
+{
+ if(BaseObj) BaseObj->Command(CMD_UPDATE, 0L, OutputClass);
+}
+
+void
+RLPwidget::cmDefaults()
+{
+ BaseObj->Command(CMD_CONFIG, 0L, OutputClass);
+}
+
+void
+RLPwidget::cmAddAxis()
+{
+ BaseObj->Command(CMD_ADDAXIS, 0L, OutputClass);
+}
+
+void
+RLPwidget::cmUndo()
+{
+ BaseObj->Command(CMD_UNDO, 0L, OutputClass);
+}
+
+void
+RLPwidget::cmFillRange()
+{
+ BaseObj->Command(CMD_FILLRANGE, 0L, OutputClass);
}
void
RLPwidget::cmInsRow()
{
BaseObj->Command(CMD_INSROW, 0L, OutputClass);
-}
+}
void
RLPwidget::cmInsCol()
@@ -2314,64 +2345,70 @@ RLPwidget::cmDelCol()
{
BaseObj->Command(CMD_DELCOL, 0L, OutputClass);
}
-
-void ToolMenu(GraphObj *b, anyOutput *o, int tm)
-{
- if(b && o) b->Command(CMD_TOOLMODE, (void*)(& tm), o);
-}
-
-void
-RLPwidget::cmtStandard()
-{
- ToolMenu(BaseObj, OutputClass, TM_STANDARD);
-}
-
-void
-RLPwidget::cmtDraw()
-{
- ToolMenu(BaseObj, OutputClass, TM_DRAW);
-}
-
-void
-RLPwidget::cmtPolyline()
-{
- ToolMenu(BaseObj, OutputClass, TM_POLYLINE);
-}
-
-void
-RLPwidget::cmtPolygon()
-{
- ToolMenu(BaseObj, OutputClass, TM_POLYGON);
-}
-
-void
-RLPwidget::cmtRectangle()
-{
- ToolMenu(BaseObj, OutputClass, TM_RECTANGLE);
-}
-
-void
-RLPwidget::cmtRoundrect()
-{
- ToolMenu(BaseObj, OutputClass, TM_ROUNDREC);
-}
-
-void
-RLPwidget::cmtEllipse()
-{
- ToolMenu(BaseObj, OutputClass, TM_ELLIPSE);
-}
-
-void
-RLPwidget::cmtArrow()
-{
- ToolMenu(BaseObj, OutputClass, TM_ARROW);
-}
-
-void
-RLPwidget::cmtText()
-{
- ToolMenu(BaseObj, OutputClass, TM_TEXT);
+
+void ToolMenu(GraphObj *b, anyOutput *o, int tm)
+{
+ if(b && o) b->Command(CMD_TOOLMODE, (void*)(& tm), o);
+}
+
+void
+RLPwidget::cmtStandard()
+{
+ ToolMenu(BaseObj, OutputClass, TM_STANDARD);
+}
+
+void
+RLPwidget::cmtDraw()
+{
+ ToolMenu(BaseObj, OutputClass, TM_DRAW);
+}
+
+void
+RLPwidget::cmtPolyline()
+{
+ ToolMenu(BaseObj, OutputClass, TM_POLYLINE);
+}
+
+void
+RLPwidget::cmtPolygon()
+{
+ ToolMenu(BaseObj, OutputClass, TM_POLYGON);
+}
+
+void
+RLPwidget::cmtRectangle()
+{
+ ToolMenu(BaseObj, OutputClass, TM_RECTANGLE);
+}
+
+void
+RLPwidget::cmtRoundrect()
+{
+ ToolMenu(BaseObj, OutputClass, TM_ROUNDREC);
+}
+
+void
+RLPwidget::cmtEllipse()
+{
+ ToolMenu(BaseObj, OutputClass, TM_ELLIPSE);
+}
+
+void
+RLPwidget::cmtArrow()
+{
+ ToolMenu(BaseObj, OutputClass, TM_ARROW);
+}
+
+void
+RLPwidget::cmtText()
+{
+ ToolMenu(BaseObj, OutputClass, TM_TEXT);
+}
+
+void
+RLPwidget::cmRepCmeans()
+{
+ if(BaseObj) rep_compmeans(BaseObj, BaseObj->data);
}
void
@@ -2379,678 +2416,706 @@ RLPwidget::cmRepanov()
{
if(BaseObj) rep_anova(BaseObj, BaseObj->data);
}
-
+
void
RLPwidget::cmRepregr()
{
if(BaseObj) rep_regression(BaseObj, BaseObj->data);
}
-
-//protected: widget events
-void
-RLPwidget::paintEvent(QPaintEvent *range)
-{
- QRect rc;
-
- rc = range->rect();
- bitBlt(this, rc.left(), rc.top(), this->mempic, rc.left(), rc.top(),
- 1+rc.right()-rc.left(), 1+rc.bottom()-rc.top());
-}
-
-void
-RLPwidget::resizeEvent(QResizeEvent *)
-{
- HScroll->resize(width() -16, 16);
- HScroll->move(0, height()-16);
- VScroll->resize(16, height()-OutputClass->MenuHeight-16);
- VScroll->move(width()-16, OutputClass->MenuHeight);
- if(BaseObj) BaseObj->Command(CMD_SETSCROLL, 0L, OutputClass);
-}
-
-void
-RLPwidget::closeEvent(QCloseEvent *e)
-{
+
+void
+RLPwidget::cmReptwoway()
+{
+ if(BaseObj) rep_twowaytable(BaseObj, BaseObj->data);
+}
+
+//protected: widget events
+void
+RLPwidget::paintEvent(QPaintEvent *range)
+{
+ QRect rc;
+
+ rc = range->rect();
+ bitBlt(this, rc.left(), rc.top(), this->mempic, rc.left(), rc.top(),
+ 1+rc.right()-rc.left(), 1+rc.bottom()-rc.top());
+}
+
+void
+RLPwidget::resizeEvent(QResizeEvent *)
+{
+ HScroll->resize(width() -16, 16);
+ HScroll->move(0, height()-16);
+ VScroll->resize(16, height()-OutputClass->MenuHeight-16);
+ VScroll->move(width()-16, OutputClass->MenuHeight);
+ if(BaseObj) BaseObj->Command(CMD_SETSCROLL, 0L, OutputClass);
+}
+
+void
+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();
}
}
- else e->accept();
-}
-
-void
-RLPwidget::mouseDoubleClickEvent(QMouseEvent *e)
-{
- MouseEvent mev = {1, e->button() == Qt::LeftButton?MOUSE_LBDOUBLECLICK:-1,e->x(),e->y()};
-
- if (BaseObj)BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-RLPwidget::mousePressEvent(QMouseEvent *e)
-{
- int i;
- MouseEvent mev = {1, e->button() == Qt::LeftButton ? MOUSE_LBDOWN : -1, e->x(), e->y()};
-
- HideTextCursor();
- i = e->state();
+ else e->accept();
+}
+
+void
+RLPwidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ MouseEvent mev = {1, e->button() == Qt::LeftButton?MOUSE_LBDOUBLECLICK:-1,e->x(),e->y()};
+
+ if (BaseObj)BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+RLPwidget::mousePressEvent(QMouseEvent *e)
+{
+ int i;
+ MouseEvent mev = {1, e->button() == Qt::LeftButton ? MOUSE_LBDOWN : -1, e->x(), e->y()};
+
+ HideTextCursor(); i = e->state();
if(i & Qt::ShiftButton) mev.StateFlags |= 0x08;
if(i & Qt::ControlButton) mev.StateFlags |= 0x10;
- if (BaseObj)BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-RLPwidget::mouseReleaseEvent(QMouseEvent *e)
+ if (BaseObj)BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+RLPwidget::mouseReleaseEvent(QMouseEvent *e)
{
int i;
- MouseEvent mev = {0, e->button() == Qt::LeftButton ? MOUSE_LBUP :
- e->button() == Qt::RightButton ? MOUSE_RBUP : -1, e->x(), e->y()};
+ MouseEvent mev = {0, e->button() == Qt::LeftButton ? MOUSE_LBUP :
+ e->button() == Qt::RightButton ? MOUSE_RBUP : -1, e->x(), e->y()};
i = e->state();
if(i & Qt::ShiftButton) mev.StateFlags |= 0x08;
if(i & Qt::ControlButton) mev.StateFlags |= 0x10;
- if (BaseObj) BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-RLPwidget::mouseMoveEvent(QMouseEvent *e)
-{
- int i;
- MouseEvent mev = {0, MOUSE_MOVE, e->x(), e->y()};
-
+ if (BaseObj) BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+RLPwidget::mouseMoveEvent(QMouseEvent *e)
+{
+ int i;
+ MouseEvent mev = {0, MOUSE_MOVE, e->x(), e->y()};
+
i = e->state();
if(i & Qt::LeftButton) mev.StateFlags |= 0x01;
if(i & Qt::ShiftButton) mev.StateFlags |= 0x08;
if(i & Qt::ControlButton) mev.StateFlags |= 0x10;
- if (BaseObj) BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-RLPwidget::keyPressEvent(QKeyEvent *e)
-{
- int i, c;
-
- if(BaseObj) switch(c = e->key()) {
- case Key_Prior:
+ if (BaseObj) BaseObj->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+RLPwidget::keyPressEvent(QKeyEvent *e)
+{
+ int i, c;
+
+ if(BaseObj) switch(c = e->key()) {
+ case Key_Prior:
i = e->state();
if(i & Qt::ShiftButton) BaseObj->Command(CMD_SHPGUP, 0L, OutputClass);
- else BaseObj->Command(CMD_PAGEUP, 0L, OutputClass);
- break;
- case Key_Next:
+ else BaseObj->Command(CMD_PAGEUP, 0L, OutputClass);
+ break;
+ case Key_Next:
i = e->state();
if(i & Qt::ShiftButton) BaseObj->Command(CMD_SHPGDOWN, 0L, OutputClass);
- else BaseObj->Command(CMD_PAGEDOWN, 0L, OutputClass);
- break;
- case Key_Left:
- if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTLEFT, 0L, OutputClass);
- else BaseObj->Command(CMD_CURRLEFT, 0L, OutputClass);
- break;
- case Key_Right:
- if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTRIGHT, 0L, OutputClass);
- else BaseObj->Command(CMD_CURRIGHT, 0L, OutputClass);
- break;
- case Key_Up:
- if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTUP, 0L, OutputClass);
- else BaseObj->Command(CMD_CURRUP, 0L, OutputClass);
- break;
- case Key_Down:
- if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTDOWN, 0L, OutputClass);
- else BaseObj->Command(CMD_CURRDOWN, 0L, OutputClass);
- break;
- case Key_Delete:
- BaseObj->Command(CMD_DELETE, 0L, OutputClass);
- break;
- case Key_Tab:
- BaseObj->Command(CMD_TAB, 0L, OutputClass);
- break;
- case Key_Backtab:
- BaseObj->Command(CMD_SHTAB, 0L, OutputClass);
- break;
- case Key_Home:
- BaseObj->Command(CMD_POS_FIRST, 0L, OutputClass);
- break;
- case Key_End:
- BaseObj->Command(CMD_POS_LAST, 0L, OutputClass);
- break;
- default:
- c = e->ascii();
- if(c == 3) cmCopy();
- else if(c == 22) cmPaste();
- else if(c == 26) cmUndo();
- else if(c >1 && c < 256)
- BaseObj->Command(CMD_ADDCHAR, (void *)(& c), OutputClass);
- break;
- }
- e->accept();
-}
-
-void
-RLPwidget::focusInEvent(QFocusEvent *e)
-{
- CurrWidgetPos.x = x(); CurrWidgetPos.y = y();
- if(BaseObj) {
- if(BaseObj->Id == GO_GRAPH) CurrGraph = (Graph*)BaseObj;
- }
-}
-
-//private functions
-void
-RLPwidget::openHistoryFile(int idx)
-{
- char *name = 0L;
-
- switch (idx) {
- case 0: name = defs.File1; break;
- case 1: name = defs.File2; break;
- case 2: name = defs.File3; break;
- case 3: name = defs.File4; break;
- case 4: name = defs.File5; break;
- case 5: name = defs.File6; break;
- }
- if(name && FileExist(name)) {
- BaseObj->Command(CMD_DROPFILE, name, OutputClass);
- defs.FileHistory(name);
- OutputClass->FileHistory();
- }
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Print and output EPS to file
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class FileEPS:public QPrinter {
-public:
- FileEPS(GraphObj *g, anyOutput *o);
-
-protected:
- int metric(int) const;
-
-private:
- GraphObj *go;
- anyOutput *out;
-};
-
-FileEPS::FileEPS(GraphObj *g, anyOutput *o)
-{
- go = g;
- out = o;
-}
-
-int
-FileEPS::metric(int m) const
-{
- if(go && out)switch (m) {
- case QPaintDeviceMetrics::PdmWidth:
- return out->un2ix(go->GetSize(SIZE_GRECT_RIGHT) - go->GetSize(SIZE_GRECT_LEFT))/10;
- case QPaintDeviceMetrics::PdmHeight:
- return out->un2ix(go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP))/10;
- case QPaintDeviceMetrics::PdmWidthMM:
- return iround((go->GetSize(SIZE_GRECT_RIGHT) - go->GetSize(SIZE_GRECT_LEFT)) *
- Units[defs.cUnits].convert);
- case QPaintDeviceMetrics::PdmHeightMM:
- return iround((go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP)) *
- Units[defs.cUnits].convert);
- }
- return QPrinter::metric(m);
-}
-
-PrintQT::PrintQT(GraphObj *g, char *file)
-{
- hres = vres = 720.0;
- units = defs.cUnits;
- Box1.Xmin = Box1.Ymin = 0.0;
- Box1.Xmax = Box1.Ymax = 6000;
- DeskRect.left = DeskRect.top = 0;
- DeskRect.right = (long)(hres*6.0);
- DeskRect.bottom = (long)(vres*8.0);
- dxf.setMatrix(0.1, 0.0, 0.0, 0.1, 0.0, 0.0);
- hgo = 0L;
- if(file) fileName = strdup(file);
- else fileName = 0L;
- go = g;
- if(fileName && go) printer = new FileEPS(g, this);
- else printer = new QPrinter;
- bPrinting = false;
-}
-
-PrintQT::~PrintQT()
-{
- if(printer) delete(printer);
- if(hgo) delete(hgo);
- if(fileName) free(fileName);
-}
-
-bool
-PrintQT::ActualSize(RECT *rc)
-{
- if(printer) {
- QPaintDeviceMetrics dm(printer); rc->top = rc->left = 0;
- rc->bottom = dm.height() *10; rc->right = dm.width() *10;
- return true;
- }
- return false;
-}
-
-bool
-PrintQT::SetLine(LineDEF *lDef)
-{
- int iw;
-
- if(lDef->width != LineWidth || lDef->width != LineWidth ||
- lDef->pattern != dPattern || lDef->color != dLineCol) {
- LineWidth = lDef->width;
- iw = iround(un2fix(lDef->width));
- dPattern = lDef->pattern;
- RLP.finc = 256.0/un2fix(lDef->patlength*8.0);
- RLP.fp = 0.0;
- if(iLine == iw && dLineCol == lDef->color) return true;
- iLine = iw;
- dLineCol = lDef->color;
- qPen.setColor(SwapRB(dLineCol));
- qPen.setWidth(iw);
- qPen.setStyle(Qt::SolidLine);
- qPen.setCapStyle(Qt::RoundCap);
- qPen.setJoinStyle(Qt::RoundJoin);
- qPainter.setPen(qPen);
- }
- return true;
-}
-
-bool
-PrintQT::SetFill(FillDEF *fill)
-{
- if(!fill) return false;
- if((fill->type & 0xff) != FILL_NONE) {
- if(!hgo) hgo = new HatchOut(this);
- if(hgo) hgo->SetFill(fill);
- }
- else {
- if(hgo) delete hgo;
- hgo = 0L;
- }
- qPainter.setBrush(QColor(SwapRB(fill->color)));
- dFillCol = fill->color;
- dFillCol2 = fill->color2;
- return true;
-}
-
-bool
-PrintQT::SetTextSpec(TextDEF *set)
-{
+ else BaseObj->Command(CMD_PAGEDOWN, 0L, OutputClass);
+ break;
+ case Key_Left:
+ if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTLEFT, 0L, OutputClass);
+ else BaseObj->Command(CMD_CURRLEFT, 0L, OutputClass);
+ break;
+ case Key_Right:
+ if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTRIGHT, 0L, OutputClass);
+ else BaseObj->Command(CMD_CURRIGHT, 0L, OutputClass);
+ break;
+ case Key_Up:
+ if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTUP, 0L, OutputClass);
+ else BaseObj->Command(CMD_CURRUP, 0L, OutputClass);
+ break;
+ case Key_Down:
+ if(e->state() & ShiftButton) BaseObj->Command(CMD_SHIFTDOWN, 0L, OutputClass);
+ else BaseObj->Command(CMD_CURRDOWN, 0L, OutputClass);
+ break;
+ case Key_Delete:
+ BaseObj->Command(CMD_DELETE, 0L, OutputClass);
+ break;
+ case Key_Tab:
+ BaseObj->Command(CMD_TAB, 0L, OutputClass);
+ break;
+ case Key_Backtab:
+ BaseObj->Command(CMD_SHTAB, 0L, OutputClass);
+ break;
+ case Key_Home:
+ BaseObj->Command(CMD_POS_FIRST, 0L, OutputClass);
+ break;
+ case Key_End:
+ BaseObj->Command(CMD_POS_LAST, 0L, OutputClass);
+ break;
+ default:
+ c = e->ascii();
+ if(c == 3) cmCopy();
+ else if(c == 22) cmPaste();
+ else if(c == 26) cmUndo();
+ else if(c >1 && c < 256)
+ BaseObj->Command(CMD_ADDCHAR, (void *)(& c), OutputClass);
+ break;
+ }
+ e->accept();
+}
+
+void
+RLPwidget::focusInEvent(QFocusEvent *e)
+{
+ CurrWidgetPos.x = x(); CurrWidgetPos.y = y();
+ if(BaseObj) {
+ if(BaseObj->Id == GO_GRAPH) CurrGraph = (Graph*)BaseObj;
+ }
+}
+
+//private functions
+void
+RLPwidget::openHistoryFile(int idx)
+{
+ char *name = 0L;
+
+ switch (idx) {
+ case 0: name = defs.File1; break;
+ case 1: name = defs.File2; break;
+ case 2: name = defs.File3; break;
+ case 3: name = defs.File4; break;
+ case 4: name = defs.File5; break;
+ case 5: name = defs.File6; break;
+ }
+ if(name && FileExist(name)) {
+ BaseObj->Command(CMD_DROPFILE, name, OutputClass);
+ defs.FileHistory(name);
+ OutputClass->FileHistory();
+ }
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Print and output EPS to file
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class FileEPS:public QPrinter {
+public:
+ FileEPS(GraphObj *g, anyOutput *o);
+
+protected:
+ int metric(int) const;
+
+private:
+ GraphObj *go;
+ anyOutput *out;
+};
+
+FileEPS::FileEPS(GraphObj *g, anyOutput *o)
+{
+ go = g;
+ out = o;
+}
+
+int
+FileEPS::metric(int m) const
+{
+ if(go && out)switch (m) {
+ case QPaintDeviceMetrics::PdmWidth:
+ return out->un2ix(go->GetSize(SIZE_GRECT_RIGHT) - go->GetSize(SIZE_GRECT_LEFT))/10;
+ case QPaintDeviceMetrics::PdmHeight:
+ return out->un2ix(go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP))/10;
+ case QPaintDeviceMetrics::PdmWidthMM:
+ return iround((go->GetSize(SIZE_GRECT_RIGHT) - go->GetSize(SIZE_GRECT_LEFT)) *
+ Units[defs.cUnits].convert);
+ case QPaintDeviceMetrics::PdmHeightMM:
+ return iround((go->GetSize(SIZE_GRECT_BOTTOM) - go->GetSize(SIZE_GRECT_TOP)) *
+ Units[defs.cUnits].convert);
+ }
+ return QPrinter::metric(m);
+}
+
+PrintQT::PrintQT(GraphObj *g, char *file)
+{
+ units = defs.cUnits;
+ dxf.setMatrix(0.1, 0.0, 0.0, 0.1, 0.0, 0.0);
+ hgo = 0L;
+ if(file) fileName = strdup(file);
+ else fileName = 0L;
+ go = g;
+ if(fileName && go) printer = new FileEPS(g, this);
+ else printer = new QPrinter(QPrinter::HighResolution);
+ hres = vres = (9.5*((double)printer->resolution()));
+ Box1.Xmin = Box1.Ymin = 0.0;
+ Box1.Xmax = Box1.Ymax = 6000;
+ DeskRect.left = DeskRect.top = 0;
+ DeskRect.right = (long)(hres*6.0);
+ DeskRect.bottom = (long)(vres*8.0);
+ bPrinting = false;
+}
+
+PrintQT::~PrintQT()
+{
+ if(printer) delete(printer);
+ if(hgo) delete(hgo);
+ if(fileName) free(fileName);
+}
+
+bool
+PrintQT::ActualSize(RECT *rc)
+{
+ if(printer) {
+ QPaintDeviceMetrics dm(printer); rc->top = rc->left = 0;
+ rc->bottom = dm.height() *10; rc->right = dm.width() *10;
+ return true;
+ }
+ return false;
+}
+
+bool
+PrintQT::SetLine(LineDEF *lDef)
+{
+ int iw;
+
+ if(lDef->width != LineWidth || lDef->width != LineWidth ||
+ lDef->pattern != dPattern || lDef->color != dLineCol) {
+ LineWidth = lDef->width;
+ iw = iround(un2fix(lDef->width));
+ dPattern = lDef->pattern;
+ RLP.finc = 256.0/un2fix(lDef->patlength*8.0);
+ RLP.fp = 0.0;
+ if(iLine == iw && dLineCol == lDef->color) return true;
+ iLine = iw;
+ dLineCol = lDef->color;
+ qPen.setColor(SwapRB(dLineCol));
+ qPen.setWidth(iw);
+ qPen.setStyle(Qt::SolidLine);
+ qPen.setCapStyle(Qt::RoundCap);
+ qPen.setJoinStyle(Qt::RoundJoin);
+ qPainter.setPen(qPen);
+ }
+ return true;
+}
+
+bool
+PrintQT::SetFill(FillDEF *fill)
+{
+ if(!fill) return false;
+ if((fill->type & 0xff) != FILL_NONE) {
+ if(!hgo) hgo = new HatchOut(this);
+ if(hgo) hgo->SetFill(fill);
+ }
+ else {
+ if(hgo) delete hgo;
+ hgo = 0L;
+ }
+ qPainter.setBrush(QColor(SwapRB(fill->color)));
+ dFillCol = fill->color;
+ dFillCol2 = fill->color2;
+ return true;
+}
+
+bool
+PrintQT::SetTextSpec(TextDEF *set)
+{
+ set->iSize = un2ix(set->fSize/7.5);
return com_SetTextSpec(set, &TxtSet, this, qFont, &qPainter);
-}
-
-bool
-PrintQT::StartPage()
-{
- if(!printer || bPrinting) return false;
- if(fileName) {
- VPorg.fy = -co2fiy(go->GetSize(SIZE_GRECT_TOP));
- VPorg.fx = -co2fix(go->GetSize(SIZE_GRECT_LEFT));
- printer->setOutputFileName(fileName);
- printer->setFullPage(true);
- qPainter.begin(printer);
- qPainter.setWorldMatrix(dxf, FALSE);
- return bPrinting = true;
- }
-
- if(printer->setup(0)){
- qPainter.begin(printer);
- qPainter.setWorldMatrix(dxf, FALSE);
- return bPrinting = true;
- }
- else return false;
-}
-
-bool
-PrintQT::EndPage()
-{
- qPainter.flush(); qPainter.end(); bPrinting = false;
- return true;
-}
-
-bool
-PrintQT::Eject()
-{
- if(!bPrinting) return false;
- qPainter.flush(); qPainter.end(); qPainter.begin(printer);
- qPainter.setWorldMatrix(dxf, FALSE);
- return true;
-}
-
-bool
-PrintQT::oGetTextExtent(char *text, int cb, int *width, int *height)
-{
- QRect rc = qPainter.boundingRect(0, 0, 10000, 1000, Qt::AlignLeft | Qt::AlignTop,
- text, cb > 0 ? cb : strlen(text));
- *width = rc.rRight() - rc.rLeft(); *height = rc.rBottom() - rc.rTop();
- return true;
-}
-
-bool
-PrintQT::oCircle(int x1, int y1, int x2, int y2, char* nam)
-{
- qPainter.drawEllipse(x1, y1, x2-x1, y2-y1);
- if(hgo) return hgo->oCircle(x1, y1, x2, y2);
- return true;
-}
-
-bool
-PrintQT::oPolyline(POINT * pts, int cp, char *nam)
-{
- int i;
-
- if(cp < 1) return false;
- if (dPattern) {
- for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
- }
- else {
- qPainter.moveTo(pts[0].x, pts[0].y);
- for (i = 1; i < cp; i++) qPainter.lineTo(pts[i].x, pts[i].y);
- }
- return true;
-}
-
-bool
-PrintQT::oRectangle(int x1, int y1, int x2, int y2, char *nam)
-{
- qPainter.drawRect(x1, y1, x2-x1-1, y2-y1-1);
- if(hgo) hgo->oRectangle(x1, y1, x2, y2, 0L);
- return true;
-}
-
-bool
-PrintQT::oSolidLine(POINT *p)
-{
- qPainter.drawLine(p[0].x, p[0].y, p[1].x, p[1].y);
- return true;
-}
-
-bool
-PrintQT::oTextOut(int x, int y, char *txt, int cb)
+}
+
+bool
+PrintQT::StartPage()
+{
+ if(!printer || bPrinting) return false;
+ if(fileName) {
+ VPorg.fy = -co2fiy(go->GetSize(SIZE_GRECT_TOP));
+ VPorg.fx = -co2fix(go->GetSize(SIZE_GRECT_LEFT));
+ printer->setOutputFileName(fileName);
+ printer->setFullPage(true);
+ qPainter.begin(printer);
+ qPainter.setWorldMatrix(dxf, FALSE);
+ return bPrinting = true;
+ }
+ if(printer->setup(0)){
+ qPainter.begin(printer);
+ qPainter.setWorldMatrix(dxf, FALSE);
+ return bPrinting = true;
+ }
+ else return false;
+}
+
+bool
+PrintQT::EndPage()
+{
+ qPainter.flush(); qPainter.end(); bPrinting = false;
+ return true;
+}
+
+bool
+PrintQT::Eject()
+{
+ if(!bPrinting) return false;
+ qPainter.flush(); qPainter.end(); qPainter.begin(printer);
+ qPainter.setWorldMatrix(dxf, FALSE);
+ return true;
+}
+
+bool
+PrintQT::oGetTextExtent(char *text, int cb, int *width, int *height)
+{
+ if(!text || !text[0]){
+ QRect rc = qPainter.boundingRect(0, 0, 10000, 1000, Qt::AlignLeft | Qt::AlignTop, "A", 1);
+ *width = rc.rLeft();
+ }
+ else {
+ QRect rc = qPainter.boundingRect(0, 0, 10000, 1000, Qt::AlignLeft | Qt::AlignTop,
+ text, cb > 0 ? cb : strlen(text));
+ *width = rc.rRight() - rc.rLeft();
+ }
+ *height = TxtSet.iSize +2;
+ return true;
+}
+
+bool
+PrintQT::oCircle(int x1, int y1, int x2, int y2, char* nam)
+{
+ qPainter.drawEllipse(x1, y1, x2-x1, y2-y1);
+ if(hgo) return hgo->oCircle(x1, y1, x2, y2);
+ return true;
+}
+
+bool
+PrintQT::oPolyline(POINT * pts, int cp, char *nam)
{
+ int i;
+
+ if(cp < 1) return false;
+ if (dPattern) {
+ for (i = 1; i < cp; i++) PatLine(pts[i-1], pts[i]);
+ }
+ else {
+ qPainter.moveTo(pts[0].x, pts[0].y);
+ for (i = 1; i < cp; i++) qPainter.lineTo(pts[i].x, pts[i].y);
+ }
+ return true;
+}
+
+bool
+PrintQT::oRectangle(int x1, int y1, int x2, int y2, char *nam)
+{
+ qPainter.drawRect(x1, y1, x2-x1-1, y2-y1-1);
+ if(hgo) hgo->oRectangle(x1, y1, x2, y2, 0L);
+ return true;
+}
+
+bool
+PrintQT::oSolidLine(POINT *p)
+{
+ qPainter.drawLine(p[0].x, p[0].y, p[1].x, p[1].y);
+ return true;
+}
+
+bool
+PrintQT::oTextOut(int x, int y, char *txt, int cb)
+{
+ if(!txt || !txt[0]) return false;
+ if(TxtSet.fSize > 0.0) TxtSet.iSize = un2ix(TxtSet.fSize);
+ if(!TxtSet.iSize) return false;
+ if(TxtSet.Align & TXA_VCENTER) y += iround(TxtSet.iSize * 0.4);
+ else if(TxtSet.Align & TXA_VBOTTOM) y -= iround(TxtSet.iSize * 0.1);
+ else y += iround(TxtSet.iSize * 1.0);
return com_TextOut(x, y, txt, &TxtSet, &qPainter, this);
}
-
-bool
-PrintQT::oPolygon(POINT *pts, int cp, char *nam)
-{
- int i;
-
- QPointArray *a;
-
- if(!pts || cp <2) return false;
- a = new QPointArray(cp);
- if (a) {
- for(i = 0; i < cp; i++) a->setPoint(i, pts[i].x, pts[i].y);
- qPainter.drawPolygon(*a);
- delete a;
- }
- if(hgo) hgo->oPolygon(pts, cp);
- return true;
-}
-
-bool
-PrintQT::oArc(int x1, int y1, int x2, int y2, int quads)
-{
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Find a suitable www browser
-void FindBrowser()
-{
- //find a suitable browser
- if(FileExist("/usr/bin/mozilla")) WWWbrowser = strdup("mozilla");
- else if(FileExist("/usr/bin/netscape")) WWWbrowser = strdup("netscape");
- else if(FileExist("/usr/bin/konqueror")) WWWbrowser = strdup("konqueror");
- else if(FileExist("/opt/kde3/bin/konqueror")) WWWbrowser = strdup("konqueror");
- //use home as startup directory
- sprintf(TmpTxt, "%s", getenv("HOME"));
- defs.currPath = strdup(TmpTxt); strcat(TmpTxt, "/.RLPlot");
- defs.IniFile = strdup(TmpTxt);
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// The MAIN antry point
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-int main (int argc, char **argv)
-{
- QApplication a(argc, argv);
- DefsRW *drw;
-
- if(argc > 1 && argv[1] && argv[1][0] && FileExist(argv[1]))
- LoadFile = strdup(argv[1]);
- QAppl = &a;
- InitTextCursor(true);
- ShowBanner(true);
- a.exec();
- if(defs.IniFile) {
- if(drw = new DefsRW()){
- drw->FileIO(FILE_WRITE); delete drw;
- }
- }
- return 0;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Dialog box support
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-DlgWidget::DlgWidget(QWidget *par, const char *name, tag_DlgObj *d)
-#ifdef Q_CHECK_PTR //n.a. in Qt version 2
-: QWidget(par, name, Qt::WType_Dialog)
-#else
-: QWidget(par, name, 0x0000002)
-#endif
-{
- parent = par;
- dlg = d;
- setFocusPolicy(StrongFocus);
-}
-
-DlgWidget::~DlgWidget()
-{
- if(OutputClass){
- ((OutputQT*)OutputClass)->widget=0L;
- delete ((OutputQT*)OutputClass);
- }
-}
-
-void
-DlgWidget::paintEvent(QPaintEvent *range)
-{
- QRect rc;
-
- rc = range->rect();
- bitBlt(this, rc.left(), rc.top(), this->mempic, rc.left(), rc.top(),
- 1+rc.right()-rc.left(), 1+rc.bottom()-rc.top());
-}
-
-void
-DlgWidget::mouseDoubleClickEvent(QMouseEvent *e)
-{
- MouseEvent mev = {1, e->button() == Qt::LeftButton?MOUSE_LBDOUBLECLICK:-1,e->x(),e->y()};
-
- if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-DlgWidget::mousePressEvent(QMouseEvent *e)
-{
- MouseEvent mev = {1, e->button() == Qt::LeftButton ? MOUSE_LBDOWN : -1, e->x(), e->y()};
-
- HideTextCursor();
- if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-DlgWidget::mouseReleaseEvent(QMouseEvent *e)
-{
- MouseEvent mev = {0, e->button() == Qt::LeftButton ? MOUSE_LBUP : -1, e->x(), e->y()};
-
- if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-DlgWidget::mouseMoveEvent(QMouseEvent *e)
-{
- MouseEvent mev = {1, e->state() == Qt::LeftButton ? MOUSE_MOVE : -1, e->x(), e->y()};
-
- if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
-}
-
-void
-DlgWidget::keyPressEvent(QKeyEvent *e)
-{
- int c;
-
- if(dlg) switch(c = e->key()) {
- case Key_Left:
- if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTLEFT, 0L, OutputClass);
- else dlg->Command(CMD_CURRLEFT, 0L, OutputClass);
- break;
- case Key_Right:
- if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTRIGHT, 0L, OutputClass);
- else dlg->Command(CMD_CURRIGHT, 0L, OutputClass);
- break;
- case Key_Up:
- if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTUP, 0L, OutputClass);
- else dlg->Command(CMD_CURRUP, 0L, OutputClass);
- break;
- case Key_Down:
- if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTDOWN, 0L, OutputClass);
- else dlg->Command(CMD_CURRDOWN, 0L, OutputClass);
- break;
- case Key_Delete:
- dlg->Command(CMD_DELETE, 0L, OutputClass);
- break;
- case Key_Tab:
- dlg->Command(CMD_TAB, 0L, OutputClass);
- break;
- case Key_Backtab:
- dlg->Command(CMD_SHTAB, 0L, OutputClass);
- break;
- case Key_Home:
- dlg->Command(CMD_POS_FIRST, 0L, OutputClass);
- break;
- case Key_End:
- dlg->Command(CMD_POS_LAST, 0L, OutputClass);
- break;
- default:
- c = e->ascii();
+
+bool
+PrintQT::oPolygon(POINT *pts, int cp, char *nam)
+{
+ int i;
+
+ QPointArray *a;
+
+ if(!pts || cp <2) return false;
+ a = new QPointArray(cp);
+ if (a) {
+ for(i = 0; i < cp; i++) a->setPoint(i, pts[i].x, pts[i].y);
+ qPainter.drawPolygon(*a);
+ delete a;
+ }
+ if(hgo) hgo->oPolygon(pts, cp);
+ return true;
+}
+
+bool
+PrintQT::oArc(int x1, int y1, int x2, int y2, int quads)
+{
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Find a suitable www browser
+void FindBrowser()
+{
+ //find a suitable browser
+ if(FileExist("/usr/bin/mozilla")) WWWbrowser = strdup("mozilla");
+ else if(FileExist("/usr/bin/netscape")) WWWbrowser = strdup("netscape");
+ else if(FileExist("/usr/bin/konqueror")) WWWbrowser = strdup("konqueror");
+ else if(FileExist("/opt/kde3/bin/konqueror")) WWWbrowser = strdup("konqueror");
+ //use home as startup directory
+ sprintf(TmpTxt, "%s", getenv("HOME"));
+ defs.currPath = strdup(TmpTxt); strcat(TmpTxt, "/.RLPlot");
+ defs.IniFile = strdup(TmpTxt);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The MAIN antry point
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+int main (int argc, char **argv)
+{
+ QApplication a(argc, argv);
+ DefsRW *drw;
+
+ if(argc > 1 && argv[1] && argv[1][0] && FileExist(argv[1]))
+ LoadFile = strdup(argv[1]);
+ QAppl = &a;
+ InitTextCursor(true);
+ ShowBanner(true);
+ a.exec();
+ if(defs.IniFile) {
+ if(drw = new DefsRW()){
+ drw->FileIO(FILE_WRITE); delete drw;
+ }
+ }
+ return 0;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Dialog box support
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+DlgWidget::DlgWidget(QWidget *par, const char *name, tag_DlgObj *d)
+#ifdef Q_CHECK_PTR //n.a. in Qt version 2
+: QWidget(par, name, Qt::WType_Dialog)
+#else
+: QWidget(par, name, 0x0000002)
+#endif
+{
+ parent = par;
+ dlg = d;
+ setFocusPolicy(StrongFocus);
+}
+
+DlgWidget::~DlgWidget()
+{
+ if(OutputClass){
+ ((OutputQT*)OutputClass)->widget=0L;
+ delete ((OutputQT*)OutputClass);
+ }
+}
+
+void
+DlgWidget::paintEvent(QPaintEvent *range)
+{
+ QRect rc;
+
+ rc = range->rect();
+ bitBlt(this, rc.left(), rc.top(), this->mempic, rc.left(), rc.top(),
+ 1+rc.right()-rc.left(), 1+rc.bottom()-rc.top());
+}
+
+void
+DlgWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ MouseEvent mev = {1, e->button() == Qt::LeftButton?MOUSE_LBDOUBLECLICK:-1,e->x(),e->y()};
+
+ if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+DlgWidget::mousePressEvent(QMouseEvent *e)
+{
+ MouseEvent mev = {1, e->button() == Qt::LeftButton ? MOUSE_LBDOWN : -1, e->x(), e->y()};
+
+ HideTextCursor();
+ if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+DlgWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ MouseEvent mev = {0, e->button() == Qt::LeftButton ? MOUSE_LBUP : -1, e->x(), e->y()};
+
+ if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+DlgWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ MouseEvent mev = {1, e->state() == Qt::LeftButton ? MOUSE_MOVE : -1, e->x(), e->y()};
+
+ if (dlg) dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, OutputClass);
+}
+
+void
+DlgWidget::keyPressEvent(QKeyEvent *e)
+{
+ int c;
+
+ if(dlg) switch(c = e->key()) {
+ case Key_Left:
+ if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTLEFT, 0L, OutputClass);
+ else dlg->Command(CMD_CURRLEFT, 0L, OutputClass);
+ break;
+ case Key_Right:
+ if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTRIGHT, 0L, OutputClass);
+ else dlg->Command(CMD_CURRIGHT, 0L, OutputClass);
+ break;
+ case Key_Up:
+ if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTUP, 0L, OutputClass);
+ else dlg->Command(CMD_CURRUP, 0L, OutputClass);
+ break;
+ case Key_Down:
+ if(e->state() & ShiftButton) dlg->Command(CMD_SHIFTDOWN, 0L, OutputClass);
+ else dlg->Command(CMD_CURRDOWN, 0L, OutputClass);
+ break;
+ case Key_Delete:
+ dlg->Command(CMD_DELETE, 0L, OutputClass);
+ break;
+ case Key_Tab:
+ dlg->Command(CMD_TAB, 0L, OutputClass);
+ break;
+ case Key_Backtab:
+ dlg->Command(CMD_SHTAB, 0L, OutputClass);
+ break;
+ case Key_Home:
+ dlg->Command(CMD_POS_FIRST, 0L, OutputClass);
+ break;
+ case Key_End:
+ dlg->Command(CMD_POS_LAST, 0L, OutputClass);
+ break;
+ default:
+ c = e->ascii();
if(c >1 && c < 256)
if(c == 26) dlg->Command(CMD_UNDO, 0L, OutputClass);
else if(c == 0x03) dlg->Command(CMD_COPY, 0L, OutputClass);
else if(c == 0x16) dlg->Command(CMD_PASTE, 0L, OutputClass);
- else dlg->Command(CMD_ADDCHAR, (void *)(& c), OutputClass);
- break;
- }
- e->accept();
-}
-
-void
-DlgWidget::focusInEvent(QFocusEvent *e)
-{
- CurrWidgetPos.x = x(); CurrWidgetPos.y = y();
-}
-
-void
-DlgWidget::focusOutEvent(QFocusEvent *e)
-{
- HideTextCursorObj(OutputClass);
- if(dlg) dlg->Command(CMD_ENDDIALOG, 0L, OutputClass);
-}
-
-void
-DlgWidget::closeEvent(QCloseEvent *e)
-{
- HideTextCursorObj(OutputClass);
- e->ignore();
- if(dlg){
- dlg->Command(CMD_UNLOCK, 0L, OutputClass);
- dlg->Command(CMD_ENDDIALOG, 0L, OutputClass);
- }
-}
-
-void
-DlgWidget::timerEvent(QTimerEvent *)
-{
- if(dlg) dlg->Command(CMD_ENDDIALOG, dlg, OutputClass);
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-void *CreateDlgWnd(char *title, int x, int y, int width, int height, tag_DlgObj *d, DWORD flags)
-{
- DlgWidget *w;
- OutputQT *o;
- int dw, dh;
-
- w = new DlgWidget(QAppl->focusWidget(), 0, d);
- w->setCaption(title);
- if(flags & 0x2) w->setFixedSize(width, height);
- else w->setFixedSize(width-6, height-16);
- if(flags & 0x1) {
- GetDesktopSize(&dw, &dh);
- w->move((dw>>1) - ((w->width())>>1), (dh>>1) - ((w->height())>>1));
- }
- else w->move(CurrWidgetPos.x+x, CurrWidgetPos.y+y);
- o = new OutputQT(w);
- o->units = defs.cUnits;
- o->Erase(0x00e0e0e0L);
- if(flags & 0x04) {
- w->startTimer(100);
- }
- d->DoPlot(o);
- w->show();
- return w;
-}
-
-void LoopDlgWnd() //keep message processing running
-{
- QAppl->processOneEvent();
-}
-
-void CloseDlgWnd(void *hDlg)
-{
+ else dlg->Command(CMD_ADDCHAR, (void *)(& c), OutputClass);
+ break;
+ }
+ e->accept();
+}
+
+void
+DlgWidget::focusInEvent(QFocusEvent *e)
+{
+ CurrWidgetPos.x = x(); CurrWidgetPos.y = y();
+}
+
+void
+DlgWidget::focusOutEvent(QFocusEvent *e)
+{
+ HideTextCursorObj(OutputClass);
+ if(dlg) dlg->Command(CMD_ENDDIALOG, 0L, OutputClass);
+}
+
+void
+DlgWidget::closeEvent(QCloseEvent *e)
+{
+ HideTextCursorObj(OutputClass);
+ e->ignore();
+ if(dlg){
+ dlg->Command(CMD_UNLOCK, 0L, OutputClass);
+ dlg->Command(CMD_ENDDIALOG, 0L, OutputClass);
+ }
+}
+
+void
+DlgWidget::timerEvent(QTimerEvent *)
+{
+ if(dlg) dlg->Command(CMD_ENDDIALOG, dlg, OutputClass);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void *CreateDlgWnd(char *title, int x, int y, int width, int height, tag_DlgObj *d, DWORD flags)
+{
+ DlgWidget *w;
+ QWidget *pw;
+ OutputQT *o;
+ int dw, dh;
+
+ w = new DlgWidget(pw = QAppl->activeWindow(), 0, d);
+ w->setCaption(title);
+ if(flags & 0x2) w->setFixedSize(width, height);
+ else w->setFixedSize(width-6, height-16);
+ if(flags & 0x1) {
+ GetDesktopSize(&dw, &dh);
+ w->move((dw>>1) - ((w->width())>>1), (dh>>1) - ((w->height())>>1));
+ }
+ else if(pw) {
+ if(pw->x() || pw->y()) {
+ x += pw->x(); y += pw->y();
+ }
+ else {
+ x += CurrWidgetPos.x; y += CurrWidgetPos.y;
+ }
+ w->move(x, y);
+ }
+ o = new OutputQT(w); o->units = defs.cUnits;
+ o->Erase(0x00e0e0e0L); if(flags & 0x04) w->startTimer(100);
+ d->DoPlot(o); w->show();
+ return w;
+}
+
+void LoopDlgWnd() //keep message processing running
+{
+ QAppl->processOneEvent();
+}
+
+void CloseDlgWnd(void *hDlg)
+{
HideCopyMark();
- if(hDlg) {
- delete((DlgWidget*) hDlg);
- }
-}
-
-void ShowDlgWnd(void *hDlg)
-{
- if(hDlg){
- ((DlgWidget*)hDlg)->show();
- ((DlgWidget*)hDlg)->setActiveWindow();
- ((DlgWidget*)hDlg)->raise();
- }
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// OS independent interface to Qt specific classes
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-anyOutput *NewDispClass(GraphObj *g)
-{
- return new OutputQT(g);
-}
-
-bool DelDispClass(anyOutput *w)
-{
- if(w) delete (OutputQT*) w;
- return true;
-}
-
-anyOutput *NewBitmapClass(int w, int h, double hr, double vr)
-{
- return new BitMapQT(w, h, hr, vr);
-}
-
-bool DelBitmapClass(anyOutput *w)
-{
- if (w) delete (BitMapQT*) w;
- return true;
-}
-
+ if(hDlg) {
+ delete((DlgWidget*) hDlg);
+ }
+}
+
+void ShowDlgWnd(void *hDlg)
+{
+ if(hDlg){
+ ((DlgWidget*)hDlg)->show();
+ ((DlgWidget*)hDlg)->setActiveWindow();
+ ((DlgWidget*)hDlg)->raise();
+ }
+}
+
+void ResizeDlgWnd(void *hDlg, int w, int h)
+{
+ ((DlgWidget*)hDlg)->setFixedSize(w-6, h-16);
+ ((DlgWidget*)hDlg)->show();
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// OS independent interface to Qt specific classes
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+anyOutput *NewDispClass(GraphObj *g)
+{
+ return new OutputQT(g);
+}
+
+bool DelDispClass(anyOutput *w)
+{
+ if(w) delete (OutputQT*) w;
+ return true;
+}
+
+anyOutput *NewBitmapClass(int w, int h, double hr, double vr)
+{
+ return new BitMapQT(w, h, hr, vr);
+}
+
+bool DelBitmapClass(anyOutput *w)
+{
+ if (w) delete (BitMapQT*) w;
+ return true;
+}
+
diff --git a/QT_Spec.h b/QT_Spec.h
index 43d6c53..ccb1f4c 100755
--- a/QT_Spec.h
+++ b/QT_Spec.h
@@ -172,8 +172,10 @@ public slots:
void cmtEllipse();
void cmtArrow();
void cmtText();
+ void cmRepCmeans();
void cmRepanov();
void cmRepregr();
+ void cmReptwoway();
void cmFile1() {openHistoryFile(0);};
void cmFile2() {openHistoryFile(1);};
void cmFile3() {openHistoryFile(2);};
diff --git a/RLPLOT.RC b/RLPLOT.RC
index cdf725d..76f54fd 100755
--- a/RLPLOT.RC
+++ b/RLPLOT.RC
@@ -135,8 +135,10 @@ BEGIN
END
POPUP "&Statistics"
BEGIN
+ MENUITEM "&Comp. Means" CM_REPCMEANS
MENUITEM "&Anova" CM_REPANOV
MENUITEM "&Regression" CM_REPREGR
+ MENUITEM "&2x2 Table" CM_REPTWOWAY
END
POPUP "&Graph"
BEGIN
diff --git a/TheDialog.cpp b/TheDialog.cpp
index 60dae4e..e3aeeba 100755
--- a/TheDialog.cpp
+++ b/TheDialog.cpp
@@ -56,7 +56,7 @@ Dialog *DialogTabStop = 0L;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Base classes to dialog items
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-DlgRoot::DlgRoot(DlgInfo *tmpl)
+DlgRoot::DlgRoot(DlgInfo *tmpl, DataObj *d)
{
int i;
RECT rc;
@@ -68,6 +68,8 @@ DlgRoot::DlgRoot(DlgInfo *tmpl)
bActive = false; Result = -1; c_go = CurrGO;
CurrDisp = 0L; oldFocus = DialogFocus; DialogFocus = 0L;
oldDefault = DialogDefault; oldTabStop = DialogTabStop;
+ data = d; ParentOut = Undo.cdisp;
+ mrk_item = 0L; //if an item has a mark its this one
if(tmpl) {
//count number of items first, then allocate memory
for(cDlgs=1;!(tmpl[cDlgs-1].flags & LASTOBJ); cDlgs++);
@@ -96,9 +98,6 @@ DlgRoot::DlgRoot(DlgInfo *tmpl)
case ARROWBUTT:
dlg[i]->dialog = new ArrowButton(this, &tmpl[i],rc,(int*)tmpl[i].ptype);
break;
- 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;
@@ -142,7 +141,7 @@ DlgRoot::DlgRoot(DlgInfo *tmpl)
dlg[i]->dialog = new InputText(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
break;
case RANGEINPUT:
- dlg[i]->dialog = new RangeInput(this, &tmpl[i],rc,(char*)tmpl[i].ptype);
+ dlg[i]->dialog = new RangeInput(this, &tmpl[i],rc,(char*)tmpl[i].ptype, data);
break;
case EDVAL1:
dlg[i]->dialog = new InputValue(this, &tmpl[i],rc,(double*)tmpl[i].ptype);
@@ -169,7 +168,7 @@ DlgRoot::DlgRoot(DlgInfo *tmpl)
dlg[i]->dialog = new GroupBox(this, &tmpl[i],rc, (char*)tmpl[i].ptype);
break;
case SHEET:
- dlg[i]->dialog = new TabSheet(this, &tmpl[i],rc, (TabSHEET *)tmpl[i].ptype);
+ dlg[i]->dialog = new TabSheet(this, &tmpl[i],rc, (TabSHEET *)tmpl[i].ptype, data);
break;
case ODBUTTON:
dlg[i]->dialog = new ODbutton(this, &tmpl[i],rc, tmpl[i].ptype);
@@ -196,6 +195,7 @@ DlgRoot::~DlgRoot()
{
int i;
+ if(data) data->Command(CMD_ETRACC, 0L, 0L);
if(dlg){
for (i = 0; dlg[i] && i < cDlgs; i++) {
//we need to delete each object using a cast on its proper type
@@ -205,7 +205,6 @@ DlgRoot::~DlgRoot()
case PUSHBUTTON: delete((PushButton*)dlg[i]->dialog); break;
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;
@@ -246,9 +245,9 @@ DlgRoot::~DlgRoot()
}
free(dlg[i]);
}
- free(dlg);
+ free(dlg); dlg=0L;
}
- if(tabstops) free(tabstops);
+ if(tabstops) free(tabstops); tabstops = 0L;
DialogFocus = oldFocus; DialogDefault = oldDefault;
DialogTabStop = oldTabStop; CurrGO = c_go;
}
@@ -274,13 +273,14 @@ DlgRoot::Command(int cmd, void *tmpl, anyOutput *o)
}
return true;
case CMD_MOUSE_EVENT:
+ if(DialogFocus && DialogFocus->type == TEXTBOX && DialogFocus->Command(cmd, tmpl, o)) return true;
mev = (MouseEvent *) tmpl;
switch(mev->Action) {
case MOUSE_LBDOWN:
bActive = true;
case MOUSE_MOVE:
- if(!(mev->StateFlags & 1))return false;
//track mouse and display controls accordingly
+ if(!(mev->StateFlags & 1))return false;
if(bActive)ForEach(CMD_MOUSE_EVENT, 0, o);
return true;
case MOUSE_LBDOUBLECLICK:
@@ -326,13 +326,13 @@ DlgRoot::Command(int cmd, void *tmpl, anyOutput *o)
HideTextCursor();
if(tabstops && DialogTabStop) {
for(i = 0; tabstops[i] && tabstops[i] != DialogTabStop && i < cDlgs; i++);
- if(tabstops[i]) i++;
+ if((tabstops[i]) || (tabstops[i]->flags & HIDDEN)) i++;
if(!tabstops[i]) i = 0;
switch(tabstops[i]->type) {
case PUSHBUTTON:
d = DialogDefault;
DialogTabStop = DialogDefault = tabstops[i];
- d->DoPlot(o);
+ if(d) d->DoPlot(o);
DialogDefault->DoPlot(o);
break;
case EDTEXT: case EDVAL1: case RANGEINPUT:
@@ -397,6 +397,13 @@ DlgRoot::Command(int cmd, void *tmpl, anyOutput *o)
for(i = 0; i < cDlgs; i++)
if(dlg[i] && dlg[i]->dialog) dlg[i]->dialog->Command(CMD_UNLOCK, 0L, 0L);
break;
+ case CMD_MARKOBJ:
+ if(mrk_item && mrk_item != (Dialog*)tmpl){
+ i = 27;
+ mrk_item->Command(CMD_ADDCHAR, &i, o);
+ }
+ mrk_item = (Dialog*)tmpl;
+ break;
}
return false;
}
@@ -406,9 +413,9 @@ DlgRoot::DoPlot(anyOutput *o)
{
int i;
- HideCopyMark();
+ HideCopyMark(); mrk_item = 0L;
if(tabstops) for(i = 0; i < cDlgs; tabstops[i++] = 0);
- if(o)CurrDisp = o;
+ if(o)CurrDisp = o; DialogDefault = 0L;
if(CurrDisp) {
CurrDisp->SetTextSpec(&DlgText);
ForEach(CMD_DOPLOT, 0, CurrDisp);
@@ -523,12 +530,12 @@ DlgRoot::GetCheck(int Id)
}
bool
-DlgRoot::GetText(int id, char *txt)
+DlgRoot::GetText(int id, char *txt, int size)
{
int i;
i = FindIndex(id);
- if(i && dlg[i]) return dlg[i]->dialog->GetText(id, txt);
+ if(i && dlg[i]) return dlg[i]->dialog->GetText(id, txt, size);
return false;
}
@@ -544,6 +551,20 @@ DlgRoot::SetText(int id, char *txt)
}
bool
+DlgRoot::SetValue(int id, double val)
+{
+ int i;
+ char tmp_txt[80];
+
+ i = FindIndex(id);
+ WriteNatFloatToBuff(tmp_txt, val);
+ if(i && dlg[i] && dlg[i]->dialog->Command(CMD_SETTEXT, tmp_txt+1, CurrDisp)) DoPlot(CurrDisp);
+ else return false;
+ return true;
+}
+
+
+bool
DlgRoot::TextStyle(int id, int style)
{
int i;
@@ -596,6 +617,7 @@ DlgRoot::GetResult()
{
int ret;
+ if(Result >= 0 && ParentOut) Undo.SetDisp(ParentOut);
//return each result only once !
ret = Result;
Result = -1;
@@ -744,8 +766,9 @@ Dialog::MBtrack(MouseEvent *mev, anyOutput *o)
case PUSHBUTTON: case ARROWBUTT: case CHECKBOX: case RADIO1:
case RADIO2: case TRASH: case CONFIG: case CHECKPIN:
if(mev->StateFlags &1) bLBstate = true;
- if(IsInRect(&hcr, mev->x, mev->y)){
- if(bLBstate && !bLBdown){
+ if(IsInRect(&hcr, mev->x, mev->y) && bLBstate){
+ if(parent && type != CHECKBOX && type != RADIO1 && type != RADIO2) parent->Command(CMD_MARKOBJ, this, o);
+ if(!bLBdown){
bLBdown = bLBstate; DoPlot(o);
return;
}
@@ -772,7 +795,7 @@ Dialog::Activate(int id, bool active)
PushButton::PushButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text)
:Dialog(par, desc, rec)
{
- if(text) Text = strdup(text);
+ if(text && text[0]) Text = (char*)memdup(text, (int)strlen(text)+1, 0);
else Text = 0L;
TextDef.Align = TXA_HCENTER | TXA_VCENTER;
}
@@ -800,8 +823,7 @@ PushButton::DoPlot(anyOutput *o)
{
POINT pts[3];
- Line.color = 0x00000000L;
- Fill.color = DlgBGhigh;
+ Line.color = 0x00000000L; Fill.color = DlgBGhigh;
o->SetLine(&Line); o->SetFill(&Fill);
if(bLBdown) o->oRectangle(cr.left, cr.top, cr.right, cr.bottom);
else {
@@ -850,14 +872,18 @@ PushButton::Select(int x, int y, anyOutput *o)
TextBox::TextBox(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text)
:Dialog(par, desc, rec)
{
- TextDef.Font = FONT_COURIER;
+ lfPOINT lfp1, lfp2;
+
+ TextDef.Font = FONT_COURIER; TextDef.Align = TXA_VBOTTOM | TXA_HLEFT;
#ifdef _WINDOWS
// TextDef.fSize unchanged
#else
TextDef.fSize *= .8;
#endif
Fill.color = 0x00ffffffL; Line.color = 0x00000000L; cont = 0L;
- if(text) cont = new mLabel(0L, 0L, rec.left+3, rec.top+1, &TextDef, text);
+ lfp1.fx = rec.left; lfp1.fy = rec.top;
+ lfp2.fx = rec.right; lfp2.fy = rec.bottom;
+ if(cont = new TextFrame(0L, 0L, &lfp1, &lfp2, text)) cont->Command(CMD_SETTEXTDEF, &TextDef, 0L);
}
TextBox::~TextBox()
@@ -871,23 +897,14 @@ TextBox::Command(int cmd, void *tmpl, anyOutput *o)
switch(cmd) {
case CMD_CURRLEFT: case CMD_CURRIGHT: case CMD_DELETE:
case CMD_POS_FIRST: case CMD_POS_LAST: case CMD_SHIFTLEFT:
- case CMD_SHIFTRIGHT: case CMD_ADDCHAR:
- if(bChecked && CurrGO && CurrGO->parent == cont){
- CurrGO->Command(cmd, tmpl, o);
- DoPlot(o); o->MrkMode = MRK_NONE;
- return CurrGO->Command(CMD_REDRAW, 0L, o); //text cursor !
- }
- case CMD_CURRUP: case CMD_CURRDOWN:
- if(bChecked && CurrGO && CurrGO->parent == cont){
- cont->Command(cmd, tmpl, o);
- DoPlot(o); o->MrkMode = MRK_NONE;
- return true;
- }
+ case CMD_SHIFTRIGHT: case CMD_ADDCHAR: case CMD_MOUSE_EVENT:
+ case CMD_COPY: case CMD_PASTE: case CMD_CURRUP:
+ case CMD_CURRDOWN:
+ if(bChecked && CurrGO && CurrGO == cont) return CurrGO->Command(cmd, tmpl, o);
break;
case CMD_SETTEXT:
- if(cont)DeleteGO(cont);
- if(tmpl) cont = new mLabel(0L, 0L, cr.left+3, cr.top+1, &TextDef, (char*)tmpl);
- return true;
+ if(cont)return cont->Command(cmd, tmpl, o);
+ return false;
}
return false;
}
@@ -895,10 +912,7 @@ TextBox::Command(int cmd, void *tmpl, anyOutput *o)
void
TextBox::DoPlot(anyOutput *o)
{
- o->SetLine(&Line); o->SetFill(&Fill);
- o->oRectangle(cr.left, cr.top, cr.right, cr.bottom);
- if(cont)cont->DoPlot(o);
- o->UpdateRect(&cr, false);
+ if(cont && o)cont->DoPlot(o);
}
bool
@@ -909,15 +923,37 @@ TextBox::Select(int x, int y, anyOutput *o)
p1.x = x; p1.y = y;
if(bActive && IsInRect(&cr, x, y) && !(flags & NOEDIT)) {
DialogDefault = DialogFocus = DialogTabStop = this;
- if(cont) bChecked = cont->Command(CMD_SELECT, &p1, o);
+ if(CurrGO = cont) bChecked = cont->Command(CMD_SELECT, &p1, o);
}
return false;
}
+void
+TextBox::MBtrack(MouseEvent *mev, anyOutput *o)
+{
+ bool bLBstate;
+ int x, y;
+
+ x = mev->x; y = mev->y;
+ if(mev->StateFlags &1) bLBstate = true;
+ else bLBstate = false;
+ if(bActive && IsInRect(&cr, x, y) && !(flags & NOEDIT) &&
+ bLBstate && cont && parent) {
+ DialogFocus = this; bChecked = true;
+ parent->Command(CMD_FOCTXT, (void*)this, 0L);
+ cont->Command(CMD_MOUSE_EVENT, mev, o);
+ parent->Command(CMD_MARKOBJ, this, o);
+ }
+}
+
bool
-TextBox::GetText(int id, char *txt)
+TextBox::GetText(int id, char *txt, int size)
{
- if(cont) return cont->Command(CMD_ALLTEXT, txt, 0L);
+ if(cont) {
+ if(!(cont->Command(CMD_ALLTEXT, TmpTxt, 0L))) return false;
+ rlp_strcpy(txt, size, TmpTxt);
+ return true;
+ }
return false;
}
@@ -1011,16 +1047,11 @@ ArrowButton::Select(int x, int y, anyOutput *o)
return false;
}
-ColorButton::ColorButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, unsigned long color)
- :Dialog(par, desc, rec)
-{
- col = color;
-}
ColorButton::ColorButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, DWORD *color)
:Dialog(par, desc, rec)
{
- col = *color;
+ col = color ? *color : 0x0L;
}
void
@@ -1321,7 +1352,7 @@ SymRadioButt::Select(int x, int y, anyOutput *o)
CheckBox::CheckBox(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text)
:Dialog(par, desc, rec)
{
- if(text)Text = strdup(text);
+ if(text && text[0])Text = (char*)memdup(text, (int)strlen(text)+1, 0);
else Text = 0L;
hcr.left = cr.left+2; hcr.right = cr.left+14;
hcr.top = cr.top+3; hcr.bottom = cr.top+15;
@@ -1338,7 +1369,7 @@ CheckBox::Command(int cmd, void *tmpl, anyOutput *o)
switch(cmd) {
case CMD_SETTEXT:
if(Text) free(Text);
- if(tmpl) Text = strdup((char *)tmpl);
+ if(tmpl && *((char*)tmpl)) Text = (char*)memdup(tmpl, (int)strlen((char*)tmpl)+1,0);
else Text = 0L;
return true;
}
@@ -1368,7 +1399,7 @@ CheckBox::DoPlot(anyOutput *o)
}
if(Text) {
o->SetTextSpec(&TextDef);
- o->oTextOut(cr.left + 20, cr.top + 1, Text, strlen(Text));
+ o->oTextOut(cr.left + 20, cr.top + 1, Text, (int)strlen(Text));
}
o->UpdateRect(&cr, false);
}
@@ -1566,7 +1597,7 @@ Config::Select(int x, int y, anyOutput *o)
RadioButton::RadioButton(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text)
:Dialog(par, desc, rec)
{
- if(text) Text = strdup(text);
+ if(text && text[0])Text = (char*)memdup(text, (int)strlen(text)+1, 0);
else Text = 0L;
switch(type) {
case RADIO0:
@@ -1596,7 +1627,7 @@ RadioButton::Command(int cmd, void *tmpl, anyOutput *o)
switch(cmd) {
case CMD_SETTEXT:
if(Text) free(Text);
- if(tmpl)Text = strdup((char *)tmpl);
+ if(tmpl && *((char*)tmpl))Text = (char*)memdup(tmpl, (int)strlen((char*)tmpl)+1, 0);
else Text = 0L;
return true;
}
@@ -1631,7 +1662,7 @@ RadioButton::DoPlot(anyOutput *o)
}
if(Text) {
o->SetTextSpec(&TextDef);
- o->oTextOut(cr.left + 20, cr.top + 1, Text, strlen(Text));
+ o->oTextOut(cr.left + 20, cr.top + 1, Text, (int)strlen(Text));
}
o->UpdateRect(&cr, false);
}
@@ -1659,7 +1690,7 @@ RadioButton::SetColor(int id, DWORD color)
Text::Text(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text)
:Dialog(par, desc, rec)
{
- if(text) txt = strdup(text);
+ if(text && text[0])txt = (char*)memdup(text, (int)strlen(text)+1, 0);
else txt = 0L;
switch (type) {
case RTEXT: TextDef.Align = TXA_HRIGHT | TXA_VTOP; break;
@@ -1679,7 +1710,7 @@ Text::Command(int cmd, void *tmpl, anyOutput *o)
switch(cmd) {
case CMD_SETTEXT:
if(txt) free(txt);
- if(tmpl)txt = strdup((char *)tmpl);
+ if(tmpl && *((char*)tmpl))txt = (char*)memdup(tmpl, (int)strlen((char*)tmpl)+1, 0);
else txt = 0L;
return true;
}
@@ -1707,9 +1738,13 @@ Text::DoPlot(anyOutput *o)
bool
Text::Select(int x, int y, anyOutput *o)
{
+ int i;
+
if(WWWbrowser && WWWbrowser[0] && txt && (flags & HREF) && IsInRect(&cr, x, y)) {
o->MouseCursor(MC_WAIT, false);
- sprintf(TmpTxt, "%s %s", WWWbrowser, txt);
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE-50, WWWbrowser);
+ TmpTxt[i++] = ' ';
+ rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, txt);
if(parent && (flags & TOUCHEXIT))parent->Command(CMD_ENDDIALOG, 0L, o);
else if(parent)parent->Command(CMD_CONTINUE, 0L, o);
#ifdef _WINDOWS
@@ -1730,6 +1765,12 @@ Text::SetColor(int id, DWORD color)
TextDef.ColTxt = color;
}
+void
+Text::MBtrack(MouseEvent *mev, anyOutput *o)
+{
+ if((mev->StateFlags &1) && IsInRect(&hcr, mev->x, mev->y) && parent) parent->Command(CMD_MARKOBJ, this, o);
+}
+
InputText::InputText(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text)
:Dialog(par, desc, rec)
{
@@ -1759,6 +1800,7 @@ InputText::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_POS_FIRST: case CMD_POS_LAST: case CMD_SHIFTLEFT:
case CMD_SHIFTRIGHT:
if(Text && bActive && !(flags & NOEDIT)){
+ if(o) Undo.SetDisp(o);
o->SetTextSpec(&TextDef);
bRet = Text->Command(cmd, o, NULL);
if(bRet && (flags & TOUCHEXIT)) parent->Command(CMD_ENDDIALOG, (void *)this, o);
@@ -1776,6 +1818,7 @@ InputText::Command(int cmd, void *tmpl, anyOutput *o)
return false;
case CMD_ADDCHAR:
if(Text && bActive && !(flags & NOEDIT)){
+ if(o) Undo.SetDisp(o);
if(flags & TOUCHEXIT) parent->Command(CMD_ENDDIALOG, (void *)this, o);
o->SetTextSpec(&TextDef);
switch(*((int*)tmpl)) {
@@ -1799,9 +1842,7 @@ InputText::Command(int cmd, void *tmpl, anyOutput *o)
}
WriteNatFloatToBuff(TmpTxt, tmpVal);
if(Text) {
- if(Text->text) free(Text->text);
- Text->text = strdup(TmpTxt+1);
- DoPlot(o);
+ Text->SetText(TmpTxt+1); DoPlot(o);
}
}
break;
@@ -1865,17 +1906,21 @@ InputText::GetInt(int id, int *val)
return true;
}
if(Text && Text->text) {
+#ifdef USE_WIN_SECURE
+ sscanf_s(Text->text, "%d", val);
+#else
sscanf(Text->text, "%d", val);
+#endif
return true;
}
return false;
}
bool
-InputText::GetText(int id, char *txt)
+InputText::GetText(int id, char *txt, int size)
{
if(Text && Text->text && Text->text[0]) {
- strcpy(txt, Text->text);
+ rlp_strcpy(txt, size, Text->text);
return true;
}
return false;
@@ -1891,11 +1936,12 @@ InputText::MBtrack(MouseEvent *mev, anyOutput *o)
if(mev->StateFlags &1) bLBstate = true;
else bLBstate = false;
if(bActive && IsInRect(&cr, x, y) && !(flags & NOEDIT) &&
- bLBstate && Text) {
+ bLBstate && Text && parent) {
DialogFocus = this;
- if(parent) parent->Command(CMD_FOCTXT, (void*)this, 0L);
+ parent->Command(CMD_FOCTXT, (void*)this, 0L);
o->SetTextSpec(&TextDef);
Text->Command(CMD_MOUSE_EVENT, o, (DataObj *)mev);
+ parent->Command(CMD_MARKOBJ, this, o);
}
}
@@ -1914,10 +1960,10 @@ InputText::Activate(int id, bool activate)
}
}
-RangeInput::RangeInput(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text)
+RangeInput::RangeInput(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text, DataObj *d)
:InputText(par, desc, rec, text)
{
- data = 0L;
+ data = d;
}
RangeInput::~RangeInput()
@@ -1964,7 +2010,7 @@ InputValue::InputValue(tag_DlgObj *par, DlgInfo * desc, RECT rec, double *value)
:InputText(par, desc, rec, 0L)
{
WriteNatFloatToBuff(TmpTxt, *value);
- if(Text) Text->text = strdup(TmpTxt+1);
+ if(Text) Text->text = (char*)memdup(TmpTxt+1, (int)strlen(TmpTxt+1)+1, 0);
}
InputValue::~InputValue()
@@ -1984,7 +2030,7 @@ IncDecValue::IncDecValue(tag_DlgObj *par, DlgInfo * desc, RECT rec, double *valu
RECT br;
WriteNatFloatToBuff(TmpTxt, *value);
- if(Text) Text->text = strdup(TmpTxt+1);
+ if(Text) Text->text = (char*)memdup(TmpTxt+1, (int)strlen(TmpTxt+1)+1, 0);
br.left = cr.right+1; br.right = br.left + 7*xbase;
br.top = cr.top+1; br.bottom = br.top + 5*ybase;
butts[0] = new ArrowButton(this, &ab[0], br, &ab1);
@@ -2044,24 +2090,30 @@ TxtHSP::TxtHSP(tag_DlgObj *par, DlgInfo *desc, RECT rec, int *align)
y2 = ((cr.top>>1) + (cr.bottom>>1))/ybase-4, y3 = cr.bottom/ybase-8;
int i;
RECT br;
+ DlgInfo d1[9];
- DlgInfo d1[] = {
- {1, 2, 0, ISRADIO, RADIO0, 0L, x1, y1, 8, 8},
- {2, 3, 0, ISRADIO, RADIO0, 0L, x2, y1, 8, 8},
- {3, 4, 0, ISRADIO, RADIO0, 0L, x3, y1, 8, 8},
- {4, 5, 0, ISRADIO, RADIO0, 0L, x1, y2, 8, 8},
- {5, 6, 0, ISRADIO, RADIO0, 0L, x2, y2, 8, 8},
- {6, 7, 0, ISRADIO, RADIO0, 0L, x3, y2, 8, 8},
- {7, 8, 0, ISRADIO, RADIO0, 0L, x1, y3, 8, 8},
- {8, 9, 0, ISRADIO, RADIO0, 0L, x2, y3, 8, 8},
- {9, 0, 0, ISRADIO | LASTOBJ, RADIO0, 0L, x3, y3, 8, 8}};
-
+ for(i = 0; i < 9; i++) {
+ d1[i].id = i+1; d1[i].next = i+2; d1[i].first = 0;
+ d1[i].flags = ISRADIO; d1[i].type = RADIO0; d1[i].ptype = 0L;
+ d1[i].w = d1[i].h = 8;
+ switch (i / 3) {
+ case 0: d1[i].y = y1; break;
+ case 1: d1[i].y = y2; break;
+ case 2: d1[i].y = y3; break;
+ }
+ switch (i % 3) {
+ case 0: d1[i].x = x1; break;
+ case 1: d1[i].x = x2; break;
+ case 2: d1[i].x = x3; break;
+ }
+ }
+ d1[8].next = 0; d1[8].flags |= LASTOBJ;
txt.ColTxt = 0x00808080L; txt.ColBg = 0x00ffffff;
txt.fSize = 8.0; txt.RotBL = txt.RotCHAR = 0.0;
txt.iSize = 0; txt.Align = TXA_HCENTER | TXA_VCENTER;
txt.Style = TXS_NORMAL; txt.Font = FONT_HELVETICA;
txt.Mode = TXM_TRANSPARENT;
- txt.text = strdup("text");
+ if(txt.text = (char*)malloc(20*sizeof(char))) rlp_strcpy(txt.text, 20, "text");
if((d2 = (DlgInfo*)malloc(9*sizeof(DlgInfo)))){
memcpy(d2, &d1,9*sizeof(DlgInfo));
if(align) switch(*align) {
@@ -2526,11 +2578,9 @@ Group::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_FLUSH:
if(Children) for(i = 0; i < numChildren; Children[i++] = 0L);
break;
- case CMD_CONTINUE:
- case CMD_ENDDIALOG:
- case CMD_TABDLG:
- case CMD_NOTABDLG:
- if(parent) return parent->Command(cmd, tmpl, o);
+ case CMD_CONTINUE: case CMD_ENDDIALOG: case CMD_TABDLG:
+ case CMD_NOTABDLG: case CMD_MARKOBJ:
+ if(parent && (flags & HIDDEN) != HIDDEN) return parent->Command(cmd, tmpl, o);
else return false;
case CMD_ADDCHILD:
if(Children && numChildren && (d = (Dialog*)tmpl)) {
@@ -2622,14 +2672,11 @@ Group::MBtrack(MouseEvent *mev, anyOutput *o)
GroupBox::GroupBox(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *txt)
:Group(par,desc, rec)
{
- if(txt)Text = strdup(txt);
+ if(txt && txt[0])Text = (char*)memdup(txt, (int)strlen(txt)+1, 0);
else Text = 0L;
- Line.color = 0x00000000L;
- Line.width = 0.0;
- Fill.color = DlgBGhigh;
- TextDef.ColBg = Fill.color;
- TextDef.Align = TXA_HLEFT | TXA_VCENTER;
- TextDef.Mode = TXM_OPAQUE;
+ Line.color = 0x00000000L; Line.width = 0.0;
+ Fill.color = DlgBGhigh; TextDef.ColBg = Fill.color;
+ TextDef.Align = TXA_HLEFT | TXA_VCENTER; TextDef.Mode = TXM_OPAQUE;
}
GroupBox::~GroupBox()
@@ -2652,17 +2699,15 @@ GroupBox::DoPlot(anyOutput *o)
o->UpdateRect(&hcr, false);
}
-TabSheet::TabSheet(tag_DlgObj *par, DlgInfo * desc, RECT rec, TabSHEET * sh)
+TabSheet::TabSheet(tag_DlgObj *par, DlgInfo * desc, RECT rec, TabSHEET * sh, DataObj *d)
:Group(par, desc, rec)
{
- if(sh->text)Text = strdup(sh->text);
+ if(sh->text && sh->text[0])Text = (char*)memdup(sh->text, (int)strlen(sh->text)+1, 0);
else Text = 0L;
- rctab.left = cr.left + sh->x1 * xbase;
- rctab.right = cr.left + sh->x2 * xbase;
- rctab.top = cr.top;
- rctab.bottom = cr.top + sh->height * ybase;
- TextDef.Align = TXA_HRIGHT | TXA_VTOP;
- flags |= ISRADIO;
+ rctab.left = cr.left + sh->x1 * xbase; rctab.right = cr.left + sh->x2 * xbase;
+ rctab.top = cr.top; rctab.bottom = cr.top + sh->height * ybase;
+ TextDef.Align = TXA_HRIGHT | TXA_VTOP; flags |= ISRADIO;
+ data = d;
}
TabSheet::~TabSheet()
@@ -2709,9 +2754,12 @@ bool
TabSheet::Select(int x, int y, anyOutput *o)
{
if(IsInRect(&rctab, x, y)) {
- if(parent) parent->Command(CMD_RADIOBUTT, (void *)this, o);
- bChecked = true;
- DoPlot(o);
+ if(data)data->Command(CMD_ETRACC, 0L, 0L);
+ if(parent) {
+ parent->Command(CMD_RADIOBUTT, (void *)this, o);
+ parent->Command(CMD_MARKOBJ, this, o);
+ }
+ bChecked = true; DoPlot(o);
if((flags & TOUCHEXIT) && parent)
parent->Command(CMD_ENDDIALOG, (void *)this, o);
return true;
@@ -2791,7 +2839,9 @@ Listbox::Listbox(tag_DlgObj *par, DlgInfo *des, RECT rec, char **list)
Fill.color = 0x00ffffffL; Line.color = 0x00000000L;
for(i = ns = 0; list && list[i]; i++); //count lines
if(strings = (char **)calloc(i+1, sizeof(char*))){
- for(ns = i, i = 0; i < ns; strings[i] = strdup(list[i]), i++);
+ for(ns = i, i = 0; i < ns; i++){
+ strings[i] = (char*)memdup(list[i], (int)strlen(list[i])+1, 0);
+ }
}
}
@@ -2908,10 +2958,10 @@ Listbox::GetInt(int id, int *val)
}
bool
-Listbox::GetText(int id, char *txt)
+Listbox::GetText(int id, char *txt, int size)
{
if(strings && ns && cl >= 0 && cl < ns){
- strcpy(txt, strings[cl]);
+ rlp_strcpy(txt, size, strings[cl]);
return true;
}
return false;
@@ -3145,7 +3195,7 @@ static char *std_text[] = {"OK", "Cancel", "", "x", "y", "z", "-", "Next >>", "<
DlgInfo *CompileDialog(char* tmpl, void **ptypes)
{
- char **lines, **fields, **flags;
+ char **lines, **fields, **flags, error[80];
int i, j, nlines, nfields, nflags;
unsigned int hv;
DlgInfo *Dlg;
@@ -3157,8 +3207,14 @@ DlgInfo *CompileDialog(char* tmpl, void **ptypes)
if(fields = split(lines[i], ',', &nfields)) {
if(nfields == 10) {
Dlg[i].id = Dlg[i].next = Dlg[i].first = 0;
+#ifdef USE_WIN_SECURE
+ sscanf_s(fields[0], "%d", &Dlg[i].id); sscanf_s(fields[1], "%d", &Dlg[i].next);
+ sscanf_s(fields[2], "%d", &Dlg[i].first);
+#else
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;
+ sscanf(fields[2], "%d", &Dlg[i].first);
+#endif
+ Dlg[i].flags = 0L;
if(flags = split(fields[3], '|', &nflags)) {
for(j = 0; j < nflags; j++){
hv = HashValue((unsigned char *)str_trim(flags[j]));
@@ -3186,7 +3242,6 @@ DlgInfo *CompileDialog(char* tmpl, void **ptypes)
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;
@@ -3222,12 +3277,32 @@ DlgInfo *CompileDialog(char* tmpl, void **ptypes)
case 51627: Dlg[i].type = CONFIG; break;
default: Dlg[i].type = NONE; break;
}
+#ifdef USE_WIN_SECURE
+ sscanf_s(fields[5], "%d", &j);
+#else
sscanf(fields[5], "%d", &j);
+#endif
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;
+#ifdef USE_WIN_SECURE
+ sscanf_s(fields[6], "%d", &Dlg[i].x); sscanf_s(fields[7], "%d", &Dlg[i].y);
+ sscanf_s(fields[8], "%d", &Dlg[i].w); sscanf_s(fields[9], "%d", &Dlg[i].h);
+#else
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);
+#endif
+ }
+ else {
+#ifdef USE_WIN_SECURE
+ sprintf_s(error, 80, "Wrong number of arguments in template line %d", i);
+#else
+ sprintf(error,"Wrong number of arguments in template line %d", i);
+#endif
+ InfoBox(error);
+ Dlg[i].id = Dlg[i].next = Dlg[i].first = 0;
+ Dlg[i].flags = 0L; Dlg[i].type = NONE;
+ Dlg[i].ptype = 0L; Dlg[i].x = Dlg[i].y = Dlg[i].w = Dlg[i].h = 0;
}
for(j = 0; j < nfields; j++)free(fields[j]);
free(fields);
@@ -3246,12 +3321,13 @@ bool UseRangeMark(DataObj *d, int type, char *r0, char *r1, char *r2, char *r3,
{
char *dst[] = {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10};
char *mrk, **ra =0L;;
- int i, j, ranges=0;
+ int i, j, k, ranges=0;
bool success = false;
RECT vrc;
AccRange *ar;
bool bRet = true;
+ for(i = 0; i < 11; i++) if(dst[i]) *dst[i] = 0;
if(d && type) {
d->ValueRec(&vrc);
if(d->Command(CMD_GETMARK, &mrk, 0L)) {
@@ -3262,8 +3338,47 @@ bool UseRangeMark(DataObj *d, int type, char *r0, char *r1, char *r2, char *r3,
case 1:
if(ranges > 1) {
for(i = 0; i < 11; i++) if(dst[i]) {
+#ifdef USE_WIN_SECURE
+ if(i < ranges) sprintf_s(dst[i], 100, "%s", ra[i]);
+ else {
+ j = sprintf_s(dst[i], 100, "%s%d:", Int2ColLabel(vrc.left, false), vrc.top+1);
+ sprintf_s(dst[i]+j, 100-j, "%s%d", Int2ColLabel(vrc.left, false), vrc.bottom+1);
+ }
+#else
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);
+ else {
+ j = sprintf(dst[i], "%s%d:", Int2ColLabel(vrc.left, false), vrc.top+1);
+ sprintf(dst[i]+j, "%s%d", Int2ColLabel(vrc.left, false), vrc.bottom+1);
+ }
+#endif
+ }
+ success = true;
+ }
+ else if(vrc.top == vrc.bottom && (vrc.right - vrc.left) >2) {
+ for(i = 0; i < 11; i++) {
+ if(dst[i]){
+#ifdef USE_WIN_SECURE
+ j = sprintf_s(dst[i], 100, "%s%d:", Int2ColLabel(vrc.left, false), vrc.top+1+i);
+ sprintf_s(dst[i]+j, 100-j, "%s%d", Int2ColLabel(vrc.right, false), vrc.top+1+i);
+#else
+ j = sprintf(dst[i], "%s%d:", Int2ColLabel(vrc.left, false), vrc.top+1+i);
+ sprintf(dst[i]+j, "%s%d", Int2ColLabel(vrc.right, false), vrc.top+1+i);
+#endif
+ }
+ }
+ success = true;
+ }
+ else if(vrc.right == vrc.left && (vrc.bottom - vrc.top) >2) {
+ for(i = 0; i < 11; i++) {
+ if(dst[i]){
+#ifdef USE_WIN_SECURE
+ j = sprintf_s(dst[i], 100, "%s%d:", Int2ColLabel(vrc.left+i, false), vrc.top+1);
+ sprintf_s(dst[i]+j, 100-j, "%s%d", Int2ColLabel(vrc.left+i, false), vrc.bottom+1);
+#else
+ j = sprintf(dst[i], "%s%d:", Int2ColLabel(vrc.left+i, false), vrc.top+1);
+ sprintf(dst[i]+j, "%s%d", Int2ColLabel(vrc.left+i, false), vrc.bottom+1);
+#endif
+ }
}
success = true;
}
@@ -3271,8 +3386,14 @@ bool UseRangeMark(DataObj *d, int type, char *r0, char *r1, char *r2, char *r3,
case 2:
for(i = 0; i < 11; i++) if(dst[i]) *(dst[i]) = 0;
if(ranges == 1) {
- for(i = 0, j = vrc.left; i < 11 && j <= vrc.right; i++, j++) {
- if(dst[i])sprintf(dst[i], "%c%d:%c%d", 'a'+i+vrc.left, vrc.top+1, 'a'+i+vrc.left, vrc.bottom+1);
+ for(i = 0, j = vrc.left; i < 11 && j <= vrc.right; i++, j++) if(dst[i]){
+#ifdef USE_WIN_SECURE
+ k = sprintf_s(dst[i], 100, "%s%d:", Int2ColLabel(vrc.left+i, false), vrc.top+1);
+ sprintf_s(dst[i]+k, 100-k, "%s%d", Int2ColLabel(vrc.left+i, false), vrc.bottom+1);
+#else
+ k = sprintf(dst[i], "%s%d:", Int2ColLabel(vrc.left+i, false), vrc.top+1);
+ sprintf(dst[i]+k, "%s%d", Int2ColLabel(vrc.left+i, false), vrc.bottom+1);
+#endif
}
}
else if(ranges > 1) {
@@ -3287,7 +3408,7 @@ bool UseRangeMark(DataObj *d, int type, char *r0, char *r1, char *r2, char *r3,
delete ar;
}
if(i < 12) for(i = 0; i < 11 && i < ranges; i++){
- if(dst[i]) strcpy(dst[i], ra[i]);
+ if(dst[i]) rlp_strcpy(dst[i], 100, ra[i]);
}
}
success = true;
@@ -3297,7 +3418,15 @@ bool UseRangeMark(DataObj *d, int type, char *r0, char *r1, char *r2, char *r3,
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(dst[i]){
+#ifdef USE_WIN_SECURE
+ j = sprintf_s(dst[i], 100, "%s%d:", Int2ColLabel(vrc.left+i, false), vrc.top+1);
+ sprintf_s(dst[i]+j, 100-j, "%s%d", Int2ColLabel(vrc.left+i, false), vrc.bottom+1);
+#else
+ j = sprintf(dst[i], "%s%d:", Int2ColLabel(vrc.left+i, false), vrc.top+1);
+ sprintf(dst[i]+j, "%s%d", Int2ColLabel(vrc.left+i, false), vrc.bottom+1);
+#endif
+ }
}
if(ra) {
for(i = 0; i < ranges; i++) if(ra[i]) free(ra[i]);
@@ -3322,38 +3451,42 @@ DWORD GetNewColor(DWORD oldColor)
"7, 0, 8, CHECKED | ISPARENT, GROUP, 0, 0, 0, 0, 0";
void *ptypes[] = {(void*)" RGB "};
DlgInfo *ColDlg = CompileDialog(NewColorTmpl, ptypes);
- DWORD currcol, newcol;
+ DWORD currcol, newcol, palette[230];
int ilevels[] = {0x0, 0x40, 0x80, 0xc0, 0xe0, 0xff};
- int i, ir, ig, ib, col, row, res;
+ int i, j, ir, ig, ib, col, row, res;
DlgRoot *Dlg;
void *hDlg;
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++) {
+ for(ir=row=col=0, i=7, j=0; 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;
- currcol = (ilevels[ib]<<16)|(ilevels[ig]<<8)|(ilevels[ir]);
+ ColDlg[i].type = COLBUTT; ColDlg[i].first = 0;
+ palette[j] = currcol = (ilevels[ib]<<16)|(ilevels[ig]<<8)|(ilevels[ir]);
ColDlg[i].flags = TOUCHEXIT | ISRADIO;
if(currcol == oldColor) ColDlg[i].flags |= CHECKED;
- ColDlg[i].ptype = (void *)currcol;
+ ColDlg[i].ptype = (void *)&palette[j];
ColDlg[i].x = 5 + col*10; ColDlg[i].y = 5 + row*10;
ColDlg[i].w = ColDlg[i].h = 10;
col++;
if(col >= 18) {
col = 0; row++;
}
- i++;
+ i++, j++;
}
+ j=j;
ColDlg[i-1].next = 0;
ColDlg[i-1].flags |= LASTOBJ;
newcol = currcol = oldColor;
- Dlg = new DlgRoot(ColDlg);
- sprintf(TmpTxt, "R: 0x%02x", currcol & 0xff);
- Dlg->SetText(4, TmpTxt);
- sprintf(TmpTxt, "G: 0x%02x", (currcol>>8) & 0xff);
- Dlg->SetText(5, TmpTxt);
- sprintf(TmpTxt, "B: 0x%02x", (currcol>>16) & 0xff);
- Dlg->SetText(6, TmpTxt);
+ Dlg = new DlgRoot(ColDlg, 0L);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, 10, "R: 0x%02x", currcol & 0xff); Dlg->SetText(4, TmpTxt);
+ sprintf_s(TmpTxt, 10, "G: 0x%02x", (currcol>>8) & 0xff); Dlg->SetText(5, TmpTxt);
+ sprintf_s(TmpTxt, 10, "B: 0x%02x", (currcol>>16) & 0xff); Dlg->SetText(6, TmpTxt);
+#else
+ sprintf(TmpTxt, "R: 0x%02x", currcol & 0xff); Dlg->SetText(4, TmpTxt);
+ sprintf(TmpTxt, "G: 0x%02x", (currcol>>8) & 0xff); Dlg->SetText(5, TmpTxt);
+ sprintf(TmpTxt, "B: 0x%02x", (currcol>>16) & 0xff); Dlg->SetText(6, TmpTxt);
+#endif
hDlg = CreateDlgWnd("Select color", 50, 50, 510, 310, Dlg,0x0L);
do {
LoopDlgWnd();
@@ -3371,12 +3504,15 @@ DWORD GetNewColor(DWORD oldColor)
currcol = newcol;
if(Dlg->GetColor(res, &newcol) && currcol != newcol) {
res = -1;
- sprintf(TmpTxt, "R: 0x%02x", newcol & 0xff);
- Dlg->SetText(4, TmpTxt);
- sprintf(TmpTxt, "G: 0x%02x", (newcol>>8) & 0xff);
- Dlg->SetText(5, TmpTxt);
- sprintf(TmpTxt, "B: 0x%02x", (newcol>>16) & 0xff);
- Dlg->SetText(6, TmpTxt);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, 10, "R: 0x%02x", newcol & 0xff); Dlg->SetText(4, TmpTxt);
+ sprintf_s(TmpTxt, 10, "G: 0x%02x", (newcol>>8) & 0xff); Dlg->SetText(5, TmpTxt);
+ sprintf_s(TmpTxt, 10, "B: 0x%02x", (newcol>>16) & 0xff); Dlg->SetText(6, TmpTxt);
+#else
+ sprintf(TmpTxt, "R: 0x%02x", newcol & 0xff); Dlg->SetText(4, TmpTxt);
+ sprintf(TmpTxt, "G: 0x%02x", (newcol>>8) & 0xff); Dlg->SetText(5, TmpTxt);
+ sprintf(TmpTxt, "B: 0x%02x", (newcol>>16) & 0xff); Dlg->SetText(6, TmpTxt);
+#endif
}
}
break;
@@ -3395,9 +3531,9 @@ static char *ConfShade_DlgTmpl =
"1,2,,DEFAULT,PUSHBUTTON,-1,95,10,45,12\n"
"2,3,,,PUSHBUTTON,-2,95,25,45,12\n"
"3,4,100,CHECKED | ISPARENT,GROUP,0,0,0,0,0\n"
- "4,5,,OWNDIALOG | TOUCHEXIT,COLBUTT,1,60,10,15,10\n"
- "5,6,,OWNDIALOG | TOUCHEXIT,COLBUTT,2,60,37,15,10\n"
- "6,7,,OWNDIALOG | TOUCHEXIT,COLBUTT,1,60,49,15,10\n"
+ "4,5,,ODEXIT,COLBUTT,1,60,10,15,10\n"
+ "5,6,,ODEXIT,COLBUTT,2,60,37,15,10\n"
+ "6,7,,ODEXIT,COLBUTT,1,60,49,15,10\n"
"7,8,,,RTEXT,3,25,37,30,9\n"
"8,9,,,RTEXT,4,25,49,30,9\n"
"9,,,,SHADE3D,5,95,50,22,20\n"
@@ -3420,7 +3556,7 @@ void ConfShade(FillDEF *oldfill)
if(!oldfill) return;
memcpy(&newFill, oldfill, sizeof(FillDEF));
newFill.type = FILL_LIGHT3D;
- if(!(Dlg = new DlgRoot(ShadeDlg))) return;
+ if(!(Dlg = new DlgRoot(ShadeDlg, 0L))) return;
if(oldfill->type & FILL_LIGHT3D) Dlg->SetCheck(101, 0L, true);
else {
Dlg->SetCheck(100, 0L, true);
@@ -3488,12 +3624,12 @@ void GetNewFill(FillDEF *oldfill)
{102, 103, 0, TOUCHEXIT, INCDECVAL1, &PrevLine.width, 119, 95, 32, 10},
{103, 104, 0, 0x0L, LTEXT, (void *) Units[defs.cUnits].display, 152, 95, 15, 8},
{104, 105, 0, 0x0L, RTEXT, (void*)"line color", 5, 95, 30, 8},
- {105, 106, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, 0x0L, 36, 95, 25, 10},
+ {105, 106, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, 0x0L, 36, 95, 25, 10},
{106, 107, 0, 0x0L, RTEXT, (void*)"pattern size", 78, 110, 40, 8},
{107, 108, 0, TOUCHEXIT, INCDECVAL1, (void*)&fscale, 119, 110, 32, 10},
{108, 109, 0, 0x0L, LTEXT, (void*)"%", 152, 110, 8, 8},
{109, 110, 0, 0x0L, RTEXT, (void*)"BG color", 5, 110, 30, 8},
- {110, 0, 0, OWNDIALOG | TOUCHEXIT, COLBUTTON, 0x0L, 36, 110, 25, 10}};
+ {110, 0, 0, OWNDIALOG | TOUCHEXIT, COLBUTT, 0x0L, 36, 110, 25, 10}};
DlgInfo *FillDlg;
DlgRoot *Dlg;
void *hDlg;
@@ -3526,7 +3662,7 @@ void GetNewFill(FillDEF *oldfill)
FillDlg[i-1].flags |= LASTOBJ;
}
else return;
- Dlg = new DlgRoot(FillDlg);
+ Dlg = new DlgRoot(FillDlg, 0L);
for(i = Dlg->FindIndex(500), j = 0; FillDlg[i].type == FILLRADIO; i++, j++)
if(*((int*)FillDlg[i].ptype) == PrevFill.type)Dlg->SetCheck(500+j, 0L, true);
Dlg->SetColor(105, PrevLine.color);
@@ -3621,8 +3757,8 @@ bool ShowLayers(GraphObj *root)
GraphObj *cgo = 0L;
if(!root) return false;
- sprintf(curr_name, "(root)");
- if(!(Dlg = new DlgRoot(PageDlg)))return false;
+ rlp_strcpy(curr_name, 50, "(root)");
+ if(!(Dlg = new DlgRoot(PageDlg, 0L)))return false;
Dlg->ItemCmd(100, CMD_OBJTREE, &ot);
if(!ot) {
delete Dlg; return false;
@@ -3721,7 +3857,7 @@ void ShowBanner(bool show)
int res, cnt = 5;
if(!show) return;
- if(!(Dlg = new DlgRoot(BannerDlg)))return;
+ if(!(Dlg = new DlgRoot(BannerDlg, 0L)))return;
#ifdef _WINDOWS
Dlg->TextSize(3, 36);
#else
@@ -3795,7 +3931,7 @@ void RLPlotInfo()
void *hDlg;
int res;
- if((Dlg = new DlgRoot(AboutDlg))) {
+ if((Dlg = new DlgRoot(AboutDlg, 0L))) {
Dlg->TextStyle(3, TXS_ITALIC | TXS_BOLD);
Dlg->TextFont(3, FONT_TIMES);
#ifdef _WINDOWS
@@ -3868,8 +4004,12 @@ DoSpShSize(DataObj *dt)
default: ch = NiceValue(((double)(celldim[2]-2))*0.259183673); break;
}
ch1 = ch; th = th1 = defs.ss_txt*100.0;
- sprintf(txt1, "%d", w1); sprintf(txt2, "%d", h1);
- Dlg = new DlgRoot(SSDlg);
+#ifdef USE_WIN_SECURE
+ sprintf_s(txt1, 40, "%d", w1); sprintf_s(txt2, 40, "%d", h1);
+#else
+ sprintf(txt1, "%d", w1); sprintf(txt2, "%d", h1);
+#endif
+ Dlg = new DlgRoot(SSDlg, dt);
hDlg = CreateDlgWnd("Change spread sheet settings", 50, 50, 320, 220, Dlg, 0x0L);
Dlg->GetValue(201, &fw1); Dlg->GetValue(204, &cw1); Dlg->GetValue(207, &ch1);
do{
@@ -3877,7 +4017,7 @@ DoSpShSize(DataObj *dt)
res = Dlg->GetResult();
switch(res) {
case 1: //OK pressed
- if(Dlg->GetText(101, txt1) && Dlg->GetText(103, txt2)) {
+ if(Dlg->GetText(101, txt1, 40) && Dlg->GetText(103, txt2, 40)) {
w2 = atol(txt1); h2 = atol(txt2);
w2 = w2 > 0 ? w2: w1; h2 = h2 > 0 ? h2: h1;
}
@@ -3923,11 +4063,11 @@ bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go)
TabSHEET tab1 = {0, 37, 10, "fill range "};
char *ra = range ? *range:0L;
double startval = 1.0, stepval = 1.0;
- static char *formula = 0L;
- if(!formula && CurrText && CurrText->isFormula()) {
- if(CurrText->GetText(TmpTxt,TMP_TXT_SIZE, false)) formula = strdup(TmpTxt);
+ static char *formula = (char*)malloc(500 * sizeof(char));
+ if(formula && CurrText && CurrText->isFormula()) {
+ if(CurrText->GetText(TmpTxt,TMP_TXT_SIZE, false)) rlp_strcpy(formula, 500, TmpTxt);
}
- if(!formula) formula = strdup("=a1");
+ if(formula) rlp_strcpy(formula, 500, "=a1");
DlgInfo RangeDlg[] = {
{1, 2, 0, DEFAULT, PUSHBUTTON, (void*)"OK", 162, 5, 38, 12},
{2, 3, 0, 0x0L, PUSHBUTTON, (void*)"Cancel", 162, 20, 38, 12},
@@ -3956,8 +4096,7 @@ bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go)
anyOutput *cdisp = Undo.cdisp;
if(!d || !range) return false;
- if(!(Dlg = new DlgRoot(RangeDlg))) return false;
- Dlg->ItemCmd(6, CMD_SET_DATAOBJ, d);
+ if(!(Dlg = new DlgRoot(RangeDlg, d))) return false;
#ifdef _WINDOWS
for(i = 23; i <= 24; i++) Dlg->TextSize(i, 12);
#else
@@ -3976,11 +4115,11 @@ bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go)
break;
case 1:
ra = 0L;
- if(!Dlg->GetText(6, TmpTxt)) {
+ if(!Dlg->GetText(6, TmpTxt, TMP_TXT_SIZE)) {
InfoBox("Range not specified\nor not valid.");
bContinue = true; res = -1;
}
- else ra = strdup(TmpTxt);
+ else ra = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
rc_dest.left = rc_dest.right = rc_dest.top = rc_dest.bottom = 0;
break;
case 7:
@@ -4011,9 +4150,9 @@ bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go)
}
}
else if(Dlg->GetCheck(8)) {
- if(formula) free(formula); formula = 0L;
if((rF = new AccRange(ra)) && rF->GetFirst(&col, &row) &&
- Dlg->GetText(22, TmpTxt) && (formula = strdup(TmpTxt))){
+ Dlg->GetText(22, TmpTxt, TMP_TXT_SIZE) && formula){
+ rlp_strcpy(formula, 500, TmpTxt);
r1 = row; c1 = col;
for( ; rF->GetNext(&col, &row); startval += stepval) {
if(formula[0] == '=') {
@@ -4054,7 +4193,7 @@ bool GetBitmapRes(double *dpi, double *width, double *height, char *header)
bool bRet = false;
int res;
- if(!(Dlg = new DlgRoot(ResDlg))) return false;
+ if(!(Dlg = new DlgRoot(ResDlg, 0L))) return false;
if(!(hDlg = CreateDlgWnd(header, 50, 50, 300, 160, Dlg, 0x0L)))return false;
do {
LoopDlgWnd();
@@ -4121,11 +4260,11 @@ void OD_scheme(int cmd, void *par, RECT *rec, anyOutput *o,
for (k = 20, j = 6; k < 50; k += 10) {
for(i = 0; i < 8; i++) {
ComSchDlg[j].id = i+k; ComSchDlg[j].next = i+k+1;
- ComSchDlg[j].type = k < 40 ? COLBUTTON : FILLBUTTON;
+ ComSchDlg[j].type = k < 40 ? COLBUTT : FILLBUTTON;
ComSchDlg[j].flags = OWNDIALOG | TOUCHEXIT;
switch(k) {
- case 20: ComSchDlg[j].ptype = (void *)Scheme1[i]; break;
- case 30: ComSchDlg[j].ptype = (void *)Scheme2[i]; break;
+ case 20: ComSchDlg[j].ptype = (void *)&Scheme1[i]; break;
+ case 30: ComSchDlg[j].ptype = (void *)&Scheme2[i]; break;
case 40: ComSchDlg[j].ptype = (void *)&Scheme3[i]; break;
}
ComSchDlg[j].x = 5 + i*9 + x; ComSchDlg[j].y = 18*(k-10)/10 + y;
@@ -4135,7 +4274,7 @@ void OD_scheme(int cmd, void *par, RECT *rec, anyOutput *o,
ComSchDlg[j-1].next = k+10;
}
ComSchDlg[j-1].next = 0; ComSchDlg[j-1].flags |= LASTOBJ;
- Dlg = new DlgRoot(ComSchDlg);
+ Dlg = new DlgRoot(ComSchDlg, 0L);
}
if(Dlg){
if(CurrScheme < 4) Dlg->SetCheck(5+CurrScheme, 0L, true);
@@ -4216,7 +4355,7 @@ static DlgInfo LinePropBase[] = {
{101, 102, 0, TOUCHEXIT, INCDECVAL1, &EditLine.width, 50, 0, 32, 10},
{102, 103, 0, 0x0L, LTEXT, 0L, 84, 0, 20, 8},
{103, 104, 0, 0x0L, RTEXT, (void*)"line color", 0, 12, 45, 8},
- {104, 105, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)EditLine.color, 50, 12, 25, 10},
+ {104, 105, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&EditLine.color, 50, 12, 25, 10},
{105, 106, 0, 0x0L, LTEXT, (void*)"pattern:", 0, 24, 25, 8},
{106, 107, 0, TOUCHEXIT, LINEPAT, (void *)&EditLine, 0, 34, 128, 4},
{107, 108, 0, 0x0L, RTEXT, (void*)"pattern length", 0, 47, 45, 8},
@@ -4245,7 +4384,7 @@ void OD_linedef(int cmd, void *par, RECT *rec, anyOutput *o,
for (i = 0; i < 11; i++) {
LinePropDlg[i].x += x; LinePropDlg[i].y += y;
}
- Dlg = new DlgRoot(LinePropDlg);
+ Dlg = new DlgRoot(LinePropDlg, 0L);
}
if(Dlg){
Dlg->SetColor(104, EditLine.color);
@@ -4318,9 +4457,9 @@ static DlgInfo FillPropBase[] = {
{101, 102, 0, 0x0L, EDVAL1, &ODLine.width, 42, 0, 25, 10},
{102, 103, 0, 0x0L, LTEXT, 0L, 69, 0, 20, 8},
{103, 104, 0, 0x0L, RTEXT, (void*)"outline color", 0, 12, 40, 8},
- {104, 105, 0, OWNDIALOG, COLBUTTON, (void *)ODLine.color, 42, 12, 25, 10},
+ {104, 105, 0, OWNDIALOG, COLBUTT, (void *)&ODLine.color, 42, 12, 25, 10},
{105, 106, 0, 0x0L, RTEXT,(void*)"fill color" , 0, 24, 40, 8},
- {106, 107, 0, TOUCHEXIT | OWNDIALOG, COLBUTTON, (void *)ODFill.color, 42, 24, 25, 10},
+ {106, 107, 0, TOUCHEXIT | OWNDIALOG, COLBUTT, (void *)&ODFill.color, 42, 24, 25, 10},
{107, 108, 0, 0x0L, RTEXT, (void*)"pattern", 0, 36, 40, 8},
{108, 0, 0, LASTOBJ | TOUCHEXIT | OWNDIALOG, FILLBUTTON, (void*)&ODFill, 42, 36, 25, 10}};
@@ -4344,7 +4483,7 @@ void OD_filldef(int cmd, void *par, RECT *rec, anyOutput *o,
for (i = 0; i < 9; i++) {
FillPropDlg[i].x += x; FillPropDlg[i].y += y;
}
- Dlg = new DlgRoot(FillPropDlg);
+ Dlg = new DlgRoot(FillPropDlg, 0L);
}
if(Dlg){
Dlg->SetColor(104, ODLine.color);
@@ -4475,21 +4614,37 @@ void OD_paperdef(int cmd, void *par, RECT *rec, anyOutput *o,
if(i < cpformats -1) {
switch(defs.cUnits) {
case 1:
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, " %s (%.1lf x %.1lf cm)", p_formats[i].name,
+ p_formats[i].mwidth/10.0, p_formats[i].mheight/10.0);
+#else
sprintf(TmpTxt, " %s (%.1lf x %.1lf cm)", p_formats[i].name,
p_formats[i].mwidth/10.0, p_formats[i].mheight/10.0);
+#endif
break;
case 2:
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, " %s (%.2lf x %.2lf inch)", p_formats[i].name,
+ p_formats[i].iwidth, p_formats[i].iheight);
+#else
sprintf(TmpTxt, " %s (%.2lf x %.2lf inch)", p_formats[i].name,
p_formats[i].iwidth, p_formats[i].iheight);
+#endif
break;
default:
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, " %s (%.0lf x %.0lf mm)", p_formats[i].name,
+ p_formats[i].mwidth, p_formats[i].mheight);
+#else
sprintf(TmpTxt, " %s (%.0lf x %.0lf mm)", p_formats[i].name,
p_formats[i].mwidth, p_formats[i].mheight);
+#endif
break;
}
- dispsize[i] = strdup(TmpTxt);
+ dispsize[i] = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0);
}
- else dispsize[i] = strdup(" Custom");
+ else if(dispsize[i] = (char*)malloc(15*sizeof(char)))
+ rlp_strcpy(dispsize[i], 15, " Custom");
}
PaperPropDlg[1].ptype = (void*)dispsize;
PaperPropDlg[7].ptype = (void*)Units[defs.cUnits].display;
@@ -4497,7 +4652,7 @@ void OD_paperdef(int cmd, void *par, RECT *rec, anyOutput *o,
for (i = 0; i < 8; i++) {
PaperPropDlg[i].x += x; PaperPropDlg[i].y += y;
}
- if(Dlg = new DlgRoot(PaperPropDlg)){
+ if(Dlg = new DlgRoot(PaperPropDlg, 0L)){
Dlg->Activate(120, false);
if(Dlg->ItemCmd(110, CMD_FINDTEXT, (void*)dispsize[pg_sel])){
if(pg_sel < (cpformats-1)) Dlg->SetText(120, dispsize[pg_sel]);
@@ -4532,7 +4687,7 @@ void OD_paperdef(int cmd, void *par, RECT *rec, anyOutput *o,
((Dialog*)par)->Command(CMD_CONTINUE, 0L, o);
Dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, o);
res = Dlg->GetResult();
- if(res == 110 && Dlg->GetText(110, TmpTxt)){
+ if(res == 110 && Dlg->GetText(110, TmpTxt, TMP_TXT_SIZE)){
if(Dlg->GetInt(110, &i)) {
if(i == cpformats-1){
Dlg->ShowItem(130, true);
@@ -4677,7 +4832,7 @@ void OD_axisplot(int cmd, void *par, RECT *rec, anyOutput *o,
if(PlotsPropDlg = (DlgInfo*)calloc(3, sizeof(DlgInfo))){
memcpy(PlotsPropDlg, PlotsDlg, 3 * sizeof(DlgInfo));
PlotsPropDlg[1].ptype = (void*)names;
- Dlg = new DlgRoot(PlotsPropDlg);
+ Dlg = new DlgRoot(PlotsPropDlg, 0L);
}
axisplot_sel = 0;
break;
@@ -4700,7 +4855,7 @@ void OD_axisplot(int cmd, void *par, RECT *rec, anyOutput *o,
((Dialog*)par)->Command(CMD_CONTINUE, 0L, o);
Dlg->Command(CMD_MOUSE_EVENT, (void *)&mev, o);
res = Dlg->GetResult();
- if(res == 110 && Dlg->GetText(110, TmpTxt)){
+ if(res == 110 && Dlg->GetText(110, TmpTxt, TMP_TXT_SIZE)){
if(Dlg->GetInt(110, &i)) {
//get selection
}
diff --git a/TheDialog.h b/TheDialog.h
index c21e44c..ad8ac0e 100755
--- a/TheDialog.h
+++ b/TheDialog.h
@@ -37,7 +37,7 @@ typedef struct {
} TabSHEET;
//types of dialogs
-enum {NONE, PUSHBUTTON, ARROWBUTT, COLBUTTON, COLBUTT, FILLBUTTON, SHADE3D, LINEBUTT, SYMBUTT,
+enum {NONE, PUSHBUTTON, ARROWBUTT, 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,
@@ -80,7 +80,7 @@ public:
virtual bool GetInt(int id, int *val) {return false;};
virtual bool SetCheck(int id, anyOutput *o, bool state) {return false;};
virtual bool GetCheck(int Id) {return bChecked;};
- virtual bool GetText(int id, char *txt) {return false;};
+ virtual bool GetText(int id, char *txt, int size) {return false;};
virtual void MBtrack(MouseEvent *mev, anyOutput *o) {return;};
virtual void Activate(int id, bool active){return;};
};
@@ -111,7 +111,7 @@ class DlgRoot:public tag_DlgObj {
public:
anyOutput *CurrDisp;
- DlgRoot(DlgInfo *tmpl);
+ DlgRoot(DlgInfo *tmpl, DataObj *d);
~DlgRoot();
bool Command(int cmd, void *tmpl, anyOutput *o);
void DoPlot(anyOutput *o);
@@ -123,8 +123,9 @@ public:
bool SetCheck(int id, anyOutput *o, bool state);
bool GetCheck(int Id);
void Activate(int id, bool active);
- bool GetText(int id, char *txt);
+ bool GetText(int id, char *txt, int size);
bool SetText(int id, char *txt);
+ bool SetValue(int id, double val);
bool TextStyle(int id, int style);
bool TextFont(int id, int font);
bool TextSize(int id, int size);
@@ -136,11 +137,13 @@ public:
anyOutput *GetOutputClass(){return CurrDisp;};
private:
+ anyOutput *ParentOut;
int cDlgs, Result, cContinue;
+ DataObj *data;
Dialog *oldFocus, *oldDefault, *oldTabStop;
bool bActive;
GraphObj *c_go;
- Dialog **tabstops;
+ Dialog **tabstops, *mrk_item;
DlgTmpl **dlg;
MouseEvent *mev;
};
@@ -164,10 +167,11 @@ public:
bool Command(int cmd, void *tmpl, anyOutput *o);
void DoPlot(anyOutput *o);
bool Select(int x, int y, anyOutput *o);
- bool GetText(int id, char *txt);
+ void MBtrack(MouseEvent *mev, anyOutput *o);
+ bool GetText(int id, char *txt, int size);
private:
- mLabel *cont;
+ TextFrame *cont;
};
class ArrowButton:public Dialog {
@@ -182,7 +186,6 @@ 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);
@@ -314,6 +317,7 @@ public:
void DoPlot(anyOutput *o);
bool Select(int x, int y, anyOutput *o);
void SetColor(int id, DWORD color);
+ void MBtrack(MouseEvent *mev, anyOutput *o);
private:
char *txt;
@@ -330,7 +334,7 @@ public:
virtual bool Select(int x, int y, anyOutput *o);
bool GetValue(int id, double *val);
bool GetInt(int id, int *val);
- bool GetText(int id, char *txt);
+ bool GetText(int id, char *txt, int size);
virtual void MBtrack(MouseEvent *mev, anyOutput *o);
virtual void Activate(int id, bool active);
@@ -340,7 +344,7 @@ private:
class RangeInput:public InputText {
public:
- RangeInput(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text);
+ RangeInput(tag_DlgObj *par, DlgInfo * desc, RECT rec, char *text, DataObj *d);
~RangeInput();
bool Command(int cmd, void *tmpl, anyOutput *o);
bool Select(int x, int y, anyOutput *o);
@@ -454,12 +458,13 @@ private:
class TabSheet:public Group {
public:
- TabSheet(tag_DlgObj *par, DlgInfo * desc, RECT rec, TabSHEET *sh);
+ TabSheet(tag_DlgObj *par, DlgInfo * desc, RECT rec, TabSHEET *sh, DataObj *d);
~TabSheet();
void DoPlot(anyOutput *o);
bool Select(int x, int y, anyOutput *o);
private:
+ DataObj *data;
RECT rctab;
char *Text;
};
@@ -485,7 +490,7 @@ public:
void DoPlot(anyOutput *o);
bool Select(int x, int y, anyOutput *o);
bool GetInt(int id, int *val);
- bool GetText(int id, char *txt);
+ bool GetText(int id, char *txt, int size);
void MBtrack(MouseEvent *mev, anyOutput *o);
private:
diff --git a/UtilObj.cpp b/UtilObj.cpp
index 0945652..2b39e4f 100755
--- a/UtilObj.cpp
+++ b/UtilObj.cpp
@@ -88,7 +88,7 @@ EditText::~EditText()
bool
EditText::AddChar(int ci, anyOutput *Out, void *data_obj)
{
- char byte1, byte2, c, *tmp;
+ unsigned char byte1, byte2, c, *tmp;
POINT MyPos;
int i;
@@ -103,18 +103,18 @@ EditText::AddChar(int ci, anyOutput *Out, void *data_obj)
}
Undo.TextCell(this, Out, text, &CursorPos, &m1, &m2, parent, 0L);
bgLine = &ETbgna; bgFill = &ETfbna; TextCol = 0x00000000L;
- if(text)length = strlen(text);
+ if(text)length = (int)strlen(text);
else length = 0;
- if(text) tmp = (char *)realloc(text, length+2);
- else tmp = (char *)calloc(2, sizeof(char));
+ if(text) tmp = (unsigned char *)realloc(text, length+2);
+ else tmp = (unsigned char *)calloc(2, sizeof(unsigned char));
if(!tmp) return false;
- text = tmp;
+ text = (char*)tmp;
byte1 = byte2 = 0;
//replace mark by character if mark exists
if(hasMark()) { //delete marked part of text
if(m1 > m2) Swap(m1, m2);
if(m2 >= (short int)strlen(text)) text[m1] = 0;
- else strcpy(text+m1, text+m2);
+ else rlp_strcpy(text+m1, TMP_TXT_SIZE, text+m2);
CursorPos = m1;
m1 = m2 = -1;
}
@@ -130,9 +130,7 @@ EditText::AddChar(int ci, anyOutput *Out, void *data_obj)
MyPos.x = Align & TXA_HRIGHT ? crb.x - 2 : loc.x + 2;
if(Out)Out->TextCursor(text, MyPos, (POINT *) NULL, &CursorPos,
scroll_et == this ? scroll_dist : scroll_dist=0);
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' && ci != ')' ? this : 0L, 0L);
- }
+ set_etracc();
return true;
}
@@ -166,6 +164,7 @@ EditText::Update(int select, anyOutput *Out, POINT *MousePos)
}
else if(select ==1) Out->TextCursor(text, MyPos, NULL, &CursorPos,
scroll_et == this ? scroll_dist : (scroll_dist=0)+2);
+ set_etracc();
}
break;
case 2: //inactive spreadsheet cell
@@ -182,7 +181,11 @@ EditText::Update(int select, anyOutput *Out, POINT *MousePos)
if(text && text[0]) {
type = ET_VALUE;
Align = TXA_VCENTER | TXA_HRIGHT;
+#ifdef USE_WIN_SECURE
+ sscanf_s(text, "%lf", &Value);
+#else
sscanf(text, "%lf", &Value);
+#endif
}
break;
case 20: //update value only
@@ -197,12 +200,17 @@ EditText::Redraw(anyOutput *Out, bool display)
RECT rc;
POINT MyPos;
char *txt, tmptxt[500];
- int w, h, o_crbx;
+ int i, w, h, o_crbx;
bool b_clip = false;
anyOutput *opc;
anyResult cres;
+ POINT grid[3];
if(!parent && disp) Out = disp;
+ if((type & ET_NODRAW_EMPTY) == ET_NODRAW_EMPTY && CurrText != this){
+ type &= ~ET_NODRAW;
+ return true;
+ }
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) {
@@ -211,9 +219,11 @@ EditText::Redraw(anyOutput *Out, bool display)
Out->TxtSet.Align = Align; Out->TxtSet.ColTxt = TextCol;
Out->TxtSet.ColBg = bgLine->color;
if(text && text[0]) {
- Out->oGetTextExtent(text, strlen(text), &w, &h);
- if(CurrText == this) {
- while((crb.x - loc.x) < (w+(h>>1))) crb.x += (rb.x - loc.x);
+ Out->oGetTextExtent(text, (int)strlen(text), &w, &h);
+ if(CurrText == this && parent && col >= 0) {
+ for(i = col+1; (crb.x - loc.x) < (w+(h>>1)); i++) {
+ crb.x += ((DataObj*)parent)->ri->GetWidth(i);
+ }
if(o_crbx > loc.x && o_crbx > crb.x && o_crbx < 4000) crb.x = o_crbx;
}
else if((crb.x - loc.x) < (w+(h>>1))) b_clip = true;
@@ -223,8 +233,12 @@ EditText::Redraw(anyOutput *Out, bool display)
rc.top = loc.y+1; rc.bottom = crb.y-2;
Out->oRectangle(loc.x, loc.y, crb.x-1, crb.y-1);
if((!text || !text[0]) && (type & 0xff) == ET_VALUE){
+#ifdef USE_WIN_SECURE
+ sprintf_s(tmptxt, 500, "%g", Value);
+#else
sprintf(tmptxt, "%g", Value);
- if(text = (char*)realloc(text, strlen(tmptxt)+2)) strcpy(text, tmptxt);
+#endif
+ if(text = (char*)realloc(text, strlen(tmptxt)+2)) rlp_strcpy(text, 500, tmptxt);
CursorPos = 0;
}
if(ftext) free(ftext); ftext = 0L;
@@ -236,30 +250,42 @@ EditText::Redraw(anyOutput *Out, bool display)
switch (cres.type) {
case ET_VALUE:
Out->TxtSet.Align = TXA_HRIGHT | TXA_VCENTER;
- b_clip = false; strcpy(tmptxt, cres.text);
+ b_clip = false; rlp_strcpy(tmptxt, 500, cres.text);
fit_num_rect(Out, rb.x - loc.x, tmptxt);
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");
+ i = (int)strlen(cres.text)+2;
+ if(ftext = (char*)realloc(ftext, i > 20 ? i : 20))rlp_strcpy(ftext, i, cres.text);
+ if(cres.text && i < sizeof(tmptxt))
+ rlp_strcpy(tmptxt, 500, cres.text[0] != '\'' ? cres.text : cres.text +1);
+ else if(cres.text)rlp_strcpy(tmptxt, 500, "#SIZE");
else tmptxt[0] = 0;
- Out->oGetTextExtent(tmptxt, strlen(tmptxt), &w, &h);
+ Out->oGetTextExtent(tmptxt, (int)strlen(tmptxt), &w, &h);
b_clip = (crb.x - loc.x) < (w+(h>>1)) ? true : false;
break;
case ET_ERROR:
- strcpy(tmptxt, "#ERROR"); break;
+ rlp_strcpy(tmptxt, 500, "#ERROR"); break;
default:
- strcpy(tmptxt, "#VALUE"); break;
+ rlp_strcpy(tmptxt, 500, "#VALUE"); break;
}
txt = tmptxt;
}
else txt = text;
+ if(b_clip && parent && col >= 0 && row >=0) {
+ Out->oGetTextExtent(txt, (int)strlen(txt), &w, &h);
+ for(i = col+1; (crb.x - loc.x) < (w+(h>>1)); i++) {
+ if(((DataObj*)parent)->isEmpty(row, i)) {
+ crb.x += ((DataObj*)parent)->ri->GetWidth(i);
+ ((DataObj*)parent)->etRows[row][i]->type |= ET_NODRAW;
+ }
+ else break;
+ }
+ if((crb.x - loc.x) >= (w+(h>>1))) b_clip = false;
+ else rc.right = crb.x;
+ }
MyPos.y = (loc.y+rb.y)>>1;
if(Out->TxtSet.Align & TXA_HRIGHT) { //right justified text
MyPos.x = crb.x-4;
@@ -273,7 +299,7 @@ EditText::Redraw(anyOutput *Out, bool display)
}
opc->Erase(bgFill->color);
opc->SetTextSpec(&Out->TxtSet); opc->TxtSet.Align = TXA_HLEFT | TXA_VCENTER;
- opc->oTextOut(4,(rb.y-loc.y)>>1, txt, strlen(txt));
+ opc->oTextOut(4,(rb.y-loc.y)>>1, txt, (int)strlen(txt));
if(!parent && CursorPos) {
Out->oGetTextExtent(txt, CursorPos, &w, &h);
while((scroll_dist + w)>(rc.right-rc.left-10)) scroll_dist -=10;
@@ -293,15 +319,19 @@ EditText::Redraw(anyOutput *Out, bool display)
}
scroll_dist = 0;
Out->oTextOut(MyPos.x, MyPos.y, txt, 0);
+ if(display && hasMark() && mx1 > loc.x && mx2 < crb.x) {
+ rc.left = mx1; rc.right = mx2;
+ Out->CopyBitmap(mx1, rc.top, Out, mx1, rc.top, mx2-mx1, rc.bottom-rc.top, true);
+ Out->MrkMode = MRK_NONE;
+ }
}
}
+ Out->SetLine((LineDEF*)&GrayLine);
+ grid[0].x = loc.x; grid[0].y = grid[1].y = crb.y-1;
+ grid[1].x = grid[2].x = crb.x-1; grid[2].y = loc.y-1;
+ Out->oPolyline(grid, 3, 0L);
if(display) {
if(!(Out->UpdateRect(&rc, false))) return false;
- if(hasMark() && mx1 > loc.x && mx2 < rb.x) {
- rc.left = mx1; rc.right = mx2;
- Out->UpdateRect(&rc, true);
- Out->MrkMode = MRK_NONE;
- }
}
return true;
}
@@ -371,6 +401,7 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
return true;
case CMD_SETFONT:
if (!text || !text[0]) return false;
+ if(Out) Undo.SetDisp(Out);
type = ET_TEXT;
if(hasMark()) {
Undo.TextCell(this, Out, text, &CursorPos, &m1, &m2, parent, 0L);
@@ -398,15 +429,16 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
for( ; w < k; w++) TmpTxt[i++] = text[w];
for(j = 0; tag2[j]; j++) TmpTxt[i++] = tag2[j];
for( ; TmpTxt[i++] = text[w]; w++);
- m1 += (w = strlen(tag1)); m2 += w; CursorPos += w;
+ m1 += (w = (int)strlen(tag1)); m2 += w; CursorPos += w;
CleanTags(TmpTxt, &m1, &m2, &CursorPos);
- if(text = (char*)realloc(text, strlen(TmpTxt)+2)) strcpy(text, TmpTxt);
+ if(text = (char*)realloc(text, strlen(TmpTxt)+2)) rlp_strcpy(text, TMP_TXT_SIZE, TmpTxt);
Command(CMD_REDRAW, Out, 0L);
return true;
}
return false;
case CMD_SETSTYLE:
if (!text || !text[0]) return false;
+ if(Out) Undo.SetDisp(Out);
type = ET_TEXT;
if(hasMark()) {
Undo.TextCell(this, Out, text, &CursorPos, &m1, &m2, parent, 0L);
@@ -446,9 +478,9 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
for( ; w < k; w++) TmpTxt[i++] = text[w];
for(j = 0; tag2[j]; j++) TmpTxt[i++] = tag2[j];
for( ; TmpTxt[i++] = text[w]; w++);
- m1 += (w = strlen(tag1)); m2 += w; CursorPos += w;
+ m1 += (w = (int)strlen(tag1)); m2 += w; CursorPos += w;
CleanTags(TmpTxt, &m1, &m2, &CursorPos);
- if(text = (char*)realloc(text, strlen(TmpTxt)+2)) strcpy(text, TmpTxt);
+ if(text = (char*)realloc(text, strlen(TmpTxt)+2)) rlp_strcpy(text, TMP_TXT_SIZE, TmpTxt);
Command(CMD_REDRAW, Out, 0L);
return true;
}
@@ -462,12 +494,12 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
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", tag1+k);
- if(text[i]) sprintf(TmpTxt+j, "%s", text+i);
- if(text = (char*)realloc(text, strlen(TmpTxt)+2)) strcpy(text, TmpTxt);
- CursorPos += strlen(tag1+k);
- Out->Focus();
- Update(1, Out, 0L);
+ j = i + rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, tag1+k);
+ if(text[i]) j += rlp_strcpy(TmpTxt+j, TMP_TXT_SIZE-j, text+i);
+ if(text = (char*)realloc(text, j+2 )) rlp_strcpy(text, j+2, TmpTxt);
+ CursorPos += (int)strlen(tag1+k);
+ Out->Focus(); Update(1, Out, 0L);
+ set_etracc();
}
return true;
case CMD_BACKSP:
@@ -494,21 +526,21 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
if (!text || !text[0]) return false;
if(m1 > m2) Swap(m1, m2);
if(m2 >= (short int)strlen(text)) text[m1] = 0;
- else strcpy(text+m1, text+m2);
- CursorPos = m1;
- m1 = m2 = -1;
+ else rlp_strcpy(text+m1, (int)strlen(text)+m1, text+m2);
+ CursorPos = m1; m1 = m2 = -1;
+ if(!text[0]) {
+ type = ET_UNKNOWN; CursorPos = 0;
+ }
if(Out) Redraw(Out, (bRet = true));
}
else if(text[CursorPos]) {
- strcpy(text + CursorPos, text + CursorPos + 1);
+ rlp_strcpy(text + CursorPos, (int)strlen(text + CursorPos), text + CursorPos + 1);
if(!text || !text[0]) {
type = ET_UNKNOWN; CursorPos = 0;
}
if(Out)Redraw(Out, (bRet = true));
}
- if(parent) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
+ set_etracc();
if(Out)Out->TextCursor(text, MyPos, (POINT *) NULL, &CursorPos,
scroll_et == this ? scroll_dist : scroll_dist=0);
return bRet;
@@ -528,7 +560,7 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
}
return false;
}
- CopyText(text, strlen(text));
+ CopyText(text, (int)strlen(text));
if(Out)Out->UpdateRect(&rMark, true);
return false;
}
@@ -538,9 +570,7 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
Undo.TextCell(this, Out, text, &CursorPos, &m1, &m2, parent, 0L);
for(i = 0; pt[i] > 0x20 && i < 81; i++) this->AddChar(pt[i], 0L, 0L);
if(Out) Redraw(Out, true); free(pt);
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
+ set_etracc();
if(i) return true;
}
return false;
@@ -550,15 +580,11 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
else if(text[CursorPos]){
m1 = CursorPos; m2 = CursorPos+1;
}
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
+ set_etracc();
if(text[CursorPos]) CursorPos++;
else return false;
case CMD_SHIFTLEFT:
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
+ set_etracc();
if (!(CursorPos)) return false;
case CMD_REDRAW:
if(cmd == CMD_SHIFTLEFT) {
@@ -584,15 +610,12 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
Out->oGetTextExtent(text+m1, m2-m1, &w, &h);
mx2 = mx1 + w;
}
- HideTextCursor(); Redraw(Out, true);
+ HideTextCursor(); Redraw(Out, true);
Out->TextCursor(text, MyPos, (POINT *) NULL, &CursorPos,
scroll_et == this ? scroll_dist : scroll_dist=0);
return true;
case CMD_CURRLEFT:
- m1 = m2 = -1;
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
+ m1 = m2 = -1; set_etracc();
if(CursorPos >0) {
CursorPos--;
if(Redraw(Out, true) && Out->TextCursor(text, MyPos, (POINT *) NULL,
@@ -607,10 +630,7 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
}
return false;
case CMD_CURRIGHT:
- m1 = m2 = -1;
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
+ m1 = m2 = -1; set_etracc();
if(text[CursorPos]){
CursorPos++;
if(Redraw(Out, true) && Out->TextCursor(text, MyPos, (POINT *) NULL,
@@ -629,21 +649,18 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
Redraw(Out, true);
return true;
case CMD_POS_FIRST: case CMD_POS_LAST:
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
- CursorPos = (cmd == CMD_POS_LAST && text && text[0]) ? strlen(text) : 0;
- m1 = m2 = -1;
- Redraw(Out, true);
+ CursorPos = (cmd == CMD_POS_LAST && text && text[0]) ? (int)strlen(text) : 0;
+ m1 = m2 = -1; Redraw(Out, true);
Out->TextCursor(text, MyPos, (POINT *) NULL, &CursorPos,
scroll_et == this ? scroll_dist : scroll_dist=0);
+ set_etracc();
return true;
case CMD_CURRDOWN: case CMD_CURRUP:
if (data_obj) {
//the following calculation of the cursor position is crude
//it is based on a aspect of 2:1 for digits
if(Align & TXA_HRIGHT) //right justified text
- MyPos.x = rb.x-4-((rb.y-loc.y-4)*(strlen(text)-CursorPos))/2;
+ MyPos.x = rb.x-4-((rb.y-loc.y-4)*((long)strlen(text)-CursorPos))/2;
else MyPos.x = loc.x+4+((rb.y-loc.y-4)*CursorPos)/2;
MyPos.y = (cmd == CMD_CURRUP) ? loc.y-2 : rb.y+2;
if(MyPos.x < loc.x) MyPos.x = loc.x +4;
@@ -658,13 +675,13 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
if(!text || !text[0]) return false;
if(mev->x <loc.x || mev->x >crb.x || mev->y <loc.y || mev->y >rb.y)return false;
if(mev->Action == MOUSE_LBDOWN) {
- m1 = m2 = -1;
+ m1 = m2 = -1;// set_etracc();
return true;
}
if(mev->Action == MOUSE_LBDOUBLECLICK) {
rMark.top = loc.y+1; rMark.bottom = rb.y-2;
- if(!Out->oGetTextExtent(text, strlen(text), &w, &h)) return false;
- m1 = 0; m2 = strlen(text);
+ if(!Out->oGetTextExtent(text, (int)strlen(text), &w, &h)) return false;
+ m1 = 0; m2 = (int)strlen(text);
if(Align & TXA_HRIGHT) { //right justfied text
rMark.right = crb.x -4; rMark.left = crb.x - w - 4;
}
@@ -672,10 +689,7 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
rMark.left = loc.x +4; rMark.right = rMark.left +w;
}
mx1 = rMark.left; mx2 = rMark.right;
- Redraw(Out, true);
- if(parent && text) {
- ((DataObj*)parent)->Command(CMD_ETRACC, text[0] == '=' ? this : 0L, 0L);
- }
+ Redraw(Out, true); set_etracc();
return true;
}
MyPos.x = Align & TXA_HRIGHT ? mev->x + 4 : mev->x - 4;
@@ -684,7 +698,7 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
j = Out->CalcCursorPos(text, Align & TXA_HRIGHT ? crb :loc, &MyPos);
if(j == m1 || j == m2) return true;
if(Align & TXA_HRIGHT) { //right justfied text
- if((i = strlen(text)-j)){
+ if((i = (int)strlen(text)-j)){
if(!Out->oGetTextExtent(text+j, i, &w, &h)) return false;
w = crb.x - w - 4;
}
@@ -706,7 +720,7 @@ EditText::Command(int cmd, anyOutput *Out, void *data_obj)
rMark.top = loc.y+1; rMark.bottom = rb.y-2;
if(rMark.right < crb.x && rMark.right > loc.x &&
rMark.left > loc.x && rMark.left < crb.x)
- Out->UpdateRect(&rMark,true);
+ Redraw(Out, true);
}
if(hasMark() && parent)
//remove range-mark of data
@@ -766,28 +780,29 @@ EditText::GetText(char *tx, int size, bool bTranslate)
else t = text;
}
else if(bTranslate) {
- GetResult(&res, false); TranslateResult(&res);
+ 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:
+ rlp_strcpy(tmp_txt, 40, 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;
+ t = res.text; break;
default:
- t = 0L; break;
+ 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 {
- memcpy(tx, text, size-1); tx[size-1] = 0;
- }
+ rlp_strcpy(tx, size, t);
return true;
}
else if((type & 0xff) == ET_VALUE) {
+#ifdef USE_WIN_SECURE
+ if(text = (char*)realloc(text, 20)) sprintf_s(text, 20, "%g", Value);
+#else
if(text = (char*)realloc(text, 20)) sprintf(text, "%g", Value);
+#endif
if(text && text[0]) return(GetText(tx, size, false));
}
return false;
@@ -863,9 +878,11 @@ EditText::SetValue(double v)
bool
EditText::SetText(char *t)
{
+ int cb;
+
Value = 0.0; type = ET_UNKNOWN;
bgLine = &ETbgnn; bgFill = &ETfbnn; TextCol = 0x00000000L;
- if(t && t[0] && (text = (char*)realloc(text, strlen(t)+2))) strcpy(text, t);
+ if(t && t[0] && (text = (char*)realloc(text, cb = (int)(strlen(t)+2)))) rlp_strcpy(text, cb, t);
else if (text) text[0] = 0;
return false;
}
@@ -896,29 +913,36 @@ EditText::isFormula()
void
EditText::FindType()
{
- int i, c1, c2, c3, c4;
+ int i, c1, c2, c3, c4, c5;
if(!text || !text[0]) {
Align = TXA_VCENTER | TXA_HRIGHT;
- if ((type && 0xff) == ET_VALUE) type = ET_VALUE;
- else type = ET_UNKNOWN;
+ if ((type & 0xff) == ET_VALUE) type = ET_VALUE;
+ else type = ET_UNKNOWN | ET_EMPTY;
return;
}
if(text[0] == '=') {
Align = TXA_VCENTER | TXA_HRIGHT;
type = ET_FORMULA;
}
- else if(isdigit(text[0]) || ((text[0] == '-' ) || text[0] == '.'
- || text[0] == defs.DecPoint[0]) && (isdigit(text[1]))) {
- for(i = c1 = c2 = c3 = c4 = 0; text[i]; i++) {
+ else if(text[0] > 31 && isdigit(text[0]) || ((text[0] == '-' ) || text[0] == '.'
+ || text[0] == defs.DecPoint[0]) && text[1]>31 && (isdigit(text[1]))) {
+ for(i = c1 = c2 = c3 = c4 = c5 = 0; text[i]; i++) {
switch(text[i]) {
case '.': c1++; break;
case '-': c2++; break;
case '/': c3++; break;
case ':': c4++; break;
+ case 'e': break;
+ case 'E': break;
+ default: if(isalpha(text[i])) c5++;
}
}
- if(c1 < 2 && c2 < 2 && !c3 && !c4 && Txt2Flt(text, &Value)) {
+ if(c5 > 0){
+ Align = TXA_VCENTER | TXA_HLEFT;
+ type = ET_TEXT;
+ }
+ else if(c1 < 2 && c2 < 2 && !c3 && !c4 && Txt2Flt(text, &Value)) {
Align = TXA_VCENTER | TXA_HRIGHT;
type = ET_VALUE;
}
@@ -963,6 +987,27 @@ EditText::FindType()
}
}
+void
+EditText::set_etracc()
+{
+ int i;
+ bool accept_range;
+ anyResult *res;
+
+ if(parent) {
+ if(hasMark()) i = m1 < m2 ? m1 : m2;
+ else i = CursorPos;
+ accept_range = (i && text && text[0] == '=' && text[i-1]!=')'
+ && text[i-1] > 31 && !(isdigit(text[i-1]) || isalpha(text[i-1])));
+ if(accept_range) {
+ res = do_formula((DataObj*)parent, text+1);
+ if(res->type != ET_ERROR) accept_range = false;
+ ((DataObj*)parent)->Command(CMD_CLEAR_ERROR, 0L, 0L);
+ }
+ ((DataObj*)parent)->Command(CMD_ETRACC, accept_range ? this : 0L, 0L);
+ }
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// output formated text - style and font changes
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1002,11 +1047,16 @@ static tag_info tags[] = {
static int font_buff[256];
static unsigned font_idx=0;
+fmtText::fmtText()
+{
+ src=0L; split_text=0L; n_split=0;
+ pos.x = pos.y = 0; flags =0x0;
+}
fmtText::fmtText(anyOutput *o, int x, int y, char *txt)
{
- if(txt && txt[0]) src=strdup(txt);
- else src=0L; split_text=0L; n_split=0;
+ if(txt && txt[0]) src = (char*)memdup(txt, (int)strlen(txt)+1, 0);
+ else src=0L; split_text=0L; n_split=0; flags = 0x0;
pos.x = x; pos.y = y; if(src)Parse();
if(o) DrawText(o);
}
@@ -1025,9 +1075,9 @@ fmtText::StyleAt(int idx, TextDEF *txt_def, int *style, int *font)
if(!src || !split_text || (idx > (int)strlen(src))) return false;
memcpy(&td, txt_def, sizeof(TextDEF));
for(i = j = 0; i < n_split; i++) {
- if((n=split_text[i].tag) >= 0 && SetTextDef(&td, n)) j += strlen(tags[n].tag);
+ if((n=split_text[i].tag) >= 0 && SetTextDef(&td, n)) j += (int)strlen(tags[n].tag);
if(j > idx) break;
- if(split_text[i].txt && split_text[i].txt[0]) j += strlen(split_text[i].txt);
+ if(split_text[i].txt && split_text[i].txt[0]) j += (int)strlen(split_text[i].txt);
if(j >= idx) break;
}
if(style) *style = td.Style; if(font) *font = td.Font;
@@ -1053,7 +1103,7 @@ fmtText::leftTag(char *txt, int cb)
int i, j, k;
for(i = 0; tags[i].tag; i++) {
- for(j = 0, k=strlen(tags[i].tag)-1; tags[i].tag[j] && k <=cb; j++, k--) {
+ for(j = 0, k=(int)strlen(tags[i].tag)-1; tags[i].tag[j] && k <=cb; j++, k--) {
if(tags[i].tag[j] != txt[cb-k]) break;
}
if(!tags[i].tag[j]) return i;
@@ -1068,7 +1118,7 @@ fmtText::cur_right(int *pos)
if(!src || !pos || !src[*pos]) return;
if(src[*pos] == '<' && (n=rightTag(src, *pos)) >= 0) {
- *pos += strlen(tags[n].tag);
+ *pos += (int)strlen(tags[n].tag);
cur_right(pos);
}
else (*pos)++;
@@ -1082,7 +1132,7 @@ fmtText::cur_left(int *pos)
if(!src || !pos || !(*pos)) return;
(*pos)--;
while (src[*pos] == '>' && (n=leftTag(src, *pos)) >= 0) {
- *pos -= strlen(tags[n].tag);
+ *pos -= (int)strlen(tags[n].tag);
}
}
@@ -1093,16 +1143,17 @@ fmtText::oGetTextExtent(anyOutput *o, int *width, int *height, int cb)
int i, n, l, l1, w, w1, h, h1;
if(!o || !width || !height) return false;
- if(!cb) cb = strlen(src);
+ if(!src || !src[0]) return false;
+ if(!cb) cb = (int)strlen(src);
if(!split_text) return o->oGetTextExtent(src, cb, width, height);
memcpy(&td1, &o->TxtSet, sizeof(TextDEF)); memcpy(&td2, &o->TxtSet, sizeof(TextDEF));
for(i = w = h = l = l1 = 0; i < n_split; i++){
if((n=split_text[i].tag) >= 0 && SetTextDef(&td2, n)) {
o->SetTextSpec(&td2);
- l += strlen(tags[n].tag);
+ l += (int)strlen(tags[n].tag);
}
if(split_text[i].txt && split_text[i].txt[0]){
- l1 = l; l += strlen(split_text[i].txt);
+ l1 = l; l += (int)strlen(split_text[i].txt);
if (l1 >= cb) break;
o->oGetTextExtent(split_text[i].txt, l >= cb ? cb-l1 : 0, &w1, &h1);
w += w1; h = h1 > h ? h1 : h;
@@ -1131,7 +1182,8 @@ fmtText::SetText(anyOutput *o, char *txt, int *px, int *py)
for(i = 0; i < n_split; i++) if(split_text[i].txt) free(split_text[i].txt);
free(split_text); split_text = 0L; n_split = 0;
}
- if(txt && txt[0]) src=strdup(txt); if(src)Parse();
+ if(txt && txt[0]) src = (char*)memdup(txt, (int)strlen(txt)+1, 0);
+ if(src)Parse();
if(o) DrawText(o);
}
@@ -1166,7 +1218,7 @@ fmtText::Parse()
int i, li, j, n;
char *tmp;
- if(!src || !(tmp = strdup(src))) return false;
+ if((flags & 0x01) || !src || !(tmp = (char*)memdup(src, (int)strlen(src)+1, 0))) return false;
for(i = li = 0; src[i]; i++) {
if(src[i] == '<' && (n=rightTag(src, i))>=0) {
if(split_text) { //more tags in text
@@ -1174,8 +1226,8 @@ fmtText::Parse()
free(tmp); return false;
}
for(j = li; j < i; j++) tmp[j-li]= src[j]; tmp[j-li]=0;
- split_text[n_split-1].txt = strdup(tmp);
- i += strlen(tags[n].tag); split_text[n_split].tag = n;
+ split_text[n_split-1].txt = (char*)memdup(tmp, (int)strlen((char*)tmp)+1, 0);
+ i += (int)strlen(tags[n].tag); split_text[n_split].tag = n;
split_text[n_split++].txt = 0L;
}
else { //first tag of text
@@ -1183,14 +1235,16 @@ fmtText::Parse()
free(tmp); return false;
}
for(j = 0; j < i; j++) tmp[j]= src[j]; tmp[j]=0;
- split_text[0].tag = -1; split_text[0].txt = strdup(tmp);
- i += strlen(tags[n].tag); split_text[1].tag = n;
+ split_text[0].tag = -1;
+ split_text[0].txt = (char*)memdup(tmp, (int)strlen((char*)tmp)+1, 0);
+ i += (int)strlen(tags[n].tag); split_text[1].tag = n;
n_split = 2;
}
li = i; i--;
}
}
- if(split_text && n_split && li < i && src[li]) split_text[n_split-1].txt = strdup(src+li);
+ if(split_text && n_split && li < i && src[li])
+ split_text[n_split-1].txt = (char*)memdup(src+li, (int)strlen((char*)src+li)+1,0);
free(tmp);
return true;
}
@@ -1318,7 +1372,100 @@ fmtText::DrawFormatted(anyOutput *o)
x = iround(fx += (w*csi)); y = iround(fy -= (w*si));
}
}
- o->SetTextSpec(&td1);
+}
+
+void
+fmtText::EditMode(bool bEdit)
+{
+ if(bEdit) flags |= 0x01;
+ else flags &= ~(0x01);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// manage formats and style of a spreadsheet range
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+RangeInfo::RangeInfo(int sel, int cw, int rh, int fw, RangeInfo *next)
+{
+ r_type = sel; col_width = cw; row_height = rh; first_width = fw;
+ ri_next = next; ar = 0L;
+}
+
+RangeInfo::RangeInfo(int sel, char *range, RangeInfo *next)
+{
+ r_type = sel; ri_next = next;
+ if(range && range[0]) {
+ ar = new AccRange(range);
+ }
+ else ar = 0L;
+}
+
+RangeInfo::~RangeInfo()
+{
+ if(ar) delete ar;
+}
+
+int
+RangeInfo::SetWidth(int w)
+{
+ if(r_type == 0 || r_type == 1) return col_width = w;
+ else if (ri_next) return ri_next->SetWidth(w);
+ return w;
+}
+
+int
+RangeInfo::SetDefWidth(int w)
+{
+ if(r_type == 0) return col_width = w;
+ else if (ri_next) return ri_next->SetDefWidth(w);
+ return w;
+}
+
+int
+RangeInfo::SetHeight(int h)
+{
+ if(r_type == 0) return row_height = h;
+ else if (ri_next) return ri_next->SetHeight(h);
+ return h;
+}
+
+int
+RangeInfo::SetFirstWidth(int w)
+{
+ if(r_type == 0) return first_width = w;
+ else if (ri_next) return ri_next->SetFirstWidth(w);
+ return w;
+}
+
+int
+RangeInfo::GetWidth(int col)
+{
+ int r, c;
+
+ if(r_type == 0) return col_width;
+ else if (ar && r_type == 1){
+ ar->GetFirst(&c, &r);
+ while(ar->NextCol(&c)) {
+ if(c == col) return col_width;
+ }
+ }
+ if(ri_next) return ri_next->GetWidth(col);
+ return 0;
+}
+
+int
+RangeInfo::GetHeight(int row)
+{
+ if(r_type == 0) return row_height;
+ else if (ri_next) return ri_next->GetHeight(row);
+ return row_height;
+}
+
+int
+RangeInfo::GetFirstWidth()
+{
+ if(r_type == 0) return first_width;
+ else if (ri_next) return ri_next->GetFirstWidth();
+ return first_width;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1328,11 +1475,13 @@ DataObj::DataObj()
{
cRows = cCols = 0;
etRows = 0L;
+ ri = new RangeInfo(0, 1, 1, 1, 0L);
}
DataObj::~DataObj()
{
FlushData();
+ delete ri;
}
bool
@@ -1408,6 +1557,17 @@ DataObj::GetSize(int *width, int *height)
return true;
}
+bool
+DataObj::isEmpty(int row, int col)
+{
+ if(row < 0 || row >= cRows || col < 0 || col >= cCols) return false;
+ if(etRows[row][col]) {
+ if((etRows[row][col]->type & 0xff) == ET_UNKNOWN)etRows[row][col]->Update(20, 0L, 0L);
+ if((etRows[row][col]->type & ET_EMPTY) == ET_EMPTY) return true;
+ }
+ return false;
+}
+
void
DataObj::FlushData()
{
@@ -1475,7 +1635,10 @@ StrData::StrData(DataObj *par, RECT *rc)
if(!(str_data[r1] = (char**)malloc((w+1) * sizeof(char*)))) break;
for(c1 = 0, c2= drc.left; c1 <= w; c1++, c2++) {
tx = src->GetTextPtr(r2, c2);
- str_data[r1][c1] = tx && *tx && *tx[0] ? strdup(*tx) : 0L;
+ if(tx && *tx && *tx[0]) {
+ str_data[r1][c1] = (char*)memdup(*tx, (int)strlen(*tx)+1, 0);
+ }
+ else str_data[r1][c1] = 0L;
}
}
}
@@ -1485,7 +1648,10 @@ StrData::StrData(DataObj *par, RECT *rc)
if(!(str_data[r1] = (char**)malloc(pw * sizeof(char*)))) break;
for(c1 = 0; c1 < pw; c1++) {
tx = src->GetTextPtr(r1, c1);
- str_data[r1][c1] = tx && *tx && *tx[0] ? strdup(*tx) : 0L;
+ if(tx && *tx && *tx[0]) {
+ str_data[r1][c1] = (char*)memdup(*tx, (int)strlen(*tx)+1, 0);
+ }
+ else str_data[r1][c1] = 0L;
}
}
drc.right = pw-1; drc.bottom = ph-1;
@@ -1543,7 +1709,7 @@ notary::~notary()
FreeStack();
}
-unsigned long
+int
notary::RegisterGO(GraphObj *go)
{
int i, j;
@@ -1565,27 +1731,27 @@ notary::RegisterGO(GraphObj *go)
}
if(gObs[i] && gObs[i][j] && gObs[i][j] == go) {
NextRegGO = ((i << 13) | j);
- return (unsigned long)i*0x2000L+j+1;
+ return i*0x2000+j+1;
}
if(gObs && gObs[0]) {
for(i = 0; i < 0x2000; i++) {
for(j = 0; j < 0x2000L; j++) {
if(gObs[i][j] == go) {
NextRegGO = ((i << 13) | j);
- return (unsigned long)i*0x2000L+j+1;
+ return i*0x2000+j+1;
}
if(!gObs[i][j]) {
gObs[i][j] = go;
NextRegGO = ((i << 13) | j);
- return (unsigned long)i*0x2000L+j+1;
+ return i*0x2000+j+1;
}
}
if(i < 0x1fffL && !gObs[i+1])
gObs[i+1] = (GraphObj **)calloc(0x2000L, sizeof(GraphObj *));
- if(i < 0x1fffL && !gObs[i+1]) return 0L;
+ if(i < 0x1fff && !gObs[i+1]) return 0;
}
}
- return 0L;
+ return 0;
}
void
@@ -1618,7 +1784,7 @@ notary::AddRegGO(GraphObj *go)
}
bool
-notary::PushGO(unsigned long id, GraphObj *go)
+notary::PushGO(unsigned int id, GraphObj *go)
{
int i, j;
@@ -1661,7 +1827,7 @@ notary::PushGO(unsigned long id, GraphObj *go)
}
GraphObj *
-notary::PopGO(unsigned long id)
+notary::PopGO(unsigned int id)
{
int i, j;
GraphObj *go;
@@ -1719,7 +1885,11 @@ notary::FreeStack()
}
free(goStack);
if(k){
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%d objects deleted\nby notary", k);
+#else
sprintf(TmpTxt,"%d objects deleted\nby notary", k);
+#endif
ErrorBox(TmpTxt);
}
}
@@ -1733,7 +1903,7 @@ AccRange::AccRange(char *asc)
{
int i, j, l;
- if(asc && *asc && (l=strlen(asc)) >1){
+ if(asc && *asc && (l=(int)strlen(asc)) >1){
txt = (char *)malloc(l+2);
for(i = j = 0; i< (int)strlen(asc); i++)
if(asc[i] > 32) txt[j++] = asc[i];
@@ -1848,7 +2018,7 @@ AccRange::Parse(int start)
if(!txt[i]) return false;
step = x1 = y1 = x2 = y2 = 0;
v = &x1;
- for (l=strlen(txt)+1 ; i < l; i++) {
+ for (l=(int)strlen(txt)+1 ; i < l; i++) {
if(txt[i] == '$') i++;
switch(step) {
case 0:
@@ -1903,13 +2073,174 @@ AccRange::Parse(int start)
return false;
}
+//get a description for the current range from the data object
+char *
+AccRange::RangeDesc(void *d, int style)
+{
+ anyResult res;
+ int cb;
+ char *desc;
+
+ if(!d || !txt || !Reset())return 0L;
+ ((DataObj*)d)->GetResult(&res, y1, x1, false);
+ if(res.type == ET_TEXT) {
+ if(res.text && res.text[0])
+ return (char*)memdup(res.text, (int)strlen(res.text)+1, 0);
+ else return 0L;
+ }
+ if(!(desc = (char*)malloc(40*sizeof(char))))return 0L;
+ if(x1 == x2) {
+ if(style == 1) cb = rlp_strcpy(desc, 40, "Col. ");
+ else if(style == 2) cb = rlp_strcpy(desc, 40, "Column ");
+ else goto rdesc_err;
+ rlp_strcpy(desc+cb, 40-cb, Int2ColLabel(x1, true));
+ return desc;
+ }
+ else if(y1 == y2) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(desc, 40, "Row %d", y1+1);
+#else
+ sprintf(desc, "Row %d", y1+1);
+#endif
+ return desc;
+ }
+rdesc_err:
+ free(desc);
+ return 0L;
+}
+
+//---------------------------------------------------------------------------
+// Use the Delauney triangulation to create a 3D mesh of dispersed data
+//---------------------------------------------------------------------------
+void
+Triangle::SetRect()
+{
+ int i, i2;
+ double dy1, dy2, dx, dy;
+ double m1, m2, mx1, mx2, my1, my2;
+
+ //setup bounding rectangle
+ rc.Xmin = rc.Xmax = pt[0].fx; rc.Ymin = rc.Ymax = pt[0].fy;
+ for(i = 1; i < 3; i++) {
+ if(pt[i].fx < rc.Xmin) rc.Xmin = pt[i].fx;
+ if(pt[i].fx > rc.Xmax) rc.Xmax = pt[i].fx;
+ if(pt[i].fy < rc.Ymin) rc.Ymin = pt[i].fy;
+ if(pt[i].fy > rc.Ymax) rc.Ymax = pt[i].fy;
+ }
+ //get three line equations in 2D
+ for(i = 0; i < 3; i++) {
+ i2 = (i+1)%3;
+ ld[i].fx = pt[i].fy;
+ if(pt[i].fx != pt[i2].fx) {
+ ld[i].fy = (pt[i2].fy - pt[i].fy) / (pt[i2].fx - pt[i].fx);
+ }
+ else ld[i].fy = HUGE_VAL;
+ }
+ //close polygon
+ pt[3].fx = pt[0].fx; pt[3].fy = pt[0].fy; pt[3].fz = pt[0].fz;
+ //circumcricle
+ dy1 = fabs(pt[0].fy - pt[1].fy); dy2 = fabs(pt[1].fy - pt[2].fy);
+ m1 = (pt[0].fx - pt[1].fx)/(pt[1].fy - pt[0].fy);
+ m2 = (pt[1].fx - pt[2].fx)/(pt[2].fy - pt[1].fy);
+ mx1 = (pt[0].fx + pt[1].fx)/2.0; my1 = (pt[0].fy + pt[1].fy)/2.0;
+ mx2 = (pt[1].fx + pt[2].fx)/2.0; my2 = (pt[1].fy + pt[2].fy)/2.0;
+ if(dy1 < 1.0e-16 && dy2 < 1.0e-16) {
+ cy = (pt[0].fy + pt[1].fy + pt[2].fy)/3.0;
+ cx = (pt[0].fx + pt[1].fx + pt[2].fx)/3.0;
+ r2 = 0.0; return;
+ }
+ else if(dy1 < 1.0e-16) {
+ cx = (pt[0].fx + pt[1].fx)/2.0; cy = m2 * (cx - mx2) + my2;
+ }
+ else if(dy2 < 1.0e-16) {
+ cx = (pt[2].fx + pt[1].fx)/2.0; cy = m1 * (cx - mx1) + my1;
+ }
+ else {
+ cx = (m1*mx1-m2*mx2+my2-my1)/(m1-m2); cy = m1*(cx - mx1) + my1;
+ }
+ dx = pt[1].fx - cx; dy = pt[1].fy - cy; r2 = dx * dx + dy * dy;
+}
+
+bool
+Triangle::TestVertex(double x, double y)
+{
+ double dx, dy;
+
+ dx = x-cx; dx = dx * dx; dy = y-cy; dy = dy * dy;
+ return (dx+dy)<r2;
+}
+
+Triangulate::Triangulate(Triangle *t_list)
+{
+ trl = t_list; edges = 0L;
+}
+
+bool
+Triangulate::AddEdge(fPOINT3D *p1, fPOINT3D *p2)
+{
+ edge *ce, *ne;
+
+ //if edge exists delete both the new and the existing edge
+ for(ce = edges, ne = 0L; (ce); ) {
+ if((ce->p1.fx == p1->fx && ce->p1.fy == p1->fy && ce->p1.fz == p1->fz
+ && ce->p2.fx == p2->fx && ce->p2.fy == p2->fy && ce->p2.fz == p2->fz)
+ || (ce->p2.fx == p1->fx && ce->p2.fy == p1->fy && ce->p2.fz == p1->fz
+ && ce->p1.fx == p2->fx && ce->p1.fy == p2->fy && ce->p1.fz == p2->fz)) {
+ if(ne) ne->next = ce->next;
+ else edges = ce->next;
+ delete ce; return true;
+ }
+ ne = ce; ce = ce->next;
+ }
+ //come here for new edge
+ if(ne = new edge()) {
+ ne->p1.fx = p1->fx; ne->p1.fy = p1->fy; ne->p1.fz = p1->fz;
+ ne->p2.fx = p2->fx; ne->p2.fy = p2->fy; ne->p2.fz = p2->fz;
+ ne->next = edges; edges = ne;
+ }
+ return false;
+}
+
+bool
+Triangulate::AddVertex(fPOINT3D *v)
+{
+ Triangle *trc, *trn, *tr1;
+ edge *ce, *ae;
+
+ for(trc = trl, trn = 0L, edges = 0L; (trc);) {
+ tr1 = trc->next;
+ //delete triangles whose circumcircle enclose the new vertex
+ if(trc->TestVertex(v->fx, v->fy)) {
+ AddEdge(&trc->pt[0], &trc->pt[1]); AddEdge(&trc->pt[1], &trc->pt[2]);
+ AddEdge(&trc->pt[0], &trc->pt[2]);
+ if(trn) trn->next = trc->next;
+ else trl = trc->next;
+ if(trl == trc) trl = 0L;
+ delete trc;
+ }
+ else trn = trc;
+ trc = tr1;
+ }
+ //create new triangles from those edges which where found only once
+ for(ce = edges; (ce); ) {
+ if(trn = new Triangle()) {
+ trn->pt[0].fx = ce->p1.fx; trn->pt[0].fy = ce->p1.fy; trn->pt[0].fz = ce->p1.fz;
+ trn->pt[1].fx = ce->p2.fx; trn->pt[1].fy = ce->p2.fy; trn->pt[1].fz = ce->p2.fz;
+ trn->pt[2].fx = v->fx; trn->pt[2].fy = v->fy; trn->pt[2].fz = v->fz;
+ trn->SetRect(); trn->next = trl; trl = trn;
+ ae = ce->next; delete(ce); ce = ae;
+ }
+ }
+ return true;
+}
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Default data vault
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Default::Default()
{
dUnits = cUnits = 0;
- strcpy(DecPoint, "."); strcpy(ColSep, ",");
+ rlp_strcpy(DecPoint, 2, "."); rlp_strcpy(ColSep, 2, ",");
Line_0.width = .4; Line_1.width = .04, Line_2.width = 0.016;
Line_0.patlength = 6.0; Line_1.patlength = 0.6; Line_2.patlength = 0.24;
Line_0.color = Line_1.color = Line_2.color = 0x00000000L; //black
@@ -1932,9 +2263,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");
+ if(fmt_date = (char*)malloc(20)) rlp_strcpy(fmt_date, 20, "Z.V.Y");
+ if(fmt_time = (char*)malloc(20)) rlp_strcpy(fmt_time, 20, "H:M:S");
+ if(fmt_datetime = (char*)malloc(20)) rlp_strcpy(fmt_datetime, 20, "Z.V.Y H:M:S");
}
Default::~Default()
@@ -2187,16 +2518,16 @@ Default::FileHistory(char *path)
{
char *tmp_path = 0L, *tmp;
char **history[] = {&File1, &File2, &File3, &File4, &File5, &File6};
- int i;
+ int i, j;
- 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--);
+ if(path && (tmp_path=(char*)malloc((i=(int)strlen(path))+10))){
+ rlp_strcpy(tmp_path, i+1, path);
+ for(j = i ; i > 0 && tmp_path[i] != '/' && tmp_path[i] != '\\'; i--);
tmp_path[i] = 0;
if(currPath) free(currPath);
- if(strlen(tmp_path)) currPath = strdup(tmp_path);
+ if(tmp_path[0]) currPath = (char*)memdup(tmp_path, i+1, 0);
else currPath = 0L;
- strcpy(tmp_path, path);
+ rlp_strcpy(tmp_path, j+1, path);
if(File1 && strcmp(File1, tmp_path)) {
for(i = 0; i < 6 && tmp_path; i++) {
if(i && *history[i] && !strcmp(File1, *history[i])){
@@ -2237,9 +2568,7 @@ Default::FileHistory(char *path)
#define CharCacheSize 1024
ReadCache::ReadCache()
{
- Cache = 0L;
- idx = max = 0;
- eof = true;
+ Cache = 0L; idx = max = 0; eof = true;
}
ReadCache::~ReadCache()
@@ -2253,8 +2582,12 @@ ReadCache::Open(char *name)
{
idx = max = 0;
eof = true;
- if(!name) iFile = 0; //use stdin
+ if(!name) iFile = -1;
+#ifdef USE_WIN_SECURE
+ else if(_sopen_s(&iFile, name, O_BINARY, 0x40, S_IWRITE) || iFile < 0) return false;
+#else
else if(-1 ==(iFile = open(name, O_BINARY))) return false;
+#endif
Cache = (unsigned char *)malloc((unsigned)(CharCacheSize + 1));
if(Cache) return true;
return false;
@@ -2263,9 +2596,12 @@ ReadCache::Open(char *name)
void
ReadCache::Close()
{
- close(iFile);
- if(Cache) free(Cache);
- Cache = 0L;
+#ifdef USE_WIN_SECURE
+ if(iFile >= 0) _close(iFile);
+#else
+ if(iFile >= 0) close(iFile);
+#endif
+ if(Cache) free(Cache); Cache = 0L;
}
unsigned char
@@ -2275,7 +2611,11 @@ ReadCache::Getc()
if(idx < max) return (last = Cache[idx++]);
else {
do {
+#ifdef USE_WIN_SECURE
+ max = _read(iFile, Cache, CharCacheSize);
+#else
max = read(iFile, Cache, CharCacheSize);
+#endif
if(max <=0) {
eof = true;
return 0;
@@ -2299,7 +2639,11 @@ ReadCache::GetField()
while(idx < max && Cache[idx] < 43) idx++;
if(idx == max){
if(max == CharCacheSize) {
+#ifdef USE_WIN_SECURE
+ max = _read(iFile, Cache, CharCacheSize);
+#else
max = read(iFile, Cache, CharCacheSize);
+#endif
idx = 0;
return GetField();
}
@@ -2383,8 +2727,8 @@ MemCache::MemCache(unsigned char *ptr)
:ReadCache()
{
if(ptr) {
- Cache = (unsigned char*) strdup((char*)ptr);
- max = strlen((char*)Cache);
+ max = (int)strlen((char*)ptr);
+ Cache = (unsigned char*) memdup(ptr, max+1, 0);
eof = false;
}
}
@@ -2464,6 +2808,22 @@ UndoObj::Flush()
pcb = &stub1; cdisp = 0L; buffers = 0L;
}
+bool
+UndoObj::isEmpty(anyOutput *o)
+{
+ int i;
+
+ if(!buffers) return true;
+ for (i = 0; i < ndisp; i++) if(buffers[i]){
+ if(o && buffers[i]->disp == o ) {
+ if(buffers[i]->count > 0) return false;
+ else return true;
+ }
+ else if(!o && buffers[i]->count > 0) return false;
+ }
+ return true;
+}
+
//select buffers associated with the current window/widget,
//create new buffers if called for the first time
void
@@ -2516,19 +2876,22 @@ UndoObj::KillDisp(anyOutput *o)
int i, j, c_buf;
if(o && buffers) {
- for(i = c_buf = 0; i < ndisp; i++) {
- if(buffers[i] && buffers[i]->disp == o) c_buf = i; break;
+ for(i = 0, c_buf = -1; i < ndisp; i++) {
+ if(buffers[i] && buffers[i]->disp == o) {
+ c_buf = i; break;
+ }
}
- if(!(c_buf)) return;
+ if(c_buf < 0) return;
if(buffers[c_buf]->buff) {
for(j = 0; j < UNDO_RING_SIZE; j++) {
if(buffers[c_buf]->buff[j]) FreeInfo(&buffers[c_buf]->buff[j]);
}
free(buffers[c_buf]->buff);
}
- free(buffers[i]); buffers[i] = 0L;
+ free(buffers[c_buf]); buffers[c_buf] = 0L;
}
- if(o == cdisp) SetDisp(ldisp);
+ if(ldisp && o == cdisp) SetDisp(ldisp);
+ else cdisp = 0L;
}
//remove references to an invalid (probabbly deleted) object
@@ -2633,6 +2996,16 @@ UndoObj::Restore(bool redraw, anyOutput*o)
((EditText*)buff[idx]->loc)->Command(CMD_MRK_DIRTY, cdisp, 0L);
}
break;
+ case UNDO_TEXTBUF:
+ if(buff[idx]->loc && buff[idx]->data) {
+ target = *((TextBuff*)buff[idx]->data)->pbuff;
+ target = ((TextBuff*)buff[idx]->data)->buff;
+ if(*((TextBuff*)buff[idx]->data)->pbuff) free(*((TextBuff*)buff[idx]->data)->pbuff);
+ *(((TextBuff*)buff[idx]->data)->pbuff) = ((TextBuff*)buff[idx]->data)->buff;
+ *(((TextBuff*)buff[idx]->data)->psize) = ((TextBuff*)buff[idx]->data)->size;
+ *(((TextBuff*)buff[idx]->data)->ppos) = ((TextBuff*)buff[idx]->data)->pos;
+ }
+ break;
case UNDO_MUTATE:
case UNDO_DEL_GO:
((GraphObj*)(buff[idx]->data))->parent = buff[idx]->owner;
@@ -2957,13 +3330,20 @@ UndoObj::ValRect(GraphObj *go, fRECT *rec, DWORD flags)
if(0 > NewItem(UNDO_RECT, flags, go, ptr, (void**)rec)) free(ptr);
}
-void
+int
UndoObj::String(GraphObj *go, char **s, DWORD flags)
{
char *ptr;
+ int iret;
- ptr = (s && *s && *(*s)) ? strdup(*(s)):0L;
+ if(s && *s && *(*s)){
+ ptr = strdup(*(s)); iret = (int)strlen(*(s));
+ }
+ else {
+ ptr = 0L; iret = 0;
+ }
if(0 > NewItem(UNDO_STRING, flags, go, ptr, (void**)s)) if(ptr) free(ptr);
+ return iret;
}
void
@@ -3092,6 +3472,23 @@ UndoObj::TextCell(EditText *et, anyOutput *o, char *text, int *cur, int *m1, int
}
}
+void
+UndoObj::TextBuffer(GraphObj *parent, int *psize, int *ppos, unsigned char **pbuff, DWORD flags, anyOutput *o)
+{
+ TextBuff *ptr;
+
+ if(o) SetDisp(o);
+ if(!parent || !psize || !ppos || !pbuff) return;
+ if(ptr = (TextBuff*)calloc(1, sizeof(TextBuff))) {
+ ptr->size = *psize; ptr->psize = psize;
+ ptr->pos = *ppos; ptr->ppos = ppos;
+ ptr->pbuff = pbuff; ptr->buff = (unsigned char*)memdup(*pbuff, ptr->size, 0);
+ if(0 > NewItem(UNDO_TEXTBUF, flags, parent, ptr, (void**)pbuff)) {
+ if(ptr->buff) free(ptr->buff); free(ptr);
+ }
+ }
+}
+
int
UndoObj::NewItem(int cmd, DWORD flags, GraphObj *owner, void *data, void **loc)
{
@@ -3129,6 +3526,11 @@ UndoObj::FreeInfo(UndoInfo** inf)
break;
case UNDO_ET:
if(((EtBuff*)((*inf)->data))->txt) free(((EtBuff*)((*inf)->data))->txt);
+ free((*inf)->data);
+ break;
+ case UNDO_TEXTBUF:
+ if(((TextBuff*)((*inf)->data))->buff) free(((TextBuff*)((*inf)->data))->buff);
+ free((*inf)->data);
break;
case UNDO_MUTATE:
case UNDO_DEL_GO:
diff --git a/Utils.cpp b/Utils.cpp
index fa95463..0a538db 100755
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -257,7 +257,7 @@ char *str_ltrim(char *str) {
}
char *str_rtrim(char *str) {
- int i;
+ size_t i;
i = strlen(str);
while(i > 0 && str[i-1] <= ' ') str[--i] = '\0';
@@ -268,13 +268,104 @@ char *str_trim(char *str) {
str = str_ltrim(str); return str_rtrim(str);
}
+//remove leading and tailing quotatation
+void rmquot(char *str)
+{
+ size_t i, len;
+ char c;
+
+ if(str && str[0] && (*str == '"' || *str == '\'')) {
+ len = strlen(str); c = *str;
+ if(str[len-1] == c) {
+ str[len-1] = 0;
+ for(i = 1; i < len; str[i-1] = str[i++]);
+ }
+ }
+}
+
+int strpos(char *needle, char *haystack)
+{
+ int i, j;
+
+ if(!needle || !needle[0] || !haystack || !haystack[0]) return -1;
+ for(i = j = 0; haystack[i]; i++, j=0) {
+ if(haystack[i] == needle[0]) for (j = 1; haystack[i+j]; j++) {
+ if(needle[j] != haystack[i+j]) break;
+ }
+ if(j && !needle[j]) return i;
+ }
+ return -1;
+}
+
+char *strreplace(char *needle, char *replace, char *haystack)
+{
+ static char *result = 0L;
+ static size_t reslen = 0;
+ size_t i, j, k, l;
+
+ if(!needle || !needle[0] || !haystack || !haystack[0]) haystack;
+ if(!result) result = (char*)malloc(reslen = 100);
+ result[0] = 0; l = strlen(needle);
+ for(i = j = k = 0; haystack[i]; i++, j=0) {
+ if(haystack[i] == needle[0]) for (j = 1; haystack[i+j]; j++) {
+ if(needle[j] != haystack[i+j]) break;
+ }
+ if(j && !needle[j]) {
+ if(replace && replace[0]) {
+ if(reslen < (i + (int)strlen(replace) + 10)) {
+ result = (char*)realloc(result, reslen += 100);
+ }
+ for(j = 0; replace[j]; j++) result[k++] = replace[j];
+ }
+ i += (l-1);
+ }
+ else result[k++] = haystack[i];
+ }
+ result[k++] = 0;
+ return result;
+}
+
+char *substr(char *text, int pos1, int pos2)
+{
+ static char *result = 0L;
+ static size_t reslen = 0;
+ int i, j;
+ size_t l;
+
+ if(!text || !text[0]) return 0L;
+ l = strlen(text);
+ if(pos1 < 0) pos1 = 0; if(pos2 < pos1) pos2 = (int)(l+1);
+ if(!result) result = (char*)malloc(reslen = 100);
+ while (reslen < l) result = (char*) realloc(result, reslen += 100);
+ for(i = 0; i < pos1 && text[i]; i++);
+ for(j = 0; i <= pos2 && text[i]; result[j++] = text[i++]);
+ result[j] = 0;
+ return result;
+}
+
+//copy string in src to dest, returning the stringlength of src
+// seek better solution for long strings
+int rlp_strcpy(char*dest, int size, char*src)
+{
+ int i;
+
+ if(dest && src) {
+ for(i = 0; i < size; i++) {
+ if(!(dest[i] = src[i])) return i;
+ }
+ dest[i-1] = 0;
+ return i-1;
+ }
+ return 0;
+}
+
// restyle formula
void ReshapeFormula(char **text)
{
int i, j, l;
if(!text || !*text || !**text) return;
- l = strlen(*text);
+ l = (int)strlen(*text);
for(i = j = 0; i < l; i++) {
if((*text)[i] == ';') {
if((*text)[i+1] == ';' || (*text)[i+1] == '\n') i++;
@@ -282,8 +373,8 @@ void ReshapeFormula(char **text)
TmpTxt[j++] = (*text)[i];
}
TmpTxt[j] = 0;
- if((int)strlen(TmpTxt) < l && TmpTxt[0]) {
- free(*text); *text = strdup(TmpTxt);
+ if(j && j <= l && TmpTxt[0]) {
+ rlp_strcpy(*text, l+1, TmpTxt);
}
}
@@ -294,21 +385,25 @@ void TranslateResult(anyResult *res)
switch (res->type) {
case ET_VALUE:
- if(res->value == HUGE_VAL) strcpy(tr_text, "inf");
- else if(res->value == -HUGE_VAL) strcpy(tr_text, "-inf");
+ if(res->value == HUGE_VAL) rlp_strcpy(tr_text, 80, "inf");
+ else if(res->value == -HUGE_VAL) rlp_strcpy(tr_text, 80, "-inf");
+#ifdef USE_WIN_SECURE
+ else sprintf_s(tr_text, 80, "%g", res->value);
+#else
else sprintf(tr_text, "%g", res->value);
+#endif
res->text = tr_text; return;
case ET_BOOL:
- sprintf(tr_text, "%s", ((int)res->value) ? "true" : "false");
+ rlp_strcpy(tr_text, 80, ((int)res->value) ? (char*)"true" : (char*)"false");
res->text = tr_text; return;
case ET_DATE:
- sprintf(tr_text, "%s", value_date(res->value, defs.fmt_date));
+ rlp_strcpy(tr_text, 80, 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));
+ rlp_strcpy(tr_text, 80, 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));
+ rlp_strcpy(tr_text, 80, value_date(res->value, defs.fmt_datetime));
res->text = tr_text; return;
case ET_TEXT:
if(res->text && res->text[0]) return;
@@ -335,7 +430,7 @@ void CleanTags(char *txt, int *i1, int *i2, int *i3)
if(no_tags[k][l] != txt[i+l]) break;
if(!no_tags[k][l]){
na = false;
- i += ((w=strlen(no_tags[k]))-1);
+ i += ((w=(int)strlen(no_tags[k]))-1);
if(i1 && *i1 > i) *i1 -= w;
if(i2 && *i2 > i) *i2 -= w;
if(i3 && *i3 > i) *i3 -= w;
@@ -374,7 +469,11 @@ char *Nat2Int(char *text) //format locale number to intranational notation
void WriteNatFloatToBuff(char *buff, double val)
{
- WriteFloatToBuff(buff, val);
+#ifdef USE_WIN_SECURE
+ sprintf_s(buff, 20, " %g", val);
+#else
+ sprintf(buff, " %g", val);
+#endif
Int2Nat(buff);
}
@@ -385,10 +484,14 @@ bool Txt2Flt(char *txt, double *val)
if(txt && txt[0] && val) {
if(!txt[1] && (txt[0] == defs.DecPoint[0] || txt[0] < '0' ||
txt[0] > '9'))return false;
- if(txt && txt[0] && (tmp = strdup(txt))){
+ if(txt && txt[0] && (tmp = (char*)memdup(txt, (int)strlen(txt)+1, 0))){
Nat2Int(tmp);
//the return value of sscanf only roughly identifies a number
+#ifdef USE_WIN_SECURE
+ if(!sscanf_s(tmp,"%lf", val)){
+#else
if(!sscanf(tmp,"%lf", val)){
+#endif
free(tmp);
return false;
}
@@ -403,7 +506,7 @@ void RmTrail(char *txt)
{
int i;
- i = strlen(txt);
+ i = (int)strlen(txt);
while(i >0 && (txt[i-1] == '0' || txt[i-1] < 32)) txt[--i] = 0;
if(i > 1 && txt[i-1] == '.') txt[i-1] = 0;
}
@@ -420,11 +523,15 @@ double NiceValue(double fv)
char *Int2ColLabel(int nr1, bool uc)
{
- static char RetTxt[10];
+ static char RetTxt[12];
int i, j, nr = nr1;
char base = uc ? 'A' : 'a';
+#ifdef USE_WIN_SECURE
+ sprintf_s(RetTxt+8, 4, "%c\0", base + (nr %26));
+#else
sprintf(RetTxt+8, "%c\0", base + (nr %26));
+#endif
nr /= 26;
for (i = 7; nr && i>=0; i--) {
j = nr %27;
@@ -446,22 +553,26 @@ char *str2xml(char *str)
for(i = j = 0; str[i] && j < 4090; i++) {
switch(str[i]) {
case '"':
- j += sprintf(TmpTxt+j, """);
+ j += rlp_strcpy(TmpTxt+j, TMP_TXT_SIZE-j, """);
break;
case '&':
- j += sprintf(TmpTxt+j, "&");
+ j += rlp_strcpy(TmpTxt+j, TMP_TXT_SIZE-j, "&");
break;
case '<':
- j += sprintf(TmpTxt+j, "<");
+ j += rlp_strcpy(TmpTxt+j, TMP_TXT_SIZE-j, "<");
break;
case '>':
- j += sprintf(TmpTxt+j, ">");
+ j += rlp_strcpy(TmpTxt+j, TMP_TXT_SIZE-j, ">");
break;
default:
if((unsigned char)str[i] <= 127) TmpTxt[j++]=str[i];
else {
- if(mbtowc(&wc, str+i, 1) >0) j += sprintf(TmpTxt+j,
- "&#%d;", ((unsigned short)wc));
+ if(mbtowc(&wc, str+i, 1) >0)
+#ifdef USE_WIN_SECURE
+ j += sprintf_s(TmpTxt+j, TMP_TXT_SIZE-j, "&#%d;", ((unsigned short)wc));
+#else
+ j += sprintf(TmpTxt+j, "&#%d;", ((unsigned short)wc));
+#endif
}
}
}
@@ -471,24 +582,28 @@ char *str2xml(char *str)
// split string str into array of strings using sep as separator
// return number of lines created in nl
+static char *split_buf = 0L;
+static int split_buf_size, split_buf_pos;
char **split(char *str, char sep, int *nl)
{
- int i, j, k, l, ns;
- char **ptr, *txt;
+ int i, j, l, ns;
+ char **ptr;
- if(!str || !sep) return 0L;
- if(!(txt = strdup(str))) return 0L;
- k = (int)strlen(txt);
- for(i = ns = 0; i < k; i++) if(txt[i] == sep) ns++;
- if(!(ptr = (char**)calloc(ns+2, sizeof(char*)))){
- free(txt); return 0L;
- }
- for(i = j = l = 0; i < k; i++) {
- if(txt[i] == sep) {
- txt[i] = 0; ptr[l++] = strdup(txt+j); j = i+1;
+ if(!str || !str[0] || !sep) return 0L;
+ split_buf_pos = 0;
+ add_to_buff(&split_buf, &split_buf_pos, &split_buf_size, str, 0);
+ if(!split_buf || !split_buf_pos) return 0L;
+ for(i = ns = 0; i < split_buf_pos; i++) if(split_buf[i] == sep) ns++;
+ if(!(ptr = (char**)calloc(ns+2, sizeof(char*)))) return 0L;
+ for(i = j = l = 0; i < split_buf_pos; i++) {
+ if(split_buf[i] == sep) {
+ split_buf[i] = 0;
+ ptr[l++] = (char*)memdup(split_buf+j, (int)strlen(split_buf+j)+1, 0);
+ j = i+1;
}
}
- ptr[l++] = strdup(txt+j); if(nl) *nl = l; free(txt);
+ ptr[l++] = (char*)memdup(split_buf+j, (int)strlen(split_buf+j)+1, 0);
+ if(nl) *nl = l;
return ptr;
}
@@ -498,13 +613,13 @@ char *fit_num_rect(anyOutput *o, int max_width, char *num_str)
char mant[20], expo[20], fmt[10];
double num;
- o->oGetTextExtent(num_str, slen = strlen(num_str), &w, &h);
+ o->oGetTextExtent(num_str, slen = (int)strlen(num_str), &w, &h);
if(w < (max_width-5)) return num_str;
//first try to remove leading zero from exponent
for(i = 0; i < slen; i++) if(num_str[i] == 'e') break;
if(num_str[i] == 'e') while (num_str[i+2] == '0') {
for(j = i+2; num_str[j]; j++) num_str[j] = num_str[j+1];
- o->oGetTextExtent(num_str, slen = strlen(num_str), &w, &h);
+ o->oGetTextExtent(num_str, slen = (int)strlen(num_str), &w, &h);
if(w < (max_width-5)) return num_str;
}
//no success: reduce the number of digit by rounding
@@ -514,21 +629,91 @@ char *fit_num_rect(anyOutput *o, int max_width, char *num_str)
}
if(num_str[i] =='e') mant[i] = 0; k = i - k-1;
for(j = 0; num_str[i]; j++, i++) expo[j] = num_str[i]; expo[j] = 0;
+#ifdef USE_WIN_SECURE
+ sscanf_s(mant, "%lf", &num);
+#else
sscanf(mant, "%lf", &num);
+#endif
if(k >0) do {
- sprintf(fmt, "%s.%dlf%s", "%", k, expo);
- sprintf(num_str, fmt, num); k--;
- o->oGetTextExtent(num_str, slen = strlen(num_str), &w, &h);
+#ifdef USE_WIN_SECURE
+ sprintf_s(fmt, 10, "%%.%dlf%s", k, expo);
+ slen = sprintf_s(num_str, 40, fmt, num); //num_str is much longer than 40
+#else
+ sprintf(fmt, "%%.%dlf%s", k, expo);
+ slen = sprintf(num_str, fmt, num);
+#endif
+ k--;
+ o->oGetTextExtent(num_str, slen, &w, &h);
if(w < (max_width-5)) return num_str;
}while (k >= 0);
//cannot fit: return hash marks instead
- for(i = w = 0; w < (max_width-5); i++) {
- sprintf(num_str+i, "#");
- o->oGetTextExtent(num_str, slen = strlen(num_str), &w, &h);
+ for(i = w = 0; w < (max_width-5) && i < 11; i++) {
+ rlp_strcpy(num_str, i+2, "##########");
+ o->oGetTextExtent(num_str, i+1, &w, &h);
}
num_str[i-1] = 0; return num_str;
}
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// utilities to add a line or number to a text buffer: memory file
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void add_to_buff(char** dest, int *pos, int *csize, char *txt, int len)
+{
+ if(!len)len = (int)strlen(txt);
+ if(!len) return;
+ if((*pos+len+1)>= *csize) {
+ *csize += 1000;
+ while(*csize < (*pos+len+1)) *csize += 1000;
+ *dest = (char*)realloc(*dest, *csize);
+ }
+ if(*dest) {
+ *pos += rlp_strcpy(*dest+*pos, len+1, txt);
+ }
+}
+
+void add_int_to_buff(char** dest, int *pos, int *csize, int value, bool lsp, int ndig)
+{
+ int len;
+ char txt[40];
+
+#ifdef USE_WIN_SECURE
+ len = sprintf_s(txt, 40, lsp ? " %d" : "%d", value);
+#else
+ len = sprintf(txt, lsp ? " %d" : "%d", value);
+#endif
+ add_to_buff(dest, pos, csize, txt, len);
+}
+
+void add_dbl_to_buff(char** dest, int *pos, int *csize, double value, bool lsp)
+{
+ int len;
+ char txt[40];
+
+#ifdef USE_WIN_SECURE
+ len = sprintf_s(txt, 40, lsp ? " %g" : "%g", value);
+#else
+ len = sprintf(txt, lsp ? " %g" : "%g", value);
+#endif
+ add_to_buff(dest, pos, csize, txt, len);
+}
+
+void add_hex_to_buff(char** dest, int *pos, int *csize, DWORD value, bool lsp)
+{
+ int len;
+ char txt[40];
+
+ if(value) {
+#ifdef USE_WIN_SECURE
+ len = sprintf_s(txt, 40, lsp ? " 0x%08x" : "0x%08x", value);
+#else
+ len = sprintf(txt, lsp ? " 0x%08x" : "0x%08x", value);
+#endif
+ add_to_buff(dest, pos, csize, txt, len);
+ }
+ else if(lsp) add_to_buff(dest, pos, csize, " 0x0", 4);
+ else add_to_buff(dest, pos, csize, "0x0", 3);
+}
+
//----------------------------------------------------------------------------
// bounding rectangle utilities
//----------------------------------------------------------------------------
@@ -840,19 +1025,17 @@ void InvertPolygon(POINT *pts, int nPts, LineDEF *Line, FillDEF *Fill, RECT *rc,
void InvertLine(POINT *pts, int nPts, LineDEF *Line, RECT *rc,
anyOutput *o, bool mark)
{
+ int i;
LineDEF OldLine;
- double minw = defs.GetSize(SIZE_DATA_LINE);
memcpy(&OldLine, Line, sizeof(LineDEF));
- if(OldLine.width <= 0.001) memcpy(&OldLine, defs.GetLine(), sizeof(LineDEF));
+ if(OldLine.width <= 0.0001) OldLine.width = 0.0001;
+ for(i = 0; o->un2fiy(OldLine.width) < 1.0 && i < 50; i++) OldLine.width *= 2.0;
OldLine.color = mark ? Line->color : 0x00ffffffL;
- OldLine.width = OldLine.width < minw ? minw * 3.0 : OldLine.width *3.0;
- o->SetLine(&OldLine);
- o->oPolyline(pts, nPts);
- OldLine.width = Line->width;
+ OldLine.width *= 3.0; o->SetLine(&OldLine);
+ o->oPolyline(pts, nPts); OldLine.width = Line->width;
OldLine.color = mark ? Line->color ^ 0x00ffffffL : Line->color;
- o->SetLine(&OldLine);
- o->oPolyline(pts, nPts);
+ o->SetLine(&OldLine); o->oPolyline(pts, nPts);
if(rc) o->UpdateRect(rc, false);
}
@@ -1069,8 +1252,13 @@ void DeleteGO(GraphObj *go)
case GO_XYSTAT: delete((xyStat*)go); break;
case GO_FITFUNC3D: delete((FitFunc3D*)go); break;
case GO_BEZIER: delete((Bezier*)go); break;
+ case GO_TEXTFRAME: delete((TextFrame*)go); break;
default:
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "Cannot delete Object\nwith Id %ld", go->Id);
+#else
sprintf(TmpTxt, "Cannot delete Object\nwith Id %ld", go->Id);
+#endif
ErrorBox(TmpTxt);
//we do not delete the object, probably we recover
}
@@ -1116,17 +1304,26 @@ bool BackupFile(char *FileName)
//no backup necessary if file does not exist
if(!(FileExist(FileName))) return true;
- strcpy(Name, FileName);
- i = strlen(Name)-1;
+ rlp_strcpy(Name, 512,FileName);
+ i = (int)strlen(Name)-1;
if(Name[--i] == '.') Name[i] = 0;
else if(Name[--i] == '.') Name[i] = 0;
else if(Name[--i] == '.') Name[i] = 0;
else return false;
i = 1;
do {
+#ifdef USE_WIN_SECURE
+ sprintf_s(ext, 6, ".%03d", i);
+ sprintf_s(TmpFileName, 512, "%s%s", Name, ext);
+ if(!(fopen_s(&TheFile, TmpFileName, "r"))) {
+ fclose(TheFile);
+ }
+ else break;
+#else
sprintf(ext, ".%03d", i);
sprintf(TmpFileName, "%s%s", Name, ext);
if((TheFile = fopen(TmpFileName, "r"))) fclose(TheFile);
+#endif
i++;
} while (i < 999 && TheFile);
if(i >= 999) { //too many backups exist already
@@ -1146,7 +1343,11 @@ bool IsRlpFile(char *FileName)
char Line[10];
bool bRet = false;
+#ifdef USE_WIN_SECURE
+ if(fopen_s(&TheFile, FileName, "r")) return false;
+#else
if(0L ==(TheFile = fopen(FileName, "r"))) return false;
+#endif
fread(Line, 1, 8, TheFile);
Line[5] = 0;
if(0 == strcmp(Line, ";RLP "))bRet = true;
@@ -1160,7 +1361,11 @@ bool IsXmlFile(char *FileName)
char Line[10];
bool bRet = false;
+#ifdef USE_WIN_SECURE
+ if(fopen_s(&TheFile, FileName, "r")) return false;
+#else
if(0L ==(TheFile = fopen(FileName, "r"))) return false;
+#endif
fread(Line, 1, 8, TheFile);
Line[6] = 0;
if(0 == strcmp(Line, "<?xml "))bRet = true;
@@ -1172,11 +1377,14 @@ bool FileExist(char *FileName)
{
FILE *TheFile;
-
+#ifdef USE_WIN_SECURE
+ if(ENOENT == fopen_s(&TheFile, FileName, "r")) return false;
+#else
if(0L ==(TheFile = fopen(FileName, "r"))) {
if(errno == ENOENT) return false;
return true;
}
+#endif
fclose(TheFile);
return true;
}
diff --git a/Version.h b/Version.h
index d899ea7..95a98b5 100755
--- a/Version.h
+++ b/Version.h
@@ -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.1.2"
+#define SZ_VERSION "1.2"
diff --git a/WinSpec.cpp b/WinSpec.cpp
index 0eac824..e59c53b 100755
--- a/WinSpec.cpp
+++ b/WinSpec.cpp
@@ -56,12 +56,14 @@ PrintWin *Printer = 0L;
char *SaveDataAsName(char *oldname)
{
static char szFile[500], szFileTitle[256];
- static char szFilter[] = "RLPlot workbook (*.rlw)\0*.rlw\0data files (*.csv)\0*.csv\0tab separated (*tsv)\0"
+ static char szFilter[] = "RLPlot workbook (*.rlw)\0*.rlw\0data files (*.csv)\0*.csv\0tab separated (*.tsv)\0"
"*.tsv\0XML (*.xml)\0*.xml\0";
OPENFILENAME ofn;
+ int i, j, cb;
+ char *ext;
szFile[0] = '\0';
- if(oldname)strcpy(szFile, oldname);
+ if(oldname)rlp_strcpy(szFile, 500, oldname);
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = GetFocus();
@@ -76,10 +78,19 @@ char *SaveDataAsName(char *oldname)
ofn.lpstrTitle = "Save Data As";
if(GetSaveFileName(&ofn)){
+ if(!(cb = (int)strlen(szFile)) || !szFile[0])return 0L;
+ if(cb < 4 || szFile[cb-4] != '.'){
+ for(i = j = 0; (j>>1) < (int)(ofn.nFilterIndex-1); i++) {
+ if(szFilter[i] == '\0') j++;
+ }
+ ext = szFilter+i;
+ for(i = 0; ext[i] && ext[i] != '*'; i++);
+ rlp_strcpy(szFile+cb, 5, ext+i+1);
+ }
defs.FileHistory(szFile);
return szFile;
}
- else return NULL;
+ else return 0L;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -91,7 +102,7 @@ char *SaveGraphAsName(char *oldname)
OPENFILENAME ofn;
szFile[0] = '\0';
- if(oldname)strcpy(szFile, oldname);
+ if(oldname)rlp_strcpy(szFile, 500, oldname);
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = GetFocus();
@@ -121,7 +132,7 @@ char *OpenGraphName(char *oldname)
OPENFILENAME ofn;
szFile[0] = '\0';
- if(oldname)strcpy(szFile, oldname);
+ if(oldname)rlp_strcpy(szFile, 500, oldname);
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = GetFocus();
@@ -153,7 +164,7 @@ char *OpenDataName(char *oldname)
OPENFILENAME ofn;
szFile[0] = '\0';
- if(oldname)strcpy(szFile, oldname);
+ if(oldname)rlp_strcpy(szFile, 500, oldname);
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = GetFocus();
@@ -188,7 +199,7 @@ void OpenExportName(GraphObj *g, char *oldname)
szFile[0] = '\0';
if(!g) return;
- if(oldname)strcpy(szFile, oldname);
+ if(oldname)rlp_strcpy(szFile, 500, oldname);
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = GetFocus();
@@ -203,21 +214,21 @@ void OpenExportName(GraphObj *g, char *oldname)
ofn.lpstrTitle = "Export Graph";
if(g && GetSaveFileName(&ofn)){
- i = strlen(szFile);
+ i = (int)strlen(szFile);
g->Command(CMD_BUSY, 0L, 0L);
- if(0==stricmp(".svg", szFile+i-4)) {
+ if(0==_stricmp(".svg", szFile+i-4)) {
DoExportSvg(g, szFile, 0L);
}
- else if(0==stricmp(".wmf", szFile+i-4)) {
+ else if(0==_stricmp(".wmf", szFile+i-4)) {
DoExportWmf(g, szFile, 600.0f, 0L);
}
- else if(0==stricmp(".eps", szFile+i-4)) {
+ else if(0==_stricmp(".eps", szFile+i-4)) {
DoExportEps(g, szFile, 0L);
}
- else if(0==stricmp(".tif", szFile+i-4)) {
+ else if(0==_stricmp(".tif", szFile+i-4)) {
DoExportTif(g, szFile, 0L);
}
- else if(0==stricmp(".tiff", szFile+i-5)) {
+ else if(0==_stricmp(".tiff", szFile+i-5)) {
DoExportTif(g, szFile, 0L);
}
else ErrorBox("Unknown file extension or format");
@@ -332,7 +343,7 @@ void ShowCopyMark(anyOutput *out, RECT *mrk, int nRec)
LineDEF liCopyMark1 = {0.0f, 1.0f, 0x00ffffffL, 0L};
LineDEF liCopyMark2 = {0.0f, 6.0f, 0x0L, 0xf0f0f0f0L};
-long FAR PASCAL TimerWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
+LRESULT FAR PASCAL TimerWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
static POINT line[5];
static int cp_mark = 0;
@@ -432,13 +443,13 @@ void TestClipboard(GraphObj *g)
else if((hmem = GetClipboardData(cf_rlpgraph)) &&
(ptr = (unsigned char*) GlobalLock(hmem))) OpenGraph(g, 0L, ptr, true);
}
- else if(g->Id == GO_PAGE) {
+ else if(g->Id == GO_PAGE || g->Id == GO_GRAPH) {
if((hmem = GetClipboardData(cf_rlpobj)) &&
(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, true);
}
- else if(g->Id == GO_GRAPH) TestClipboard(g->parent);
+ else TestClipboard(g->parent);
if(hmem) GlobalUnlock(hmem);
CloseClipboard();
}
@@ -457,7 +468,7 @@ void CopyText(char *txt, int len)
unsigned char* buf;
if(!txt || !txt[0]) return;
- if(!len) len = strlen(txt);
+ if(!len) len = (int)strlen(txt);
OpenClipboard(MainWnd);
EmptyClipboard();
if(hmem = GlobalAlloc(GMEM_MOVEABLE, len+2)) {
@@ -477,7 +488,7 @@ unsigned char* PasteText()
OpenClipboard(MainWnd);
if((hmem = GetClipboardData(CF_TEXT)) && (ptr = (unsigned char*) GlobalLock(hmem))){
- ret = (unsigned char*) strdup((char*)ptr);
+ ret = (unsigned char*) _strdup((char*)ptr);
}
if(hmem) GlobalUnlock(hmem);
CloseClipboard();
@@ -497,13 +508,51 @@ void GetDesktopSize(int *width, int *height)
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Get long reference to pointer (win64-compatibility)
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static void **ptrs = 0L;
+static size_t s_ptrs = 0;
+static size_t n_ptrs = 1;
+
+long lptrref(void* ptr)
+{
+ size_t i;
+
+ if((n_ptrs +1) > s_ptrs){
+ ptrs = (void **)realloc(ptrs, (s_ptrs += 1000) * sizeof(void*));
+ }
+ if(!ptrs) return 0L;
+ for(i = 1; i < n_ptrs; i++){
+ if(ptrs[i]== ptr) return (long)i;
+ if(ptr && !ptrs[i]){
+ ptrs[i] = ptr;
+ return (long)i;
+ }
+ }
+ //new pointer
+ ptrs[n_ptrs++] = ptr;
+ return (long)(n_ptrs-1);
+}
+
+void *reflptr(long ref)
+{
+ if(ref > 0 && ref < (long)n_ptrs && ptrs) return ptrs[ref];
+ return 0L;
+}
+
+void noreflptr(long ref)
+{
+ if(ref > 0 && ref < (long)n_ptrs && ptrs) ptrs[ref]=0L;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Common code for any Windows output class
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool com_oTextOut(int x, int y, char *txt, int cb,
HFONT *hFont, HDC *dc, TextDEF *td, bool win95mode, anyOutput *o)
{
XFORM xf;
- w_char *uc;
+ WCHAR *uc;
int i, ix, iy, align;
if(!*hFont || !txt || !txt[0]) return false;
@@ -534,19 +583,19 @@ bool com_oTextOut(int x, int y, char *txt, int cb,
xf.eDx = (float)x;
xf.eDy = (float)y;
SetWorldTransform(*dc, &xf);
- if(td->Font==FONT_GREEK && (uc=(w_char*)calloc(strlen(txt)+1, sizeof(w_char)))) {
+ if(td->Font==FONT_GREEK && (uc=(WCHAR *)calloc(strlen(txt)+1, sizeof(WCHAR)))) {
for(i = 0; txt[i]; i++) {
if((txt[i] >= 'A' && txt[i] <= 'Z')) uc[i] = txt[i] - 'A' + 0x391;
else if((txt[i] >= 'a' && txt[i] <= 'z')) uc[i] = txt[i] - 'a' + 0x3B1;
else uc[i] = txt[i];
}
TextOutW(*dc, ix, iy+((td->Align & TXA_VCENTER) ? - td->iSize/2 : 0), uc,
- (cb > 0) ? cb : strlen(txt));
+ (cb > 0) ? cb : (int)strlen(txt));
free(uc);
}
else {
TextOut(*dc, ix, iy+((td->Align & TXA_VCENTER) ? - td->iSize/2 : 0), txt,
- (cb > 0) ? cb : strlen(txt));
+ (cb > 0) ? cb : (int)strlen(txt));
}
// DrawText(*dc, txt, (cb> 0)? cb : strlen(txt), 0L /*LPRECT*/, uFormat);
ModifyWorldTransform(*dc, &xf, MWT_IDENTITY);
@@ -554,19 +603,19 @@ bool com_oTextOut(int x, int y, char *txt, int cb,
return true;
}
else {
- if(!win95mode && td->Font==FONT_GREEK && (uc=(w_char*)calloc(strlen(txt)+1, sizeof(w_char)))) {
+ if(!win95mode && td->Font==FONT_GREEK && (uc=(WCHAR *)calloc(strlen(txt)+1, sizeof(WCHAR)))) {
for(i = 0; txt[i]; i++) {
if((txt[i] >= 'A' && txt[i] <= 'Z')) uc[i] = txt[i] - 'A' + 0x391;
else if((txt[i] >= 'a' && txt[i] <= 'z')) uc[i] = txt[i] - 'a' + 0x3B1;
else uc[i] = txt[i];
}
TextOutW(*dc, x+ix, iy + ((td->Align & TXA_VCENTER) ? y - td->iSize/2 : y), uc,
- (cb > 0) ? cb : strlen(txt));
+ (cb > 0) ? cb : (int)strlen(txt));
free(uc);
return true;
}
else if(TextOut(*dc, x+ix, iy + ((td->Align & TXA_VCENTER) ? y - td->iSize/2 : y), txt,
- (cb > 0) ? cb : strlen(txt))) return true;
+ (cb > 0) ? cb : (int)strlen(txt))) return true;
}
return false;
}
@@ -590,7 +639,7 @@ bool com_SetTextSpec(TextDEF *set, anyOutput *o, HFONT *hFont, TextDEF *TxtSet,
if((TxtSet->Style & TXS_SUPER) || (TxtSet->Style & TXS_SUB))
FontRec.lfHeight = o->un2iy(set->fSize*0.71);
else FontRec.lfHeight = TxtSet->iSize;
- if(FontRec.lfHeight <8) FontRec.lfHeight = 8;
+ if(FontRec.lfHeight <2) FontRec.lfHeight = 2;
FontRec.lfWidth = 0;
if(win95mode) { //Win 95, 98
FontRec.lfEscapement = iround(TxtSet->RotBL*10); //text angle
@@ -612,17 +661,17 @@ bool com_SetTextSpec(TextDEF *set, anyOutput *o, HFONT *hFont, TextDEF *TxtSet,
default:
FontRec.lfCharSet = ANSI_CHARSET;
FontRec.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
- strcpy(FontRec.lfFaceName, "Arial");
+ rlp_strcpy(FontRec.lfFaceName, 32, "Arial");
break;
case FONT_GREEK: case FONT_TIMES:
FontRec.lfCharSet = ANSI_CHARSET;
FontRec.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
- strcpy(FontRec.lfFaceName, "Times New Roman");
+ rlp_strcpy(FontRec.lfFaceName, 32, "Times New Roman");
break;
case FONT_COURIER:
FontRec.lfCharSet = ANSI_CHARSET;
FontRec.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
- strcpy(FontRec.lfFaceName, "Courier New");
+ rlp_strcpy(FontRec.lfFaceName, 32, "Courier New");
break;
}
newFont = CreateFontIndirect(&FontRec);
@@ -859,7 +908,7 @@ BitMapWin::oGetTextExtent(char *text, int cb, int *width, int *height)
double si, csi, d;
if(!text) return false;
- if(!GetTextExtentPoint32(memDC, text, cb ? cb : strlen(text), &TextExtent))return false;
+ if(!GetTextExtentPoint32(memDC, text, cb ? cb : (int)strlen(text), &TextExtent))return false;
if(fabs(TxtSet.RotBL) >0.01) {
si = fabs(sin(TxtSet.RotBL * 0.01745329252)); csi = fabs(cos(TxtSet.RotBL * 0.01745329252));
d = si > csi ? 1.0/si : 1.0/csi;
@@ -1341,7 +1390,7 @@ OutputWin::FileHistory()
if(!(hSubMenu = GetSubMenu(GetMenu(hWnd), 0))) return;
if(!HistMenuSize) AppendMenu(hSubMenu, MF_SEPARATOR, 0L, 0L);
for(i = 0; i < 6 && *history[i]; i++) {
- k = strlen(*history[i]);
+ k = (int)strlen(*history[i]);
for (j = 0; j < k && defs.currPath[j] == (*history[i])[j]; j++);
if((*history[i])[j] == '\\' || (*history[i])[j] == '/') j++;
if(i < HistMenuSize) {
@@ -1363,8 +1412,13 @@ OutputWin::CreateNewWindow(void *g)
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);
+#if _MSC_VER >= 1400
+ SetWindowLongPtr(hWnd, 0, lptrref(g)); // g is the parent graphic obj
+ SetWindowLongPtr(hWnd, GWL_USERDATA, lptrref(this));
+#else
+ SetWindowLong(hWnd, 0, lptrref(g)); // g is the parent graphic obj
+ SetWindowLong(hWnd, GWL_USERDATA, lptrref(this));
+#endif
if(BitMapWin::Erase(0x00cbcbcb)) {
GetClientRect(hWnd, &ClientRect);
InvalidateRect(hWnd, &ClientRect, FALSE);
@@ -1582,19 +1636,19 @@ PrintWin::PrintWin()
while(TmpTxt[i] && TmpTxt[i] != ',') i++;
TmpTxt[i] = 0;
if (i >2) {
- PrintDevice = strdup(TmpTxt);
+ PrintDevice = _strdup(TmpTxt);
i++;
j = i;
while(TmpTxt[i] && TmpTxt[i] != ',') i++;
if(i-j > 2) {
TmpTxt[i] = 0;
- PrintDriver = strdup(TmpTxt+j);
+ PrintDriver = _strdup(TmpTxt+j);
i++;
j = i;
while(TmpTxt[i] && TmpTxt[i] != ',') i++;
if(i-j > 2) {
TmpTxt[i] = 0;
- PrintPort = strdup(TmpTxt+j);
+ PrintPort = _strdup(TmpTxt+j);
//Get default paper setup
if(hDC = CreateDC(PrintDriver, PrintDevice, PrintPort, 0L)) {
pw = GetDeviceCaps(hDC, PHYSICALWIDTH);
@@ -1815,14 +1869,14 @@ void FindBrowser()
}
else text[i+1] = 0;
}
- WWWbrowser = strdup(text+1);
+ WWWbrowser = _strdup(text+1);
}
else {
for(i = size-1; i >5; i--) {
- if(0 == stricmp(text+i-3, ".exe")) break;
+ if(0 == _stricmp(text+i-3, ".exe")) break;
else text[i] = 0;
}
- WWWbrowser = strdup(text);
+ WWWbrowser = _strdup(text);
}
}
//find user default data directory
@@ -1833,7 +1887,7 @@ void FindBrowser()
size= 599;
RegQueryValueEx(hdl, "HOMEPATH", 0, 0, (unsigned char*)(text+strlen(text)),
(unsigned long*)&size);
- defs.currPath = strdup(text);
+ defs.currPath = _strdup(text);
}
//find user application data directory
if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
@@ -1841,8 +1895,12 @@ void FindBrowser()
KEY_READ, &hdl)) {
text[0] = 0; size=599;
RegQueryValueEx(hdl, "AppData", 0, 0, (unsigned char*)text, (unsigned long*)&size);
+#ifdef USE_WIN_SECURE
+ strcat_s(text, 600, "\\RLPlot");
+#else
strcat(text, "\\RLPlot");
- defs.IniFile = strdup(text);
+#endif
+ defs.IniFile = _strdup(text);
}
//find country specific information
// its not a perfect place to do it, but a good one
@@ -1861,7 +1919,7 @@ void FindBrowser()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Windos entry point
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance,
+int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
WNDCLASS wndclass;
@@ -1871,14 +1929,15 @@ WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance,
//OS dependent initialization
dlgtxtheight = 16;
- if(lpCmdLine && lpCmdLine[0] && FileExist(lpCmdLine)) LoadFile = strdup(lpCmdLine);
- else if(lpCmdLine) { //probably Unicode
+ if(lpCmdLine && lpCmdLine[0] && FileExist(lpCmdLine)) LoadFile = _strdup(lpCmdLine);
+ else if(lpCmdLine) { //probably Unicode
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%s", lpCmdLine);
+#else
sprintf(TmpTxt, "%s", lpCmdLine);
- if(TmpTxt[0] == '"'){
- strcpy(TmpTxt, TmpTxt+1);
- if(TmpTxt[0]) TmpTxt[strlen(TmpTxt)-1] = 0;
- }
- if(TmpTxt[0]) LoadFile= strdup(TmpTxt);
+#endif
+ rmquot(TmpTxt);
+ if(TmpTxt[0]) LoadFile= _strdup(TmpTxt);
}
hInstance = hInst;
wndclass.style = CS_BYTEALIGNWINDOW | CS_DBLCLKS;
@@ -1913,7 +1972,7 @@ WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance,
if(Printer) delete Printer;
InitTextCursor(false);
UnregisterClass(name, hInstance);
- return msg.wParam;
+ return (int)msg.wParam;
}
void CopyData(GraphObj *g, unsigned int cf)
@@ -1935,7 +1994,7 @@ void CopyData(GraphObj *g, unsigned int cf)
if(cf == cf_rlpxml && g->Command(CMD_COPY_XML, &dt, 0L)) break;
else return;
}
- cb = strlen((char*)dt);
+ cb = (long)strlen((char*)dt);
if(hmem = GlobalAlloc(GMEM_MOVEABLE, cb+2)) {
if(buf = (unsigned char *)GlobalLock(hmem)) {
memcpy(buf, dt, cb+1);
@@ -2039,8 +2098,8 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
HDC dc;
int cc;
- g = (GraphObj *) GetWindowLong(hwnd, 0);
- w = (OutputWin *) GetWindowLong(hwnd, GWL_USERDATA);
+ g = (GraphObj *) reflptr(GetWindowLong(hwnd, 0));
+ w = (OutputWin *) reflptr(GetWindowLong(hwnd, GWL_USERDATA));
if(g && w) switch(message) {
case WM_SETFOCUS:
if(g->Id == GO_GRAPH) CurrGraph = (Graph*)g;
@@ -2152,18 +2211,31 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
return 0;
case CM_PASTE:
w->MouseCursor(MC_WAIT, true);
- if(g->Id == GO_SPREADDATA || g->Id == GO_PAGE ||
- g->Id == GO_GRAPH) TestClipboard(g);
+ if(g->Id == GO_SPREADDATA) TestClipboard(g);
+ else if(g->Id == GO_PAGE || g->Id == GO_GRAPH){
+ if(CurrGO && CurrGO->Id == GO_TEXTFRAME && CurrGO->Command(CMD_PASTE, 0L, w));
+ else TestClipboard(g);
+ }
g->Command(CMD_MOUSECURSOR, 0L, w);
return 0;
case CM_COPY: case CM_CUT:
EmptyClip();
+ if(g->Id != GO_SPREADDATA && CurrGO && CurrGO->Id == GO_TEXTFRAME) {
+ if(CurrGO->Command(CMD_COPY, 0L, w))return 0;
+ }
OpenClipboard(hwnd);
if(g->Id == GO_SPREADDATA && g->Command(wParam == CM_CUT ? CMD_CUT : CMD_QUERY_COPY, 0L, w)) {
SetClipboardData(CF_TEXT, NULL);
SetClipboardData(CF_SYLK, NULL);
SetClipboardData(cf_rlpxml, NULL);
}
+ else if(g->Id == GO_PAGE) {
+ SetClipboardData(CF_METAFILEPICT, NULL);
+ SetClipboardData(CF_BITMAP, NULL);
+ SetClipboardData(cf_rlpgraph, NULL);
+ if(g->Id == GO_PAGE && CurrGraph) CopyGraph(CurrGraph, cf_rlpobj);
+ copy_obj = g;
+ }
CloseClipboard();
return 0;
case CM_UPDATE:
@@ -2171,6 +2243,9 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
return 0;
case CM_COPYGRAPH:
EmptyClip();
+ if(CurrGO && CurrGO->Id == GO_TEXTFRAME) {
+ if(CurrGO->Command(CMD_COPY, 0L, w))return 0;
+ }
OpenClipboard(GetFocus());
SetClipboardData(CF_METAFILEPICT, NULL);
SetClipboardData(CF_BITMAP, NULL);
@@ -2358,15 +2433,26 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
case CM_DELCOL:
g->Command(CMD_DELCOL, 0L, w);
return 0;
+ case CM_REPCMEANS:
+ if(g->data) rep_compmeans(g, g->data);
+ return 0;
case CM_REPANOV:
if(g->data) rep_anova(g, g->data);
return 0;
case CM_REPREGR:
if(g->data) rep_regression(g, g->data);
return 0;
+ case CM_REPTWOWAY:
+ if(g->data) rep_twowaytable(g, g->data);
+ return 0;
default:
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "Command 0x%x (%d)\nreceived", wParam & 0xffff,
+ wParam & 0xffff);
+#else
sprintf(TmpTxt, "Command 0x%x (%d)\nreceived", wParam & 0xffff,
wParam & 0xffff);
+#endif
MessageBox(hwnd, TmpTxt, "Info", MB_OK | MB_ICONINFORMATION);
}
return 0;
@@ -2388,7 +2474,7 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
EndPaint(hwnd, &ps);
break;
}
- return DefWindowProc(hwnd, message, wParam, lParam);
+ return (long)DefWindowProc(hwnd, message, wParam, lParam);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2396,7 +2482,7 @@ long FAR PASCAL WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const char dlgname[] = "RLDLGWIN";
-long FAR PASCAL DlgWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
+LRESULT FAR PASCAL DlgWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
OutputWin *w;
tag_DlgObj *d;
@@ -2405,8 +2491,8 @@ long FAR PASCAL DlgWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
MouseEvent mev;
int i, cc;
- d = (tag_DlgObj *) GetWindowLong(hwnd, 0);
- w = (OutputWin *) GetWindowLong(hwnd, GWL_USERDATA);
+ d = (tag_DlgObj *) reflptr(GetWindowLong(hwnd, 0));
+ w = (OutputWin *) reflptr(GetWindowLong(hwnd, GWL_USERDATA));
switch(message) {
case WM_CREATE:
break;
@@ -2422,9 +2508,12 @@ long FAR PASCAL DlgWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
d->Command(CMD_UNLOCK, 0L, w);
d->Command(CMD_ENDDIALOG, 0L, w);
SetWindowLong(hwnd, 0, NULL);
+ noreflptr(GetWindowLong(hwnd, 0));
}
if(w) {
+ w->hWnd = 0L;
SetWindowLong(hwnd, GWL_USERDATA, NULL);
+ noreflptr(GetWindowLong(hwnd, GWL_USERDATA));
delete w;
}
break;
@@ -2512,8 +2601,8 @@ void *CreateDlgWnd(char *title, int x, int y, int width, int height, tag_DlgObj
w = new OutputWin(0L, hDlg);
w->units = defs.cUnits;
if(hDlg && w && w->Erase(0x00e0e0e0L)) {
- SetWindowLong(hDlg, GWL_USERDATA, (long)w);
- SetWindowLong(hDlg, 0, (long)d);
+ SetWindowLong(hDlg, GWL_USERDATA, lptrref(w));
+ SetWindowLong(hDlg, 0, lptrref(d));
if(flags & 0x01) { //center on screen
GetWindowRect(hDlg, &BoxRec);
GetClientRect(GetDesktopWindow(), &DeskRect);
@@ -2553,6 +2642,15 @@ void ShowDlgWnd(void *hDlg)
SetFocus((HWND)hDlg);
}
+void ResizeDlgWnd(void *hDlg, int w, int h)
+{
+ HWND hwnd = (HWND)hDlg;
+ RECT rc;
+
+ GetWindowRect(hwnd, &rc);
+ SetWindowPos(hwnd, HWND_TOPMOST, rc.left, rc.top, w, h, 0);
+ ShowDlgWnd(hDlg);
+}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OS independent interface to Windows specific classes
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/exprlp.cpp b/exprlp.cpp
index 309dbdc..4b0a5e5 100755
--- a/exprlp.cpp
+++ b/exprlp.cpp
@@ -1,35 +1,35 @@
-//exprlp.cpp, Copyright (c) 2002-2006 R.Lackner
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <locale.h>
-#include <unistd.h> //required for unlink()
-#include "Version.h"
-#include "rlplot.h"
-
-int file_fmt = FF_UNKNOWN;
-bool bQuiet = false, bSVGtype = false, bDelete = false;
-char *szFile1 = 0L, *szFile2 = 0L;
-int dlgtxtheight = 12; //stub: not used
+//exprlp.cpp, Copyright (c) 2002-2006 R.Lackner
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <unistd.h> //required for unlink()
+#include "Version.h"
+#include "rlplot.h"
+
+int file_fmt = FF_UNKNOWN;
+bool bQuiet = false, bSVGtype = false, bDelete = false;
+char *szFile1 = 0L, *szFile2 = 0L;
+int dlgtxtheight = 12; //stub: not used
char *name1, *name2; //the filenames
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// direct messages to console
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-void InfoBox(char *Msg)
-{
- if(!bQuiet) fprintf(stderr, "exprlp INFO: %s\n", Msg);
-}
-
-void ErrorBox(char *Msg)
-{
- if(!bQuiet) fprintf(stderr, "exprlp ERROR: %s\n", Msg);
-}
-
-bool YesNoBox(char *Msg)
-{
-return false;
-}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// direct messages to console
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void InfoBox(char *Msg)
+{
+ if(!bQuiet) fprintf(stderr, "exprlp INFO: %s\n", Msg);
+}
+
+void ErrorBox(char *Msg)
+{
+ if(!bQuiet) fprintf(stderr, "exprlp ERROR: %s\n", Msg);
+}
+
+bool YesNoBox(char *Msg)
+{
+return false;
+}
int YesNoCancelBox(char *Msg)
{
@@ -52,184 +52,184 @@ unsigned char* PasteText()
{
return 0L;
}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// create a root object to handle I/O
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class ExpRoot:public GraphObj{
-public:
- ExpRoot(char *file1, char *file2);
- ~ExpRoot();
- bool Command(int cmd, void *tmpl, anyOutput *o);
-
-private:
- GraphObj *go;
-};
-
-ExpRoot::ExpRoot(char *file1, char *file2):GraphObj(0L, 0L)
-{
- if(file1 && strcmp("-", file1)) name1 = file1;
- else name1 = 0L;
- if(file2 && strcmp("-", file2)) name2 = file2;
- else name2 = 0L;
- go = 0L;
- OpenGraph(this, name1, 0L, false);
- if(bDelete && name1 && name1[0]) unlink(name1);
-}
-
-ExpRoot::~ExpRoot()
-{
- if(go) {
- DeleteGO(go);
- if(!bQuiet)fprintf(stderr, "Object deleted after read\n");
- }
-}
-
-bool
-ExpRoot::Command(int cmd, void *tmpl, anyOutput *o)
-{
- int i;
-
- switch(cmd) {
- case CMD_DROP_GRAPH:
- go = (GraphObj*)tmpl;
- if(go) {
- go->Command(CMD_SET_DATAOBJ, 0L, 0L);
- switch(file_fmt){
- case FF_SVG:
- DoExportSvg(go, name2, bSVGtype ? 1L : 0L);
- break;
- case FF_WMF:
- DoExportWmf(go, name2, 600.0f, 0L);
- break;
- case FF_EPS:
- DoExportEps(go, name2, 0L);
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// create a root object to handle I/O
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class ExpRoot:public GraphObj{
+public:
+ ExpRoot(char *file1, char *file2);
+ ~ExpRoot();
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+
+private:
+ GraphObj *go;
+};
+
+ExpRoot::ExpRoot(char *file1, char *file2):GraphObj(0L, 0L)
+{
+ if(file1 && strcmp("-", file1)) name1 = file1;
+ else name1 = 0L;
+ if(file2 && strcmp("-", file2)) name2 = file2;
+ else name2 = 0L;
+ go = 0L;
+ OpenGraph(this, name1, 0L, false);
+ if(bDelete && name1 && name1[0]) unlink(name1);
+}
+
+ExpRoot::~ExpRoot()
+{
+ if(go) {
+ DeleteGO(go);
+ if(!bQuiet)fprintf(stderr, "Object deleted after read\n");
+ }
+}
+
+bool
+ExpRoot::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ int i;
+
+ switch(cmd) {
+ case CMD_DROP_GRAPH:
+ go = (GraphObj*)tmpl;
+ if(go) {
+ go->Command(CMD_SET_DATAOBJ, 0L, 0L);
+ switch(file_fmt){
+ case FF_SVG:
+ DoExportSvg(go, name2, bSVGtype ? 1L : 0L);
+ break;
+ case FF_WMF:
+ DoExportWmf(go, name2, 600.0f, 0L);
+ break;
+ case FF_EPS:
+ DoExportEps(go, name2, 0L);
break;
case FF_RLP:
SaveGraphAs(go);
- break;
- default:
- ErrorBox("Unknown file extension or format of destination");
- }
- DeleteGO(go);
- go = 0L;
- }
- break;
- }
- return true;
-}
-
-
-int Usage()
-{
- printf("______________________________________________________________\n");
- printf("\nexprlp: RLPlot export utility, version %s.\n", SZ_VERSION);
- printf("Copyright (C) 2002-2005 R. Lackner\n");
- printf("This is free software published under the GNU\n");
- printf("general public licence (GPL).\n");
- printf("\nUsage: exprlp [options] <input> [options] [<output>]\n");
- printf("\nOptions:\n");
- printf(" - use stdin/stdout as input or output file; requires\n");
- printf(" that file format is set by -e | -s | -w option\n");
- printf(" not an option in the strict sense\n");
- printf(" -h print this information\n");
- printf(" -d delete input file after read\n");
- printf(" -e output Encapsulated PostScript, *.eps\n");
- printf(" -s output Scalable Vector Graphics, *.svg\n");
- printf(" -S like -s, start output with \"Content-Type: image/svg+xml\"\n");
- printf(" -v print RLPlot version\n");
- printf(" -w output Windows Meta File, *.wmf\n");
- printf(" -q quiet mode: suppress output to the console\n");
- printf("\nExamples:\n");
- printf(" exprlp foo.rlp foo.svg ;exports Scalable Vector Graphics\n");
- printf(" exprlp -q foo.rlp foo.eps ;exports Encapsulated PostScript, no messages\n");
- printf(" exprlp foo.rlp foo.wmf ;exports Windows Meta File\n");
- printf(" exprlp -sq foo.rlp - ;exports SVG to the console, no messages\n");
- printf(" exprlp -eq - - ;converts inputfile from stdin to EPS\n");
- printf(" on stdout: useful for pipes\n");
- printf("\n switch character is either \'-\' or \'/\'\n");
- printf("______________________________________________________________\n\n");
- if(szFile1) free(szFile1); if(szFile2) free(szFile2);
- szFile1 = szFile2 = 0L;
- return 1;
-}
-
-int main (int argc, char **argv)
-{
- ExpRoot *base = 0L;
- int i, j, k;
-
- for (i = 1, j = 0; i < argc; i++) {
- if(argv[i][0] == '-' || (argv[i][0] == '/' && strlen(argv[i]) < 5)) {
- //check for switch
- for(k = 1; argv[i][k-1]; k++) {
- switch(argv[i][k]){
- case 'h': case 'H': case '?':
- return Usage();
- case 'd':
- bDelete = true;
- break;
- case 'S':
- bSVGtype = true;
- case 's':
- file_fmt = FF_SVG;
- break;
- case 'e': case 'E':
- file_fmt = FF_EPS;
- break;
+ break;
+ default:
+ ErrorBox("Unknown file extension or format of destination");
+ }
+ DeleteGO(go);
+ go = 0L;
+ }
+ break;
+ }
+ return true;
+}
+
+
+int Usage()
+{
+ printf("______________________________________________________________\n");
+ printf("\nexprlp: RLPlot export utility, version %s.\n", SZ_VERSION);
+ printf("Copyright (C) 2002-2005 R. Lackner\n");
+ printf("This is free software published under the GNU\n");
+ printf("general public licence (GPL).\n");
+ printf("\nUsage: exprlp [options] <input> [options] [<output>]\n");
+ printf("\nOptions:\n");
+ printf(" - use stdin/stdout as input or output file; requires\n");
+ printf(" that file format is set by -e | -s | -w option\n");
+ printf(" not an option in the strict sense\n");
+ printf(" -h print this information\n");
+ printf(" -d delete input file after read\n");
+ printf(" -e output Encapsulated PostScript, *.eps\n");
+ printf(" -s output Scalable Vector Graphics, *.svg\n");
+ printf(" -S like -s, start output with \"Content-Type: image/svg+xml\"\n");
+ printf(" -v print RLPlot version\n");
+ printf(" -w output Windows Meta File, *.wmf\n");
+ printf(" -q quiet mode: suppress output to the console\n");
+ printf("\nExamples:\n");
+ printf(" exprlp foo.rlp foo.svg ;exports Scalable Vector Graphics\n");
+ printf(" exprlp -q foo.rlp foo.eps ;exports Encapsulated PostScript, no messages\n");
+ printf(" exprlp foo.rlp foo.wmf ;exports Windows Meta File\n");
+ printf(" exprlp -sq foo.rlp - ;exports SVG to the console, no messages\n");
+ printf(" exprlp -eq - - ;converts inputfile from stdin to EPS\n");
+ printf(" on stdout: useful for pipes\n");
+ printf("\n switch character is either \'-\' or \'/\'\n");
+ printf("______________________________________________________________\n\n");
+ if(szFile1) free(szFile1); if(szFile2) free(szFile2);
+ szFile1 = szFile2 = 0L;
+ return 1;
+}
+
+int main (int argc, char **argv)
+{
+ ExpRoot *base = 0L;
+ int i, j, k;
+
+ for (i = 1, j = 0; i < argc; i++) {
+ if(argv[i][0] == '-' || (argv[i][0] == '/' && strlen(argv[i]) < 5)) {
+ //check for switch
+ for(k = 1; argv[i][k-1]; k++) {
+ switch(argv[i][k]){
+ case 'h': case 'H': case '?':
+ return Usage();
+ case 'd':
+ bDelete = true;
+ break;
+ case 'S':
+ bSVGtype = true;
+ case 's':
+ file_fmt = FF_SVG;
+ break;
+ case 'e': case 'E':
+ file_fmt = FF_EPS;
+ break;
case 'r': case 'R':
file_fmt = FF_RLP;
break;
- case 'w': case 'W':
- file_fmt = FF_WMF;
- break;
- case 'q': case 'Q':
- bQuiet = true;
- break;
- case 'v': case 'V':
- printf("RLPlot version %s\n", SZ_VERSION);
- return 0;
- case '\0':
- if(k == 1) {
- if(j == 0) szFile1 = strdup("-");
- else if(j == 1) szFile2 = strdup("-");
- j++;
- }
- break;
- }
- }
- }
- else switch(j) {
- case 0:
- szFile1 = strdup(argv[i]);
- j++;
- break;
- case 1:
- szFile2 = strdup(argv[i]);
- j++;
- }
- }
- if(file_fmt == FF_UNKNOWN && szFile2 && (i = strlen(szFile2)) > 4) {
- if(0==strcmp(".svg", szFile2+i-4)) file_fmt = FF_SVG;
- else if(0==strcmp(".wmf", szFile2+i-4)) file_fmt = FF_WMF;
- else if(0==strcmp(".eps", szFile2+i-4)) file_fmt = FF_EPS;
+ case 'w': case 'W':
+ file_fmt = FF_WMF;
+ break;
+ case 'q': case 'Q':
+ bQuiet = true;
+ break;
+ case 'v': case 'V':
+ printf("RLPlot version %s\n", SZ_VERSION);
+ return 0;
+ case '\0':
+ if(k == 1) {
+ if(j == 0) szFile1 = strdup("-");
+ else if(j == 1) szFile2 = strdup("-");
+ j++;
+ }
+ break;
+ }
+ }
+ }
+ else switch(j) {
+ case 0:
+ szFile1 = strdup(argv[i]);
+ j++;
+ break;
+ case 1:
+ szFile2 = strdup(argv[i]);
+ j++;
+ }
+ }
+ if(file_fmt == FF_UNKNOWN && szFile2 && (i = strlen(szFile2)) > 4) {
+ if(0==strcmp(".svg", szFile2+i-4)) file_fmt = FF_SVG;
+ else if(0==strcmp(".wmf", szFile2+i-4)) file_fmt = FF_WMF;
+ else if(0==strcmp(".eps", szFile2+i-4)) file_fmt = FF_EPS;
else if(0==strcmp(".rlp", szFile2+i-4)) file_fmt = FF_RLP;
- }
- if(file_fmt == FF_UNKNOWN) {
- if(szFile1)printf("\n**** Unknown file extension or format ****\n\n");
- return Usage();
- }
- if(!bQuiet) {
- fprintf(stderr,"Input file \"%s\"\n", szFile1);
- fprintf(stderr,"Output file \"%s\"\n", szFile2);
- }
- setlocale(LC_ALL, "");
- if(!szFile1) return Usage();
- base = new ExpRoot(szFile1, szFile2);
- if(base) {
- delete base;
- }
- if(szFile1) free(szFile1); if(szFile2) free(szFile2);
- return 0;
-}
+ }
+ if(file_fmt == FF_UNKNOWN) {
+ if(szFile1)printf("\n**** Unknown file extension or format ****\n\n");
+ return Usage();
+ }
+ if(!bQuiet) {
+ fprintf(stderr,"Input file \"%s\"\n", szFile1);
+ fprintf(stderr,"Output file \"%s\"\n", szFile2);
+ }
+ setlocale(LC_ALL, "");
+ if(!szFile1) return Usage();
+ base = new ExpRoot(szFile1, szFile2);
+ if(base) {
+ delete base;
+ }
+ if(szFile1) free(szFile1); if(szFile2) free(szFile2);
+ return 0;
+}
diff --git a/menu.h b/menu.h
index 3146703..8e02c7f 100755
--- a/menu.h
+++ b/menu.h
@@ -92,6 +92,8 @@
#define CM_SHPGUP 615
#define CM_SHPGDOWN 616
-#define CM_REPANOV 650
-#define CM_REPREGR 651
-
+#define CM_REPCMEANS 650
+#define CM_REPANOV 651
+#define CM_REPREGR 652
+#define CM_REPTWOWAY 653
+
diff --git a/mfcalc.cpp b/mfcalc.cpp
index 3705bb6..9d20746 100644
--- a/mfcalc.cpp
+++ b/mfcalc.cpp
@@ -9,48 +9,52 @@
#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
+#define PBLOCK 262
+#define PI 263
+#define E 264
+#define CLVAL 265
+#define PSEP 266
+#define IF 267
+#define ELSE 268
+#define BTRUE 269
+#define BFALSE 270
+#define DATE1 271
+#define TIME1 272
+#define DATETIME1 273
+#define DIM 274
+#define WHILE 275
+#define VAR 276
+#define FNCT 277
+#define BFNCT 278
+#define AFNCT 279
+#define SFNCT 280
+#define FUNC1 281
+#define FUNC2 282
+#define FUNC3 283
+#define TXT 284
+#define SRFUNC 285
+#define YYFNC 286
+#define FUNC4 287
+#define YYFNC2 288
+#define YYFNC3 289
+#define CLAUSE 290
+#define SER 291
+#define COLR 292
+#define COLC 293
+#define AND 294
+#define OR 295
+#define EQ 296
+#define NE 297
+#define GT 298
+#define GE 299
+#define LT 300
+#define LE 301
+#define NEG 302
+#define INC 303
+#define DEC 304
+#define PINC 305
+#define PDEC 306
+#define PDIM 307
/*
@@ -97,9 +101,10 @@ public:
void SetValue(void* dest, void* src);
void SetName(char *nam);
void InitSS();
+ void NoInit();
private:
- bool isSSval;
+ bool isSSval, isValid;
};
@@ -123,6 +128,8 @@ typedef struct{
}YYSTYPE;
+static int yy_maxiter = 1000;
+
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);
@@ -132,7 +139,7 @@ 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, char* dum);
+static void eval(YYSTYPE *dst, YYSTYPE *sr);
static int range_array(YYSTYPE * res, char *range);
static int range_array2(YYSTYPE *res1, YYSTYPE *res2);
static void exec_clause(YYSTYPE *res);
@@ -163,23 +170,23 @@ static int parse_level = 0; //count reentrances into parser
-#define YYFINAL 222
+#define YYFINAL 269
#define YYFLAG -32768
-#define YYNTBASE 65
+#define YYNTBASE 69
-#define YYTRANSLATE(x) ((unsigned)(x) <= 303 ? yytranslate[x] : 72)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 307 ? yytranslate[x] : 76)
static const char yytranslate[] = { 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 59,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 63,
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, 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, 65,
+ 66, 53, 52, 37, 51, 2, 54, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 68, 64, 2,
+ 36, 2, 42, 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,
- 51, 2, 63, 58, 2, 2, 2, 2, 2, 2,
+ 55, 2, 67, 56, 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,
@@ -198,9 +205,9 @@ static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
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
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 38,
+ 39, 40, 41, 43, 44, 45, 46, 47, 48, 49,
+ 50, 57, 58, 59, 60, 61, 62
};
#if YYDEBUG != 0
@@ -212,72 +219,84 @@ static const short yyprhs[] = { 0,
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
+ 308, 312, 317, 324, 331, 338, 345, 354, 363, 372,
+ 381, 390, 399, 408, 417, 423, 431, 435, 439, 443,
+ 447, 451, 454, 457, 460, 463, 467, 470, 474, 480,
+ 485, 492, 498, 504, 508, 512, 518, 524, 530
};
static const short yyrhs[] = { -1,
- 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
+ 69, 70, 0, 63, 0, 64, 0, 37, 0, 75,
+ 63, 0, 75, 64, 0, 75, 37, 0, 71, 63,
+ 0, 71, 64, 0, 1, 63, 0, 5, 0, 71,
+ 52, 75, 0, 75, 52, 71, 0, 71, 52, 71,
+ 0, 31, 65, 75, 66, 0, 31, 65, 75, 12,
+ 71, 66, 0, 31, 65, 75, 12, 75, 66, 0,
+ 31, 65, 75, 37, 71, 66, 0, 31, 65, 75,
+ 37, 75, 66, 0, 71, 0, 22, 40, 22, 0,
+ 6, 0, 75, 0, 73, 37, 73, 0, 73, 38,
+ 75, 0, 72, 0, 3, 39, 3, 0, 4, 0,
+ 24, 65, 75, 66, 0, 15, 0, 16, 0, 75,
+ 43, 75, 0, 75, 44, 75, 0, 75, 45, 75,
+ 0, 75, 46, 75, 0, 75, 47, 75, 0, 75,
+ 48, 75, 0, 75, 49, 75, 0, 75, 50, 75,
+ 0, 3, 0, 74, 0, 30, 0, 11, 0, 9,
+ 0, 10, 0, 22, 0, 7, 0, 22, 36, 75,
+ 0, 22, 36, 71, 0, 23, 65, 75, 66, 0,
+ 25, 65, 73, 66, 0, 25, 65, 75, 12, 73,
+ 66, 0, 25, 65, 75, 12, 75, 12, 75, 66,
+ 0, 26, 65, 71, 66, 0, 26, 65, 75, 66,
+ 0, 26, 65, 71, 12, 71, 66, 0, 26, 65,
+ 75, 12, 71, 66, 0, 26, 65, 75, 12, 75,
+ 66, 0, 26, 65, 71, 12, 75, 66, 0, 26,
+ 65, 71, 37, 71, 66, 0, 26, 65, 75, 37,
+ 71, 66, 0, 26, 65, 71, 37, 75, 66, 0,
+ 26, 65, 75, 37, 75, 66, 0, 28, 65, 72,
+ 12, 72, 66, 0, 28, 65, 72, 12, 72, 12,
+ 72, 66, 0, 29, 65, 73, 12, 73, 66, 0,
+ 29, 65, 73, 12, 73, 12, 72, 66, 0, 33,
+ 65, 75, 12, 75, 12, 73, 12, 72, 66, 0,
+ 27, 65, 73, 12, 72, 66, 0, 32, 65, 66,
+ 0, 32, 65, 73, 66, 0, 34, 65, 75, 12,
+ 75, 66, 0, 34, 65, 71, 12, 75, 66, 0,
+ 34, 65, 75, 12, 71, 66, 0, 34, 65, 71,
+ 12, 71, 66, 0, 35, 65, 71, 12, 71, 12,
+ 71, 66, 0, 35, 65, 75, 12, 71, 12, 71,
+ 66, 0, 35, 65, 71, 12, 75, 12, 71, 66,
+ 0, 35, 65, 71, 12, 71, 12, 75, 66, 0,
+ 35, 65, 75, 12, 75, 12, 71, 66, 0, 35,
+ 65, 75, 12, 71, 12, 75, 66, 0, 35, 65,
+ 71, 12, 75, 12, 75, 66, 0, 35, 65, 75,
+ 12, 75, 12, 75, 66, 0, 13, 65, 75, 66,
+ 7, 0, 13, 65, 75, 66, 7, 14, 7, 0,
+ 21, 8, 7, 0, 75, 52, 75, 0, 75, 51,
+ 75, 0, 75, 53, 75, 0, 75, 54, 75, 0,
+ 22, 58, 0, 22, 59, 0, 58, 22, 0, 59,
+ 22, 0, 75, 56, 75, 0, 51, 75, 0, 65,
+ 73, 66, 0, 20, 22, 55, 75, 67, 0, 75,
+ 55, 75, 67, 0, 75, 55, 75, 67, 36, 75,
+ 0, 3, 40, 3, 40, 3, 0, 3, 68, 3,
+ 68, 3, 0, 3, 40, 3, 0, 3, 68, 3,
+ 0, 75, 42, 75, 41, 75, 0, 75, 42, 5,
+ 41, 5, 0, 75, 42, 5, 41, 75, 0, 75,
+ 42, 75, 41, 5, 0
};
#endif
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 128, 129, 132, 132, 132, 133, 134, 135, 136, 137,
- 138, 141, 143, 144, 145, 146, 147, 148, 149, 150,
- 153, 155, 159, 160, 161, 162, 163, 164, 168, 169,
- 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
- 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
- 192, 193, 194, 196, 199, 200, 201, 202, 203, 204,
- 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
- 215, 216, 217, 218, 219, 223, 227, 228, 230, 231,
- 232, 233, 234, 235, 236, 237, 239, 241, 243, 244,
- 245, 246, 247, 248, 249, 250
+ 132, 133, 136, 136, 136, 137, 138, 139, 140, 141,
+ 142, 145, 147, 148, 149, 150, 151, 152, 153, 154,
+ 157, 159, 163, 164, 165, 166, 167, 168, 172, 173,
+ 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
+ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
+ 196, 197, 198, 200, 203, 204, 205, 206, 207, 208,
+ 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
+ 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
+ 229, 230, 231, 232, 233, 234, 235, 239, 243, 247,
+ 248, 250, 251, 252, 253, 254, 255, 256, 257, 259,
+ 261, 263, 264, 265, 266, 267, 268, 269, 270
};
#endif
@@ -285,26 +304,28 @@ static const short yyrline[] = { 0,
#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
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
+"STR","ARR","BLOCK","PBLOCK","PI","E","CLVAL","PSEP","IF","ELSE","BTRUE","BFALSE",
+"DATE1","TIME1","DATETIME1","DIM","WHILE","VAR","FNCT","BFNCT","AFNCT","SFNCT",
+"FUNC1","FUNC2","FUNC3","TXT","SRFUNC","YYFNC","FUNC4","YYFNC2","YYFNC3","'='",
+"','","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,
- 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
+ 69, 69, 70, 70, 70, 70, 70, 70, 70, 70,
+ 70, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 72, 72, 73, 73, 73, 73, 73, 73, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+ 75, 75, 75, 75, 75, 75, 75, 75, 75
};
static const short yyr2[] = { 0,
@@ -315,295 +336,358 @@ static const short yyr2[] = { 0,
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
+ 3, 4, 6, 6, 6, 6, 8, 8, 8, 8,
+ 8, 8, 8, 8, 5, 7, 3, 3, 3, 3,
+ 3, 2, 2, 2, 2, 3, 2, 3, 5, 4,
+ 6, 5, 5, 3, 3, 5, 5, 5, 5
};
static const short yydefact[] = { 1,
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,
+ 31, 32, 0, 0, 47, 0, 0, 0, 0, 0,
+ 0, 0, 43, 0, 0, 0, 0, 0, 5, 0,
+ 0, 0, 3, 4, 0, 2, 0, 42, 0, 11,
+ 0, 0, 0, 0, 0, 0, 92, 93, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 97, 94, 95, 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, 0, 6,
+ 7, 104, 105, 0, 0, 87, 50, 49, 0, 0,
+ 0, 24, 0, 0, 0, 0, 0, 0, 0, 71,
0, 0, 0, 0, 0, 0, 0, 0, 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, 98, 15, 13, 0, 0, 33, 34, 35, 36,
+ 37, 38, 39, 40, 89, 14, 88, 90, 91, 0,
+ 96, 0, 0, 0, 0, 51, 30, 52, 0, 0,
+ 0, 55, 0, 0, 56, 0, 0, 0, 0, 0,
+ 16, 72, 0, 0, 0, 0, 0, 88, 28, 22,
+ 25, 26, 0, 0, 100, 102, 103, 85, 99, 0,
+ 24, 0, 0, 0, 0, 0, 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
+ 0, 0, 0, 0, 0, 107, 108, 109, 106, 0,
+ 0, 53, 0, 57, 60, 61, 63, 58, 59, 62,
+ 64, 70, 0, 65, 0, 67, 17, 18, 19, 20,
+ 0, 76, 74, 75, 73, 0, 0, 0, 0, 101,
+ 86, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 66, 68, 0, 77, 80, 79,
+ 83, 78, 82, 81, 84, 0, 69, 0, 0
};
static const short yydefgoto[] = { 1,
- 33, 61, 62, 63, 35, 64
+ 36, 67, 68, 69, 38, 70
};
static const short yypact[] = {-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
+ 242, -55, -3,-32768,-32768,-32768,-32768,-32768,-32768, -52,
+-32768,-32768, -7, 9, 70, -44, -42, -33, 4, 6,
+ 7, 28,-32768, 31, 47, 52, 73, 95,-32768, 707,
+ 41, 93,-32768,-32768, 369,-32768, 50,-32768, 822,-32768,
+ 131, 158, 707, 112, 162, 426,-32768,-32768, 707, 707,
+ 369, 426, 369, 483, 369, 707, 305, 707, 426, 426,
+-32768,-32768,-32768, -30,-32768, 65, 118,-32768, -26, 363,
+ 426,-32768,-32768,-32768, 540, 707, 707, 707, 707, 707,
+ 707, 707, 707, 707, 426, 707, 707, 707, 707,-32768,
+-32768, 159, 103, 871, 707,-32768, 118, 363, 896, 921,
+ -19, 135, -6, 731, 54, 163, 363, 61, 757,-32768,
+ -4, 420, -11, 477, -9, 534, 707, 195, 181, 369,
+ 707,-32768,-32768, 86, 165, 1272, 699, 699, 141, 141,
+ 141, 141, 141, 141, 86,-32768, 86, 12, 12, 299,
+-32768, 204, 210, 207, 845,-32768,-32768,-32768, 369, 426,
+ 426,-32768, 426, 426,-32768, 483, 483, 369, 426, 426,
+-32768,-32768, 707, 426, 426, 426, 426, 86,-32768,-32768,
+ 182, 1287, 597, 654, 183,-32768,-32768, 209,-32768, -2,
+ 591, -36, 946, -27, 971, 38, 996, 43, 1021, 155,
+ -5, -10, 67, 1046, 69, 1071, 648, 78, 1096, 79,
+ 1121, -8, 783, 2, 802,-32768, 1287,-32768, 1287, 707,
+ 218,-32768, 707,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 483,-32768, 483,-32768,-32768,-32768,-32768,-32768,
+ 369,-32768,-32768,-32768,-32768, 426, 426, 426, 426, 1287,
+-32768, 1146, 160, 161, 88, 80, 1171, 85, 1196, 91,
+ 1221, 102, 1246,-32768,-32768,-32768, 483,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768, 164,-32768, 228,-32768
};
static const short yypgoto[] = {-32768,
--32768, 42, -48, -46,-32768, -1
+-32768, 51, -49, -31,-32768, -1
};
-#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,
+#define YYLAST 1343
+
+
+static const short yytable[] = { 39,
+ 164, 225, 166, 236, 106, 150, 223, 40, 118, 41,
+ 120, 121, 43, 238, 44, 71, 45, 120, 121, 101,
+ 49, 105, 50, 108, 71, 111, 120, 121, 61, 214,
+ 151, 51, 120, 121, 120, 121, 41, 42, 216, 122,
+ 71, 94, 71, 71, 98, 71, 148, 99, 100, 102,
+ 104, 37, 107, 71, 109, 226, 112, 114, 116, 152,
+ 224, 162, 62, 212, 42, 156, 88, 89, 52, 124,
+ 53, 54, 158, 126, 127, 128, 129, 130, 131, 132,
+ 133, 134, 135, 137, 138, 139, 140, 141, 171, 71,
+ 120, 121, 55, 145, 71, 56, 97, 120, 121, 257,
+ 46, 71, 103, 218, 119, 46, 190, 191, 220, 113,
+ 115, 57, 72, 73, 63, 168, 58, 180, 71, 172,
+ 71, 123, 47, 48, 120, 121, 192, 47, 48, 71,
+ 71, 71, 227, 92, 229, 136, 71, 59, 86, 87,
+ 88, 89, 71, 232, 234, 258, 149, 181, 183, 185,
+ 260, 187, 189, 71, 107, 107, 262, 194, 196, 60,
+ 93, 197, 199, 201, 203, 205, 95, 264, 96, 71,
+ 143, 207, 209, 243, 157, 244, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 84, 117, 86, 87, 88, 89, 169, 142, 245,
+ 182, 184, 170, 186, 188, 173, 176, 266, 240, 193,
+ 195, 242, 177, 178, 198, 200, 202, 204, 210, 121,
+ 222, 107, 211, 107, 241, 255, 256, 269, 0, 267,
+ 0, 0, 0, 0, 247, 249, 251, 253, 0, 0,
+ 0, 268, 2, 0, 3, 4, 5, 0, 6, 0,
+ 7, 8, 9, 0, 10, 107, 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,
+ 22, 23, 24, 25, 26, 27, 28, 0, 29, 0,
+ 0, 0, 0, 0, 0, 0, 246, 248, 250, 252,
+ 0, 0, 30, 0, 0, 0, 0, 0, 0, 31,
+ 32, 0, 0, 0, 33, 34, 35, 64, 4, 5,
+ 65, 6, 0, 7, 8, 9, 0, 10, 0, 11,
+ 12, 0, 0, 0, 13, 14, 66, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 117, 86, 87, 88, 89, 30, 0, 0, 0, 0,
+ 0, 0, 31, 32, 0, 175, 0, 0, 0, 35,
+ 110, 64, 4, 5, 65, 6, 0, 7, 8, 9,
+ 0, 10, 0, 11, 12, 0, 0, 0, 13, 14,
+ 66, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 88, 89, 30,
+ 0, 0, 0, 0, 0, 0, 31, 32, 3, 4,
+ 5, 163, 6, 35, 7, 8, 9, 0, 10, 0,
+ 11, 12, 0, 0, 0, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 117, 86, 87, 88, 89, 30, 0, 0, 0,
+ 0, 0, 0, 31, 32, 3, 4, 5, 165, 6,
+ 35, 7, 8, 9, 0, 10, 0, 11, 12, 0,
+ 0, 0, 13, 14, 66, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 30, 0, 0, 0, 0, 0, 0,
+ 31, 32, 3, 4, 125, 167, 6, 35, 7, 8,
+ 9, 0, 10, 0, 11, 12, 0, 0, 0, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 0, 25, 26, 27, 28, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 30, 0, 0, 0, 0, 0, 0, 31, 32, 3,
+ 4, 206, 213, 6, 35, 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
+ 17, 18, 19, 20, 21, 22, 23, 0, 25, 26,
+ 27, 28, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 30, 0, 0,
+ 0, 0, 0, 0, 31, 32, 3, 4, 208, 231,
+ 6, 35, 7, 8, 9, 0, 10, 0, 11, 12,
+ 0, 0, 0, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 0, 25, 26, 27, 28, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 117,
+ 86, 87, 88, 89, 30, 0, 0, 0, 0, 3,
+ 4, 31, 32, 6, 0, 7, 8, 9, 35, 10,
+ 0, 11, 12, 0, 0, 0, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 0, 25, 26,
+ 27, 28, 153, 78, 79, 80, 81, 82, 83, 84,
+ 117, 86, 87, 88, 89, 0, 0, 30, 0, 0,
+ 0, 0, 0, 0, 31, 32, 0, 154, 159, 0,
+ 0, 35, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 160, 237, 0, 155, 0, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 117, 86,
+ 87, 88, 89, 239, 0, 0, 0, 0, 0, 0,
+ 0, 0, 161, 0, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 88, 89, 0,
+ 0, 0, 0, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89, 74, 0,
+ 0, 0, 0, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89, 0, 0,
+ 0, 0, 0, 0, 90, 91, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 117, 86, 87, 88,
+ 89, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 179, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 117, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 144, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 117, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 146, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 117, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 147, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 215, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 217, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 219, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 221, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 228, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 230, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 233, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 235, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 117, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 254, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 259, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 261, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 263, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 265, 174, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 117, 86, 87, 88, 89, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 117, 86,
+ 87, 88, 89
};
static const short yycheck[] = { 1,
- 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,
+ 12, 12, 12, 12, 54, 12, 12, 63, 39, 40,
+ 37, 38, 65, 12, 22, 52, 8, 37, 38, 51,
+ 65, 53, 65, 55, 52, 57, 37, 38, 30, 66,
+ 37, 65, 37, 38, 37, 38, 40, 68, 66, 66,
+ 52, 43, 52, 52, 46, 52, 66, 49, 50, 51,
+ 52, 1, 54, 52, 56, 66, 58, 59, 60, 66,
+ 66, 66, 22, 66, 68, 12, 55, 56, 65, 71,
+ 65, 65, 12, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89, 120, 52,
+ 37, 38, 65, 95, 52, 65, 46, 37, 38, 12,
+ 36, 52, 52, 66, 40, 36, 156, 157, 66, 59,
+ 60, 65, 63, 64, 22, 117, 65, 149, 52, 121,
+ 52, 71, 58, 59, 37, 38, 158, 58, 59, 52,
+ 52, 52, 66, 3, 66, 85, 52, 65, 53, 54,
+ 55, 56, 52, 66, 66, 66, 12, 149, 150, 151,
+ 66, 153, 154, 52, 156, 157, 66, 159, 160, 65,
+ 3, 163, 164, 165, 166, 167, 55, 66, 7, 52,
+ 68, 173, 174, 223, 12, 225, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 51, 52, 53, 54, 55, 56, 3, 40, 231,
+ 150, 151, 22, 153, 154, 41, 3, 257, 210, 159,
+ 160, 213, 3, 7, 164, 165, 166, 167, 36, 38,
+ 66, 223, 14, 225, 7, 66, 66, 0, -1, 66,
+ -1, -1, -1, -1, 236, 237, 238, 239, -1, -1,
+ -1, 0, 1, -1, 3, 4, 5, -1, 7, -1,
+ 9, 10, 11, -1, 13, 257, 15, 16, -1, -1,
+ -1, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, -1, 37, -1,
+ -1, -1, -1, -1, -1, -1, 236, 237, 238, 239,
+ -1, -1, 51, -1, -1, -1, -1, -1, -1, 58,
+ 59, -1, -1, -1, 63, 64, 65, 3, 4, 5,
+ 6, 7, -1, 9, 10, 11, -1, 13, -1, 15,
+ 16, -1, -1, -1, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
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
+ 52, 53, 54, 55, 56, 51, -1, -1, -1, -1,
+ -1, -1, 58, 59, -1, 67, -1, -1, -1, 65,
+ 66, 3, 4, 5, 6, 7, -1, 9, 10, 11,
+ -1, 13, -1, 15, 16, -1, -1, -1, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 51,
+ -1, -1, -1, -1, -1, -1, 58, 59, 3, 4,
+ 5, 12, 7, 65, 9, 10, 11, -1, 13, -1,
+ 15, 16, -1, -1, -1, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 51, -1, -1, -1,
+ -1, -1, -1, 58, 59, 3, 4, 5, 12, 7,
+ 65, 9, 10, 11, -1, 13, -1, 15, 16, -1,
+ -1, -1, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 51, -1, -1, -1, -1, -1, -1,
+ 58, 59, 3, 4, 5, 12, 7, 65, 9, 10,
+ 11, -1, 13, -1, 15, 16, -1, -1, -1, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ -1, 32, 33, 34, 35, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 51, -1, -1, -1, -1, -1, -1, 58, 59, 3,
+ 4, 5, 12, 7, 65, 9, 10, 11, -1, 13,
+ -1, 15, 16, -1, -1, -1, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, -1, 32, 33,
+ 34, 35, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 51, -1, -1,
+ -1, -1, -1, -1, 58, 59, 3, 4, 5, 12,
+ 7, 65, 9, 10, 11, -1, 13, -1, 15, 16,
+ -1, -1, -1, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, -1, 32, 33, 34, 35, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 51, -1, -1, -1, -1, 3,
+ 4, 58, 59, 7, -1, 9, 10, 11, 65, 13,
+ -1, 15, 16, -1, -1, -1, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, -1, 32, 33,
+ 34, 35, 12, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, -1, -1, 51, -1, -1,
+ -1, -1, -1, -1, 58, 59, -1, 37, 12, -1,
+ -1, 65, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, 37, 12, -1, 66, -1, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 12, -1, -1, -1, -1, -1, -1,
+ -1, -1, 66, -1, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, -1,
+ -1, -1, -1, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 37, -1,
+ -1, -1, -1, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, -1, -1,
+ -1, -1, -1, -1, 63, 64, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 67, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 66, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
@@ -934,7 +1018,7 @@ yynewstate:
#endif
/* Get the current used size of the three stacks, in elements. */
- int size = yyssp - yyss + 1;
+ int size = (int)(yyssp - yyss) + 1;
#ifdef yyoverflow
/* Each stack pointer address is followed by the size of
@@ -1271,7 +1355,7 @@ case 47:
{yyvsp[0].tptr->GetValue(&yyval);;
break;}
case 48:
-{eval(&yyvsp[0], &yyval, 0L);;
+{eval(&yyvsp[0], &yyval);;
break;}
case 49:
{yyvsp[-2].tptr->SetValue(&yyval, &yyvsp[0]);;
@@ -1295,10 +1379,10 @@ case 54:
yyval.val = ((yyvsp[-7].tptr->fnctptr)(&yyval)); yyval.type = NUM;;
break;}
case 55:
-{yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval, 0L)); yyval.type = NUM;;
+{yyval.type = NUM; yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval, 0L));;
break;}
case 56:
-{yyvsp[-1].text = string_value(&yyvsp[-1]); yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval, 0L)); yyval.type = NUM;;
+{yyval.type = NUM; yyvsp[-1].text = string_value(&yyvsp[-1]); yyval.val = ((yyvsp[-3].tptr->fnctptr)(&yyvsp[-1], &yyval, 0L));;
break;}
case 57:
{yyval.val = ((yyvsp[-5].tptr->fnctptr)(&yyvsp[-3], &yyval, yyvsp[-1].text)); yyval.type = NUM;;
@@ -1349,85 +1433,127 @@ 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;;
+{(*yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);;
break;}
case 74:
-{yyval.val = yyvsp[-4].val != 0.0 ? eval(&yyvsp[-2], &yyval, 0L) : eval(&yyvsp[0], &yyval, 0L);;
+{(*yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);;
break;}
case 75:
+{(*yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 76:
+{(*yyvsp[-5].tptr->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 77:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 78:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 79:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 80:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 81:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 82:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 83:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 84:
+{(*yyvsp[-7].tptr->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);;
+ break;}
+case 85:
+{if(yyvsp[-2].val != 0.0)eval(&yyval, &yyvsp[0]);;
+ break;}
+case 86:
+{yyvsp[-4].val != 0.0 ? eval(&yyval, &yyvsp[-2]) : eval(&yyval, &yyvsp[0]);;
+ break;}
+case 87:
+{for(int i=0; i< yy_maxiter; i++){
+ eval(&yyval, &yyvsp[-1]);
+ if(yyval.val != 0.0)eval(&yyval, &yyvsp[0]);
+ else break;};
+ break;}
+case 88:
{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:
+case 89:
{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:
+case 90:
{yyval.val = yyvsp[-2].val * yyvsp[0].val; yyval.type = NUM;;
break;}
-case 78:
+case 91:
{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:
+case 92:
{yyval.val=yyvsp[-1].tptr->GetValue(); yyvsp[-1].tptr->SetValue(yyval.val+1.0); yyval.val -= 1.0; yyval.type = NUM;;
break;}
-case 81:
+case 93:
{yyval.val=yyvsp[-1].tptr->GetValue(); yyvsp[-1].tptr->SetValue(yyval.val-1.0); yyval.val += 1.0; yyval.type = NUM;;
break;}
-case 82:
+case 94:
{yyval.val=yyvsp[0].tptr->GetValue(); yyvsp[0].tptr->SetValue(yyval.val+1.0); yyval.type = NUM;;
break;}
-case 83:
+case 95:
{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);;
+case 96:
+{yyval.val = (yyvsp[0].val >0 && yyvsp[0].val/2.0 == floor(yyvsp[0].val/2.0)) ? fabs(pow(yyvsp[-2].val,yyvsp[0].val) ): pow(yyvsp[-2].val, yyvsp[0].val); yyval.type = NUM;;
break;}
-case 85:
+case 97:
+{yyval.val = -yyvsp[0].val; yyval.type = NUM;;
+ break;}
+case 98:
{memcpy(&yyval, &yyvsp[-1], sizeof(YYSTYPE)); yyvsp[-1].a_data = 0L; yyvsp[-1].a_count = 0;;
break;}
-case 86:
+case 99:
{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:
+case 100:
{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:
+case 101:
{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:
+case 102:
{make_time(&yyval, yyvsp[-4].val, yyvsp[-2].val, yyvsp[0].val+1.0e-10);;
break;}
-case 90:
+case 103:
{make_time(&yyval, yyvsp[-4].val, yyvsp[-2].val, yyvsp[0].val+1.0e-10);;
break;}
-case 91:
+case 104:
{make_time(&yyval, yyvsp[-2].val, yyvsp[0].val, 1.0e-10);;
break;}
-case 92:
+case 105:
{make_time(&yyval, yyvsp[-2].val, yyvsp[0].val, 1.0e-10);;
break;}
-case 93:
+case 106:
{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
break;}
-case 94:
+case 107:
{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
break;}
-case 95:
+case 108:
{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
break;}
-case 96:
+case 109:
{memcpy(&yyval, yyvsp[-4].val != 0.0 ? &yyvsp[-2] : &yyvsp[0], sizeof(YYSTYPE));
break;}
}
@@ -1659,7 +1785,7 @@ 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;
+ var = 0.0; isSSval = isValid = false;
a_data = 0L; a_count = 0;
fnctptr = (double (*)(...))nop;
}
@@ -1684,6 +1810,7 @@ symrec::GetValue()
isSSval = false;
row = col = -1;
}
+ if(!isValid) NoInit();
return var;
}
@@ -1698,6 +1825,7 @@ symrec::GetValue(void *re)
res->a_data = 0L; res->a_count = 0;
//GetResult( , , ,true) inhibits reentrance into parser !
if(curr_data->GetResult(&ares, row, col, parse_level > MAX_PARSE)){
+ isValid = true;
if(text) free(text); text = 0L;
switch(ares.type) {
case ET_VALUE:
@@ -1729,6 +1857,7 @@ symrec::GetValue(void *re)
isSSval = false;
row = col = -1;
}
+ if(!isValid) NoInit();
if(a_data && a_count) {
res->a_data = a_data; res->a_count = a_count;
res->val = 0.0; res->type = ARR;
@@ -1755,6 +1884,7 @@ symrec::SetValue(double v)
isSSval = false;
row = col = -1;
}
+ isValid = true;
a_data = 0L; a_count = 0;
return var = v;
}
@@ -1774,9 +1904,11 @@ symrec::SetValue(void* d, void* s)
else curr_data->SetValue(row, col, src->val);
curr_data->Command(CMD_UPDATE, 0L, 0L);
}
+ isValid = true;
var = src->val;
if(text) free(text); text = 0L;
- if(src->text && src->text[0]) text = strdup(src->text);
+ if(src->text && src->text[0])
+ text =(char*)memdup(src->text, (int)strlen(src->text)+1, 0);
a_data = src->a_data; a_count = src->a_count;
GetValue(d);
return;
@@ -1786,7 +1918,8 @@ void
symrec::SetName(char *nam)
{
if(name || !nam || !nam[0]) return;
- name = strdup(nam);
+ name = (char*)memdup(nam, (int)strlen(nam)+1, 0);
+ isValid = false;
if((name && curr_data) && (isalpha(name[0]) || name[0] == '$') && isdigit(name[strlen(name)-1])) isSSval=true;
}
@@ -1801,6 +1934,19 @@ symrec::InitSS()
}
}
+void
+symrec::NoInit()
+{
+ char message[200];
+
+#ifdef USE_WIN_SECURE
+ sprintf_s(message, 80, "Accessing variable '%s'\nwithout initialization!\n", name);
+#else
+ sprintf(message, "Accessing variable '%s'\nwithout initialization!\n", name);
+#endif
+ yywarn(message, true);
+}
+
static void yyerror(char *s)
{
//called by yyparse on error
@@ -1815,6 +1961,17 @@ static void yyargserr(char *s)
last_err_desc = "#ARGS";
}
+static char txt_tokenerr[80];
+static void yytokenerr(int c)
+{
+#ifdef USE_WIN_SECURE
+ sprintf_s(txt_tokenerr, 80, "Illegal character\nor token '%c'\n", (char)c);
+#else
+ sprintf(txt_tokenerr, "Illegal character\nor token '%c'\n", (char)c);
+#endif
+ yyerror(txt_tokenerr);
+}
+
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) {
@@ -1824,6 +1981,23 @@ static void make_time(YYSTYPE *dst, double h, double m, double s)
dst->val /= 24.0; dst->type = TIME1;
}
+static char yywarn_text[200];
+char *yywarn(char *txt, bool bNew)
+{
+ if(bNew) {
+ if(txt && txt[0]) {
+ rlp_strcpy(yywarn_text, 200, txt);
+ return yywarn_text;
+ }
+ else {
+ yywarn_text[0] = 0;
+ return 0L;
+ }
+ }
+ else if(yywarn_text[0]) return yywarn_text;
+ else return 0L;
+}
+
static void store_res(YYSTYPE *res)
{
if(last_err_desc) {
@@ -1883,10 +2057,15 @@ static void store_res(YYSTYPE *res)
static char *add_strings(char *st1, char *st2)
{
char *newstr, *ret;
+ int cb;
if(st1 && st2) {
- if(newstr = (char*)malloc(strlen(st1) +strlen(st2) +4)) {
+ if(newstr = (char*)malloc(cb = (int)(strlen(st1) +strlen(st2) +4))) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(newstr, cb, "%s%s", st1, st2);
+#else
sprintf(newstr, "%s%s", st1, st2);
+#endif
ret = PushString(newstr);
free(newstr);
return ret;
@@ -1936,16 +2115,34 @@ static void pop_syntax()
}
}
-static double eval(YYSTYPE *sr, YYSTYPE *dst, char *dum)
+static void eval(YYSTYPE *dst, YYSTYPE *sr)
{
+ char *s_buffer;
+ int s_buff_pos, s_yychar, s_yynerrs, length;
anyResult *ar;
- if(dum) yyerror("parse error");
- if(!sr || !sr->text) return 0.0;
+ if(!sr || !sr->text) return;
parse_level++;
- ar = do_formula(0L, sr->text);
+ s_buffer = buffer; s_buff_pos = buff_pos;
+ s_yychar = yychar; s_yynerrs = yynerrs;
+ if (sr->text && (length=(int)strlen(sr->text)) && (buffer = (char*)malloc(length+2))) {
+ strcpy(buffer, sr->text); buffer[length++] = ';';
+ buffer[length] = 0; buff_pos = 0;
+ do {
+ yyparse();
+ }while(buff_pos < length);
+ free(buffer); ar = &line_res;
+ buffer = s_buffer; buff_pos = s_buff_pos;
+ yychar = s_yychar; yynerrs = s_yynerrs;
+ }
+ else return;
yylval.a_data = 0L; yylval.a_count = 0;
switch(ar->type) {
+ case ET_BOOL:
+ dst->type = BOOLVAL;
+ dst->val = ar->value;
+ dst->text = 0L;
+ break;
case ET_VALUE:
dst->type = NUM;
dst->val = ar->value;
@@ -1963,7 +2160,6 @@ static double eval(YYSTYPE *sr, YYSTYPE *dst, char *dum)
break;
}
parse_level--;
- return dst->val;
}
// more functions
@@ -2155,7 +2351,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(d_variance(sr->a_count, sr->a_data))/sqrt(sr->a_count);
+ sr->val = sqrt(d_variance(sr->a_count, sr->a_data))/sqrt((double)sr->a_count);
}
return sr->val;
}
@@ -2259,7 +2455,7 @@ static double norminv(YYSTYPE *sr)
if(!sr) return 0.0;
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);
+ sr->val = distinv(norm_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], sr->a_data[1]);
}
else yyargserr("Wrong number of arguments\nin call to norminv(p, mean, SD).");
return sr->val;
@@ -2336,7 +2532,7 @@ 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);
+ sr->val = distinv(lognorm_dist, sr->a_data[1], sr->a_data[2], sr->a_data[0], sr->a_data[1]);
}
else yyargserr("Wrong number of arguments\nin call to lognorminv(p, mean, SD).");
return sr->val;
@@ -2353,6 +2549,17 @@ static double chidist(YYSTYPE *sr)
return sr->val;
}
+static double chifreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 2){
+ sr->val = chi_freq(sr->a_data[0], sr->a_data[1]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to chifreq(x, df).");
+ return sr->val;
+}
+
static double chiinv(YYSTYPE *sr)
{
if(!sr) return 0.0;
@@ -2375,12 +2582,26 @@ static double tdist(YYSTYPE *sr)
return sr->val;
}
+static double tfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 2){
+ sr->val = t_freq(sr->a_data[0], sr->a_data[1]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to tfreq(x, df).");
+ return sr->val;
+}
+
static double tinv(YYSTYPE *sr)
{
+ double dtmp;
+
if(!sr) return 0.0;
sr->val = 0.0;
+ dtmp = sr->a_data[1] > 1.0E+10 ? 1.0E+10 : sr->a_data[1];
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);
+ sr->val = fabs(distinv(t_dist,dtmp, 1.0, sr->a_data[0], 2.0));
}
else yyargserr("Wrong number of arguments\nin call to tinv(p, df).");
return sr->val;
@@ -2411,7 +2632,7 @@ static double poisfreq(YYSTYPE *sr)
static double fdist(YYSTYPE *sr)
{
if(!sr) return 0.0;
- sr->val = 0;
+ sr->val = 0.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]);
}
@@ -2419,6 +2640,17 @@ static double fdist(YYSTYPE *sr)
return sr->val;
}
+static double ffreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = f_freq(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to ffreq(x, df1, df2).");
+ return sr->val;
+}
+
static double finv(YYSTYPE *sr)
{
if(!sr) return 0.0;
@@ -2491,7 +2723,7 @@ 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);
+ sr1->val = sr2->val = d_ttest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data, 0L);
}
else yyargserr("Bad arguments in call to function\nttest(array1; array2[;\"dest\"]).");
return sr1->val;
@@ -2513,7 +2745,7 @@ 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);
+ sr1->val = sr2->val = d_utest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data, 0L);
}
else yyargserr("Bad arguments in call to function\nutest2(array1; array2[;\"dest\"]).");
return sr1->val;
@@ -2743,6 +2975,94 @@ 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);
}
+static void _strpos(YYSTYPE *dst, YYSTYPE *src1, YYSTYPE *src2)
+{
+ dst->type = NUM;
+ dst->val = (double)strpos(src1->text, src2->text);
+}
+
+static void strrepl(YYSTYPE *dst, YYSTYPE *src1, YYSTYPE *src2, YYSTYPE *src3)
+{
+ dst->type = STR;
+ dst->text = PushString(strreplace(src1->text, src2->text, src3->text));
+}
+
+static void _substr(YYSTYPE *dst, YYSTYPE *src1, YYSTYPE *src2, YYSTYPE *src3)
+{
+ dst->type = STR;
+ dst->text = PushString(substr(src1->text, (int)(src2->val), (int)(src3->val)));
+}
+
+static double asc(YYSTYPE *sr, YYSTYPE *dst, char *dum)
+{
+ if(dum) yyerror("parse error");
+ if(!sr || !sr->text) return 0.0;
+ return (double)((unsigned char)(sr->text[0]));
+}
+
+static void chr(YYSTYPE *dst, YYSTYPE *src)
+{
+ char tpl[] = "?\0";
+
+ if(!dst || !src) return;
+ tpl[0] = (src->val >=32.0 && src->val <= 255.0) ? (char)(src->val) : '?';
+ dst->type = STR;
+ dst->text = PushString(tpl);
+}
+
+static void to_upper(YYSTYPE *dst, YYSTYPE *src)
+{
+ int i;
+
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ for(i = 0; src->text[i]; i++) dst->text[i] = toupper(src->text[i]);
+ }
+ else dst->text = 0L;
+}
+
+static void to_lower(YYSTYPE *dst, YYSTYPE *src)
+{
+ int i;
+
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ for(i = 0; src->text[i]; i++) dst->text[i] = tolower(src->text[i]);
+ }
+ else dst->text = 0L;
+}
+
+static void uc_first(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ dst->text[0] = toupper(src->text[0]);
+ }
+ else dst->text = 0L;
+}
+
+static void uc_word(YYSTYPE *dst, YYSTYPE *src)
+{
+ int i;
+
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ dst->text[0] = toupper(src->text[0]);
+ for(i = 1; src->text[i]; i++) {
+ if(isalpha(src->text[i]) && src->text[i-1] < 'A') dst->text[i] = toupper(src->text[i]);
+ }
+ }
+ else dst->text = 0L;
+}
+
// Store strings in a list
static char **str_list = 0L;
static int n_str = 0;
@@ -2833,7 +3153,11 @@ void InitArithFuncs(DataObj *d)
double (*fnct)(double);
};
fdef fncts[] = {
- INIT_SYM(FUNC4, "classes", classes),
+ INIT_SYM(YYFNC, "toupper", to_upper), INIT_SYM(YYFNC, "tolower", to_lower),
+ INIT_SYM(YYFNC, "ucfirst", uc_first), INIT_SYM(YYFNC, "ucword", uc_word),
+ INIT_SYM(SFNCT, "asc", asc), INIT_SYM(YYFNC, "chr", chr),
+ INIT_SYM(YYFNC3, "strrepl",strrepl), INIT_SYM(YYFNC3, "substr", _substr),
+ INIT_SYM(YYFNC2, "strpos",_strpos), 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),
@@ -2844,7 +3168,7 @@ void InitArithFuncs(DataObj *d)
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(YYFNC, "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),
@@ -2859,10 +3183,14 @@ void InitArithFuncs(DataObj *d)
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, "tdist", tdist),
+ INIT_SYM(AFNCT, "tfreq", tfreq),
+ INIT_SYM(AFNCT, "tinv", tinv),
INIT_SYM(AFNCT, "poisdist", poisdist), INIT_SYM(AFNCT, "poisfreq", poisfreq),
INIT_SYM(AFNCT, "expdist", expdist), INIT_SYM(AFNCT, "expfreq", expfreq),
- INIT_SYM(AFNCT, "expinv", expinv), INIT_SYM(AFNCT, "fdist", fdist),
+ INIT_SYM(AFNCT, "expinv", expinv),
+ INIT_SYM(AFNCT, "fdist", fdist),
+ INIT_SYM(AFNCT, "ffreq", ffreq),
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),
@@ -2872,8 +3200,9 @@ void InitArithFuncs(DataObj *d)
INIT_SYM(AFNCT, "norminv", norminv), INIT_SYM(AFNCT, "normfreq", normfreq),
INIT_SYM(AFNCT, "lognormdist", lognormdist), INIT_SYM(AFNCT, "lognormfreq", lognormfreq),
INIT_SYM(AFNCT, "lognorminv",lognorminv), INIT_SYM(AFNCT, "chidist", chidist),
+ INIT_SYM(AFNCT, "chifreq", chifreq),
INIT_SYM(AFNCT, "chiinv", chiinv), INIT_SYM(SFNCT, "strlen", _strlen),
- INIT_SYM(SFNCT, "eval", eval), INIT_SYM(FNCT, "erf", errf),
+ INIT_SYM(YYFNC, "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),
@@ -3188,6 +3517,9 @@ static int is_ttoken(unsigned int h_nam, unsigned int h2_nam)
case 362:
if(h2_nam == 42878) return IF;
break;
+ case 28421:
+ if(h2_nam == 82147317) return (syntax_level->last_tok = WHILE);
+ break;
case 1457:
if(h2_nam == 18357885) return DIM;
break;
@@ -3204,24 +3536,66 @@ static int is_ttoken(unsigned int h_nam, unsigned int h2_nam)
return 0;
}
+static char *copy_block()
+{
+ char first[50], last[50], *res, *src;
+ int i, j, level, mode;
+
+ src = buffer + buff_pos-1;
+ switch(*src){
+ case '{':
+ first[0] = '{'; last[0] = '}'; break;
+ case '(':
+ first[0] = '('; last[0] = ')'; break;
+ }
+ if(!(res = (char*)malloc(strlen(src)+2))) return 0L;
+ for(i = 1, level = mode = j = 0; src[i]; i++) {
+ res[j++] = src[i];
+ if(mode && level) { //embeded string
+ if(src[i] == last[level]) {
+ mode = 0; level--;
+ }
+ res[j++] = src[i];
+ }
+ else {
+ if(src[i] == last[level]) {
+ if(level) level--;
+ else {
+ res[j-1] = 0; buff_pos += j;
+ return res;
+ }
+ }
+ else switch(src[i]) {
+ case '"':
+ level++; first[level] = last[level] = '"'; break;
+ case '\'':
+ level++; first[level] = last[level] = '\''; break;
+ case '{':
+ level++; first[level] = '{'; last[level] = '}'; break;
+ case '(':
+ level++; first[level] = '('; last[level] = ')'; break;
+ }
+ }
+ }
+ return res;
+}
+
static symrec *curr_sym;
static int yylex (void)
{
int i, c, tok;
unsigned int h_nam, h2_nam;
- char tmp_txt[80];
+ char tmp_txt[80], *block;
symrec *s;
while((c = buffer[buff_pos++]) == ' ' || c == '\t'); //get first nonwhite char
if(!c) return 0;
//test for block statement
if(c == '{') {
- for(i= 0; i < 79 && ((tok = buffer[buff_pos]) && (tok != '}')); buff_pos++) {
- tmp_txt[i++] = (char)tok;
+ if(block = copy_block()) {
+ yylval.text = PushString(block);
+ free(block);
}
- if(buffer[buff_pos] == '}')buff_pos++;
- tmp_txt[i] = 0;
- yylval.text = PushString(tmp_txt);
return yylval.type = BLOCK;
}
//test for '..' operator
@@ -3230,7 +3604,7 @@ static int yylex (void)
return yylval.type = SER;
}
//test for number
- if(c == '.' || isdigit(c)) {
+ if(c > 31 &&(c == '.' || isdigit(c))) {
for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) == '.' || isdigit(c)); buff_pos++) {
tmp_txt[i++] = (char)c;
if(i && buffer[buff_pos+1] == 'e' && (buffer[buff_pos+2] == '-' || buffer[buff_pos+2] == '+')){
@@ -3247,8 +3621,8 @@ static int yylex (void)
return yylval.type = NUM;
}
//test for name or stringtoken
- if(isalpha(c) || c=='$') {
- for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) && (isalnum(c) || c == '$')); buff_pos++) {
+ if(c > 31 && (isalpha(c) || c=='$')) {
+ for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) && c > 31 && (isalnum(c) || c == '$')); buff_pos++) {
tmp_txt[i++] = (char)c;
}
tmp_txt[i] = 0;
@@ -3309,6 +3683,13 @@ static int yylex (void)
pop_syntax();
break;
case '(':
+ if(syntax_level->last_tok == WHILE){
+ if(block = copy_block()) {
+ yylval.text = PushString(block);
+ free(block);
+ }
+ return yylval.type = PBLOCK;
+ }
push_syntax();
case '?':
if(syntax_level) syntax_level->last_tok = c;
@@ -3335,6 +3716,7 @@ static int yylex (void)
buff_pos++; return tok;
}
//Any other character is a token by itself
+ if(c < 0 || c > 127)yytokenerr(c);
return c;
}
@@ -3361,7 +3743,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
push_parser();
init_table();
if(param) {
- length = strlen(param);
+ length = (int)strlen(param);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return false;
@@ -3373,7 +3755,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
}while(buff_pos < length);
free(buffer); buffer = 0L;
}
- length = strlen(expr);
+ length = (int)strlen(expr);
buffer = expr; sx = putsym(hn_x, h2_x, VAR);
for(x = x1; step > 0.0 ? x <= x2 : x >= x2; x += step) {
if(sx){
@@ -3420,7 +3802,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
push_parser();
init_table();
if(param) {
- length = strlen(param);
+ length = (int)strlen(param);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return false;
@@ -3432,7 +3814,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
}while(buff_pos < length);
free(buffer); buffer = 0L;
}
- length = strlen(expr); buffer = expr;
+ length = (int)strlen(expr); buffer = expr;
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);
@@ -3476,7 +3858,7 @@ anyResult *do_formula(DataObj *d, char *expr)
return &ret;
}
push_parser(); //make code reentrant
- init_table(); length = strlen(expr);
+ init_table(); length = (int)strlen(expr);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return &ret;
@@ -3502,20 +3884,21 @@ anyResult *do_formula(DataObj *d, char *expr)
bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
{
- int length, tok, pos, i;
+ int length, length2, tok, pos, i;
char *res, desc1[2], desc2[2];
if(d) curr_data = d;
if(!curr_data || !of || !nf) return false;
push_parser(); //make code reentrant
- init_table(); length = strlen(of);
+ init_table(); length = (int)strlen(of);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return false;
}
strcpy(buffer, of); buffer[length++] = ';';
buffer[length] = 0; buff_pos = pos = 0;
- res = (char *)calloc(length*2+10, sizeof(char));
+ if(!(res = (char *)calloc(length2 = (length*2+10), sizeof(char))))return false;
+ length2--;
do {
tok = yylex ();
if(tok && tok < 256) {
@@ -3524,97 +3907,121 @@ bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
}
else switch(tok) {
case NUM:
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, 20, "%g", yylval.val);
+#else
pos += sprintf(res+pos, "%g", yylval.val);
+#endif
break;
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);
+ case YYFNC2: case YYFNC3:
+ pos += rlp_strcpy(res+pos, length2-pos, curr_sym->name);
break;
case COLR: case COLC:
- pos += sprintf(res+pos, ":");
+ res[pos++] = ':';
break;
case PSEP:
- pos += sprintf(res+pos, ";");
+ res[pos++] = ';';
break;
case CLVAL:
- pos += sprintf(res+pos, "$$");
+ res[pos++] = '$'; res[pos++] = '$';
break;
case CLAUSE:
- pos += sprintf(res+pos, " where ");
+ pos += rlp_strcpy(res+pos, length2-pos, " where ");
break;
case VAR:
curr_sym->InitSS();
if(curr_sym->col >= 0 && curr_sym->row >= 0) {
desc1[0] = desc1[1] = desc2[0] = desc2[1] = 0;
- for(i=strlen(curr_sym->name)-1; i>0 && isdigit(curr_sym->name[i]); i--);
+ for(i=(int)strlen(curr_sym->name)-1; i>0 && isdigit(curr_sym->name[i]); i--);
if(curr_sym->name[0] == '$') desc1[0] = '$';
if(curr_sym->name[i] == '$') desc2[0] = '$';
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, length2-pos, "%s%s%s%d", desc1,
+#else
pos += sprintf(res+pos, "%s%s%s%d", desc1,
+#endif
Int2ColLabel(desc1[0] || curr_sym->col < c0 ? curr_sym->col : curr_sym->col+dx >=0 ?
curr_sym->col+dx > c0 ? curr_sym->col+dx : c0 : 0, false),
desc2, desc2[0] || curr_sym->row < r0 ? curr_sym->row+1 : curr_sym->row + dy >= 0 ?
curr_sym->row+dy > r0 ? curr_sym->row+1+dy : r0 : 1);
}
- else pos += sprintf(res+pos, "%s ", curr_sym->name);
+ else pos += rlp_strcpy(res+pos, length2-pos, curr_sym->name);
break;
case STR:
pos += sprintf(res+pos, "\"%s\"", yylval.text && yylval.text[0] ? yylval.text : "");
break;
case SER:
- pos += sprintf(res+pos, "..");
+ res[pos++] = '.'; res[pos++] = '.';
break;
case INC:
- pos += sprintf(res+pos, "++");
+ res[pos++] = '+'; res[pos++] = '+';
break;
case DEC:
- pos += sprintf(res+pos, "--");
+ res[pos++] = '-'; res[pos++] = '-';
break;
case PI:
- pos += sprintf(res+pos, "pi");
+ res[pos++] = 'p'; res[pos++] = 'i';
break;
case E:
- pos += sprintf(res+pos, "e");
+ res[pos++] = 'e';
break;
case BTRUE:
- pos += sprintf(res+pos, "true");
+ pos += rlp_strcpy(res+pos, length2-pos, "true");
break;
case BFALSE:
- pos += sprintf(res+pos, "false");
+ pos += rlp_strcpy(res+pos, length2-pos, "false");
break;
case AND:
- pos += sprintf(res+pos, " && ");
+ pos += rlp_strcpy(res+pos, length2-pos, " && ");
break;
case OR:
- pos += sprintf(res+pos, " || ");
+ pos += rlp_strcpy(res+pos, length2-pos, " || ");
break;
case EQ:
- pos += sprintf(res+pos, " == ");
+ pos += rlp_strcpy(res+pos, length2-pos, " == ");
break;
case NE:
- pos += sprintf(res+pos, " != ");
+ pos += rlp_strcpy(res+pos, length2-pos, " != ");
break;
case GT:
- pos += sprintf(res+pos, ">");
+ res[pos++] = '>';
break;
case GE:
- pos += sprintf(res+pos, ">=");
+ res[pos++] = '>'; res[pos++] = '=';
break;
case LT:
- pos += sprintf(res+pos, "<");
+ res[pos++] = '<';
break;
case LE:
- pos += sprintf(res+pos, "<=");
+ res[pos++] = '<'; res[pos++] = '=';
break;
case IF:
- pos += sprintf(res+pos, "if");
+ res[pos++] = 'i'; res[pos++] = 'f';
+ break;
+ case WHILE:
+ pos += rlp_strcpy(res+pos, length2-pos, "while");
break;
case ELSE:
- pos += sprintf(res+pos, "else");
+ pos += rlp_strcpy(res+pos, length2-pos, "else");
break;
case BLOCK:
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, TMP_TXT_SIZE-pos, "{%s}", yylval.text && yylval.text[0] ? yylval.text : "");
+#else
pos += sprintf(res+pos, "{%s}", yylval.text && yylval.text[0] ? yylval.text : "");
+#endif
+ break;
+ case PBLOCK:
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, TMP_TXT_SIZE-pos, "(%s)", yylval.text && yylval.text[0] ? yylval.text : "");
+#else
+ pos += sprintf(res+pos, "(%s)", yylval.text && yylval.text[0] ? yylval.text : "");
+#endif
break;
}
+ res[pos] = 0;
}while(buff_pos < length);
while((res[pos-1] == ';' || res[pos-1] == ' ') && pos > 0) { res[pos-1] = 0; pos--;}
strcpy(nf, res); free(res);
@@ -3641,7 +4048,7 @@ static void fcurve(double x, double z, double **a, double *y, double dyda[], int
//calc result
symx->SetValue(x); symz->SetValue(z);
buffer = txt_formula;
- buff_pos = 0; length = strlen(txt_formula);
+ buff_pos = 0; length = (int)strlen(txt_formula);
do { yyparse(); }while(buff_pos < length);
if(sy = getsym(hn_y, h2_y)) *y = sy->GetValue();
else *y = line_res.value;
@@ -3726,7 +4133,7 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
}
//common initialization for parser tasks
push_parser(); //make code reentrant
- init_table(); length = strlen(*par);
+ init_table(); length = (int)strlen(*par);
//process parameters
if(!(buffer = (char*)malloc(length+2))){
clear_table(); pop_parser();
@@ -3775,10 +4182,11 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
l += sprintf(tmp_txt+j, "%s%s=%g;", j && k ? " " : "", parsym[i]->name, parsym[i]->GetValue());
j += l; k += l;
}
- free(*par); *par = strdup(tmp_txt);
+ free(*par);
+ *par = (char*)memdup(tmp_txt, (int)strlen(tmp_txt)+1, 0);
if(chi_2) *chi_2 = chisq;
//write back spreadsheet data if necessary
- buffer = *par; length = strlen(buffer);
+ buffer = *par; length = (int)strlen(buffer);
do {
yyparse();
}while(buff_pos < length);
@@ -3797,11 +4205,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 3069b87..e033364 100755
--- a/mfcalc.y
+++ b/mfcalc.y
@@ -43,9 +43,10 @@ public:
void SetValue(void* dest, void* src);
void SetName(char *nam);
void InitSS();
+ void NoInit();
private:
- bool isSSval;
+ bool isSSval, isValid;
};
@@ -69,6 +70,8 @@ typedef struct{
}YYSTYPE;
+static int yy_maxiter = 1000;
+
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);
@@ -78,7 +81,7 @@ 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, char* dum);
+static void eval(YYSTYPE *dst, YYSTYPE *sr);
static int range_array(YYSTYPE * res, char *range);
static int range_array2(YYSTYPE *res1, YYSTYPE *res2);
static void exec_clause(YYSTYPE *res);
@@ -101,9 +104,10 @@ static int parse_level = 0; //count reentrances into parser
#define MAX_PARSE 20 //maximum number of reentances
%}
-%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
+%token <val> NUM BOOLVAL STR ARR BLOCK PBLOCK PI E CLVAL PSEP IF ELSE
+%token <val> BTRUE BFALSE DATE1 TIME1 DATETIME1 DIM WHILE
+%token <tptr> VAR FNCT BFNCT AFNCT SFNCT FUNC1 FUNC2 FUNC3 TXT SRFUNC YYFNC
+%token <tptr> FUNC4 YYFNC2 YYFNC3
%type <val> exp str_exp arr bool
%right '='
@@ -117,11 +121,11 @@ static int parse_level = 0; //count reentrances into parser
%left '-' '+'
%left '*' '/'
%left '['
-%left NEG /* negation-unary minus */
+%left '^' /* exponentiation */
+%left NEG /* negation-unary minus */
%left INC DEC /* increment, decrement */
%left PINC PDEC /* pre- increment, decrement */
%left PDIM /* dimension array */
-%right '^' /* exponentiation */
/* Grammar follows */
%%
@@ -186,7 +190,7 @@ exp: NUM {$$ = $1; yyval.type = NUM;}
|PI {$$ = _PI; yyval.type = NUM;}
|E {$$ = 2.71828182845905; yyval.type = NUM;}
|VAR {$1->GetValue(&yyval);}
- |BLOCK {eval(&yyvsp[0], &yyval, 0L);}
+ |BLOCK {eval(&yyvsp[0], &yyval);}
|VAR '=' exp {$1->SetValue(&yyval, &yyvsp[0]);}
|VAR '=' str_exp {$1->SetValue(&yyval, &yyvsp[0]);}
|FNCT '(' exp ')' {$$ = (($1->fnctptr)($3)); yyval.type = NUM;}
@@ -196,8 +200,8 @@ exp: NUM {$$ = $1; 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 ')' {yyval.type = NUM; $$ = (($1->fnctptr)(&yyvsp[-1], &yyval, 0L));}
+ |SFNCT '(' exp ')' {yyval.type = NUM; yyvsp[-1].text = string_value(&yyvsp[-1]); $$ = (($1->fnctptr)(&yyvsp[-1], &yyval, 0L));}
|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;}
@@ -214,8 +218,24 @@ exp: NUM {$$ = $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);}
+ |YYFNC2 '(' exp PSEP exp ')' {(*$1->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC2 '(' str_exp PSEP exp ')' {(*$1->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC2 '(' exp PSEP str_exp ')' {(*$1->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC2 '(' str_exp PSEP str_exp ')' {(*$1->fnctptr)(&yyval, &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' str_exp PSEP str_exp PSEP str_exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' exp PSEP str_exp PSEP str_exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' str_exp PSEP exp PSEP str_exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' str_exp PSEP str_exp PSEP exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' exp PSEP exp PSEP str_exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' exp PSEP str_exp PSEP exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' str_exp PSEP exp PSEP exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |YYFNC3 '(' exp PSEP exp PSEP exp')' {(*$1->fnctptr)(&yyval, &yyvsp[-5], &yyvsp[-3], &yyvsp[-1]);}
+ |IF '(' exp ')' BLOCK {if($3 != 0.0)eval(&yyval, &yyvsp[0]);}
+ |IF '(' exp ')' BLOCK ELSE BLOCK {$3 != 0.0 ? eval(&yyval, &yyvsp[-2]) : eval(&yyval, &yyvsp[0]);}
+ |WHILE PBLOCK BLOCK {for(int i=0; i< yy_maxiter; i++){
+ eval(&yyval, &yyvsp[-1]);
+ if(yyval.val != 0.0)eval(&yyval, &yyvsp[0]);
+ else break;}}
|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;
@@ -227,12 +247,12 @@ exp: NUM {$$ = $1; yyval.type = NUM;}
|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;}
|INC VAR %prec PINC {$$=$2->GetValue(); $2->SetValue($$+1.0); yyval.type = NUM;}
|DEC VAR %prec PDEC {$$=$2->GetValue(); $2->SetValue($$-1.0); yyval.type = NUM;}
- |exp '^' exp {$$ = pow($1, $3);}
+ |exp '^' exp {$$ = ($3 >0 && $3/2.0 == floor($3/2.0)) ? fabs(pow($1,$3) ): pow($1, $3); yyval.type = NUM;}
+ |'-' exp %prec NEG {$$ = -$2; yyval.type = NUM;}
|'(' 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);}
@@ -256,7 +276,7 @@ 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;
+ var = 0.0; isSSval = isValid = false;
a_data = 0L; a_count = 0;
fnctptr = (double (*)(...))nop;
}
@@ -281,6 +301,7 @@ symrec::GetValue()
isSSval = false;
row = col = -1;
}
+ if(!isValid) NoInit();
return var;
}
@@ -295,6 +316,7 @@ symrec::GetValue(void *re)
res->a_data = 0L; res->a_count = 0;
//GetResult( , , ,true) inhibits reentrance into parser !
if(curr_data->GetResult(&ares, row, col, parse_level > MAX_PARSE)){
+ isValid = true;
if(text) free(text); text = 0L;
switch(ares.type) {
case ET_VALUE:
@@ -326,6 +348,7 @@ symrec::GetValue(void *re)
isSSval = false;
row = col = -1;
}
+ if(!isValid) NoInit();
if(a_data && a_count) {
res->a_data = a_data; res->a_count = a_count;
res->val = 0.0; res->type = ARR;
@@ -352,6 +375,7 @@ symrec::SetValue(double v)
isSSval = false;
row = col = -1;
}
+ isValid = true;
a_data = 0L; a_count = 0;
return var = v;
}
@@ -371,9 +395,11 @@ symrec::SetValue(void* d, void* s)
else curr_data->SetValue(row, col, src->val);
curr_data->Command(CMD_UPDATE, 0L, 0L);
}
+ isValid = true;
var = src->val;
if(text) free(text); text = 0L;
- if(src->text && src->text[0]) text = strdup(src->text);
+ if(src->text && src->text[0])
+ text =(char*)memdup(src->text, (int)strlen(src->text)+1, 0);
a_data = src->a_data; a_count = src->a_count;
GetValue(d);
return;
@@ -383,7 +409,8 @@ void
symrec::SetName(char *nam)
{
if(name || !nam || !nam[0]) return;
- name = strdup(nam);
+ name = (char*)memdup(nam, (int)strlen(nam)+1, 0);
+ isValid = false;
if((name && curr_data) && (isalpha(name[0]) || name[0] == '$') && isdigit(name[strlen(name)-1])) isSSval=true;
}
@@ -398,6 +425,19 @@ symrec::InitSS()
}
}
+void
+symrec::NoInit()
+{
+ char message[200];
+
+#ifdef USE_WIN_SECURE
+ sprintf_s(message, 80, "Accessing variable '%s'\nwithout initialization!\n", name);
+#else
+ sprintf(message, "Accessing variable '%s'\nwithout initialization!\n", name);
+#endif
+ yywarn(message, true);
+}
+
static void yyerror(char *s)
{
//called by yyparse on error
@@ -412,6 +452,17 @@ static void yyargserr(char *s)
last_err_desc = "#ARGS";
}
+static char txt_tokenerr[80];
+static void yytokenerr(int c)
+{
+#ifdef USE_WIN_SECURE
+ sprintf_s(txt_tokenerr, 80, "Illegal character\nor token '%c'\n", (char)c);
+#else
+ sprintf(txt_tokenerr, "Illegal character\nor token '%c'\n", (char)c);
+#endif
+ yyerror(txt_tokenerr);
+}
+
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) {
@@ -421,6 +472,23 @@ static void make_time(YYSTYPE *dst, double h, double m, double s)
dst->val /= 24.0; dst->type = TIME1;
}
+static char yywarn_text[200];
+char *yywarn(char *txt, bool bNew)
+{
+ if(bNew) {
+ if(txt && txt[0]) {
+ rlp_strcpy(yywarn_text, 200, txt);
+ return yywarn_text;
+ }
+ else {
+ yywarn_text[0] = 0;
+ return 0L;
+ }
+ }
+ else if(yywarn_text[0]) return yywarn_text;
+ else return 0L;
+}
+
static void store_res(YYSTYPE *res)
{
if(last_err_desc) {
@@ -480,10 +548,15 @@ static void store_res(YYSTYPE *res)
static char *add_strings(char *st1, char *st2)
{
char *newstr, *ret;
+ int cb;
if(st1 && st2) {
- if(newstr = (char*)malloc(strlen(st1) +strlen(st2) +4)) {
+ if(newstr = (char*)malloc(cb = (int)(strlen(st1) +strlen(st2) +4))) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(newstr, cb, "%s%s", st1, st2);
+#else
sprintf(newstr, "%s%s", st1, st2);
+#endif
ret = PushString(newstr);
free(newstr);
return ret;
@@ -533,16 +606,34 @@ static void pop_syntax()
}
}
-static double eval(YYSTYPE *sr, YYSTYPE *dst, char *dum)
+static void eval(YYSTYPE *dst, YYSTYPE *sr)
{
+ char *s_buffer;
+ int s_buff_pos, s_yychar, s_yynerrs, length;
anyResult *ar;
- if(dum) yyerror("parse error");
- if(!sr || !sr->text) return 0.0;
+ if(!sr || !sr->text) return;
parse_level++;
- ar = do_formula(0L, sr->text);
+ s_buffer = buffer; s_buff_pos = buff_pos;
+ s_yychar = yychar; s_yynerrs = yynerrs;
+ if (sr->text && (length=(int)strlen(sr->text)) && (buffer = (char*)malloc(length+2))) {
+ strcpy(buffer, sr->text); buffer[length++] = ';';
+ buffer[length] = 0; buff_pos = 0;
+ do {
+ yyparse();
+ }while(buff_pos < length);
+ free(buffer); ar = &line_res;
+ buffer = s_buffer; buff_pos = s_buff_pos;
+ yychar = s_yychar; yynerrs = s_yynerrs;
+ }
+ else return;
yylval.a_data = 0L; yylval.a_count = 0;
switch(ar->type) {
+ case ET_BOOL:
+ dst->type = BOOLVAL;
+ dst->val = ar->value;
+ dst->text = 0L;
+ break;
case ET_VALUE:
dst->type = NUM;
dst->val = ar->value;
@@ -560,7 +651,6 @@ static double eval(YYSTYPE *sr, YYSTYPE *dst, char *dum)
break;
}
parse_level--;
- return dst->val;
}
// more functions
@@ -752,7 +842,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(d_variance(sr->a_count, sr->a_data))/sqrt(sr->a_count);
+ sr->val = sqrt(d_variance(sr->a_count, sr->a_data))/sqrt((double)sr->a_count);
}
return sr->val;
}
@@ -856,7 +946,7 @@ static double norminv(YYSTYPE *sr)
if(!sr) return 0.0;
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);
+ sr->val = distinv(norm_dist,sr->a_data[1], sr->a_data[2], sr->a_data[0], sr->a_data[1]);
}
else yyargserr("Wrong number of arguments\nin call to norminv(p, mean, SD).");
return sr->val;
@@ -933,7 +1023,7 @@ 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);
+ sr->val = distinv(lognorm_dist, sr->a_data[1], sr->a_data[2], sr->a_data[0], sr->a_data[1]);
}
else yyargserr("Wrong number of arguments\nin call to lognorminv(p, mean, SD).");
return sr->val;
@@ -950,6 +1040,17 @@ static double chidist(YYSTYPE *sr)
return sr->val;
}
+static double chifreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 2){
+ sr->val = chi_freq(sr->a_data[0], sr->a_data[1]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to chifreq(x, df).");
+ return sr->val;
+}
+
static double chiinv(YYSTYPE *sr)
{
if(!sr) return 0.0;
@@ -972,12 +1073,26 @@ static double tdist(YYSTYPE *sr)
return sr->val;
}
+static double tfreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 2){
+ sr->val = t_freq(sr->a_data[0], sr->a_data[1]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to tfreq(x, df).");
+ return sr->val;
+}
+
static double tinv(YYSTYPE *sr)
{
+ double dtmp;
+
if(!sr) return 0.0;
sr->val = 0.0;
+ dtmp = sr->a_data[1] > 1.0E+10 ? 1.0E+10 : sr->a_data[1];
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);
+ sr->val = fabs(distinv(t_dist,dtmp, 1.0, sr->a_data[0], 2.0));
}
else yyargserr("Wrong number of arguments\nin call to tinv(p, df).");
return sr->val;
@@ -1008,7 +1123,7 @@ static double poisfreq(YYSTYPE *sr)
static double fdist(YYSTYPE *sr)
{
if(!sr) return 0.0;
- sr->val = 0;
+ sr->val = 0.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]);
}
@@ -1016,6 +1131,17 @@ static double fdist(YYSTYPE *sr)
return sr->val;
}
+static double ffreq(YYSTYPE *sr)
+{
+ if(!sr) return 0.0;
+ sr->val = 0.0;
+ if(sr->a_data && sr->a_count == 3){
+ sr->val = f_freq(sr->a_data[0], sr->a_data[1], sr->a_data[2]);
+ }
+ else yyargserr("Wrong number of arguments\nin call to ffreq(x, df1, df2).");
+ return sr->val;
+}
+
static double finv(YYSTYPE *sr)
{
if(!sr) return 0.0;
@@ -1088,7 +1214,7 @@ 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);
+ sr1->val = sr2->val = d_ttest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data, 0L);
}
else yyargserr("Bad arguments in call to function\nttest(array1; array2[;\"dest\"]).");
return sr1->val;
@@ -1110,7 +1236,7 @@ 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);
+ sr1->val = sr2->val = d_utest(sr1->a_data, sr2->a_data, sr1->a_count, sr2->a_count, dest, curr_data, 0L);
}
else yyargserr("Bad arguments in call to function\nutest2(array1; array2[;\"dest\"]).");
return sr1->val;
@@ -1340,6 +1466,94 @@ 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);
}
+static void _strpos(YYSTYPE *dst, YYSTYPE *src1, YYSTYPE *src2)
+{
+ dst->type = NUM;
+ dst->val = (double)strpos(src1->text, src2->text);
+}
+
+static void strrepl(YYSTYPE *dst, YYSTYPE *src1, YYSTYPE *src2, YYSTYPE *src3)
+{
+ dst->type = STR;
+ dst->text = PushString(strreplace(src1->text, src2->text, src3->text));
+}
+
+static void _substr(YYSTYPE *dst, YYSTYPE *src1, YYSTYPE *src2, YYSTYPE *src3)
+{
+ dst->type = STR;
+ dst->text = PushString(substr(src1->text, (int)(src2->val), (int)(src3->val)));
+}
+
+static double asc(YYSTYPE *sr, YYSTYPE *dst, char *dum)
+{
+ if(dum) yyerror("parse error");
+ if(!sr || !sr->text) return 0.0;
+ return (double)((unsigned char)(sr->text[0]));
+}
+
+static void chr(YYSTYPE *dst, YYSTYPE *src)
+{
+ char tpl[] = "?\0";
+
+ if(!dst || !src) return;
+ tpl[0] = (src->val >=32.0 && src->val <= 255.0) ? (char)(src->val) : '?';
+ dst->type = STR;
+ dst->text = PushString(tpl);
+}
+
+static void to_upper(YYSTYPE *dst, YYSTYPE *src)
+{
+ int i;
+
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ for(i = 0; src->text[i]; i++) dst->text[i] = toupper(src->text[i]);
+ }
+ else dst->text = 0L;
+}
+
+static void to_lower(YYSTYPE *dst, YYSTYPE *src)
+{
+ int i;
+
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ for(i = 0; src->text[i]; i++) dst->text[i] = tolower(src->text[i]);
+ }
+ else dst->text = 0L;
+}
+
+static void uc_first(YYSTYPE *dst, YYSTYPE *src)
+{
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ dst->text[0] = toupper(src->text[0]);
+ }
+ else dst->text = 0L;
+}
+
+static void uc_word(YYSTYPE *dst, YYSTYPE *src)
+{
+ int i;
+
+ if(!dst || !src) return;
+ dst->type = STR;
+ if(src->text && src->text[0]) {
+ dst->text = PushString(src->text);
+ dst->text[0] = toupper(src->text[0]);
+ for(i = 1; src->text[i]; i++) {
+ if(isalpha(src->text[i]) && src->text[i-1] < 'A') dst->text[i] = toupper(src->text[i]);
+ }
+ }
+ else dst->text = 0L;
+}
+
// Store strings in a list
static char **str_list = 0L;
static int n_str = 0;
@@ -1430,7 +1644,11 @@ void InitArithFuncs(DataObj *d)
double (*fnct)(double);
};
fdef fncts[] = {
- INIT_SYM(FUNC4, "classes", classes),
+ INIT_SYM(YYFNC, "toupper", to_upper), INIT_SYM(YYFNC, "tolower", to_lower),
+ INIT_SYM(YYFNC, "ucfirst", uc_first), INIT_SYM(YYFNC, "ucword", uc_word),
+ INIT_SYM(SFNCT, "asc", asc), INIT_SYM(YYFNC, "chr", chr),
+ INIT_SYM(YYFNC3, "strrepl",strrepl), INIT_SYM(YYFNC3, "substr", _substr),
+ INIT_SYM(YYFNC2, "strpos",_strpos), 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),
@@ -1441,7 +1659,7 @@ void InitArithFuncs(DataObj *d)
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(YYFNC, "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),
@@ -1456,10 +1674,14 @@ void InitArithFuncs(DataObj *d)
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, "tdist", tdist),
+ INIT_SYM(AFNCT, "tfreq", tfreq),
+ INIT_SYM(AFNCT, "tinv", tinv),
INIT_SYM(AFNCT, "poisdist", poisdist), INIT_SYM(AFNCT, "poisfreq", poisfreq),
INIT_SYM(AFNCT, "expdist", expdist), INIT_SYM(AFNCT, "expfreq", expfreq),
- INIT_SYM(AFNCT, "expinv", expinv), INIT_SYM(AFNCT, "fdist", fdist),
+ INIT_SYM(AFNCT, "expinv", expinv),
+ INIT_SYM(AFNCT, "fdist", fdist),
+ INIT_SYM(AFNCT, "ffreq", ffreq),
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),
@@ -1469,8 +1691,9 @@ void InitArithFuncs(DataObj *d)
INIT_SYM(AFNCT, "norminv", norminv), INIT_SYM(AFNCT, "normfreq", normfreq),
INIT_SYM(AFNCT, "lognormdist", lognormdist), INIT_SYM(AFNCT, "lognormfreq", lognormfreq),
INIT_SYM(AFNCT, "lognorminv",lognorminv), INIT_SYM(AFNCT, "chidist", chidist),
+ INIT_SYM(AFNCT, "chifreq", chifreq),
INIT_SYM(AFNCT, "chiinv", chiinv), INIT_SYM(SFNCT, "strlen", _strlen),
- INIT_SYM(SFNCT, "eval", eval), INIT_SYM(FNCT, "erf", errf),
+ INIT_SYM(YYFNC, "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),
@@ -1785,6 +2008,9 @@ static int is_ttoken(unsigned int h_nam, unsigned int h2_nam)
case 362:
if(h2_nam == 42878) return IF;
break;
+ case 28421:
+ if(h2_nam == 82147317) return (syntax_level->last_tok = WHILE);
+ break;
case 1457:
if(h2_nam == 18357885) return DIM;
break;
@@ -1801,24 +2027,66 @@ static int is_ttoken(unsigned int h_nam, unsigned int h2_nam)
return 0;
}
+static char *copy_block()
+{
+ char first[50], last[50], *res, *src;
+ int i, j, level, mode;
+
+ src = buffer + buff_pos-1;
+ switch(*src){
+ case '{':
+ first[0] = '{'; last[0] = '}'; break;
+ case '(':
+ first[0] = '('; last[0] = ')'; break;
+ }
+ if(!(res = (char*)malloc(strlen(src)+2))) return 0L;
+ for(i = 1, level = mode = j = 0; src[i]; i++) {
+ res[j++] = src[i];
+ if(mode && level) { //embeded string
+ if(src[i] == last[level]) {
+ mode = 0; level--;
+ }
+ res[j++] = src[i];
+ }
+ else {
+ if(src[i] == last[level]) {
+ if(level) level--;
+ else {
+ res[j-1] = 0; buff_pos += j;
+ return res;
+ }
+ }
+ else switch(src[i]) {
+ case '"':
+ level++; first[level] = last[level] = '"'; break;
+ case '\'':
+ level++; first[level] = last[level] = '\''; break;
+ case '{':
+ level++; first[level] = '{'; last[level] = '}'; break;
+ case '(':
+ level++; first[level] = '('; last[level] = ')'; break;
+ }
+ }
+ }
+ return res;
+}
+
static symrec *curr_sym;
static int yylex (void)
{
int i, c, tok;
unsigned int h_nam, h2_nam;
- char tmp_txt[80];
+ char tmp_txt[80], *block;
symrec *s;
while((c = buffer[buff_pos++]) == ' ' || c == '\t'); //get first nonwhite char
if(!c) return 0;
//test for block statement
if(c == '{') {
- for(i= 0; i < 79 && ((tok = buffer[buff_pos]) && (tok != '}')); buff_pos++) {
- tmp_txt[i++] = (char)tok;
+ if(block = copy_block()) {
+ yylval.text = PushString(block);
+ free(block);
}
- if(buffer[buff_pos] == '}')buff_pos++;
- tmp_txt[i] = 0;
- yylval.text = PushString(tmp_txt);
return yylval.type = BLOCK;
}
//test for '..' operator
@@ -1827,7 +2095,7 @@ static int yylex (void)
return yylval.type = SER;
}
//test for number
- if(c == '.' || isdigit(c)) {
+ if(c > 31 &&(c == '.' || isdigit(c))) {
for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) == '.' || isdigit(c)); buff_pos++) {
tmp_txt[i++] = (char)c;
if(i && buffer[buff_pos+1] == 'e' && (buffer[buff_pos+2] == '-' || buffer[buff_pos+2] == '+')){
@@ -1844,8 +2112,8 @@ static int yylex (void)
return yylval.type = NUM;
}
//test for name or stringtoken
- if(isalpha(c) || c=='$') {
- for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) && (isalnum(c) || c == '$')); buff_pos++) {
+ if(c > 31 && (isalpha(c) || c=='$')) {
+ for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) && c > 31 && (isalnum(c) || c == '$')); buff_pos++) {
tmp_txt[i++] = (char)c;
}
tmp_txt[i] = 0;
@@ -1906,6 +2174,13 @@ static int yylex (void)
pop_syntax();
break;
case '(':
+ if(syntax_level->last_tok == WHILE){
+ if(block = copy_block()) {
+ yylval.text = PushString(block);
+ free(block);
+ }
+ return yylval.type = PBLOCK;
+ }
push_syntax();
case '?':
if(syntax_level) syntax_level->last_tok = c;
@@ -1932,6 +2207,7 @@ static int yylex (void)
buff_pos++; return tok;
}
//Any other character is a token by itself
+ if(c < 0 || c > 127)yytokenerr(c);
return c;
}
@@ -1958,7 +2234,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
push_parser();
init_table();
if(param) {
- length = strlen(param);
+ length = (int)strlen(param);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return false;
@@ -1970,7 +2246,7 @@ bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOIN
}while(buff_pos < length);
free(buffer); buffer = 0L;
}
- length = strlen(expr);
+ length = (int)strlen(expr);
buffer = expr; sx = putsym(hn_x, h2_x, VAR);
for(x = x1; step > 0.0 ? x <= x2 : x >= x2; x += step) {
if(sx){
@@ -2017,7 +2293,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
push_parser();
init_table();
if(param) {
- length = strlen(param);
+ length = (int)strlen(param);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return false;
@@ -2029,7 +2305,7 @@ bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double
}while(buff_pos < length);
free(buffer); buffer = 0L;
}
- length = strlen(expr); buffer = expr;
+ length = (int)strlen(expr); buffer = expr;
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);
@@ -2073,7 +2349,7 @@ anyResult *do_formula(DataObj *d, char *expr)
return &ret;
}
push_parser(); //make code reentrant
- init_table(); length = strlen(expr);
+ init_table(); length = (int)strlen(expr);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return &ret;
@@ -2099,20 +2375,21 @@ anyResult *do_formula(DataObj *d, char *expr)
bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
{
- int length, tok, pos, i;
+ int length, length2, tok, pos, i;
char *res, desc1[2], desc2[2];
if(d) curr_data = d;
if(!curr_data || !of || !nf) return false;
push_parser(); //make code reentrant
- init_table(); length = strlen(of);
+ init_table(); length = (int)strlen(of);
if(!(buffer = (char*)malloc(length+2))){
pop_parser();
return false;
}
strcpy(buffer, of); buffer[length++] = ';';
buffer[length] = 0; buff_pos = pos = 0;
- res = (char *)calloc(length*2+10, sizeof(char));
+ if(!(res = (char *)calloc(length2 = (length*2+10), sizeof(char))))return false;
+ length2--;
do {
tok = yylex ();
if(tok && tok < 256) {
@@ -2121,97 +2398,121 @@ bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0)
}
else switch(tok) {
case NUM:
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, 20, "%g", yylval.val);
+#else
pos += sprintf(res+pos, "%g", yylval.val);
+#endif
break;
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);
+ case YYFNC2: case YYFNC3:
+ pos += rlp_strcpy(res+pos, length2-pos, curr_sym->name);
break;
case COLR: case COLC:
- pos += sprintf(res+pos, ":");
+ res[pos++] = ':';
break;
case PSEP:
- pos += sprintf(res+pos, ";");
+ res[pos++] = ';';
break;
case CLVAL:
- pos += sprintf(res+pos, "$$");
+ res[pos++] = '$'; res[pos++] = '$';
break;
case CLAUSE:
- pos += sprintf(res+pos, " where ");
+ pos += rlp_strcpy(res+pos, length2-pos, " where ");
break;
case VAR:
curr_sym->InitSS();
if(curr_sym->col >= 0 && curr_sym->row >= 0) {
desc1[0] = desc1[1] = desc2[0] = desc2[1] = 0;
- for(i=strlen(curr_sym->name)-1; i>0 && isdigit(curr_sym->name[i]); i--);
+ for(i=(int)strlen(curr_sym->name)-1; i>0 && isdigit(curr_sym->name[i]); i--);
if(curr_sym->name[0] == '$') desc1[0] = '$';
if(curr_sym->name[i] == '$') desc2[0] = '$';
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, length2-pos, "%s%s%s%d", desc1,
+#else
pos += sprintf(res+pos, "%s%s%s%d", desc1,
+#endif
Int2ColLabel(desc1[0] || curr_sym->col < c0 ? curr_sym->col : curr_sym->col+dx >=0 ?
curr_sym->col+dx > c0 ? curr_sym->col+dx : c0 : 0, false),
desc2, desc2[0] || curr_sym->row < r0 ? curr_sym->row+1 : curr_sym->row + dy >= 0 ?
curr_sym->row+dy > r0 ? curr_sym->row+1+dy : r0 : 1);
}
- else pos += sprintf(res+pos, "%s ", curr_sym->name);
+ else pos += rlp_strcpy(res+pos, length2-pos, curr_sym->name);
break;
case STR:
pos += sprintf(res+pos, "\"%s\"", yylval.text && yylval.text[0] ? yylval.text : "");
break;
case SER:
- pos += sprintf(res+pos, "..");
+ res[pos++] = '.'; res[pos++] = '.';
break;
case INC:
- pos += sprintf(res+pos, "++");
+ res[pos++] = '+'; res[pos++] = '+';
break;
case DEC:
- pos += sprintf(res+pos, "--");
+ res[pos++] = '-'; res[pos++] = '-';
break;
case PI:
- pos += sprintf(res+pos, "pi");
+ res[pos++] = 'p'; res[pos++] = 'i';
break;
case E:
- pos += sprintf(res+pos, "e");
+ res[pos++] = 'e';
break;
case BTRUE:
- pos += sprintf(res+pos, "true");
+ pos += rlp_strcpy(res+pos, length2-pos, "true");
break;
case BFALSE:
- pos += sprintf(res+pos, "false");
+ pos += rlp_strcpy(res+pos, length2-pos, "false");
break;
case AND:
- pos += sprintf(res+pos, " && ");
+ pos += rlp_strcpy(res+pos, length2-pos, " && ");
break;
case OR:
- pos += sprintf(res+pos, " || ");
+ pos += rlp_strcpy(res+pos, length2-pos, " || ");
break;
case EQ:
- pos += sprintf(res+pos, " == ");
+ pos += rlp_strcpy(res+pos, length2-pos, " == ");
break;
case NE:
- pos += sprintf(res+pos, " != ");
+ pos += rlp_strcpy(res+pos, length2-pos, " != ");
break;
case GT:
- pos += sprintf(res+pos, ">");
+ res[pos++] = '>';
break;
case GE:
- pos += sprintf(res+pos, ">=");
+ res[pos++] = '>'; res[pos++] = '=';
break;
case LT:
- pos += sprintf(res+pos, "<");
+ res[pos++] = '<';
break;
case LE:
- pos += sprintf(res+pos, "<=");
+ res[pos++] = '<'; res[pos++] = '=';
break;
case IF:
- pos += sprintf(res+pos, "if");
+ res[pos++] = 'i'; res[pos++] = 'f';
+ break;
+ case WHILE:
+ pos += rlp_strcpy(res+pos, length2-pos, "while");
break;
case ELSE:
- pos += sprintf(res+pos, "else");
+ pos += rlp_strcpy(res+pos, length2-pos, "else");
break;
case BLOCK:
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, TMP_TXT_SIZE-pos, "{%s}", yylval.text && yylval.text[0] ? yylval.text : "");
+#else
pos += sprintf(res+pos, "{%s}", yylval.text && yylval.text[0] ? yylval.text : "");
+#endif
+ break;
+ case PBLOCK:
+#ifdef USE_WIN_SECURE
+ pos += sprintf_s(res+pos, TMP_TXT_SIZE-pos, "(%s)", yylval.text && yylval.text[0] ? yylval.text : "");
+#else
+ pos += sprintf(res+pos, "(%s)", yylval.text && yylval.text[0] ? yylval.text : "");
+#endif
break;
}
+ res[pos] = 0;
}while(buff_pos < length);
while((res[pos-1] == ';' || res[pos-1] == ' ') && pos > 0) { res[pos-1] = 0; pos--;}
strcpy(nf, res); free(res);
@@ -2238,7 +2539,7 @@ static void fcurve(double x, double z, double **a, double *y, double dyda[], int
//calc result
symx->SetValue(x); symz->SetValue(z);
buffer = txt_formula;
- buff_pos = 0; length = strlen(txt_formula);
+ buff_pos = 0; length = (int)strlen(txt_formula);
do { yyparse(); }while(buff_pos < length);
if(sy = getsym(hn_y, h2_y)) *y = sy->GetValue();
else *y = line_res.value;
@@ -2323,7 +2624,7 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
}
//common initialization for parser tasks
push_parser(); //make code reentrant
- init_table(); length = strlen(*par);
+ init_table(); length = (int)strlen(*par);
//process parameters
if(!(buffer = (char*)malloc(length+2))){
clear_table(); pop_parser();
@@ -2372,10 +2673,11 @@ int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
l += sprintf(tmp_txt+j, "%s%s=%g;", j && k ? " " : "", parsym[i]->name, parsym[i]->GetValue());
j += l; k += l;
}
- free(*par); *par = strdup(tmp_txt);
+ free(*par);
+ *par = (char*)memdup(tmp_txt, (int)strlen(tmp_txt)+1, 0);
if(chi_2) *chi_2 = chisq;
//write back spreadsheet data if necessary
- buffer = *par; length = strlen(buffer);
+ buffer = *par; length = (int)strlen(buffer);
do {
yyparse();
}while(buff_pos < length);
@@ -2394,11 +2696,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/no_gui.cpp b/no_gui.cpp
index 5199654..eee8d1d 100755
--- a/no_gui.cpp
+++ b/no_gui.cpp
@@ -130,7 +130,7 @@ FrmRect::SetColor(int select, DWORD col)
return false;
}
-void
+void
FrmRect::DoMark(anyOutput *o, bool mark)
{
}
@@ -172,7 +172,7 @@ bool GetPaper(double *w, double *h)
*w = *h = 1.0;
return true;
}
-
+
bool Symbol::PropertyDlg()
{
return false;
@@ -218,7 +218,7 @@ bool Arrow::PropertyDlg()
return false;
}
-void *
+void *
Arrow::ObjThere(int x, int y)
{
return 0L;
@@ -279,19 +279,29 @@ bool Label::PropertyDlg()
return false;
}
-void
-Label::ShowCursor(anyOutput *o)
+void Label::ShowCursor(anyOutput *o)
{
}
-bool
-Label::AddChar(int ci, anyOutput *o)
+bool Label::AddChar(int ci, anyOutput *o)
{
return true;
}
-void
-Label::CalcCursorPos(int x, int y, anyOutput *o)
+void Label::CalcCursorPos(int x, int y, anyOutput *o)
+{
+}
+
+bool TextFrame::PropertyDlg()
+{
+ return false;
+}
+
+void TextFrame::ShowCursor(anyOutput *o)
+{
+}
+
+void TextFrame::CalcCursorPos(int x, int y, anyOutput *o)
{
}
@@ -547,4 +557,4 @@ bool DelBitmapClass(anyOutput *w)
{
return false;
}
-
+
diff --git a/reports.cpp b/reports.cpp
index bff14c5..ab73a4d 100755
--- a/reports.cpp
+++ b/reports.cpp
@@ -18,25 +18,30 @@
//
// Create statistical reports
//
-
+
#include "rlplot.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
+#include <ctype.h>
#include "TheDialog.h"
extern char TmpTxt[];
extern Default defs;
+extern GraphObj *LastOpenGO;
+
+#define _PREC 1.0e-12
//prototypes: WinSpec.cpp
void *CreateDlgWnd(char *title, int x, int y, int width, int height, tag_DlgObj *d, DWORD flags);
-static int curr_id;
+static int curr_id, cbSymLineStr;
static fRECT dBounds;
static TextDEF txtdef1, txtdef2;
static double linsp1, linsp2;
+static char SymLineStr[40];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// init report variables
@@ -59,46 +64,61 @@ static void rep_init()
#ifdef _WINDOWS
linsp1 = txtdef1.fSize*1.2; linsp2 = txtdef1.fSize*1.5;
#else
- linsp1 = txtdef1.fSize*1.5; linsp2 = txtdef1.fSize*2.0;
+ linsp1 = txtdef1.fSize*1.7; linsp2 = txtdef1.fSize*2.5;
+#endif
+#ifdef USE_WIN_SECURE
+ cbSymLineStr = sprintf_s(SymLineStr, 40, "Line= %g 1 0x0 0x0\n", defs.GetSize(SIZE_SYM_LINE));
+#else
+ cbSymLineStr = sprintf(SymLineStr, "Line= %g 1 0x0 0x0\n", defs.GetSize(SIZE_SYM_LINE));
#endif
-
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// utility to add a line to a text buffer
+// create a text label for a report
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-static void add_to_buff(char** dest, int *pos, int *csize, char *txt)
+static char* mk_label(double x, double y, bool moveable, int align, TextDEF *td, char*text)
{
- int len;
+ int csize, pos = 0;
+ char *res;
- len = strlen(txt);
- if((*pos+len+1)>= *csize) {
- *dest = (char*)realloc(*dest, *csize += 1000);
- }
- if(*dest) {
- *pos += sprintf(*dest+*pos, "%s", txt);
- }
+ if(!(res = (char*)malloc(csize = 1000)))return 0L;
+ res[pos++] = '\n'; res[pos++] = '[';
+ add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=Label]\nPos=", 12);
+ add_dbl_to_buff(&res, &pos, &csize, x, true);
+ add_dbl_to_buff(&res, &pos, &csize, y, true);
+ res[pos++] = '\n';
+ if(moveable) add_to_buff(&res, &pos, &csize, "moveable= 1\n", 12);
+ add_to_buff(&res, &pos, &csize, "TxtDef= 0x0 0x00ffffff", 22);
+ add_dbl_to_buff(&res, &pos, &csize, td->fSize, true);
+ add_dbl_to_buff(&res, &pos, &csize, td->RotBL, true);
+ add_dbl_to_buff(&res, &pos, &csize, td->RotCHAR, true);
+ add_int_to_buff(&res, &pos, &csize, align, true, 0);
+ add_to_buff(&res, &pos, &csize, " 1 0 0 \"", 8);
+ add_to_buff(&res, &pos, &csize, text, 0);
+ add_to_buff(&res, &pos, &csize, "\"\n", 2);
+ return res;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// create a text label for a report
+// print values to string
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-static char* mk_label(double x, double y, bool moveable, int align, TextDEF *td, char*text)
+static int dbl_to_str1(char *dest, int size, char* fmt, double val)
{
- int csize, pos = 0;
- char *res, line[120];
+#ifdef USE_WIN_SECURE
+ return sprintf_s(dest, size, fmt, val);
+#else
+ return sprintf(dest, fmt, val);
+#endif
+}
- if(!(res = (char*)malloc(csize = 1000)))return 0L;
- sprintf(line, "\n[%d=Label]\nPos= %g %g\n", curr_id++, x, y);
- add_to_buff(&res, &pos, &csize, line);
- if(moveable) {
- sprintf(line, "moveable= 1\n");
- add_to_buff(&res, &pos, &csize, line);
- }
- sprintf(line, "TxtDef= 0x00000000 0x00ffffff %g %g %g %d 1 0 0 \"%s\"\n",
- td->fSize, td->RotBL, td->RotCHAR, align, text);
- add_to_buff(&res, &pos, &csize, line);
- return res;
+static int dbl_to_str2(char *dest, int size, char* fmt, double val1, double val2)
+{
+#ifdef USE_WIN_SECURE
+ return sprintf_s(dest, size, fmt, val1, val2);
+#else
+ return sprintf(dest, fmt, val1, val2);
+#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -109,6 +129,7 @@ static void mk_header(Page *page, char* desc)
time_t ti = time(0L);
char *txt_obj, label[80];
double rpos;
+ int cb;
if(!page) return;
rpos = page->GetSize(SIZE_GRECT_RIGHT) - txtdef1.fSize*5.0;
@@ -117,12 +138,19 @@ static void mk_header(Page *page, char* desc)
OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
free(txt_obj);
}
+#ifdef USE_WIN_SECURE
+ ctime_s(label, 32, &ti);
+#else
+ rlp_strcpy(label, 25, ctime(&ti));
+#endif
+ label[24] = 0;
if(txt_obj = mk_label(rpos, page->GetSize(SIZE_GRECT_TOP)+txtdef1.fSize*5.0,
- false, TXA_HRIGHT, &txtdef1, ctime(&ti))) {
+ false, TXA_HRIGHT, &txtdef1, label)) {
OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
free(txt_obj);
}
- sprintf(label, "RLPlot %s", SZ_VERSION);
+ cb = rlp_strcpy(label, 80, "RLPlot ");
+ cb += rlp_strcpy(label+cb, 80-cb, SZ_VERSION);
if(txt_obj = mk_label(rpos, page->GetSize(SIZE_GRECT_BOTTOM)-txtdef1.fSize*6.0,
false, TXA_HRIGHT, &txtdef1, label)) {
OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
@@ -136,18 +164,96 @@ static void mk_header(Page *page, char* desc)
static void mk_hr(GraphObj *parent, double x1, double x2, double y)
{
int csize, pos = 0;
- char *res, line[120];
+ char *res;
- if(!(res = (char*)malloc(csize = 1000)))return;
- sprintf(line, "\n[%d=polyline]\nData=(2){ %g %g %g %g}\n", curr_id++, x1, y, x2, y);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Line= %g %g 0x0 0x0\n", txtdef1.fSize/20.0, txtdef1.fSize);
- add_to_buff(&res, &pos, &csize, line);
+ if(!(res = (char*)malloc(csize = 100)))return;
+ res[pos++] = '\n'; res[pos++] = '[';
+ add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=polyline]\nData= (2){", 21);
+ add_dbl_to_buff(&res, &pos, &csize, x1, false);
+ add_dbl_to_buff(&res, &pos, &csize, y, true);
+ add_dbl_to_buff(&res, &pos, &csize, x2, true);
+ add_dbl_to_buff(&res, &pos, &csize, y, true);
+ add_to_buff(&res, &pos, &csize, "}\nLine=", 7);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.fSize/20.0, true);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.fSize, true);
+ add_to_buff(&res, &pos, &csize, " 0x0 0x0\n", 9);
OpenGraph(parent, 0L, (unsigned char*)res, false);
free(res);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// create a means report
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static double mk_mean_report(GraphObj *parent, double x, double y, double *da, int n, double ci, char *name)
+{
+ static char *mean_fmts[] = {"Mean = %g", "Std.Dev. = %g", "N = %g", "Std.Err. = %g", 0L,
+ "Kurtosis = %g", "Skewness = %g"};
+ char *txt_obj, desc[80];
+ int i, cb;
+ double v, t, res[10];
+
+ cb = rlp_strcpy(desc, 20, "<b>"); cb += rlp_strcpy(desc+cb, 20-cb, name);
+ cb += rlp_strcpy(desc+cb, 20-cb, ":</b>");
+ if(txt_obj = mk_label(x, y, false, TXA_HLEFT, &txtdef1, desc)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); y += linsp1;
+ }
+ x += (txtdef1.fSize*3.0);
+ cb = dbl_to_str1(desc, 80, "%g%%%% C.I. = %%g", ci*100.0);
+ mean_fmts[4] = (char*)malloc(cb+2);
+ rlp_strcpy(mean_fmts[4], cb+1, desc); t = distinv(t_dist, n-1, 1, 1.0-ci, 2.0);
+ v = d_variance(n, da, &res[0], 0L); res[2] = (double)n;
+ res[1] = sqrt(v); res[3] = res[1] / sqrt(res[2]);
+ res[4] = res[3] *t; res[5] = d_kurt(n, da);
+ res[6] = d_skew(n, da);
+ for(i = 0; i < 7; i++) {
+ dbl_to_str1(desc, 80, mean_fmts[i], res[i]);
+ if(txt_obj = mk_label(x, y, false, TXA_HLEFT, &txtdef1, desc)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); y += linsp1/1.2;
+ }
+ if(i == 2) y += linsp1/3.6;
+ }
+ free(mean_fmts[4]); mean_fmts[4] = 0L;
+ return y;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// create a median report
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static double mk_median_report(GraphObj *parent, double x, double y, double *da, int n, double ci, char *name)
+{
+ static char *mean_fmts[] = {"Median = %g", "25%% = %g", "75%% = %g", "N = %g", "Min. = %g", "Max. = %g" };
+ char *txt_obj, desc[80];
+ int i, cb;
+ double res[6];
+
+ if(!da || !parent || !n) return y;
+ cb = rlp_strcpy(desc, 20, "<b>"); cb += rlp_strcpy(desc+cb, 20-cb, name);
+ cb += rlp_strcpy(desc+cb, 20-cb, ":</b>");
+ if(txt_obj = mk_label(x, y, false, TXA_HLEFT, &txtdef1, desc)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); y += linsp1;
+ }
+ x += (txtdef1.fSize*3.0);
+ d_quartile(n, da, &res[1], &res[0], &res[2]);
+ res[4] = res[5] = *da;
+ for(i = 1; i < n; i++) {
+ if(da[i] > res[5]) res[5] = da[i]; if(da[i] < res[4]) res[4] = da[i];
+ }
+ res[3] = (double)n;
+ for(i = 0; i < 6; i++) {
+ dbl_to_str1(desc, 80, mean_fmts[i], res[i]);
+ if(txt_obj = mk_label(x, y, false, TXA_HLEFT, &txtdef1, desc)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); y += linsp1/1.2;
+ }
+ }
+ return y;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// create report table for anova ...
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static void mk_table(GraphObj *parent, double x, double y, int type, double **dda)
@@ -157,15 +263,20 @@ static void mk_table(GraphObj *parent, double x, double y, int type, double **dd
(char*)"Among groups", type == 2 ? (char*)"Unexplained":(char*)"Within groups", "Total"};
char *cfmt[8];
int i, j, nl, nc[8];
- double posc[8];
+ double posc[8], cinc;
char *txt_obj;
+#ifdef _WINDOWS
+ cinc = txtdef1.fSize;
+#else
+ cinc = txtdef1.fSize *1.3;
+#endif
switch(type) {
case 1: case 2:
nl = 3; nc[0] = 5; nc[1] = 3; nc[2] = 2;
- posc[0] = x + txtdef1.fSize*14.0; posc[1] = posc[0] + txtdef1.fSize*5.0;
- posc[2] = posc[1] + txtdef1.fSize*6.0; posc[3] = posc[2] + txtdef1.fSize*6.0;
- posc[4] = posc[3] + txtdef1.fSize*6.0; cfmt[0] = "%.0lf";
+ posc[0] = x + cinc*14.0; posc[1] = posc[0] + cinc*5.0;
+ posc[2] = posc[1] + cinc*6.0; posc[3] = posc[2] + cinc*6.0;
+ posc[4] = posc[3] + cinc*6.0; cfmt[0] = "%.0lf";
cfmt[1] = GetNumFormat(floor(log10(dda[2][1])-3.0));
cfmt[2] = GetNumFormat(floor(log10(dda[0][2]+dda[0][1])-3.0));
cfmt[3] = "%0.3lf"; cfmt[4] = "%0.4lf";
@@ -185,7 +296,7 @@ static void mk_table(GraphObj *parent, double x, double y, int type, double **dd
if(i) posc[i] += linsp1;
}
mk_hr(parent, x, posc[4], y + linsp1);
- y += (txtdef1.fSize *1.5);
+ y += linsp2;
}
for(i = 0; i < nl; i++) {
if(txt_obj = mk_label(x, y, false, TXA_HLEFT, &txtdef1, rheaders[i+1])) {
@@ -194,8 +305,12 @@ static void mk_table(GraphObj *parent, double x, double y, int type, double **dd
}
for(j = 0; j < nc[i]; j++) {
if(j == 4 && dda[i][j] > 0.0 && dda[i][j] < 0.0001)
- strcpy(TmpTxt, "< 0.0001");
+ rlp_strcpy(TmpTxt, 10, "< 0.0001");
+#ifdef USE_WIN_SECURE
+ else sprintf_s(TmpTxt, 20, cfmt[j], dda[i][j]);
+#else
else sprintf(TmpTxt, cfmt[j], dda[i][j]);
+#endif
if(txt_obj = mk_label(posc[j], y, false, TXA_HRIGHT, &txtdef1, TmpTxt)) {
OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
free(txt_obj);
@@ -210,81 +325,211 @@ static void mk_table(GraphObj *parent, double x, double y, int type, double **dd
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// create a boxplot for a report
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char* mk_boxplot(double *x, double *y, double *by1, double *by2, double *wy1, double *wy2, int *ny, int n,
+ char *s_nam, char *b_nam, char *w_nam)
+{
+ int i, csize, pos, first_s, first_b, first_w, first_l;
+ char *res;
+ double size;
+
+ if(!(res = (char*)malloc(csize = 2000)))return 0L;
+ if(n < 20) size = defs.GetSize(SIZE_SYMBOL);
+ else size = defs.GetSize(SIZE_SYMBOL)/2.0 + 20.0 * defs.GetSize(SIZE_SYMBOL)/(2.0 * n);
+ first_b = curr_id;
+ for(i = pos = 0; i < n && res; i++) {
+ add_to_buff(&res, &pos, &csize, "\n[", 2); add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=Box]\nType= 256\nHigh=", 21);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, by2[i], true);
+ add_to_buff(&res, &pos, &csize,"\nLow=", 5);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, by1[i], true);
+ add_to_buff(&res, &pos, &csize,"\nSize= 60\n", 10);
+ add_to_buff(&res, &pos, &csize, "\nName= \"", 8);
+ add_to_buff(&res, &pos, &csize, b_nam, 0);
+ add_to_buff(&res, &pos, &csize, "\"\n", 2);
+ }
+ first_w = curr_id;
+ for(i = 0; i < n && res; i++) {
+ add_to_buff(&res, &pos, &csize, "\n[", 2); add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=Whisker]\nHigh=", 15);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, wy2[i], true);
+ add_to_buff(&res, &pos, &csize,"\nLow=", 5);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, wy1[i], true);
+ add_to_buff(&res, &pos, &csize, "\nDesc= \"", 8);
+ add_to_buff(&res, &pos, &csize, w_nam, 0);
+ add_to_buff(&res, &pos, &csize, "\"\n", 2);
+ }
+ first_s = curr_id;
+ for(i = 0; i < n && res; i++) {
+ add_to_buff(&res, &pos, &csize, "\n[", 2); add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=Symbol]\nType= 10\nPos=", 22);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, y[i], true);
+ add_to_buff(&res, &pos, &csize, "\nSize=", 6); add_dbl_to_buff(&res, &pos, &csize, size, true);
+ add_to_buff(&res, &pos, &csize, "\n", 1);
+ add_to_buff(&res, &pos, &csize, SymLineStr, cbSymLineStr);
+ add_to_buff(&res, &pos, &csize, "FillCol= 0x00ffffff\n", 20);
+ if(s_nam) {
+ add_to_buff(&res, &pos, &csize, "Name=\"", 6);
+ add_to_buff(&res, &pos, &csize, s_nam, 0); add_to_buff(&res, &pos, &csize, "\"\n", 2);
+ }
+ }
+ first_l = curr_id;
+ for(i = 0; i < n && res; i++) {
+ add_to_buff(&res, &pos, &csize, "\n[", 2);
+ add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=Label]\nPos=", 12);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, wy2[i], true);
+ add_to_buff(&res, &pos, &csize, "\nDist= 0", 8);
+ add_dbl_to_buff(&res, &pos, &csize, -txtdef1.fSize/4.0, true);
+ add_to_buff(&res, &pos, &csize, "\nFlags= 0x00000011\nTxtDef= 0x00000000 0x00ffffff", 48);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.fSize, true);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.RotBL, true);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.RotCHAR, true);
+ add_int_to_buff(&res, &pos, &csize, TXA_HCENTER | TXA_VBOTTOM, true, 0);
+ add_to_buff(&res, &pos, &csize, " 1 0 0 \"", 8);
+ if(n < 7) add_to_buff(&res, &pos, &csize, "n = ", 4);
+ add_int_to_buff(&res, &pos, &csize, ny[i], false, 0);
+ add_to_buff(&res, &pos, &csize, "\"\n", 2);
+ }
+ add_to_buff(&res,&pos,&csize, "\n[", 2); add_int_to_buff(&res,&pos,&csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=BoxPlot]\nBounds=", 17);
+ add_dbl_to_buff(&res,&pos,&csize, dBounds.Xmin, true); add_dbl_to_buff(&res,&pos,&csize, dBounds.Ymax, true);
+ add_dbl_to_buff(&res,&pos,&csize, dBounds.Xmax, true); add_dbl_to_buff(&res,&pos,&csize, dBounds.Ymin, true);
+
+ add_to_buff(&res,&pos,&csize, "\nBoxes=(", 0); add_int_to_buff(&res,&pos,&csize, n, false, 0);
+ add_to_buff(&res,&pos,&csize, "){", 2);
+ for(i = 0; i < n; i++, first_b++) {
+ add_int_to_buff(&res,&pos,&csize, first_b, false, 0); add_to_buff(&res,&pos,&csize, ",", 1);
+ if(i && (i%16)== 0 && first_b < (curr_id-2)) add_to_buff(&res, &pos, &csize, "\n ", 4);
+ }
+ while(res[pos-1] == ',' || res[pos-1] < 33) pos --; add_to_buff(&res, &pos, &csize, "}\n", 2);
+ add_to_buff(&res,&pos,&csize, "\nWhiskers=(", 0); add_int_to_buff(&res,&pos,&csize, n, false, 0);
+ add_to_buff(&res,&pos,&csize, "){", 2);
+ for(i = 0; i < n; i++, first_w++) {
+ add_int_to_buff(&res,&pos,&csize, first_w, false, 0); add_to_buff(&res,&pos,&csize, ",", 1);
+ if(i && (i%16)== 0 && first_b < (curr_id-2)) add_to_buff(&res, &pos, &csize, "\n ", 4);
+ }
+ while(res[pos-1] == ',' || res[pos-1] < 33) pos --; add_to_buff(&res, &pos, &csize, "}\n", 2);
+ add_to_buff(&res,&pos,&csize, "\nSymbols=(", 10); add_int_to_buff(&res,&pos,&csize, n, false, 0);
+ add_to_buff(&res,&pos,&csize, "){", 2);
+ for(i = 0; i < n; i++, first_s++) {
+ add_int_to_buff(&res,&pos,&csize, first_s, false, 0); add_to_buff(&res,&pos,&csize, ",", 1);
+ if(i && (i%16)== 0 && first_s < (curr_id-2)) add_to_buff(&res, &pos, &csize, "\n ", 4);
+ }
+ while(res[pos-1] == ',' || res[pos-1] < 33) pos --; add_to_buff(&res, &pos, &csize, "}\n", 2);
+ add_to_buff(&res,&pos,&csize, "\nLabels=(", 9); add_int_to_buff(&res,&pos,&csize, n, false, 0);
+ add_to_buff(&res,&pos,&csize, "){", 2);
+ for(i = 0; i < n; i++, first_l++) {
+ add_int_to_buff(&res,&pos,&csize, first_l, false, 0); add_to_buff(&res,&pos,&csize, ",", 1);
+ if(i && (i%16)== 0 && first_s < (curr_id-2)) add_to_buff(&res, &pos, &csize, "\n ", 4);
+ }
+ while(res[pos-1] == ',' || res[pos-1] < 33) pos --; add_to_buff(&res, &pos, &csize, "}\n", 2);
+ return res;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// create a scatterplot for a report
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-static char* mk_scatt(double *x, double *y, double *ss, int *ny, int n)
+static char* mk_scatt(double *x, double *y, double *ss, int *ny, int n, char *s_nam, char *x_desc, char *y_desc)
{
int i, csize, pos, first;
- char *res, line[80];
+ char *res;
double size, linew, tmp;
- if(!(res = (char*)malloc(csize = 1000)))return 0L;
+ if(!(res = (char*)malloc(csize = 2000)))return 0L;
if(n < 20) size = defs.GetSize(SIZE_SYMBOL);
else size = defs.GetSize(SIZE_SYMBOL)/2.0 + 20.0 * defs.GetSize(SIZE_SYMBOL)/(2.0 * n);
linew = defs.GetSize(SIZE_SYM_LINE);
first = curr_id;
for(i = pos = 0; i < n && res; i++) {
- sprintf(line, "\n[%d=Symbol]\nPos= %g %g\n", curr_id++, x ? x[i] : (double)(i+1), y[i]);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Size= %g\n", size);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Line= %g 1 0x0 0x0\nFillCol= 0x00ffffff\n", linew);
- add_to_buff(&res, &pos, &csize, line);
+ add_to_buff(&res, &pos, &csize, "\n[", 2); add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=Symbol]\nPos=", 13);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, y[i], true);
+ add_to_buff(&res, &pos, &csize, "\nSize=", 6); add_dbl_to_buff(&res, &pos, &csize, size, true);
+ add_to_buff(&res, &pos, &csize, "\n", 1);
+ add_to_buff(&res, &pos, &csize, SymLineStr, cbSymLineStr);
+ add_to_buff(&res, &pos, &csize, "FillCol= 0x00ffffff\n", 20);
+ if(s_nam) {
+ add_to_buff(&res, &pos, &csize, "Name=\"", 6);
+ add_to_buff(&res, &pos, &csize, s_nam, 0); add_to_buff(&res, &pos, &csize, "\"\n", 2);
+ }
}
if(ss && ny) {
for(i = 0; i < n && res; i++) {
if(ny[i] > 1) tmp = sqrt(ss[i]/(ny[i]-1));
else tmp = 0.0;
- sprintf(line, "\n[%d=ErrorBar]\nPos= %g %g\n", curr_id++, x ? x[i] : (double)(i+1), y[i]);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Err= %g\nDesc= \"Std. Dev.\"\n", tmp);
- add_to_buff(&res, &pos, &csize, line);
+ add_to_buff(&res, &pos, &csize, "\n[", 2);
+ add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=ErrorBar]\nPos=", 15);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, y[i], true);
+ add_to_buff(&res, &pos, &csize, "\nErr=", 5);
+ add_dbl_to_buff(&res, &pos, &csize, tmp, true);
+ add_to_buff(&res, &pos, &csize, "\nDesc= \"Std. Dev.\"\n", 19);
}
for(i = 0; i < n && res; i++) {
if(ny[i] > 1) tmp = sqrt(ss[i]/(ny[i]-1));
else tmp = 0.0;
- sprintf(line, "\n[%d=Label]\nPos= %g %g\n", curr_id++, x ? x[i]:(double)(i+1), y[i] +tmp);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Dist= 0 %g\nFlags= 0x00000011\n", -txtdef1.fSize/4.0);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "TxtDef= 0x00000000 0x00ffffff %g %g %g %d 1 0 0 \"%s%d\"\n",
- txtdef1.fSize, txtdef1.RotBL, txtdef1.RotCHAR, TXA_HCENTER | TXA_VBOTTOM,
- n > 6 ? "" : "n = ", ny[i]);
- add_to_buff(&res, &pos, &csize, line);
+ add_to_buff(&res, &pos, &csize, "\n[", 2);
+ add_int_to_buff(&res, &pos, &csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=Label]\nPos=", 12);
+ add_dbl_to_buff(&res, &pos, &csize, x ? x[i] : (double)(i+1), true);
+ add_dbl_to_buff(&res, &pos, &csize, y[i] +tmp, true);
+ add_to_buff(&res, &pos, &csize, "\nDist= 0", 8);
+ add_dbl_to_buff(&res, &pos, &csize, -txtdef1.fSize/4.0, true);
+ add_to_buff(&res, &pos, &csize, "\nFlags= 0x00000011\nTxtDef= 0x00000000 0x00ffffff", 48);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.fSize, true);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.RotBL, true);
+ add_dbl_to_buff(&res, &pos, &csize, txtdef1.RotCHAR, true);
+ add_int_to_buff(&res, &pos, &csize, TXA_HCENTER | TXA_VBOTTOM, true, 0);
+ add_to_buff(&res, &pos, &csize, " 1 0 0 \"", 8);
+ if(n < 7) add_to_buff(&res, &pos, &csize, "n = ", 4);
+ add_int_to_buff(&res, &pos, &csize, ny[i], false, 0);
+ add_to_buff(&res, &pos, &csize, "\"\n", 2);
}
}
- sprintf(line, "\n[%d=PlotScatt]\n", curr_id++);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Bounds= %g %g %g %g\n", dBounds.Xmin, dBounds.Ymax, dBounds.Xmax, dBounds.Ymin);
- add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Symbols=(%d){", n); add_to_buff(&res, &pos, &csize, line);
+ add_to_buff(&res,&pos,&csize, "\n[", 2); add_int_to_buff(&res,&pos,&csize, curr_id++, false, 0);
+ add_to_buff(&res, &pos, &csize, "=PlotScatt]\nBounds=", 19);
+ add_dbl_to_buff(&res,&pos,&csize, dBounds.Xmin, true); add_dbl_to_buff(&res,&pos,&csize, dBounds.Ymax, true);
+ add_dbl_to_buff(&res,&pos,&csize, dBounds.Xmax, true); add_dbl_to_buff(&res,&pos,&csize, dBounds.Ymin, true);
+ add_to_buff(&res,&pos,&csize, "\nSymbols=(", 10); add_int_to_buff(&res,&pos,&csize, n, false, 0);
+ add_to_buff(&res,&pos,&csize, "){", 2);
for(i = 0; i < n; i++, first++) {
- sprintf(line, "%s%d", i ? "," : "", first);
- add_to_buff(&res, &pos, &csize, line);
- if(i && (i%16) && first < (curr_id-2)) {
- sprintf(line, "\n "); add_to_buff(&res, &pos, &csize, line);
- }
+ add_int_to_buff(&res,&pos,&csize, first, false,0); add_to_buff(&res,&pos,&csize, ",", 1);
+ if(i && (i%16)== 0 && first < (curr_id-2)) add_to_buff(&res, &pos, &csize, "\n ", 4);
}
- sprintf(line, "}\n"); add_to_buff(&res, &pos, &csize, line);
+ while(res[pos-1] == ',' || res[pos-1] < 33) pos --; add_to_buff(&res, &pos, &csize, "}\n", 2);
if(ss && ny) {
- sprintf(line, "ErrBars=(%d){", n); add_to_buff(&res, &pos, &csize, line);
+ add_to_buff(&res,&pos,&csize, "ErrBars=(", 9); add_int_to_buff(&res,&pos,&csize, n, false, 0);
+ add_to_buff(&res,&pos,&csize, "){", 2);
for(i = 0; i < n; i++, first++) {
- sprintf(line, "%s%d", i ? "," : "", first);
- add_to_buff(&res, &pos, &csize, line);
- if(i && (i%16) && first < (curr_id-2)) {
- sprintf(line, "\n "); add_to_buff(&res, &pos, &csize, line);
- }
+ add_int_to_buff(&res,&pos,&csize, first,false,0); add_to_buff(&res,&pos,&csize, ",", 1);
+ if(i && (i%16)== 0 && first < (curr_id-2)) add_to_buff(&res, &pos, &csize, "\n ", 4);
}
- sprintf(line, "}\n"); add_to_buff(&res, &pos, &csize, line);
- sprintf(line, "Labels=(%d){", n); add_to_buff(&res, &pos, &csize, line);
+ while(res[pos-1] == ',' || res[pos-1] < 33) pos --; add_to_buff(&res, &pos, &csize, "}\n", 2);
+ add_to_buff(&res,&pos,&csize, "Labels=(", 8); add_int_to_buff(&res,&pos,&csize, n, false, 0);
+ add_to_buff(&res,&pos,&csize, "){", 2);
for(i = 0; i < n; i++, first++) {
- sprintf(line, "%s%d", i ? "," : "", first);
- add_to_buff(&res, &pos, &csize, line);
- if(i && (i%16) && first < (curr_id-2)) {
- sprintf(line, "\n "); add_to_buff(&res, &pos, &csize, line);
- }
+ add_int_to_buff(&res,&pos,&csize, first,false,0); add_to_buff(&res,&pos,&csize, ",", 1);
+ if(i && (i%16)== 0 && first < (curr_id-2)) add_to_buff(&res, &pos, &csize, "\n ", 4);
}
- sprintf(line, "}\n"); add_to_buff(&res, &pos, &csize, line);
+ while(res[pos-1] == ',' || res[pos-1] < 33) pos --; add_to_buff(&res, &pos, &csize, "}\n", 2);
+ }
+ if(x_desc && x_desc[0]){
+ add_to_buff(&res,&pos,&csize, "x_info= \"", 9); add_to_buff(&res,&pos,&csize, x_desc, 0);
+ add_to_buff(&res,&pos,&csize, "\"\n", 2);
+ }
+ if(y_desc && y_desc[0]){
+ add_to_buff(&res,&pos,&csize, "y_info= \"", 9); add_to_buff(&res,&pos,&csize, y_desc, 0);
+ add_to_buff(&res,&pos,&csize, "\"\n", 2);
}
return res;
}
@@ -323,16 +568,18 @@ rep_anova(GraphObj *parent, DataObj *data)
if(!parent || !data) return;
if(!(AnovaDlg = CompileDialog(AnovaDlg_Tmpl, dyndata))) return;
- if(data->Command(CMD_GETMARK, &mrk, 0L)) {
- strcpy(TmpTxt, mrk);
- }
+ if(data->Command(CMD_GETMARK, &mrk, 0L))rlp_strcpy(TmpTxt, TMP_TXT_SIZE, mrk);
else {
data->ValueRec(&rec);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "%s%d", Int2ColLabel(rec.left,false), rec.top + 1);
+ sprintf_s(TmpTxt+i, TMP_TXT_SIZE-i, ":%s%d", Int2ColLabel(rec.right, false), rec.bottom+1);
+#else
i = sprintf(TmpTxt,"%s%d", Int2ColLabel(rec.left,false), rec.top + 1);
sprintf(TmpTxt+i, ":%s%d", Int2ColLabel(rec.right, false), rec.bottom+1);
+#endif
}
- if(!(Dlg = new DlgRoot(AnovaDlg)))return;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(AnovaDlg, data)))return;
hDlg = CreateDlgWnd("One Way Anova", 50, 50, 420, 220, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -347,7 +594,7 @@ rep_anova(GraphObj *parent, DataObj *data)
break;
}
}while (res < 0);
- if(res == 1 && Dlg->GetText(101, TmpTxt) &&(rD = new AccRange(TmpTxt))
+ if(res == 1 && Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE) &&(rD = new AccRange(TmpTxt))
&& rD->BoundRec(&rec) && (res_tab = (double**)calloc(3, sizeof(double*)))
&& (res_tab[0] = (double*) malloc(5*sizeof(double)))
&& (res_tab[1] = (double*) malloc(5*sizeof(double)))
@@ -370,7 +617,7 @@ rep_anova(GraphObj *parent, DataObj *data)
for(i = rec.top; i <= rec.bottom; i++) {
ncols[i-rec.top] = 0; cols[i-rec.top] = (double*)malloc(nr * sizeof(double));
if(cols[i-rec.top]) for(j = rec.left; j <= rec.right; j++) {
- if(data->GetValue(j, i, &tmp)) cols[i-rec.top][ncols[i-rec.top]++] = tmp;
+ if(data->GetValue(i, j, &tmp)) cols[i-rec.top][ncols[i-rec.top]++] = tmp;
}
}
}
@@ -387,7 +634,7 @@ rep_anova(GraphObj *parent, DataObj *data)
mtot += csums[i]; ntot += ncols[i];
if(ncols[i]) csums[i] /= ((double)ncols[i]);
}
- dBounds.Xmin = 0.0; dBounds.Xmax = nc;
+ dBounds.Xmin = 0.5; dBounds.Xmax = nc;
if(ntot) mtot /= ((double)ntot);
for(i = 0; i < nc; i++) {
for(j = 0, css[i] = 0.0; j < ncols[i]; j++) {
@@ -407,7 +654,7 @@ rep_anova(GraphObj *parent, DataObj *data)
res_tab[0][4] = f_dist(res_tab[0][3], res_tab[0][0], res_tab[1][0]);
page = new Page(parent, data);
mk_header(page, "<b>One Way ANOVA</b>");
- if((graph = new Graph(parent, data, 0L)) && (txt_obj = mk_scatt(0L, csums, css, ncols, nc))){
+ if((graph = new Graph(parent, data, 0L)) && (txt_obj = mk_scatt(0L, csums, css, ncols, nc, "Mean", 0L, "Means <u>+</u> S.D."))){
OpenGraph(graph, 0L, (unsigned char*)txt_obj, false);
free(txt_obj); graph->moveable = 0;
graph->GRect.Xmin += (txtdef1.fSize*5.0); graph->GRect.Xmax += (txtdef1.fSize*5.0);
@@ -434,6 +681,77 @@ rep_anova(GraphObj *parent, DataObj *data)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// linear regression analysis
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static double mk_regr_summary(GraphObj *parent, double x, double y, double *dres, double ci, int n)
+{
+ char *txt_obj;
+ char *fmts[] = {"slope = %g", "intercept = %g", "observations = %g", "r<sup> 2</sup> = %g", "r = %g"};
+ char *ci_fmt = "%g - %g";
+ char lbl[80];
+ double z, s;
+ double x1 = x + txtdef1.fSize*3.0;
+ double x2 = x + txtdef1.fSize*20.0;
+#ifdef _WINDOWS
+ double hrw = txtdef1.fSize*38.0;
+#else
+ double hrw = txtdef1.fSize*1.3*38.0;
+#endif
+
+ if(txt_obj = mk_label(x, y, false, TXA_HLEFT, &txtdef1, "<b>Regression:</b>")) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ dbl_to_str1(lbl, 80, "%g%% C.I.", ci);
+ if(txt_obj = mk_label(x2, y, false, TXA_HCENTER, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ mk_hr(parent, x, x+hrw, y+txtdef1.fSize*1.2);
+ y += linsp1*1.5; dbl_to_str1(lbl, 80, fmts[0], dres[0]);
+ if(txt_obj = mk_label(x1, y, false, TXA_HLEFT, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ dbl_to_str2(lbl, 80, ci_fmt, dres[0]-dres[10], dres[0]+dres[10]);
+ if(txt_obj = mk_label(x2, y, false, TXA_HCENTER, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ y += linsp1; dbl_to_str1(lbl, 80, fmts[1], dres[1]);
+ if(txt_obj = mk_label(x1, y, false, TXA_HLEFT, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ dbl_to_str2(lbl, 80, ci_fmt, dres[1]-dres[11], dres[1]+dres[11]);
+ if(txt_obj = mk_label(x2, y, false, TXA_HCENTER, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ y += linsp1; dbl_to_str1(lbl, 80, fmts[2], (double)n);
+ if(txt_obj = mk_label(x1, y, false, TXA_HLEFT, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ y += linsp1; dbl_to_str1(lbl, 80, fmts[3], dres[12]);
+ if(txt_obj = mk_label(x1, y, false, TXA_HLEFT, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ y += linsp1; dbl_to_str1(lbl, 80, fmts[4], sqrt(dres[12]));
+ if(txt_obj = mk_label(x1, y, false, TXA_HLEFT, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ z = 0.5 * log((1.0+sqrt(dres[12])+_PREC)/(1.0-sqrt(dres[12])+_PREC)); //Fishers z-transform
+ s = distinv(t_dist, 1.0E+10, 1.0, (100-ci)/100.0, 2.0)/sqrt((double)(n-3));
+ dbl_to_str2(lbl, 80, ci_fmt, tanh(z-s), tanh(z+s));
+ if(txt_obj = mk_label(x2, y, false, TXA_HCENTER, &txtdef1, lbl)) {
+ OpenGraph(parent, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+ mk_hr(parent, x, x+hrw, y+txtdef1.fSize*1.2);
+ return y + linsp1*3.0;
+}
+
static char *RegrDlg_Tmpl =
"1,2,,DEFAULT,PUSHBUTTON,-1,148,10,45,12\n"
"2,3,,,PUSHBUTTON,-2,148,25,45,12\n"
@@ -463,18 +781,17 @@ rep_regression(GraphObj *parent, DataObj *data)
int i, n, n1, rx, cx, ry, cy, res, align = 0;
bool bContinue = false, bParZ;
AccRange *rX = 0L, *rY = 0L;
- double *x = 0L, *y = 0L, **res_tab = 0L;
+ double *x = 0L, *y = 0L, **res_tab = 0L, c_x, c_y;
double sx, sy, dx, dy, sxy, sxx, syy, sdy, df, t, ts, ty;
- double dres[10], ly[4], regr_sum[5][3];
- char *txt_obj;
+ double dres[14], ly[4];
+ char *txt_obj, *x_desc=0L, *y_desc=0L;
Graph *graph;
Page *page;
if(!parent || !data) return;
if(!(RegrDlg = CompileDialog(RegrDlg_Tmpl, dyndata))) return;
UseRangeMark(data, 1, TmpTxt, TmpTxt+100);
- if(!(Dlg = new DlgRoot(RegrDlg)))return;
- Dlg->ItemCmd(101, CMD_SET_DATAOBJ, data); Dlg->ItemCmd(103, CMD_SET_DATAOBJ, data);
+ if(!(Dlg = new DlgRoot(RegrDlg, data)))return;
hDlg = CreateDlgWnd("Linear Regression", 50, 50, 420, 260, Dlg, 0x0L);
do {
LoopDlgWnd();
@@ -489,16 +806,16 @@ rep_regression(GraphObj *parent, DataObj *data)
break;
case 1:
Dlg->GetValue(105, &ci); bParZ = Dlg->GetCheck(107);
- if(rX) delete rX; if(rY) delete rY;
+ if(rX) delete rX; if(rY) delete rY;
rX = rY = 0L;
- if(Dlg->GetText(101, TmpTxt)) rX = new AccRange(TmpTxt);
+ if(Dlg->GetText(101, TmpTxt, TMP_TXT_SIZE)) rX = new AccRange(TmpTxt);
n = rX ? rX->CountItems() : 0;
if(!n) {
ErrorBox("range not specified\nor not valid.");
bContinue = true;
res = -1;
}
- if(n && Dlg->GetText(103, TmpTxt) && (rY = new AccRange(TmpTxt))){
+ if(n && Dlg->GetText(103, TmpTxt, TMP_TXT_SIZE) && (rY = new AccRange(TmpTxt))){
if(n != rY->CountItems()) {
ErrorBox("both ranges must be given\nand must have the same size");
bContinue = true;
@@ -514,6 +831,7 @@ rep_regression(GraphObj *parent, DataObj *data)
&& (res_tab[0] = (double*) malloc(5*sizeof(double)))
&& (res_tab[1] = (double*) malloc(5*sizeof(double)))
&& (res_tab[2] = (double*) malloc(5*sizeof(double)))) {
+ x_desc = rX->RangeDesc(data, 0); y_desc = rY->RangeDesc(data, 0);
rX->GetFirst(&cx, &rx); rY->GetFirst(&cy, &ry);
rep_init();
dBounds.Xmin = dBounds.Ymin = HUGE_VAL; dBounds.Xmax = dBounds.Ymax = -HUGE_VAL;
@@ -550,21 +868,50 @@ rep_regression(GraphObj *parent, DataObj *data)
dres[5] = sxx/(n-1); dres[6] = syy/(n-1); dres[7] = sdy;
dres[8] = sxy/sdy*sxy/sxx; dres[9] = f_dist(dres[8], 1.0, df);
t = distinv(t_dist, df, 1.0, (100.0-ci)/100.0, 2.0);
+ dres[10] = t * sqrt(dres[7]/sxx);
+ dres[11] = t * sqrt(dres[7]*(dres[2]*dres[2]/sxx +1.0/(double)n));
if (n && (graph = new Graph(parent, data, 0L))) {
+ if(txt_obj = mk_scatt(x, y, 0L, 0L, n, "Data", x_desc, y_desc)){
+ OpenGraph(graph, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj);
+ }
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "[1=Function]\nx1= %g\nx2= %g\nxstep= %g\nLine= %g 1 0x000000ff 0x0\n",
+ dBounds.Xmin, dBounds.Xmax, (dBounds.Xmax -dBounds.Xmin)/100.0, defs.GetSize(SIZE_DATA_LINE));
+ i += sprintf_s(TmpTxt+i, TMP_TXT_SIZE-i, "f_xy=\"%g+x*%g\\n\"\n", dres[1], dres[0]);
+ i += sprintf_s(TmpTxt+i, TMP_TXT_SIZE-i, "Desc=\"Regression\"\n");
+ OpenGraph(graph, 0L, (unsigned char*)TmpTxt, false);
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "[1=Function]\nx1= %g\nx2= %g\nxstep= %g\nLine= %g 1 0x000000ff 0x0\n",
+ dBounds.Xmin, dBounds.Xmax, (dBounds.Xmax -dBounds.Xmin)/100.0, defs.GetSize(SIZE_DATA_LINE)*0.5);
+ i += sprintf_s(TmpTxt+i, TMP_TXT_SIZE-i, "f_xy=\"y=%g+x*%g;\\nts=sqrt((((x-%g)^2)/%g+%g)*%g);\\ny=y+ts*%g\\n\"\n",
+ dres[1], dres[0], dres[2], sxx, (1.0/(double)n), dres[7], t);
+ i += sprintf_s(TmpTxt+i, TMP_TXT_SIZE-i, "Desc=\"%g%% C.I.\"\n", ci);
+ OpenGraph(graph, 0L, (unsigned char*)TmpTxt, false);
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "[1=Function]\nx1= %g\nx2= %g\nxstep= %g\nLine= %g 1 0x000000ff 0x0\n",
+ dBounds.Xmin, dBounds.Xmax, (dBounds.Xmax -dBounds.Xmin)/100.0, defs.GetSize(SIZE_DATA_LINE)*0.5);
+ i += sprintf_s(TmpTxt+i, TMP_TXT_SIZE-i, "f_xy=\"y=%g+x*%g;\\nts=sqrt((((x-%g)^2)/%g+%g)*%g);\\ny=y-ts*%g\\n\"\n",
+ dres[1], dres[0], dres[2], sxx, (1.0/(double)n), dres[7], t);
+ i += sprintf_s(TmpTxt+i, TMP_TXT_SIZE-i, "Desc=\"%g%% C.I.\"\n", ci);
+ OpenGraph(graph, 0L, (unsigned char*)TmpTxt, false);
+#else
i = sprintf(TmpTxt, "[1=Function]\nx1= %g\nx2= %g\nxstep= %g\nLine= %g 1 0x000000ff 0x0\n",
dBounds.Xmin, dBounds.Xmax, (dBounds.Xmax -dBounds.Xmin)/100.0, defs.GetSize(SIZE_DATA_LINE));
- i += sprintf(TmpTxt+i, "f_xy=\"%g+x*%g\\n\"", dres[1], dres[0]);
+ i += sprintf(TmpTxt+i, "f_xy=\"%g+x*%g\\n\"\n", dres[1], dres[0]);
+ i += sprintf(TmpTxt+i, "Desc=\"Regression\"\n");
OpenGraph(graph, 0L, (unsigned char*)TmpTxt, false);
i = sprintf(TmpTxt, "[1=Function]\nx1= %g\nx2= %g\nxstep= %g\nLine= %g 1 0x000000ff 0x0\n",
dBounds.Xmin, dBounds.Xmax, (dBounds.Xmax -dBounds.Xmin)/100.0, defs.GetSize(SIZE_DATA_LINE)*0.5);
- i += sprintf(TmpTxt+i, "f_xy=\"y=%g+x*%g;\\nts=sqrt((((x-%g)^2)/%g+%g)*%g);\\ny=y+ts*%g\\n\"",
+ i += sprintf(TmpTxt+i, "f_xy=\"y=%g+x*%g;\\nts=sqrt((((x-%g)^2)/%g+%g)*%g);\\ny=y+ts*%g\\n\"\n",
dres[1], dres[0], dres[2], sxx, (1.0/(double)n), dres[7], t);
+ i += sprintf(TmpTxt+i, "Desc=\"%g%% C.I.\"\n", ci);
OpenGraph(graph, 0L, (unsigned char*)TmpTxt, false);
i = sprintf(TmpTxt, "[1=Function]\nx1= %g\nx2= %g\nxstep= %g\nLine= %g 1 0x000000ff 0x0\n",
dBounds.Xmin, dBounds.Xmax, (dBounds.Xmax -dBounds.Xmin)/100.0, defs.GetSize(SIZE_DATA_LINE)*0.5);
- i += sprintf(TmpTxt+i, "f_xy=\"y=%g+x*%g;\\nts=sqrt((((x-%g)^2)/%g+%g)*%g);\\ny=y-ts*%g\\n\"",
+ i += sprintf(TmpTxt+i, "f_xy=\"y=%g+x*%g;\\nts=sqrt((((x-%g)^2)/%g+%g)*%g);\\ny=y-ts*%g\\n\"\n",
dres[1], dres[0], dres[2], sxx, (1.0/(double)n), dres[7], t);
+ i += sprintf(TmpTxt+i, "Desc=\"%g%% C.I.\"\n", ci);
OpenGraph(graph, 0L, (unsigned char*)TmpTxt, false);
+#endif
ts = t * sqrt(dres[7]*((dBounds.Xmax-dres[2])*(dBounds.Xmax-dres[2])/sxx +1.0/(double)n));
ty = dBounds.Xmax * dres[0] +dres[1];
ly[0] = ty +ts; ly[1] = ty -ts;
@@ -575,13 +922,13 @@ rep_regression(GraphObj *parent, DataObj *data)
if(ly[i] < dBounds.Ymin) dBounds.Ymin = ly[i];
if(ly[i] > dBounds.Ymax) dBounds.Ymax = ly[i];
}
- if(txt_obj = mk_scatt(x, y, 0L, 0L, n)){
- OpenGraph(graph, 0L, (unsigned char*)txt_obj, false);
- free(txt_obj);
- }
- if(!bParZ) sprintf(TmpTxt, "y = %g %c %g * x", dres[1],
- (dres[0] < 0.0 ? '-' : '+'), fabs(dres[0]));
+#ifdef USE_WIN_SECURE
+ if(!bParZ) sprintf_s(TmpTxt, TMP_TXT_SIZE, "y = %g %c %g * x",dres[1],(dres[0] < 0.0 ? '-' : '+'), fabs(dres[0]));
+ else sprintf_s(TmpTxt, TMP_TXT_SIZE, "y = %g * x", fabs(dres[0]));
+#else
+ if(!bParZ) sprintf(TmpTxt, "y = %g %c %g * x",dres[1],(dres[0] < 0.0 ? '-' : '+'), fabs(dres[0]));
else sprintf(TmpTxt, "y = %g * x", fabs(dres[0]));
+#endif
if(txt_obj = mk_label((graph->GetSize(SIZE_DRECT_LEFT) + graph->GetSize(SIZE_DRECT_RIGHT))/2.0,
graph->GetSize(SIZE_DRECT_TOP)+txtdef1.fSize/2.0, true, TXA_HCENTER, &txtdef1, TmpTxt)) {
OpenGraph(graph, 0L, (unsigned char*)txt_obj, false);
@@ -597,9 +944,15 @@ rep_regression(GraphObj *parent, DataObj *data)
res_tab[1][1] = syy-res_tab[0][1]; res_tab[2][1] = syy;
res_tab[0][2] = res_tab[0][1]; res_tab[1][2] = res_tab[1][1]/df;
res_tab[0][3] = dres[8]; res_tab[0][4] = dres[9];
- regr_sum[1][0] = res_tab[0][1]/syy; regr_sum[0][0] = sqrt(regr_sum[1][0]);
- mk_table(page, graph->GRect.Xmin, graph->GetSize(SIZE_GRECT_BOTTOM)+txtdef2.fSize*3.0,
- 2, res_tab);
+ dres[12] = res_tab[0][1]/res_tab[2][1];
+ c_y = graph->GetSize(SIZE_GRECT_BOTTOM)+txtdef2.fSize*3.0;
+ c_x = graph->GRect.Xmin;
+ c_y = mk_regr_summary(page, c_x, c_y, dres, ci, n);
+ if(txt_obj = mk_label(c_x, c_y, false, TXA_HLEFT, &txtdef1, "<b>Anova:</b>")) {
+ OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); c_y += txtdef1.fSize*1.5;
+ }
+ mk_table(page, c_x, c_y, 2, res_tab);
parent->Command(CMD_DROP_GRAPH, page, 0L);
}
}
@@ -608,6 +961,315 @@ rep_regression(GraphObj *parent, DataObj *data)
for(i = 0; i < 3; i++) if(res_tab[i]) free(res_tab[i]);
free(res_tab);
}
- if(x) free(x); if(y) free(y);
- if(rX) delete rX; if(rY) delete rY; free(RegrDlg);
+ if(x_desc) free(x_desc); if(y_desc)free(y_desc);
+ if(x) free(x); if(y) free(y);
+ if(rX) delete rX; if(rY) delete rY; free(RegrDlg);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// 2x2 table
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+static char *twDlg_Tmpl =
+ "1,2,100,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "2,3,400,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "3,4,600,ISPARENT | CHECKED,GROUP,0,0,0,0,0\n"
+ "4,5,,DEFAULT,PUSHBUTTON,-1,168,10,45,12\n"
+ "5,,,,PUSHBUTTON,2,168,25,45,12\n"
+ "100,101,,,CTEXT,1,35,10,40,8\n"
+ "101,102,,,EDTEXT,0,35,20,40,10\n"
+ "102,103,,,EDTEXT,0,77,20,40,10\n"
+ "103,104,,,EDTEXT,0,35,32,40,10\n"
+ "104,105,,,EDTEXT,0,77,32,40,10\n"
+ "105,106,,,LTEXT,3,10,20,40,8\n"
+ "106,107,,,LTEXT,4,10,32,40,8\n"
+ "107,,,,CTEXT,5,77,10,40,8\n"
+ "400,401,,,EDTEXT,0,119,20,40,10\n"
+ "401,402,,,EDTEXT,0,119,32,40,10\n"
+ "402,403,,,EDTEXT,0,35,44,40,10\n"
+ "403,404,,,EDTEXT,0,77,44,40,10\n"
+ "404,405,,,EDTEXT,0,119,44,40,10\n"
+ "405,406,,,CTEXT,6,119,10,40,8\n"
+ "406,407,,,LTEXT,7,10,44,40,8\n"
+ "407,408,,,LTEXT,2,35,59,40,8\n"
+ "408,409,,,LTEXT,2,35,69,40,8\n"
+ "409,410,,,LTEXT,8,119,59,60,8\n"
+ "410,,,,LTEXT,0,119,69,60,8\n"
+ "600,601,,DEFAULT,PUSHBUTTON,-1,128,10,45,12\n"
+ "601,,,LASTOBJ,PUSHBUTTON,-2,128,25,45,12";
+
+void rep_twowaytable(GraphObj *parent, DataObj *data)
+{
+ DlgInfo *twDlg;
+ void *dyndata[] = {(void*)"Group A", (void*)"Close", (void*)"Case 1", (void*)"Case 2",
+ (void*)"Group B", (void*)"A + B", (void*)"C1+C2", (void*)"Fisher's exact:"};
+ DlgRoot *Dlg;
+ void *hDlg;
+ int i, level, res;
+ int v_idx[] = {101,102,400,103,104,401,402,403,404};
+ double v[9], chi2, p, dn, pf;
+
+ if(!parent || !data) return;
+ if(!(twDlg = CompileDialog(twDlg_Tmpl, dyndata))) return;
+ if(!(Dlg = new DlgRoot(twDlg, data)))return;
+ for(i = 400; i < 405; i++) Dlg->Activate(i, false);
+ level = 0;
+ if (!level) {
+ Dlg->ShowItem(2, false); Dlg->ShowItem(4, false);
+ Dlg->ShowItem(5, false);
+ hDlg = CreateDlgWnd("2x2 Table", 50, 50, 450, 200, Dlg, 0);
+ ResizeDlgWnd(hDlg, 370, 150);
+ }
+ else {
+ Dlg->ShowItem(3, false);
+ hDlg = CreateDlgWnd("2x2 Table", 50, 50, 450, 200, Dlg, 0);
+ }
+ do {
+ LoopDlgWnd();
+ res = Dlg->GetResult();
+ switch(res) {
+ case 0:
+ res = -1;
+ break;
+ case 600: //level 0 OK
+ Dlg->ShowItem(2, true); Dlg->ShowItem(4, true);
+ Dlg->ShowItem(5, true); Dlg->ShowItem(3, false);
+ ResizeDlgWnd(hDlg, 450, 200); Dlg->Command(CMD_REDRAW, 0L, 0L);
+ level = 1;
+ case 4: //level 1 OK
+ for(i = 0; i < 9; i++) {
+ v[i] = 0.0; Dlg->GetValue(v_idx[i], &v[i]);
+ v[i] = fabs(floor(v[i]));
+ }
+ v[2] = v[0] + v[1]; v[5] = v[3] + v[4];
+ v[6] = v[0] + v[3]; v[7] = v[1] + v[4];
+ v[8] = v[6] + v[7]; chi2 = v[0]*v[4]-v[1]*v[3];
+ if(v[2] < 32.0 && v[5] < 32.0 && v[6] < 32.0 && v[7] < 32.0) {
+ pf = factrl((int)v[2])/factrl((int)v[0])*factrl((int)v[5])/factrl((int)v[1])
+ *factrl((int)v[6])/factrl((int)v[3])*factrl((int)v[7])/factrl((int)v[4]);
+ pf /= factrl((int)v[8]);
+ dbl_to_str1(TmpTxt, TMP_TXT_SIZE, "P = %g", pf);
+ Dlg->SetText(410, pf >= 0.001 ? TmpTxt : (char*)"P < 0.001");
+ }
+ else Dlg->SetText(410, "- - -");
+ dn = (v[2]*v[5]*v[6]*v[7]);
+ chi2 = dn > 0.0 ? (chi2*chi2*v[8])/dn : 0.0;
+ p = chi_dist(chi2, 1.0, 1.0);
+ for(i = 0; i < 9; i++) {
+ dbl_to_str1(TmpTxt, TMP_TXT_SIZE, "%g", v[i]);
+ Dlg->SetText(v_idx[i], TmpTxt);
+ }
+ dbl_to_str1(TmpTxt, TMP_TXT_SIZE, "Chi2 = %g", chi2);
+ Dlg->SetText(407, TmpTxt);
+ if(p >= 0.001) {
+ dbl_to_str1(TmpTxt, TMP_TXT_SIZE, "P = %g", p);
+ Dlg->SetText(408, TmpTxt);
+ }
+ else Dlg->SetText(408, "P < 0.001");
+ Dlg->Command(CMD_REDRAW, 0L, 0L);
+ res= -1;
+ break;
+ }
+ }while (res < 0);
+ CloseDlgWnd(hDlg);
+ delete Dlg; free(twDlg);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// compare means of two groups
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void rep_compmeans(GraphObj *parent, DataObj *data)
+{
+ TabSHEET tab1 = {0, 42, 10, "Data Input"};
+ double ci = 95.0;
+ DlgInfo *MeanDlg;
+ void *dyndata[] = {(void*)&tab1, (void*)"range for first variable",
+ (void*)"range for second variable", (void*)"confidence interval:",
+ (void*)&ci, (void*)" "};
+ char *ttest[] = {"Student's t = %g", "P = %g", "P(corr.) = %g"};
+ char *utest[] = {"Mann-Whitney U = %g", "z = %g", "P = %g", "z(corr.) = %g", "P(corr.) = %g"};
+ char g1_nam[20], g2_nam[20], *c_name;
+ DlgRoot *Dlg;
+ void *hDlg;
+ int i, j, res, n1, n2, r, c, *ny;
+ bool bContinue = false;
+ double *d1, *d2, *rs, dtmp, cx, cy, min1,max1, min2, max2;
+ scaleINFO scale = {{0.0, 0.9}, {0.0, 0.9}, {0.0, 0.9}};
+ char *txt_obj;
+ AccRange *rD;
+ Graph *graph;
+ Page *page;
+
+ if(!parent || !data) return;
+ if(!(MeanDlg = CompileDialog(RegrDlg_Tmpl, dyndata))) return;
+ UseRangeMark(data, 1, TmpTxt, TmpTxt+100);
+ if(!(Dlg = new DlgRoot(MeanDlg, data)))return;
+ Dlg->ShowItem(107, false);
+ d1 = d2 = 0L;
+ hDlg = CreateDlgWnd("Compare Means", 50, 50, 420, 260, Dlg, 0x0L);
+ do {
+ LoopDlgWnd();
+ res = Dlg->GetResult();
+ switch (res) {
+ case 0:
+ if(bContinue) res = -1;
+ else if(Dlg->GetCheck(10)) res = -1;
+ break;
+ case -1:
+ bContinue = false;
+ break;
+ case 1:
+ if(d1) free(d1); if(d2) free(d2); d1 = d2 = 0L;
+ min1 = min2 = dBounds.Ymin = HUGE_VAL; max1 = max2 = dBounds.Ymax = -HUGE_VAL;
+ if(Dlg->GetText(101,TmpTxt,TMP_TXT_SIZE)&&(rD=new AccRange(TmpTxt))&&(n1=rD->CountItems())&&(d1=(double*)malloc(n1*sizeof(double)))){
+ if(c_name = rD->RangeDesc(data, 2)) {
+ rlp_strcpy(g1_nam, 20, c_name); g1_nam[0] = toupper(g1_nam[0]);
+ free(c_name);
+ }
+ else rlp_strcpy(g1_nam, 20, "Group 1");
+ for(n1 = 0, rD->GetFirst(&c, &r); rD->GetNext(&c, &r); ) {
+ if(data->GetValue(r, c, &dtmp)){
+ if(dBounds.Ymin > dtmp) dBounds.Ymin = dtmp;
+ if(dBounds.Ymax < dtmp) dBounds.Ymax = dtmp;
+ if(min1 > dtmp) min1 = dtmp; if(max1 < dtmp) max1 = dtmp;
+ d1[n1++] = dtmp;
+ }
+ }
+ delete rD;
+ }
+ if(Dlg->GetText(103,TmpTxt,TMP_TXT_SIZE)&&(rD=new AccRange(TmpTxt))&&(n2=rD->CountItems())&&(d2=(double*)malloc(n1*sizeof(double)))){
+ if(c_name = rD->RangeDesc(data, 2)) {
+ rlp_strcpy(g2_nam, 20, c_name); g2_nam[0] = toupper(g2_nam[0]);
+ free(c_name);
+ }
+ else rlp_strcpy(g2_nam, 20, "Group 2");
+ for(n2 = 0, rD->GetFirst(&c, &r); rD->GetNext(&c, &r); ) {
+ if(data->GetValue(r, c, &dtmp)){
+ if(dBounds.Ymin > dtmp) dBounds.Ymin = dtmp;
+ if(dBounds.Ymax < dtmp) dBounds.Ymax = dtmp;
+ if(min2 > dtmp) min2 = dtmp; if(max2 < dtmp) max2 = dtmp;
+ d2[n2++] = dtmp;
+ }
+ }
+ delete rD;
+ }
+ if(!d1 || !d2 || n1 < 2 || n2 < 2) {
+ InfoBox("Insufficient data to calculate means!");
+ bContinue = true;
+ res = -1;
+ }
+ Dlg->GetValue(105, &ci);
+ break;
+ }
+ }while (res < 0);
+ if(res == 1 && d1 && d2 && n1>1 && n2>1 && (rs = (double*)malloc(40*sizeof(double))) && (ny = (int*)malloc(2*sizeof(int)))) {
+ dBounds.Xmin = 0.5; rs[0] = 1.0; dBounds.Xmax = 2.3; rs[1] = 2.0;
+ dtmp = d_variance(n1, d1, &rs[2], 0L); rs[10] = sqrt(dtmp);
+ dtmp = d_variance(n2, d2, &rs[3], 0L); rs[11] = sqrt(dtmp);
+ rs[12] = (double)n1; rs[13] = (double)n2;
+ rs[6] = rs[10]/sqrt(rs[12]); rs[7] = rs[11]/sqrt(rs[13]);
+ rs[4] = rs[2] - rs[6]; rs[5] = rs[3] - rs[7];
+ rs[6] += rs[2]; rs[7] += rs[3];
+ rs[8] = rs[2] - rs[10]; rs[9] = rs[3] - rs[11];
+ rs[10] += rs[2]; rs[11] += rs[3];
+ ny[0] = n1; ny[1] = n2;
+ rep_init(); page = new Page(parent, data);
+ ci /= 100.0;
+ mk_header(page, "<b>Compare Means of Two Groups</b>");
+ if((graph = new Graph(parent, data, 0L)) && (txt_obj = mk_boxplot(rs, rs+2, rs+4, rs+6, rs+8, rs+10,
+ ny, 2,"Mean","Std. Err.","Std. Dev."))){
+ scale.sx.fx = (txtdef1.fSize*5.0); scale.sy.fx = (txtdef1.fSize*10.0);
+ graph->GRect.Xmax = defs.GetSize(SIZE_GRECT_BOTTOM);
+ graph->DRect.Xmin *= 0.8; graph->moveable = 0;
+ graph->DRect.Xmax = graph->GRect.Xmax - (txtdef1.fSize*2.0);
+ OpenGraph(graph, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); graph->Command(CMD_SCALE, &scale, 0L);
+ cx = graph->GetSize(SIZE_GRECT_RIGHT)+txtdef1.fSize*3.0;
+ cy = mk_mean_report(page, cx, graph->GetSize(SIZE_GRECT_TOP), d1, n1, ci, g1_nam);
+ cy = mk_mean_report(page, cx, cy + txtdef1.fSize, d2, n2, ci, g2_nam);
+ cy += linsp1;
+ if(txt_obj = mk_label(graph->GetSize(SIZE_GRECT_RIGHT)+txtdef1.fSize*3.0, cy, false, TXA_HLEFT,
+ &txtdef1, "<b>t-Test:</b>")) {
+ OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); cy += linsp1;
+ }
+ d_ttest(d1, d2, n1, n2, 0L, 0L, rs+15);
+ for(i = 0; i < 3; i++) {
+ switch(i) {
+ case 0:
+ dtmp = rs[24]; break;
+ case 1:
+ dtmp = rs[21]; break;
+ case 2:
+ dtmp = rs[23]; break;
+ }
+#ifdef USE_WIN_SECURE
+ j = sprintf_s(TmpTxt, 80, ttest[i], dtmp);
+#else
+ j = sprintf(TmpTxt, ttest[i], dtmp);
+#endif
+ if(i && dtmp < 0.0001) {
+ while(TmpTxt[j] != '=' && j) j--;
+ rlp_strcpy(TmpTxt+j, 10, "< 0.0001");
+ }
+ if(txt_obj = mk_label(cx+(txtdef1.fSize*3.0), cy, false, TXA_HLEFT, &txtdef1, TmpTxt)) {
+ OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); cy += linsp1/1.2;
+ }
+ }
+ page->Command(CMD_DROP_GRAPH, graph, 0L);
+ }
+ d_quartile(n1, d1, &rs[6], &rs[2], &rs[4]);
+ d_quartile(n2, d2, &rs[7], &rs[3], &rs[5]);
+ rs[8] = min1; rs[9] = min2; rs[10] = max1; rs[11] = max2;
+ cy = graph->GetSize(SIZE_GRECT_BOTTOM)+txtdef2.fSize*3.0;
+ if((graph = new Graph(parent, data, 0L)) && (txt_obj = mk_boxplot(rs, rs+2, rs+4, rs+6, rs+8, rs+10,
+ ny, 2,"Median","25-75%","Min./Max."))){
+ scale.sy.fx = cy;
+ graph->GRect.Xmax = defs.GetSize(SIZE_GRECT_BOTTOM);
+ graph->DRect.Xmin *= 0.8; graph->moveable = 0;
+ graph->DRect.Xmax = graph->GRect.Xmax - (txtdef1.fSize*2.0);
+ OpenGraph(graph, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); graph->Command(CMD_SCALE, &scale, 0L);
+ cy = mk_median_report(page, cx, graph->GetSize(SIZE_GRECT_TOP), d1, n1, .95, g1_nam);
+ cy = mk_median_report(page, cx, cy + txtdef1.fSize, d2, n2, .95, g2_nam);
+ cy += linsp1;
+ if(txt_obj = mk_label(graph->GetSize(SIZE_GRECT_RIGHT)+txtdef1.fSize*3.0, cy, false, TXA_HLEFT,
+ &txtdef1, "<b>u-Test:</b>")) {
+ OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); cy += linsp1;
+ }
+ d_utest(d1, d2, n1, n2, 0L, 0L, rs+15);
+ for(i = 0; i < 5; i++) {
+ switch(i) {
+ case 0:
+ dtmp = rs[17]; break;
+ case 1:
+ dtmp = rs[18]; break;
+ case 2:
+ dtmp = rs[21]; break;
+ case 3:
+ dtmp = rs[22]; break;
+ case 4:
+ dtmp = rs[23]; break;
+ }
+#ifdef USE_WIN_SECURE
+ j = sprintf_s(TmpTxt, 80, utest[i], dtmp);
+#else
+ j = sprintf(TmpTxt, utest[i], dtmp);
+#endif
+ if(i && dtmp < 0.0001) {
+ while(TmpTxt[j] != '=' && j) j--;
+ rlp_strcpy(TmpTxt+j, 10, "< 0.0001");
+ }
+ if(txt_obj = mk_label(cx+(txtdef1.fSize*3.0), cy, false, TXA_HLEFT, &txtdef1, TmpTxt)) {
+ OpenGraph(page, 0L, (unsigned char*)txt_obj, false);
+ free(txt_obj); cy += linsp1/1.2;
+ }
+ }
+ page->Command(CMD_DROP_GRAPH, graph, 0L);
+ }
+ parent->Command(CMD_DROP_GRAPH, page, 0L); free(rs);
+ }
+ CloseDlgWnd(hDlg); delete Dlg;
+ free(MeanDlg); if(d1) free(d1); if(d2) free(d2);
}
diff --git a/rlp_math.cpp b/rlp_math.cpp
index e8d2aac..0f6d86f 100755
--- a/rlp_math.cpp
+++ b/rlp_math.cpp
@@ -635,7 +635,17 @@ double lognorm_freq(double x, double m, double s)
//chi square distribution
double chi_dist(double x, double df, double)
{
- return gammq(df/2.0, x/2);
+ return gammq(df/2.0, x/2.0);
+}
+
+double chi_freq(double x, double df)
+{
+ if(x < 0.0 || df <= 0.0) return 0.0;
+ if(x < 1.0e-32) x = 1.0e-32;
+//formula by Wikipedia
+// return exp(log(2.0)*(1.0-df/2.0)+log(x)*(df-1.0)+x*x/-2.0-gammln(df/2.0));
+//formula by StatSoft's STATISTICA documentation
+ return exp(-x/2.0+log(x)*(df/2.0-1.0)-log(2.0)*df/2.0-gammln(df/2.0));
}
//t-distribution
@@ -644,6 +654,15 @@ double t_dist(double t, double df, double)
return betai(df/2.0, 0.5, (df/(df+t*t)));
}
+double t_freq(double t, double df)
+{
+ double a, b, c, d;
+
+ a = gammln((df+1.0)/2.0); b = log(sqrt(df * _PI));
+ c = gammln(df/2.0); d = log(1.0+t*t/df) * (df+1)/2.0;
+ return exp(a-b-c-d);
+}
+
//poisson distribution
double pois_dist(double x, double m, double)
{
@@ -656,13 +675,18 @@ double f_dist(double f, double df1, double df2)
return betai(df2/2.0, df1/2.0, df2/(df2+df1*f));
}
+double f_freq(double x, double df1, double df2)
+{
+ double a, b, c, d;
+
+ a = gammln((df1+df2)/2.0); b = gammln(df1/2.0) + gammln(df2/2.0);
+ c = log(df1/df2) * df1/2.0 + log(x) * (df1/2.0-1.0);
+ d = log(1+(df1/df2)*x) * (-(df1+df2)/2.0);
+ return exp(a-b+c+d);
+}
+
//---------------------------------------------------------------------------
// Inverse of statitistical functions:
-// Use a combination of the Newton-Raphson method and bisection
-// 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. 273 ff.
-
// funcd supplies the function value fn and the derivative df of the function sf at x
void funcd(double x, double *fn, double *df, double (*sf)(double, double, double),
double df1, double df2, double p)
@@ -671,6 +695,10 @@ void funcd(double x, double *fn, double *df, double (*sf)(double, double, double
*fn = (sf)(x, df1, df2);
if(sf == norm_dist) *df = norm_freq(x, df1,df2);
+ else if(sf == chi_dist) *df = -chi_freq(x, df1);
+ else if(sf == t_dist) *df = -2.0 * t_freq(x, df1);
+ else if(sf == f_dist) *df = -1.0 * f_freq(x, df1, df2);
+// if(true){
else {
y1 = (sf)(x * 0.995, df1, df2);
y2 = (sf)(x * 1.005, df1, df2);
@@ -679,50 +707,23 @@ void funcd(double x, double *fn, double *df, double (*sf)(double, double, double
*fn = *fn - p;
}
-//distinv does actual bisection and Newton-Raphson root finding
+//distinv does actual Newton-Raphson root finding
double distinv(double (*sf)(double, double, double), double df1, double df2, double p, double x0)
{
- int j = 0;
- double df, dx, dxold, f, fh, fl;
- double swap, temp, xh, xl, rts;
- double x1 = x0/2.0, x2 = x0+x1;
-
- do {
- funcd(x1, &fl, &df, sf, df1, df2, p);
- funcd(x2, &fh, &df, sf, df1, df2, p);
- if(++j > 200) return 0.0;
- if(fl*fh < 0.0) break;
- dx = fabs(x2-x1);
- x1 = (x1 > dx) ? x1-dx : x1/2.0; x2 += dx;
- }while(fl*fh >= 0.0);
- if(fl <= 0.0) {
- xl = x1; xh = x2;
- }
- else {
- xh = x1; xl = x2;
- swap = fl; fl = fh; fh = swap;
- }
- rts = x0; dxold = fabs(x2-x1); dx = dxold;
- funcd(rts, &f, &df, sf, df1, df2, p);
- for(j = 1; j <= 500; j++) {
- if((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0) || (fabs(2.0*f) > fabs(dxold * df))) {
- dxold = dx; dx = 0.5 * (xh-xl); rts = xl + dx;
- if(xl == rts) return rts;
- }
- else {
- dxold = dx; dx = f/df; temp = rts; rts -= dx;
- if(temp == rts) return rts;
- }
- if(fabs(dx) < _PREC) return rts;
- funcd(rts, &f, &df, sf, df1, df2, p);
- if(f < 0.0) {
- xl = rts; fl = f;
- }
- else {
- xh = rts; fh = f;
+ int i, j;
+ double df, dx, f, rtn;
+
+ for(j = 0, rtn = dx = x0; j < 100; j++) {
+ for( i= 0; i < 100; i++) {
+ funcd(rtn, &f, &df, sf, df1, df2, p);
+ if(fabs(df) > 1.0e-12) break;
+ rtn += (dx = dx/2.0);
+ if(i >= 99) return HUGE_VAL;
}
+ dx = f/df*(0.01*(double)(100-j)); rtn -= dx;
+ if(fabs(dx) < _PREC && j > 3) return rtn;
}
- return rts;
+ return rtn;
}
//---------------------------------------------------------------------------
@@ -841,9 +842,16 @@ 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;
+// double x, skew;
+
+// sd = sqrt(d_variance(n, v, &avg, 0L));
+// for(i = 0, skew = 0.0; i < n; i++){
+// x = (v[i]-avg)/sd;
+// skew += (x*x*x - skew)/((double)(i+1));
+// }
+// return skew;
+ for(i = 0, avg = 0.0; i < n; i++) avg += ((v[i]-avg)/((double)(i+1)));
+ for(i = 0, 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));
}
@@ -950,13 +958,10 @@ void crank(int n, double *w0, double *s)
w[j] = j; ++j;
}
else {
- for(jt = j+1; jt <= n; jt++)
- if(w[jt] != w[j]) break;
+ for(jt = j+1; jt <= n; jt++) if(w[jt] != w[j]) break;
rank = 0.5 * (j+jt-1);
for(ji = j; ji <= (jt-1); ji++) w[ji] = rank;
- t = jt -j;
- *s += t*t*t -t;
- j = jt;
+ t = jt -j; *s += t*t*t -t; j = jt;
}
}
if(j == n) w[n] = n;
@@ -1093,10 +1098,10 @@ double d_covar(double *x, double *y, int n, char *dest, DataObj *data)
}
//Mann-Whitney U Test
-double d_utest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
+double d_utest(double *x, double *y, int n1, int n2, char *dest, DataObj *data, double *results)
{
- double *da, *ta, u1, u2, su, tmp;
- double res[7];
+ double *da, *ta, u1, u2, su, su1, ts, dn1 = n1, dn2 = n2;
+ double res[9];
AccRange *rD;
int i, j, n, r, c;
@@ -1112,29 +1117,35 @@ double d_utest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
for(j = 0; j < n2; j++) {
da[i] = y[j]; ta[i++] = 2.0;
}
- SortArray2(n, da, ta); crank(n, da, &tmp);
+ SortArray2(n, da, ta); crank(n, da, &ts);
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;
+ free(da); free(ta);
+ u1 = (dn1*dn2 + (dn1*(dn1+1))/2.0) - res[0]; u2 = (dn1*dn2 + ((dn2+1)*dn2)/2.0) - res[1];
+ su = sqrt((dn1*dn2*(dn1+dn2+1))/12.0); res[2] = u2 > u1 ? u2 : u1;
+ su1 = ((dn1*dn2)/((dn1+dn2)*(dn1+dn2-1))) * (((dn1+dn2)*(dn1+dn2)*(dn1+dn2)-(dn1+dn2)-ts)/12.0);
+ su1 = sqrt(su1);
res[3] = (res[2] - (n1*n2)/2.0)/su; res[6] = errfc(res[3]/_SQRT2);
+ res[4] = n1; res[5] = n2;
+ res[7] = (res[2] - (n1*n2)/2.0)/su1; res[8] = errfc(res[7]/_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++) {
+ for(i = 0; i < 9 && rD->GetNext(&c, &r); i++) {
data->SetValue(r, c, res[i]);
}
data->Command(CMD_UPDATE, 0L, 0L);
delete rD;
}
- return res[6];
+ else if(results) {
+ for(i = 0; i < 9; i++) results[i] = res[i];
+ }
+ return res[8];
}
//t-test
-double d_ttest(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 *results)
{
int i, r, c;
double sx, sy, mx, my, d, df, p;
@@ -1148,7 +1159,7 @@ double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
//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;
+ df -= 2.0; df = floor(df);
// an alternative formula for correction
// p = (sx/(double)n1)*(sx/(double)n1)/(double)(n1-1) + (sy/(double)n2)*(sy/(double)n2)/(double)(n2-1);
@@ -1167,6 +1178,12 @@ double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data)
data->Command(CMD_UPDATE, 0L, 0L);
delete rD;
}
+ else if(results) {
+ results[0] = mx; results[1] = sqrt(sx/(double)(n1-1)); results[2] = n1;
+ results[3] = my; results[4] = sqrt(sy/(double)(n2-1)); results[5] = n2;
+ results[7] = df; df = (n1-1) + (n2-1); results[6] = betai(df/2.0, 0.5, (df/(df+d*d)));
+ results[8] = p; results[9] = d;
+ }
return p;
}
@@ -1299,7 +1316,11 @@ static int parse_date (rlp_datetime *dt, char *src, char *fmt)
switch (fmt[i]) {
case 'Y': case 'y': // year is numeric
if(j && src[j] == '-' || src[j] == '/' || src[j] == '.') j++;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s(src+j, "%d", &dt->year)) {
+#else
if(sscanf(src+j, "%d", &dt->year)) {
+#endif
if(dt->year < 0) return 0;
while(isdigit(src[j])) j++;
if(dt->year<60) dt->year += 2000;
@@ -1323,7 +1344,11 @@ static int parse_date (rlp_datetime *dt, char *src, char *fmt)
break;
case 'V': case 'v': // or numeric
if(j && src[j] == '-' || src[j] == '/' || src[j] == '.') j++;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s(src+j, "%d", &dt->month)) {
+#else
if(sscanf(src+j, "%d", &dt->month)) {
+#endif
if(dt->month <= 0 || dt->month > 12) return 0;
j++; if(isdigit(src[j])) j++;
}
@@ -1331,14 +1356,22 @@ static int parse_date (rlp_datetime *dt, char *src, char *fmt)
break;
case 'Z': case 'z': // day of month is numeric
if(j && src[j] == '-' || src[j] == '/' || src[j] == '.') j++;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s(src+j, "%d", &dt->dom)) {
+#else
if(sscanf(src+j, "%d", &dt->dom)) {
+#endif
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
+#ifdef USE_WIN_SECURE
+ if(sscanf_s(src+j, "%2d", &dt->hours)) {
+#else
if(sscanf(src+j, "%2d", &dt->hours)) {
+#endif
if(dt->hours < 0 || dt->hours > 23) return 0;
j++; if(isdigit(src[j])) j++;
}
@@ -1346,7 +1379,11 @@ static int parse_date (rlp_datetime *dt, char *src, char *fmt)
break;
case 'M': case 'm': // minutes are numeric
if(j && src[j] == ' ' || src[j] == ':') j++;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s(src+j, "%2d", &dt->minutes)) {
+#else
if(sscanf(src+j, "%2d", &dt->minutes)) {
+#endif
if(dt->minutes < 0 || dt->minutes >= 60) return 0;
j++; if(isdigit(src[j])) j++;
}
@@ -1355,7 +1392,11 @@ static int parse_date (rlp_datetime *dt, char *src, char *fmt)
case 'S': case 's': // seconds are numeric
case 'T': case 't':
if(j && src[j] == ' ' || src[j] == ':') j++;
+#ifdef USE_WIN_SECURE
+ if(sscanf_s(src+j, "%lf", &dt->seconds)) {
+#else
if(sscanf(src+j, "%lf", &dt->seconds)) {
+#endif
if(dt->seconds < 0.0 || dt->seconds >= 60.0) return 0;
while(isdigit(src[j]) || src[j] == '.') j++;
}
@@ -1390,6 +1431,78 @@ static char *date2text(rlp_datetime *dt, char *fmt)
secs = dt->seconds;
if (secs > 59.4999) secs = 59.4999;
for(pos = i = 0; fmt[i] && pos < 70; i++) {
+#ifdef USE_WIN_SECURE
+ switch(fmt[i]) {
+ case 'Y':
+ if(dt->year) pos+=sprintf_s(res+pos, 80-pos, "%4d", dt->year);
+ else pos += sprintf_s(res+pos, 80-pos, "####"); break;
+ case 'y':
+ if(dt->year) pos+=sprintf_s(res+pos, 80-pos, "%02d", (dt->year %100));
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'Z':
+ if(dt->dom) pos+=sprintf_s(res+pos, 80-pos, "%02d", dt->dom);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'z':
+ if(dt->dom) pos+=sprintf_s(res+pos, 80-pos, "%d", dt->dom);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'X':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf_s(res+pos, 80-pos, "%s", dt_month[dt->month-1]);
+ else pos += sprintf_s(res+pos, 80-pos, "###"); break;
+ case 'x':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf_s(res+pos, 80-pos, "%s", dt_months[dt->month-1]);
+ else pos += sprintf_s(res+pos, 80-pos, "###"); break;
+ case 'V':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf_s(res+pos, 80-pos, "%02d", dt->month);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'v':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf_s(res+pos, 80-pos, "%d", dt->month);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'W':
+ if(dt->month >0 && dt->month < 13) pos+=sprintf_s(res+pos, 80-pos, "%c", dt_month[dt->month-1][0]);
+ else pos += sprintf_s(res+pos, 80-pos, "#"); break;
+ case 'D':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf_s(res+pos, 80-pos, "%s", dt_day[dt->dow-1]);
+ else pos += sprintf_s(res+pos, 80-pos, "###"); break;
+ case 'd':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf_s(res+pos, 80-pos, "%s", dt_days[dt->dow-1]);
+ else pos += sprintf_s(res+pos, 80-pos, "###"); break;
+ case 'E':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf_s(res+pos, 80-pos, "%02d", dt->dow);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'e':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf_s(res+pos, 80-pos, "%d", dt->dow);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'F':
+ if(dt->dow >0 && dt->dow < 8) pos+=sprintf_s(res+pos, 80-pos, "%c", dt_day[dt->dow-1][0]);
+ else pos += sprintf_s(res+pos, 80-pos, "#"); break;
+ case 'H':
+ if(dt->hours >=0 && dt->hours < 24) pos+=sprintf_s(res+pos, 80-pos, "%02d", dt->hours);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'h':
+ if(dt->hours >=0 && dt->hours < 24) pos+=sprintf_s(res+pos, 80-pos, "%d", dt->hours);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'M':
+ if(dt->minutes >=0 && dt->minutes < 60) pos+=sprintf_s(res+pos, 80-pos, "%02d", dt->minutes);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'm':
+ if(dt->minutes >=0 && dt->minutes < 60) pos+=sprintf_s(res+pos, 80-pos, "%d", dt->minutes);
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'S':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf_s(res+pos, 80-pos, "%02d", iround(secs));
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 's':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf_s(res+pos, 80-pos, "%d", iround(secs));
+ else pos += sprintf_s(res+pos, 80-pos, "##"); break;
+ case 'T':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf_s(res+pos, 80-pos, "%02.2lf", dt->seconds);
+ else pos += sprintf_s(res+pos, 80-pos, "##.##"); break;
+ case 't':
+ if(dt->seconds >=0.0 && dt->seconds < 60.0) pos+=sprintf_s(res+pos, 80-pos, "%.2lf", dt->seconds);
+ else pos += sprintf_s(res+pos, 80-pos, "##.##"); break;
+ default:
+ pos += sprintf_s(res+pos, 80-pos, "%c", fmt[i]); break;
+ }
+#else
switch(fmt[i]) {
case 'Y':
if(dt->year) pos+=sprintf(res+pos, "%4d", dt->year);
@@ -1460,7 +1573,8 @@ static char *date2text(rlp_datetime *dt, char *fmt)
default:
pos += sprintf(res+pos, "%c", fmt[i]); break;
}
- }
+#endif
+ }
res[pos] = 0;
return res;
}
@@ -1554,8 +1668,14 @@ double now_today()
{
double res = 0.0;
time_t ti = time(0L);
+#ifdef USE_WIN_SECURE
+ char dtbuff[80];
+ ctime_s(dtbuff, 80, &ti);
+ date_value(dtbuff+4, "x z H:M:S Y", &res);
+#else
date_value(ctime(&ti)+4, "x z H:M:S Y", &res);
+#endif
return res;
}
@@ -1574,158 +1694,6 @@ void split_date(double dv, int *y, int *mo, int *dom, int *dow, int *doy, int *h
//---------------------------------------------------------------------------
// Use the Delauney triangulation to create a 3D mesh of dispersed data
//
-class Triangle {
-public:
- Triangle *next;
- fPOINT3D pt[4];
-
- void SetRect();
- bool TestVertex(double x, double y);
-
-private:
- double cx, cy, r2; //circumcircle
- fRECT rc; //bounding rectangle
- lfPOINT ld[3]; //line eqations
-};
-
-class Triangulate {
-public:
- Triangle *trl;
-
- Triangulate(Triangle *t_list);
- bool AddEdge(fPOINT3D *p1, fPOINT3D *p2);
- bool AddVertex(fPOINT3D *v);
-
-private:
- typedef struct edge {
- edge *next;
- fPOINT3D p1, p2;
- };
- edge *edges;
-};
-
-void
-Triangle::SetRect()
-{
- int i, i2;
- double dy1, dy2, dx, dy;
- double m1, m2, mx1, mx2, my1, my2;
-
- //setup bounding rectangle
- rc.Xmin = rc.Xmax = pt[0].fx; rc.Ymin = rc.Ymax = pt[0].fy;
- for(i = 1; i < 3; i++) {
- if(pt[i].fx < rc.Xmin) rc.Xmin = pt[i].fx;
- if(pt[i].fx > rc.Xmax) rc.Xmax = pt[i].fx;
- if(pt[i].fy < rc.Ymin) rc.Ymin = pt[i].fy;
- if(pt[i].fy > rc.Ymax) rc.Ymax = pt[i].fy;
- }
- //get three line equations in 2D
- for(i = 0; i < 3; i++) {
- i2 = (i+1)%3;
- ld[i].fx = pt[i].fy;
- if(pt[i].fx != pt[i2].fx) {
- ld[i].fy = (pt[i2].fy - pt[i].fy) / (pt[i2].fx - pt[i].fx);
- }
- else ld[i].fy = HUGE_VAL;
- }
- //close polygon
- pt[3].fx = pt[0].fx; pt[3].fy = pt[0].fy; pt[3].fz = pt[0].fz;
- //circumcricle
- dy1 = fabs(pt[0].fy - pt[1].fy); dy2 = fabs(pt[1].fy - pt[2].fy);
- m1 = (pt[0].fx - pt[1].fx)/(pt[1].fy - pt[0].fy);
- m2 = (pt[1].fx - pt[2].fx)/(pt[2].fy - pt[1].fy);
- mx1 = (pt[0].fx + pt[1].fx)/2.0; my1 = (pt[0].fy + pt[1].fy)/2.0;
- mx2 = (pt[1].fx + pt[2].fx)/2.0; my2 = (pt[1].fy + pt[2].fy)/2.0;
- if(dy1 < 1.0e-16 && dy2 < 1.0e-16) {
- cy = (pt[0].fy + pt[1].fy + pt[2].fy)/3.0;
- cx = (pt[0].fx + pt[1].fx + pt[2].fx)/3.0;
- r2 = 0.0; return;
- }
- else if(dy1 < 1.0e-16) {
- cx = (pt[0].fx + pt[1].fx)/2.0; cy = m2 * (cx - mx2) + my2;
- }
- else if(dy2 < 1.0e-16) {
- cx = (pt[2].fx + pt[1].fx)/2.0; cy = m1 * (cx - mx1) + my1;
- }
- else {
- cx = (m1*mx1-m2*mx2+my2-my1)/(m1-m2); cy = m1*(cx - mx1) + my1;
- }
- dx = pt[1].fx - cx; dy = pt[1].fy - cy; r2 = dx * dx + dy * dy;
-}
-
-bool
-Triangle::TestVertex(double x, double y)
-{
- double dx, dy;
-
- dx = x-cx; dx = dx * dx; dy = y-cy; dy = dy * dy;
- return (dx+dy)<r2;
-}
-
-Triangulate::Triangulate(Triangle *t_list)
-{
- trl = t_list; edges = 0L;
-}
-
-bool
-Triangulate::AddEdge(fPOINT3D *p1, fPOINT3D *p2)
-{
- edge *ce, *ne;
-
- //if edge exists delete both the new and the existing edge
- for(ce = edges, ne = 0L; (ce); ) {
- if((ce->p1.fx == p1->fx && ce->p1.fy == p1->fy && ce->p1.fz == p1->fz
- && ce->p2.fx == p2->fx && ce->p2.fy == p2->fy && ce->p2.fz == p2->fz)
- || (ce->p2.fx == p1->fx && ce->p2.fy == p1->fy && ce->p2.fz == p1->fz
- && ce->p1.fx == p2->fx && ce->p1.fy == p2->fy && ce->p1.fz == p2->fz)) {
- if(ne) ne->next = ce->next;
- else edges = ce->next;
- delete ce; return true;
- }
- ne = ce; ce = ce->next;
- }
- //come here for new edge
- if(ne = new edge()) {
- ne->p1.fx = p1->fx; ne->p1.fy = p1->fy; ne->p1.fz = p1->fz;
- ne->p2.fx = p2->fx; ne->p2.fy = p2->fy; ne->p2.fz = p2->fz;
- ne->next = edges; edges = ne;
- }
- return false;
-}
-
-bool
-Triangulate::AddVertex(fPOINT3D *v)
-{
- Triangle *trc, *trn, *tr1;
- edge *ce, *ae;
-
- for(trc = trl, trn = 0L, edges = 0L; (trc);) {
- tr1 = trc->next;
- //delete triangles whose circumcircle enclose the new vertex
- if(trc->TestVertex(v->fx, v->fy)) {
- AddEdge(&trc->pt[0], &trc->pt[1]); AddEdge(&trc->pt[1], &trc->pt[2]);
- AddEdge(&trc->pt[0], &trc->pt[2]);
- if(trn) trn->next = trc->next;
- else trl = trc->next;
- if(trl == trc) trl = 0L;
- delete trc;
- }
- else trn = trc;
- trc = tr1;
- }
- //create new triangles from those edges which where found only once
- for(ce = edges; (ce); ) {
- if(trn = new Triangle()) {
- trn->pt[0].fx = ce->p1.fx; trn->pt[0].fy = ce->p1.fy; trn->pt[0].fz = ce->p1.fz;
- trn->pt[1].fx = ce->p2.fx; trn->pt[1].fy = ce->p2.fy; trn->pt[1].fz = ce->p2.fz;
- trn->pt[2].fx = v->fx; trn->pt[2].fy = v->fy; trn->pt[2].fz = v->fz;
- trn->SetRect(); trn->next = trl; trl = trn;
- ae = ce->next; delete(ce); ce = ae;
- }
- }
- return true;
-}
-
Triangle* Triangulate1(char *xr, char *yr, char *zr, DataObj *data)
{
AccRange *rX, *rY, *rZ;
diff --git a/rlplot.cpp b/rlplot.cpp
index 6e58fb9..5084b18 100755
--- a/rlplot.cpp
+++ b/rlplot.cpp
@@ -1,5118 +1,5242 @@
-//RLPlot.cpp, Copyright 2000-2006 R.Lackner
-//
-// This file is part of RLPlot.
-//
-// RLPlot is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// RLPlot is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with RLPlot; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-#include "rlplot.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-extern tag_Units Units[];
-extern char TmpTxt[];
-extern Default defs;
-
-GraphObj *CurrGO, *TrackGO; //Selected Graphic Objects
-Label *CurrLabel = 0L;
-Graph *CurrGraph = 0L;
-Axis **CurrAxes = 0L;
+//RLPlot.cpp, Copyright 2000-2006 R.Lackner
+//
+// This file is part of RLPlot.
+//
+// RLPlot is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// RLPlot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RLPlot; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#include "rlplot.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+extern tag_Units Units[];
+extern char TmpTxt[];
+extern Default defs;
+
+GraphObj *CurrGO, *TrackGO; //Selected Graphic Objects
+Label *CurrLabel = 0L;
+Graph *CurrGraph = 0L;
+Axis **CurrAxes = 0L;
dragHandle *CurrHandle = 0L;
-UndoObj Undo;
-int cGraphs = 0;
-int cPlots = 0;
-int cPages = 0;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// grapic objects
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-GraphObj::GraphObj(GraphObj *par, DataObj *d)
-{
- parent = par; data = d; Id = GO_UNKNOWN;
- type = moveable = 0; name = 0L;
- rDims.left = rDims.right = rDims.top = rDims.bottom = 0;
-}
-
-GraphObj::~GraphObj()
-{
- if(name)free(name);
- name = 0L;
- if(CurrGO == this) CurrGO = 0L;
- if(TrackGO == this) TrackGO = 0L;
-}
-
-double
-GraphObj::GetSize(int select)
-{
- if(parent) return parent->GetSize(select);
- else return defs.GetSize(select);
-}
-
-DWORD
-GraphObj::GetColor(int select){
- return defs.Color(select);
-}
+UndoObj Undo;
+int cGraphs = 0;
+int cPlots = 0;
+int cPages = 0;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// grapic objects
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GraphObj::GraphObj(GraphObj *par, DataObj *d)
+{
+ parent = par; data = d; Id = GO_UNKNOWN;
+ type = moveable = 0; name = 0L;
+ rDims.left = rDims.right = rDims.top = rDims.bottom = 0;
+}
+
+GraphObj::~GraphObj()
+{
+ if(name)free(name); name = 0L;
+ if(CurrGO == this) CurrGO = 0L;
+ if(TrackGO == this) TrackGO = 0L;
+}
+
+double
+GraphObj::GetSize(int select)
+{
+ if(parent) return parent->GetSize(select);
+ else return defs.GetSize(select);
+}
+
+DWORD
+GraphObj::GetColor(int select){
+ return defs.Color(select);
+}
void
GraphObj::RegGO(void *n)
{
((notary*)n)->AddRegGO(this);
}
-
-void *
-GraphObj::ObjThere(int x, int y)
-{
- if(IsInRect(&rDims, x, y)) return this;
- else return 0L;
-}
-
-void
-GraphObj::Track(POINT *p, anyOutput *o)
-{
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// This is a special object to read certain svg-settings from a *.rlp file
-svgOptions::svgOptions(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(defs.svgScript) free(defs.svgScript);
- if(defs.svgAttr) free(defs.svgAttr);
- defs.svgScript = defs.svgAttr = 0L;
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- if(script) defs.svgScript = script;
- if(svgattr) defs.svgAttr = svgattr;
- script = svgattr = 0L;
- }
- Id=GO_SVGOPTIONS;
-}
-
-svgOptions::~svgOptions()
-{
- if(script)free(script);
- script = 0L;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Symbols are graphic objects
-Symbol::Symbol(GraphObj *par, DataObj *d, double x, double y, int which,
- int xc, int xr, int yc, int yr):GraphObj(par, d)
-{
- //Symbols with no parent are part of a dialog
- FileIO(INIT_VARS);
- fPos.fx = x;
- fPos.fy = y;
- type = which;
- Id = GO_SYMBOL;
- if(xc >= 0 && xr >= 0 && yc >= 0 && yr >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*2)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- cssRef = 2;
- }
- }
-}
-
-Symbol::Symbol(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- SymFill.hatch = (LineDEF *) NULL;
- }
-}
-
-Symbol::~Symbol()
-{
- Command(CMD_FLUSH, 0L, 0L);
-}
-
-double
-Symbol::GetSize(int select)
-{
- switch(select) {
- case SIZE_MINE:
- case SIZE_SYMBOL:
- return size;
- case SIZE_SYM_LINE:
- return SymLine.width;
- case SIZE_XPOS:
- return fPos.fx;
- case SIZE_YPOS:
- return fPos.fy;
- default:
- return parent ? parent->GetSize(select) : defs.GetSize(select);
- }
-}
-
-bool
-Symbol::SetSize(int select, double value)
-{
- switch(select & 0xfff){
- case SIZE_MINE:
- case SIZE_SYMBOL:
- size = value;
- return true;
- case SIZE_SYM_LINE:
- SymLine.width = value;
- return true;
- case SIZE_XPOS:
- fPos.fx = value;
- return true;
- case SIZE_YPOS:
- fPos.fy = value;
- return true;
- }
- return false;
-}
-
-DWORD
-Symbol::GetColor(int select)
-{
- switch(select) {
- case COL_SYM_LINE:
- return SymLine.color;
- case COL_SYM_FILL:
- return SymFill.color;
- default:
- return parent ? parent->GetColor(select) : defs.Color(select);
- }
-}
-
-bool
-Symbol::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_SYM_LINE:
- SymLine.color = col;
- if(SymTxt) SymTxt->ColTxt = col;
- return true;
- case COL_SYM_FILL:
- SymFill.color = col;
- return true;
- default:
- return false;
- }
-}
-
-void
-Symbol::DoPlot(anyOutput *target)
-{
- int ix, iy, rx, ry, atype;
- lfPOINT fip;
- POINT pts[5];
- FillDEF cf;
-
- if(size <= 0.001) return;
- atype = (type & 0xfff);
- memcpy(&cf, &SymFill, sizeof(FillDEF));
- if(atype == SYM_CIRCLEF || atype == SYM_RECTF || atype == SYM_TRIAUF ||
- atype == SYM_TRIADF || atype == SYM_DIAMONDF) cf.color = SymLine.color;
- if(type & SYM_POS_PARENT) {
- if(!parent) return;
- fip.fx = parent->GetSize(SIZE_XCENTER);
- fip.fy = parent->GetSize(SIZE_YCENTER);
- }
- else if(!target->fp2fip(&fPos, &fip)) return;
- ix = iround(fip.fx); iy = iround(fip.fy);
- target->SetLine(&SymLine);
- switch(atype){
- default:
- case SYM_CIRCLE: //circle
- case SYM_CIRCLEF: //filled circle
- rx = target->un2ix(size/2.0); ry = target->un2iy(size/2.0);
- target->SetFill(&cf);
- target->oCircle(ix-rx, iy-ry, ix+rx+1, iy+ry+1, name);
- rx--;ry--; //smaller marking rectangle
- break;
- case SYM_RECT: //rectange (square)
- case SYM_RECTF: //filled rectangle
- rx = target->un2ix(size/2.25676);
- ry = target->un2iy(size/2.25676);
- target->SetFill(&cf);
- target->oRectangle(ix-rx, iy-ry, ix+rx+1, iy+ry+1, name);
- break;
- case SYM_TRIAU: //triangles up and down, open or closed
- case SYM_TRIAUF: case SYM_TRIAD: case SYM_TRIADF:
- rx = target->un2ix(size/1.48503);
- ry = target->un2iy(size/1.48503);
- target->SetFill(&cf);
- pts[0].x = pts[3].x = ix - rx; pts[1].x = ix; pts[2].x = ix+rx;
- if(atype == SYM_TRIAU || atype == SYM_TRIAUF) { //patch by anonymous
- pts[0].y = pts[2].y = pts[3].y = iy+target->un2iy(size*0.38878f);
- pts[1].y = iy-target->un2iy(size*0.77756f);
- }
- else {
- pts[0].y = pts[2].y = pts[3].y = iy-target->un2iy(size*0.38878f);
- pts[1].y = iy+target->un2iy(size*0.77756f);
- }
- target->oPolygon(pts, 4);
- rx--; ry--;
- break;
- case SYM_DIAMOND: case SYM_DIAMONDF:
- rx = target->un2ix(size/1.59588f);
- ry = target->un2iy(size/1.59588f);
- target->SetFill(&cf);
- pts[0].x = pts[2].x = pts[4].x = ix;
- pts[0].y = pts[4].y = iy -ry;
- pts[1].x = ix +rx; pts[1].y = pts[3].y = iy;
- pts[2].y = iy +ry; pts[3].x = ix-rx;
- target->oPolygon(pts, 5);
- rx--; ry--;
- break;
- case SYM_STAR: //star is a combination of + and x symbols
- case SYM_PLUS: //draw a + sign
- case SYM_HLINE: case SYM_VLINE:
- rx = target->un2ix(size/2.0f);
- ry = target->un2iy(size/2.0f);
- pts[0].x = pts[1].x = ix;
- pts[0].y = iy - ry; pts[1].y = iy + ry +1;
- if(type != SYM_HLINE) target->oPolyline(pts, 2);
- pts[0].x = ix -rx; pts[1].x = ix + rx +1;
- pts[0].y = pts[1].y = iy;
- if(atype != SYM_VLINE) target->oPolyline(pts, 2);
- if(atype == SYM_VLINE){ rx = 2; break;}
- if(atype == SYM_HLINE){ ry = 2; break;}
- if(atype == SYM_PLUS) break; //continue with x symbol for star
- case SYM_CROSS: //draw a x symbol
- rx = target->un2ix(size/2.5);
- ry = target->un2iy(size/2.5);
- pts[0].x = ix - rx; pts[1].x = ix + rx;
- pts[0].y = iy - ry; pts[1].y = iy + ry;
- target->oPolyline(pts, 2);
- Swap(pts[0].y, pts[1].y);
- target->oPolyline(pts, 2);
- break;
- case SYM_TEXT:
- if(!SymTxt) Command(CMD_SETTEXT, (void *)"text", target);
- if(!SymTxt || !SymTxt->text || !SymTxt->text[0])return;
- SymTxt->iSize = target->un2iy(SymTxt->fSize = size *1.5);
- target->SetTextSpec(SymTxt);
- fmtText(target, ix, iy, SymTxt->text);
- if (target->oGetTextExtent(SymTxt->text, 0, &rx, &ry)){
- rx >>= 1; ry >>= 1;
- }
- else rx = ry = 10;
- }
- rDims.left = ix-rx-1; rDims.right = ix+rx+1;
- rDims.top = iy-ry-1; rDims.bottom = iy+ry+1;
-}
-
-bool
-Symbol::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- char *tmptxt;
- AccRange *ac;
- int i, r, c;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(SymTxt) {
- if(SymTxt->text) free(SymTxt->text);
- free(SymTxt);
- }
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name)free(name); name = 0L;
- return true;
- case CMD_REDRAW:
- //if we come here its most likely the result of Undo
- if(parent && parent->Id==GO_REGRESSION)
- return parent->Command(CMD_MRK_DIRTY, 0L, o);
- return false;
- case CMD_GETTEXT:
- if(SymTxt && SymTxt->text && tmpl) {
- strcpy((char*)tmpl, SymTxt->text);
- return true;
- }
- return false;
- case CMD_SYMTEXT_UNDO:
- if(SymTxt && SymTxt->text){
- Undo.String(this, &SymTxt->text, UNDO_CONTINUE);
- if(tmpl) {
- if(SymTxt->text = (char*)realloc(SymTxt->text, strlen((char*)tmpl))+2)
- strcpy(SymTxt->text, (char*)tmpl);
- }
- else if(SymTxt->text) SymTxt->text[0] = 0;
- return true;
- }
- //fall through if its new
- case CMD_SYMTEXT: case CMD_SETTEXT:
- if(!SymTxt && (SymTxt = (TextDEF *) calloc(1, sizeof(TextDEF)))) {
- SymTxt->ColTxt = SymLine.color; SymTxt->fSize = size*1.5;
- SymTxt->ColBg = parent ? parent->GetColor(COL_BG) : 0x00ffffffL;
- SymTxt->Align = TXA_VCENTER | TXA_HCENTER;
- SymTxt->Style = TXS_NORMAL; SymTxt->Mode = TXM_TRANSPARENT;
- SymTxt->Font = FONT_HELVETICA; SymTxt->text = 0L;
- }
- if(!SymTxt) return false;
- if(tmpl) {
- if(SymTxt->text = (char*)realloc(SymTxt->text, strlen((char*)tmpl)+1))
- strcpy(SymTxt->text, (char*)tmpl);
- }
- else if(SymTxt->text) SymTxt->text[0] = 0;
- return true;
- case CMD_SYM_TYPE:
- if(tmpl)type = *((int*)tmpl);
- return true;
- case CMD_GETTEXTDEF:
- if(!SymTxt || !tmpl) return false;
- memcpy(tmpl, SymTxt, sizeof(TextDEF));
- return true;
- case CMD_SYMTEXTDEF: case CMD_SETTEXTDEF:
- if(!tmpl)return false;
- if(SymTxt) tmptxt = SymTxt->text;
- else tmptxt = 0L;
- if(!SymTxt && !(SymTxt = (TextDEF *) calloc(1, sizeof(TextDEF)))) return false;
- memcpy(SymTxt, tmpl, sizeof(TextDEF));
- SymTxt->text = tmptxt;
- return true;
- case CMD_SYM_RANGETEXT: case CMD_RANGETEXT:
- if(!data || !tmpl) return false;
- if(!(tmptxt = (char*)malloc(500)))return false;
- if((ac = new AccRange((char*)tmpl)) && ac->GetFirst(&c, &r)) {
- for(i = 0, tmptxt[0] = 0; i <= idx; i++) ac->GetNext(&c, &r);
- data->GetText(r, c, tmptxt, 500);
- delete(ac);
- }
- Command(CMD_SETTEXT, tmptxt, 0L);
- free(tmptxt);
- return true;
- case CMD_SET_DATAOBJ:
- Id = GO_SYMBOL;
- data = (DataObj *)tmpl;
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- o->ShowMark(&rDims, MRK_INVERT);
- CurrGO = this;
- return true;
- }
- break;
- }
- break;
- case CMD_UPDATE:
- if(ssRef && cssRef >1 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
- return true;
- }
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Bubbles are graphic objects
-Bubble::Bubble(GraphObj *par, DataObj *d, double x, double y, double s, int which,
- FillDEF *fill, LineDEF *outline, int xc, int xr, int yc, int yr, int sc,
- int sr):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- fPos.fx = x; fPos.fy = y; fs = s;
- type = which;
- if(fill) {
- memcpy(&BubbleFill,fill, sizeof(FillDEF));
- if(BubbleFill.hatch) memcpy(&BubbleFillLine, BubbleFill.hatch, sizeof(LineDEF));
- }
- BubbleFill.hatch = &BubbleFillLine;
- if(outline)memcpy(&BubbleLine, outline, sizeof(LineDEF));
- Id = GO_BUBBLE;
- if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || sc >= 0 || sr >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- ssRef[2].x = sc; ssRef[2].y = sr;
- cssRef = 3;
- }
- }
-}
-
-Bubble::Bubble(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-Bubble::~Bubble()
-{
- Command(CMD_FLUSH, 0L, 0L);
-}
-
-void
-Bubble::DoPlot(anyOutput *o)
-{
- int x1, y1, x2, y2, ix, iy, tmp;
- double fix, fiy;
-
- o->SetLine(&BubbleLine);
- o->SetFill(&BubbleFill);
- switch(type & 0x0f0) {
- case BUBBLE_UNITS:
- fix = o->un2fix(fs); fiy = o->un2fiy(fs);
- break;
- case BUBBLE_XAXIS:
- fix = (o->fx2fix(fPos.fx+fs) - o->fx2fix(fPos.fx-fs))/2.0;
- fiy = fix * (o->un2fiy(10.0f)/o->un2fix(10.0f)); //x and y resolution different ?
- break;
- case BUBBLE_YAXIS:
- fix = (o->fy2fiy(fPos.fy-fs) - o->fy2fiy(fPos.fy+fs))/2.0;
- fiy = fix * (o->un2fiy(10.0f)/o->un2fix(10.0f)); //x and y resolution different ?
- break;
- }
- fix = fix < 0.0 ? -fix : fix; //sign must be positive
- fiy = fiy < 0.0 ? -fiy : fiy;
- rDims.left = rDims.right = iround(o->fx2fix(fPos.fx));
- rDims.top = rDims.bottom = iround(o->fy2fiy(fPos.fy));
- switch(type & 0x00f) {
- case BUBBLE_CIRCLE:
- ix = (int)(fix/2.0); iy = (int)(fiy/2.0);
- tmp = iround(o->fx2fix(fPos.fx)); x1 = tmp - ix; x2 = tmp + ix;
- tmp = iround(o->fy2fiy(fPos.fy)); y1 = tmp - iy; y2 = tmp + iy;
- o->oCircle(x1, y1, x2, y2, name);
- UpdateMinMaxRect(&rDims, x1, y1); UpdateMinMaxRect(&rDims, x2, y2);
- break;
- case BUBBLE_SQUARE:
- if((type & 0xf00) == BUBBLE_CIRCUM) {
- ix = iround(fix*.392699081); iy = iround(fiy*.392699081);
- }
- else if((type & 0xf00) == BUBBLE_AREA) {
- ix = iround(fix*.443113462); iy = iround(fiy*.443113462);
- }
- else {
- ix = iround(fix*.353553391); iy = iround(fiy*.353553391);
- }
- tmp = iround(o->fx2fix(fPos.fx)); x1 = tmp - ix; x2 = tmp + ix;
- tmp = iround(o->fy2fiy(fPos.fy)); y1 = tmp - iy; y2 = tmp + iy;
- o->oRectangle(x1, y1, x2, y2, name);
- UpdateMinMaxRect(&rDims, x1, y1); UpdateMinMaxRect(&rDims, x2, y2);
- break;
- case BUBBLE_UPTRIA:
- case BUBBLE_DOWNTRIA:
- if((type & 0xf00) == BUBBLE_CIRCUM) {
- fix *= .523598775; fiy *= .523598775;
- }
- else if((type & 0xf00) == BUBBLE_AREA) {
- fix *= .673386843; fiy *= .673386843;
- }
- else {
- fix *=.433012702; fiy *= .433012702;
- }
- ix = iround(fix); iy = iround(fiy*.57735);
- tmp = iround(o->fx2fix(fPos.fx));
- pts[0].x = pts[3].x = tmp - ix; pts[1].x = tmp + ix; pts[2].x = tmp;
- tmp = iround(o->fy2fiy(fPos.fy));
- if((type & 0x00f) == BUBBLE_UPTRIA) {
- pts[0].y = pts[1].y = pts[3].y = tmp + iy;
- pts[2].y = tmp - iround(fiy*1.1547);
- }
- else {
- pts[0].y = pts[1].y = pts[3].y = tmp - iy;
- pts[2].y = tmp + iround(fiy*1.1547);
- }
- o->oPolygon(pts, 4);
- UpdateMinMaxRect(&rDims, pts[0].x, pts[0].y);
- UpdateMinMaxRect(&rDims, pts[1].x, pts[2].y);
- break;
- }
-}
-
-void
-Bubble::DoMark(anyOutput *o, bool mark)
-{
- if(mark) {
- BubbleFillLine.color ^= 0x00ffffffL;
- BubbleFill.color ^= 0x00ffffffL;
- DoPlot(o);
- BubbleFill.color ^= 0x00ffffffL;
- BubbleFillLine.color ^= 0x00ffffffL;
- }
- else {
- if(parent) parent->DoPlot(o);
- else DoPlot(o);
- }
- o->UpdateRect(&rDims, false);
-}
-
-bool
-Bubble::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- bool bSelected = false;
- unsigned long n, s;
- POINT p;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name)free(name); name = 0L;
- return true;
- case CMD_LEGEND:
- if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
- ((Legend*)tmpl)->HasFill(&BubbleLine, &BubbleFill);
- break;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, p.x = mev->x, p.y = mev->y) && !CurrGO) {
- switch(type & 0x00f) {
- case BUBBLE_CIRCLE:
- n = s = p.x - ((rDims.right+rDims.left)>>1);
- s *= n;
- n = p.y - ((rDims.bottom+rDims.top)>>1);
- n = isqr(s += n*n) -2;
- bSelected = ((unsigned)((rDims.right-rDims.left)>>1) > n);
- break;
- case BUBBLE_SQUARE:
- bSelected = true;
- break;
- case BUBBLE_UPTRIA:
- case BUBBLE_DOWNTRIA:
- if(!(bSelected = IsInPolygon(&p, pts, 4)))
- bSelected = IsCloseToPL(p, pts, 4);
- break;
- }
- if(bSelected) o->ShowMark(this, MRK_GODRAW);
- return bSelected;
- }
- break;
- }
- break;
- case CMD_SET_DATAOBJ:
- Id = GO_BUBBLE;
- data = (DataObj*)tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >2 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &fs);
- return true;
- }
- return false;
- case CMD_BUBBLE_ATTRIB:
- if(tmpl) {
- type &= ~0xff0;
- type |= (*((int*)tmpl) & 0xff0);
- return true;
- }
- return false;
- case CMD_BUBBLE_TYPE:
- if(tmpl) {
- type &= ~0x00f;
- type |= (*((int*)tmpl) & 0x00f);
- return true;
- }
- return false;
- case CMD_BUBBLE_FILL:
- if(tmpl) {
- BubbleFill.type = ((FillDEF*)tmpl)->type;
- BubbleFill.color = ((FillDEF*)tmpl)->color;
- BubbleFill.scale = ((FillDEF*)tmpl)->scale;
- if(((FillDEF*)tmpl)->hatch)
- memcpy(&BubbleFillLine, ((FillDEF*)tmpl)->hatch, sizeof(LineDEF));
- }
- return true;
- case CMD_BUBBLE_LINE:
- if(tmpl) memcpy(&BubbleLine, tmpl, sizeof(LineDEF));
- return true;
- case CMD_AUTOSCALE:
- return DoAutoscale(o);
- break;
- }
- return false;
-}
-bool
-Bubble::DoAutoscale(anyOutput *o)
+void *
+GraphObj::ObjThere(int x, int y)
{
- double dx, dy;
+ if(IsInRect(&rDims, x, y)) return this;
+ else return 0L;
+}
- switch(type & 0x0f0) {
- case BUBBLE_XAXIS: case BUBBLE_YAXIS:
- dx = dy = fs/2.0; break;
- case BUBBLE_UNITS:
- dx = fPos.fx/20; dy = fPos.fy/20; break;
+void
+GraphObj::Track(POINT *p, anyOutput *o)
+{
+}
+
+double
+GraphObj::DefSize(int select)
+{
+ if(parent) return parent->DefSize(select);
+ else return defs.GetSize(select);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// This is a special object to read certain svg-settings from a *.rlp file
+svgOptions::svgOptions(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(defs.svgScript) free(defs.svgScript);
+ if(defs.svgAttr) free(defs.svgAttr);
+ defs.svgScript = defs.svgAttr = 0L;
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ if(script) defs.svgScript = script;
+ if(svgattr) defs.svgAttr = svgattr;
+ script = svgattr = 0L;
}
- ((Plot*)parent)->CheckBounds(fPos.fx+dx, fPos.fy-dy);
- ((Plot*)parent)->CheckBounds(fPos.fx-dx, fPos.fy+dy);
- return true;
+ Id=GO_SVGOPTIONS;
}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Bars are graphic objects
-Bar::Bar(GraphObj *par, DataObj *d, double x, double y, int which,int xc, int xr,
- int yc, int yr):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- parent = par;
- fPos.fx = x;
- fPos.fy = y;
- type = which;
- if(type & BAR_RELWIDTH) size = 60.0;
- data = d;
- Id = GO_BAR;
- if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*2)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- cssRef = 2;
- }
- }
-}
-
-Bar::Bar(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-Bar::~Bar()
-{
- if(mo) DelBitmapClass(mo); mo = 0L;
- Command(CMD_FLUSH, 0L, 0L);
-}
-
-double
-Bar::GetSize(int select)
-{
- switch(select){
- case SIZE_XPOS: return fPos.fx;
- case SIZE_YPOS: return fPos.fy;
- }
- return 0.0;
-}
-
-bool
-Bar::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_BAR:
- size = value;
- return true;
- case SIZE_BAR_LINE:
- BarLine.width = value;
- return true;
- case SIZE_XBASE:
- BarBase.fx = value;
- return true;
- case SIZE_YBASE:
- BarBase.fy = value;
- return true;
- }
- return false;
-}
-
-bool
-Bar::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_BAR_LINE:
- BarLine.color = col;
- return true;
- case COL_BAR_FILL:
- BarFill.color = col;
- return true;
- }
- return false;
-}
-
-void
-Bar::DoPlot(anyOutput *target)
-{
- int w;
- double fBase, rsize;
- POINT pts[2];
-
- if(!parent || size <= 0.001) return;
- target->SetLine(&BarLine);
- target->SetFill(&BarFill);
- switch(type & 0xff) {
- case BAR_VERTU: case BAR_VERTT: case BAR_VERTB:
- switch(type & 0xff) {
- case BAR_VERTB:
- fBase = parent->GetSize(SIZE_BOUNDS_BOTTOM);
- break;
- case BAR_VERTT:
- fBase = parent->GetSize(SIZE_BOUNDS_TOP);
- break;
- case BAR_VERTU:
- fBase = BarBase.fy;
- break;
- }
- if(type & BAR_RELWIDTH) {
- rsize = size * parent->GetSize(SIZE_BARMINX)/100.0;
- pts[0].x = iround(target->fx2fix(fPos.fx - rsize/2.0));
- pts[1].x = iround(target->fx2fix(fPos.fx + rsize/2.0));
- }
- else {
- w = target->un2ix(size);
- pts[0].x = iround(target->fx2fix(fPos.fx)) - (w>>1);
- pts[1].x = pts[0].x + w;
- }
- if(type & BAR_CENTERED) {
- pts[0].y = iround(target->fy2fiy(fBase - (fPos.fy - fBase)));
- pts[1].y = iround(target->fy2fiy(fBase + (fPos.fy - fBase)));
- }
- else {
- pts[0].y = iround(target->fy2fiy(fBase));
- pts[1].y = iround(target->fy2fiy(fPos.fy));
- }
- break;
- case BAR_HORU: case BAR_HORR: case BAR_HORL:
- switch(type & 0xff) {
- case BAR_HORL:
- fBase = parent->GetSize(SIZE_BOUNDS_LEFT);
- break;
- case BAR_HORR:
- fBase = parent->GetSize(SIZE_BOUNDS_RIGHT);
- break;
- case BAR_HORU:
- fBase = BarBase.fx;
- break;
- }
- if(type & BAR_RELWIDTH) {
- rsize = size * parent->GetSize(SIZE_BARMINY)/100.0;
- pts[0].y = iround(target->fy2fiy(fPos.fy - rsize/2.0));
- pts[1].y = iround(target->fy2fiy(fPos.fy + rsize/2.0));
- }
- else {
- w = target->un2iy(size);
- pts[0].y = target->fy2iy(fPos.fy) - w/2;
- pts[1].y = pts[0].y+w;
- }
- if(type & BAR_CENTERED) {
- pts[0].x = target->fx2ix(fBase - (fPos.fx - fBase));
- pts[1].x = target->fx2ix(fBase + (fPos.fx - fBase));
- }
- else {
- pts[0].x = target->fx2ix(fBase);
- pts[1].x = target->fx2ix(fPos.fx);
- }
- break;
- default:
- return;
- }
- if(pts[0].x == pts[1].x || pts[0].y == pts[1].y) {
- target->oSolidLine(pts);
- }
- else target->oRectangle(pts[0].x, pts[0].y, pts[1].x, pts[1].y, name);
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
-}
-void
-Bar::DoMark(anyOutput *o, bool mark)
+svgOptions::~svgOptions()
{
- int i;
+ if(script)free(script);
+ script = 0L;
+}
- if(mark){
- memcpy(&mrc, &rDims, sizeof(RECT));
- 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);
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Symbols are graphic objects
+Symbol::Symbol(GraphObj *par, DataObj *d, double x, double y, int which,
+ int xc, int xr, int yc, int yr):GraphObj(par, d)
+{
+ //Symbols with no parent are part of a dialog
+ FileIO(INIT_VARS);
+ fPos.fx = x;
+ fPos.fy = y;
+ type = which;
+ Id = GO_SYMBOL;
+ if(xc >= 0 && xr >= 0 && yc >= 0 && yr >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*2)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ cssRef = 2;
+ }
}
- else RestoreRectBitmap(&mo, &mrc, o);
}
-
-bool
-Bar::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- FillDEF *TmpFill;
- lfPOINT bl;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name)free(name); name = 0L;
- return true;
- case CMD_LEGEND:
- if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
- ((Legend*)tmpl)->HasFill(&BarLine, &BarFill);
- break;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- o->ShowMark(CurrGO = this, MRK_GODRAW);
- return true;
- }
- break;
- }
- return false;
- case CMD_BAR_FILL:
- TmpFill = (FillDEF *)tmpl;
- if(TmpFill) {
- BarFill.type = TmpFill->type;
- BarFill.color = TmpFill->color;
- BarFill.scale = TmpFill->scale;
- if(TmpFill->hatch) memcpy(&HatchLine, TmpFill->hatch, sizeof(LineDEF));
- }
- return true;
- case CMD_BAR_TYPE:
- if(tmpl) type = *((int*)tmpl);
- return true;
- case CMD_SET_DATAOBJ:
- Id = GO_BAR;
- data = (DataObj *)tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >1 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
- switch(type & 0xff) {
- case BAR_VERTU:
- case BAR_VERTT:
- case BAR_VERTB:
- bl.fx = fPos.fx;
- switch (type & 0xff) {
- case BAR_VERTU:
- bl.fy = BarBase.fy;
- break;
- case BAR_VERTT:
- case BAR_VERTB:
- bl.fy = 0.0f; //cannot resolve
- break;
- }
- if(type & BAR_CENTERED) bl.fy -= fPos.fy;
- break;
- case BAR_HORU:
- case BAR_HORR:
- case BAR_HORL:
- bl.fy = fPos.fy;
- switch(type & 0xff) {
- case BAR_HORU:
- bl.fx = BarBase.fx;
- case BAR_HORR:
- case BAR_HORL:
- bl.fx = 0.0f; //cannot resolve
- }
- if(type & BAR_CENTERED) bl.fx -= fPos.fx;
- break;
- }
- ((Plot*)parent)->CheckBounds(bl.fx, bl.fy);
- return true;
- }
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Data line is a graphic object
-DataLine::DataLine(GraphObj *par, DataObj *d, char *xrange, char *yrange):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- Id = GO_DATALINE;
- if(xrange)ssXref = strdup(xrange); if(yrange)ssYref = strdup(yrange);
- SetValues();
-}
-
-DataLine::DataLine(GraphObj *par, DataObj *d, lfPOINT *val, long nval):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- Values = val; nPnt = nval; nPntSet = nPnt-1;
- Id = GO_DATALINE;
-}
-
-DataLine::DataLine(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-DataLine::~DataLine()
-{
- if(Values)free(Values); Values = 0L;
- if(pts) free(pts); pts = 0L;
- if(ssXref) free(ssXref); ssXref = 0L;
- if(ssYref) free(ssYref); ssYref = 0L;
- if(mo) DelBitmapClass(mo); mo = 0L;
- if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);
-}
-
-bool
-DataLine::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_DATA_LINE:
- LineDef.color = col;
- return true;
- }
- return false;
-}
-
-void
-DataLine::DoPlot(anyOutput *target)
-{
- int i;
- lfPOINT fip;
- POINT pn, *tmppts;
-
- if(!Values || nPntSet < 1) return;
- if (nPntSet >= nPnt) nPntSet = nPnt-1;
- if(mo) DelBitmapClass(mo); mo = 0L;
- if(pts) free(pts); pts = 0L;
- if((type & 0xff) == 9 || (type & 0xff) == 10) //splines
- pts = (POINT *)malloc(sizeof(POINT)*1000);
- else if(type & 0xff) pts = (POINT *)malloc(sizeof(POINT)*(nPntSet+2)*2);
- else pts = (POINT *)malloc(sizeof(POINT)*(nPntSet+2));
- if(!pts) return;
- if(max.fx > min.fx && max.fy > min.fy) dirty = false;
- else if(dirty) Command(CMD_AUTOSCALE, 0L, target);
- cp = 0;
- switch(type & 0x0f) {
- case 0: default:
- for (i = 0; i <= nPntSet; i++){
- target->fp2fip(Values+i, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- AddToPolygon(&cp, pts, &pn);
- }
- break;
- case 5:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- target->fp2fip(Values+1, &fip);
- pn.y += (pn.y -iround(fip.fy))>>1;
- AddToPolygon(&cp, pts, &pn);
- case 1:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(+fip.fy);
- for (i = 0; i <= nPntSet; i++){
- target->fp2fip(Values+i, &fip);
- pn.x = iround(fip.fx); AddToPolygon(&cp, pts, &pn);
- pn.y = iround(fip.fy); AddToPolygon(&cp, pts, &pn);
- }
- if((type &0xf) == 5) {
- target->fp2fip(Values+i-2, &fip);
- pn.x += (pn.x - iround(fip.fx))>>1;
- AddToPolygon(&cp, pts, &pn);
- }
- break;
- case 6:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- target->fp2fip(Values+1, &fip);
- pn.x += (pn.x - iround(fip.fx))>>1;
- AddToPolygon(&cp, pts, &pn);
- case 2:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- for (i = 0; i <= nPntSet; i++){
- target->fp2fip(Values+i, &fip);
- pn.y = iround(fip.fy); AddToPolygon(&cp, pts, &pn);
- pn.x = iround(fip.fx); AddToPolygon(&cp, pts, &pn);
- }
- if((type &0xf) == 6) {
- target->fp2fip(Values+i-2, &fip);
- pn.y += (pn.y - iround(fip.fy))>>1;
- AddToPolygon(&cp, pts, &pn);
- }
- break;
- case 7:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- target->fp2fip(Values+1, &fip);
- pn.x += (pn.x - iround(fip.fx))>>1;
- AddToPolygon(&cp, pts, &pn);
- case 3:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- for (i = 0; i <= nPntSet; i++){
- target->fp2fip(Values+i, &fip);
- pn.x = (pn.x + iround(fip.fx))>>1; AddToPolygon(&cp, pts, &pn);
- pn.y = iround(fip.fy); AddToPolygon(&cp, pts, &pn);
- pn.x = iround(fip.fx);
- }
- AddToPolygon(&cp, pts, &pn);
- if((type &0xf) == 7) {
- target->fp2fip(Values+i-2, &fip);
- pn.x += (pn.x - iround(fip.fx))>>1;
- AddToPolygon(&cp, pts, &pn);
- }
- break;
- case 8:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- target->fp2fip(Values+1, &fip);
- pn.y += (pn.y - iround(fip.fy))>>1;
- AddToPolygon(&cp, pts, &pn);
- case 4:
- target->fp2fip(Values, &fip);
- pn.x = iround(fip.fx); pn.y = iround(fip.fy);
- for (i = 0; i <= nPntSet; i++){
- target->fp2fip(Values+i, &fip);
- pn.y = (pn.y + iround(fip.fy))>>1; AddToPolygon(&cp, pts, &pn);
- pn.x = iround(fip.fx); AddToPolygon(&cp, pts, &pn);
- pn.y = iround(fip.fy);
- }
- AddToPolygon(&cp, pts, &pn);
- if((type &0xf) == 8) {
- target->fp2fip(Values+i-2, &fip);
- pn.y += (pn.y - iround(fip.fy))>>1;
- AddToPolygon(&cp, pts, &pn);
- }
- break;
- case 9: case 10:
- DrawSpline(target);
- break;
- }
- if(cp < 2) return;
- if(isPolygon) { //for mark polygon only !!
- AddToPolygon(&cp, pts, pts);
- }
- else{
- 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);
- for(i = 2; i < cp; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
- i = 2*target->un2ix(LineDef.width); //increase size of rectangle for marks
- IncrementMinMaxRect(&rDims, i);
-}
-
-void
-DataLine::DoMark(anyOutput *o, bool mark)
-{
- if(pts && cp && o){
- if(mark){
- memcpy(&mrc, &rDims, sizeof(RECT));
- IncrementMinMaxRect(&mrc, 6 + o->un2ix(LineDef.width));
- mo = GetRectBitmap(&mrc, o);
- InvertLine(pts, cp, &LineDef, &mrc, o, mark);
- }
- else if(mo) RestoreRectBitmap(&mo, &mrc, o);
- }
-}
-
-bool
-DataLine::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- bool bFound = false;
- POINT p1;
- int i;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPntSet <1)
- return false;
- if(isPolygon && IsInPolygon(&p1, pts, cp)) bFound = true;
- if(bFound || IsCloseToPL(p1,pts,cp))
- return o->ShowMark(this, MRK_GODRAW);
- }
- break;
- case CMD_SET_DATAOBJ:
- Id = isPolygon ? GO_DATAPOLYGON : GO_DATALINE;
- data = (DataObj*)tmpl;
- return true;
- case CMD_MRK_DIRTY:
- dirty= true;
- case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, 0L);
- return false;
- case CMD_LEGEND:
- if(tmpl && ((GraphObj*)tmpl)->Id == GO_LEGEND) {
- if(Id == GO_DATALINE) ((Legend*)tmpl)->HasFill(&LineDef, 0L);
- }
- break;
- case CMD_SET_LINE:
- if(tmpl) memcpy(&LineDef, tmpl, sizeof(LineDEF));
- return true;
- case CMD_UPDATE:
- Undo.DataMem(this, (void**)&Values, nPnt * sizeof(lfPOINT), &nPnt, UNDO_CONTINUE);
- Undo.ValLong(this, &nPntSet, UNDO_CONTINUE);
- SetValues();
- return true;
- case CMD_AUTOSCALE:
- if(nPntSet < 1 || !Values) return false;
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- if(dirty) {
- min.fx = max.fx = Values[0].fx; min.fy = max.fy = Values[0].fy;
- for (i = 1; i <= nPntSet; i++){
- min.fx = Values[i].fx < min.fx ? Values[i].fx : min.fx;
- max.fx = Values[i].fx > max.fx ? Values[i].fx : max.fx;
- min.fy = Values[i].fy < min.fy ? Values[i].fy : min.fy;
- max.fy = Values[i].fy > max.fy ? Values[i].fy : max.fy;
- }
- }
- ((Plot*)parent)->CheckBounds(min.fx, min.fy);
- ((Plot*)parent)->CheckBounds(max.fx, max.fy);
- dirty = false;
- return true;
- }
- return false;
- }
- return false;
-}
-
-void
-DataLine::SetValues()
-{
- AccRange *rX, *rY1=0L, *rY2=0L;
- int i, j, k, l, m, n;
- double x, y;
- char *yref1 = 0L, *yref2 = 0L;
- lfPOINT *tmpValues = Values;
-
- if(!ssXref || !ssYref) return;
- if(!(yref1 = strdup(ssYref)))return;
- for(i = 0; yref1[i]; i++) {
- if(yref1[i] == ';') {
- yref1[i++] = 0;
- while(yref1[i] && yref1[i] < 33) i++;
- yref2 = strdup(yref1+i);
- }
- }
- nPnt = nPntSet = 0;
- min.fx = min.fy = HUGE_VAL; max.fx = max.fy = -HUGE_VAL;
- rX = new AccRange(ssXref); rY1 = new AccRange(yref1);
- if(!rX || !rY1){
- if(yref1) free(yref1); if(yref2) free(yref2);
- if(rX) delete(rX); if(rY1) delete(rY1);
- return;
- }
- if(yref2 &&((nPnt = rX->CountItems()) == (rY1->CountItems()))) {
- if(!(Values = (lfPOINT *)realloc(Values, ((nPnt*2+2) * sizeof(lfPOINT))))) return;
- if(!(rY2 = new AccRange(yref2))) {
- if(yref1) free(yref1); if(yref2) free(yref2);
- if(rX) delete(rX); if(rY1) delete(rY1);
- return;
- }
- if(rX->GetFirst(&i, &j) && rY1->GetFirst(&k, &l) &&
- rX->GetNext(&i, &j) && rY1->GetNext(&k, &l) &&
- rY2->GetFirst(&m, &n) && rY2->GetNext(&m, &n)) do {
- if(data->GetValue(j, i, &x)){
- if(data->GetValue(l, k, &y)){
- Values[nPntSet].fx = x; Values[nPntSet++].fy = y;
- }
- if(data->GetValue(n, m, &y)){
- Values[nPntSet].fx = x; Values[nPntSet++].fy = y;
- }
- }
- }while(rX->GetNext(&i, &j) && rY1->GetNext(&k, &l) && rY2->GetNext(&m, &n));
- }
- else {
- if((nPnt = rX->CountItems()) != (rY1->CountItems())) return;
- if(!(Values = (lfPOINT *)realloc(Values, (nPnt+2) * sizeof(lfPOINT)))) return;
- if(rX->GetFirst(&i, &j) && rY1->GetFirst(&k, &l) &&
- rX->GetNext(&i, &j) && rY1->GetNext(&k, &l)) do {
- if(data->GetValue(j, i, &x) && data->GetValue(l, k, &y)){
- Values[nPntSet].fx = x; Values[nPntSet++].fy = y;
- }
- }while(rX->GetNext(&i, &j) && rY1->GetNext(&k, &l));
- }
- nPnt = nPntSet; nPntSet--; dirty = true;
- Command(CMD_AUTOSCALE, 0L, 0L);
- if(tmpValues && Values != tmpValues) Undo.InvalidGO(this);
- if(rX) delete(rX); if(rY1) delete(rY1); if(rY2) delete(rY2);
- if(yref1) free(yref1); if(yref2) free(yref2);
-}
-
-void
-DataLine::LineData(lfPOINT *val, long nval)
+
+Symbol::Symbol(int src):GraphObj(0L, 0L)
{
- lfPOINT *ov = Values;
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ SymFill.hatch = (LineDEF *) NULL;
+ }
+}
- if(!val || nval <2) return;
- if(nval > nPnt && nPnt > 1 && Values){
- if(!(Values = (lfPOINT *)realloc(Values, ((nval*2+2) * sizeof(lfPOINT))))) return;
- if(ov != Values) Undo.InvalidGO(this);
- }
- else if(!Undo.busy) Undo.DataMem(this, (void**)&Values, nPnt * sizeof(lfPOINT), &nPnt, UNDO_CONTINUE);
- memcpy(Values, val, nval * sizeof(lfPOINT));
- if(pts) free(pts); pts = 0L; dirty = true;
- free(val); nPnt = nval; nPntSet = nPnt-1;
-}
+Symbol::~Symbol()
+{
+ Command(CMD_FLUSH, 0L, 0L);
+}
-void
-DataLine::DrawCurve(anyOutput *target)
+double
+Symbol::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_MINE:
+ case SIZE_SYMBOL:
+ return size;
+ case SIZE_SYM_LINE:
+ return SymLine.width;
+ case SIZE_XPOS:
+ return fPos.fx;
+ case SIZE_YPOS:
+ return fPos.fy;
+ default:
+ return DefSize(select);
+ }
+}
+
+bool
+Symbol::SetSize(int select, double value)
+{
+ switch(select & 0xfff){
+ case SIZE_MINE:
+ case SIZE_SYMBOL:
+ size = value;
+ return true;
+ case SIZE_SYM_LINE:
+ SymLine.width = value;
+ return true;
+ case SIZE_XPOS:
+ fPos.fx = value;
+ return true;
+ case SIZE_YPOS:
+ fPos.fy = value;
+ return true;
+ }
+ return false;
+}
+
+DWORD
+Symbol::GetColor(int select)
{
+ switch(select) {
+ case COL_SYM_LINE:
+ return SymLine.color;
+ case COL_SYM_FILL:
+ return SymFill.color;
+ default:
+ return parent ? parent->GetColor(select) : defs.Color(select);
+ }
+}
+
+bool
+Symbol::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_SYM_LINE:
+ SymLine.color = col;
+ if(SymTxt) SymTxt->ColTxt = col;
+ return true;
+ case COL_SYM_FILL:
+ SymFill.color = col;
+ return true;
+ default:
+ return false;
+ }
}
void
-DataLine::DrawSpline(anyOutput *target)
+Symbol::DoPlot(anyOutput *target)
{
- int i, j, k, klo, khi, ptsize = 1000;
- double *y2, min, max, x, y, h, b, a;
- POINT pn;
- lfPOINT *scvals;
-
- if(!(y2 = (double*)malloc(sizeof(double)*(nPnt)))) return;
- if(!(scvals = (lfPOINT*)malloc(sizeof(lfPOINT)*(nPnt)))){
- free(y2);
- return;
+ int ix, iy, rx, ry, atype;
+ lfPOINT fip;
+ POINT pts[5];
+ FillDEF cf;
+
+ if(size <= 0.001) return;
+ atype = (type & 0xfff);
+ memcpy(&cf, &SymFill, sizeof(FillDEF));
+ if(atype == SYM_CIRCLEF || atype == SYM_RECTF || atype == SYM_TRIAUF ||
+ atype == SYM_TRIADF || atype == SYM_DIAMONDF) cf.color = SymLine.color;
+ if(type & SYM_POS_PARENT) {
+ if(!parent) return;
+ fip.fx = parent->GetSize(SIZE_XCENTER);
+ fip.fy = parent->GetSize(SIZE_YCENTER);
}
- if((type & 0x0f) == 9 || (type & 0x0f) == 10) {
- if((type & 0x0f) == 9) for(i = 0; i < nPnt; i++) {
- scvals[i].fx = target->fx2fix(Values[i].fx);
- scvals[i].fy = target->fy2fiy(Values[i].fy);
+ else if(!target->fp2fip(&fPos, &fip)) return;
+ ix = iround(fip.fx); iy = iround(fip.fy);
+ target->SetLine(&SymLine);
+ switch(atype){
+ default:
+ case SYM_CIRCLE: //circle
+ case SYM_CIRCLEF: //filled circle
+ rx = target->un2ix(size/2.0); ry = target->un2iy(size/2.0);
+ target->SetFill(&cf);
+ target->oCircle(ix-rx, iy-ry, ix+rx+1, iy+ry+1, name);
+ rx--;ry--; //smaller marking rectangle
+ break;
+ case SYM_RECT: //rectange (square)
+ case SYM_RECTF: //filled rectangle
+ rx = target->un2ix(size/2.25676);
+ ry = target->un2iy(size/2.25676);
+ target->SetFill(&cf);
+ target->oRectangle(ix-rx, iy-ry, ix+rx+1, iy+ry+1, name);
+ break;
+ case SYM_TRIAU: //triangles up and down, open or closed
+ case SYM_TRIAUF: case SYM_TRIAD: case SYM_TRIADF:
+ rx = target->un2ix(size/1.48503);
+ ry = target->un2iy(size/1.48503);
+ target->SetFill(&cf);
+ pts[0].x = pts[3].x = ix - rx; pts[1].x = ix; pts[2].x = ix+rx;
+ if(atype == SYM_TRIAU || atype == SYM_TRIAUF) { //patch by anonymous
+ pts[0].y = pts[2].y = pts[3].y = iy+target->un2iy(size*0.38878f);
+ pts[1].y = iy-target->un2iy(size*0.77756f);
}
- else for(i = 0; i < nPnt; i++) {
- scvals[i].fy = target->fx2fix(Values[i].fx);
- scvals[i].fx = target->fy2fiy(Values[i].fy);
+ else {
+ pts[0].y = pts[2].y = pts[3].y = iy-target->un2iy(size*0.38878f);
+ pts[1].y = iy+target->un2iy(size*0.77756f);
}
- SortFpArray(nPnt, scvals);
- min = scvals[0].fx; max = scvals[nPnt-1].fx;
- for(i = j = 0; i < (nPnt-1); i++, j++) {
- y = scvals[i].fy; scvals[j].fx = scvals[i].fx;
- for(k = 1; scvals[i+1].fx == scvals[i].fx; k++) {
- y += scvals[i+1].fy; i++;
- }
- scvals[j].fy = y/((double)k);
+ target->oPolygon(pts, 4);
+ rx--; ry--;
+ break;
+ case SYM_DIAMOND: case SYM_DIAMONDF:
+ rx = target->un2ix(size/1.59588f);
+ ry = target->un2iy(size/1.59588f);
+ target->SetFill(&cf);
+ pts[0].x = pts[2].x = pts[4].x = ix;
+ pts[0].y = pts[4].y = iy -ry;
+ pts[1].x = ix +rx; pts[1].y = pts[3].y = iy;
+ pts[2].y = iy +ry; pts[3].x = ix-rx;
+ target->oPolygon(pts, 5);
+ rx--; ry--;
+ break;
+ case SYM_STAR: //star is a combination of + and x symbols
+ case SYM_PLUS: //draw a + sign
+ case SYM_HLINE: case SYM_VLINE:
+ rx = target->un2ix(size/2.0f);
+ ry = target->un2iy(size/2.0f);
+ pts[0].x = pts[1].x = ix;
+ pts[0].y = iy - ry; pts[1].y = iy + ry +1;
+ if(type != SYM_HLINE) target->oPolyline(pts, 2);
+ pts[0].x = ix -rx; pts[1].x = ix + rx +1;
+ pts[0].y = pts[1].y = iy;
+ if(atype != SYM_VLINE) target->oPolyline(pts, 2);
+ if(atype == SYM_VLINE){ rx = 2; break;}
+ if(atype == SYM_HLINE){ ry = 2; break;}
+ if(atype == SYM_PLUS) break; //continue with x symbol for star
+ case SYM_CROSS: //draw a x symbol
+ rx = target->un2ix(size/2.5);
+ ry = target->un2iy(size/2.5);
+ pts[0].x = ix - rx; pts[1].x = ix + rx;
+ pts[0].y = iy - ry; pts[1].y = iy + ry;
+ target->oPolyline(pts, 2);
+ Swap(pts[0].y, pts[1].y);
+ target->oPolyline(pts, 2);
+ break;
+ case SYM_TEXT:
+ if(!SymTxt) Command(CMD_SETTEXT, (void *)"text", target);
+ if(!SymTxt || !SymTxt->text || !SymTxt->text[0])return;
+ SymTxt->iSize = target->un2iy(SymTxt->fSize = size *1.5);
+ target->SetTextSpec(SymTxt);
+ fmtText(target, ix, iy, SymTxt->text);
+ if (target->oGetTextExtent(SymTxt->text, 0, &rx, &ry)){
+ rx >>= 1; ry >>= 1;
}
- if(scvals[i].fx > scvals[i-1].fx) {
- scvals[j].fx = scvals[i].fx; scvals[j].fy = scvals[i].fy;
- j++;
+ else rx = ry = 10;
+ }
+ rDims.left = ix-rx-1; rDims.right = ix+rx+1;
+ rDims.top = iy-ry-1; rDims.bottom = iy+ry+1;
+}
+
+bool
+Symbol::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ char *tmptxt;
+ AccRange *ac;
+ int i, r, c;
+
+ switch (cmd) {
+ case CMD_SCALE:
+ if(!tmpl) return false;
+ size *= ((scaleINFO*)tmpl)->sy.fy;
+ SymLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ if(SymTxt) {
+ SymTxt->fSize *= ((scaleINFO*)tmpl)->sy.fy;
+ SymTxt->iSize = 0;
}
- spline(scvals, j, y2);
- h = scvals[1].fx - scvals[0].fx; // klo and khi bracket the input value of x
- for(x = min, klo = 0, i = khi = 1; x < max && i < j; x += 1.0) {
- while(x > scvals[i].fx) {
- klo++; khi++; i++;
- h = scvals[khi].fx - scvals[klo].fx;
- }
- a = (scvals[khi].fx - x) / h; b = (x - scvals[klo].fx) / h;
- y = a * scvals[klo].fy + b * scvals[khi].fy + ((a*a*a - a) * y2[klo] + (b*b*b - b) * y2[khi]) * (h*h)/6.0;
- if((type & 0x0f) == 9) {
- pn.x = iround(x); pn.y = iround(y);
- }
- else {
- pn.x = iround(y); pn.y = iround(x);
+ return true;
+ case CMD_FLUSH:
+ if(SymTxt) {
+ if(SymTxt->text) free(SymTxt->text);
+ free(SymTxt);
+ }
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name)free(name); name = 0L;
+ return true;
+ case CMD_REDRAW:
+ //if we come here its most likely the result of Undo
+ if(parent && parent->Id==GO_REGRESSION)
+ return parent->Command(CMD_MRK_DIRTY, 0L, o);
+ return false;
+ case CMD_GETTEXT:
+ if(SymTxt && SymTxt->text && tmpl) {
+ rlp_strcpy((char*)tmpl, 50, SymTxt->text);
+ return true;
+ }
+ return false;
+ case CMD_SYMTEXT_UNDO:
+ if(SymTxt && SymTxt->text){
+ c = Undo.String(this, &SymTxt->text, UNDO_CONTINUE);
+ i = (int)strlen((char*)tmpl); i = i > c ? i+2 : c+2;
+ if(tmpl) {
+ if(SymTxt->text = (char*)realloc(SymTxt->text, i)) rlp_strcpy(SymTxt->text, i, (char*)tmpl);
}
- if(cp >= ptsize) {
- ptsize += 1000;
- pts = (POINT*)realloc(pts, sizeof(POINT)*ptsize);
+ else if(SymTxt->text) SymTxt->text[0] = 0;
+ return true;
+ }
+ //fall through if its new
+ case CMD_SYMTEXT: case CMD_SETTEXT:
+ if(!SymTxt && (SymTxt = (TextDEF *) calloc(1, sizeof(TextDEF)))) {
+ SymTxt->ColTxt = SymLine.color; SymTxt->fSize = size*1.5;
+ SymTxt->ColBg = parent ? parent->GetColor(COL_BG) : 0x00ffffffL;
+ SymTxt->Align = TXA_VCENTER | TXA_HCENTER;
+ SymTxt->Style = TXS_NORMAL; SymTxt->Mode = TXM_TRANSPARENT;
+ SymTxt->Font = FONT_HELVETICA; SymTxt->text = 0L;
+ }
+ if(!SymTxt) return false;
+ if(tmpl) {
+ i = (int) strlen((char*)tmpl) + 2;
+ if(SymTxt->text = (char*)realloc(SymTxt->text, i)) rlp_strcpy(SymTxt->text, i, (char*)tmpl);
+ }
+ else if(SymTxt->text) SymTxt->text[0] = 0;
+ return true;
+ case CMD_SYM_TYPE:
+ if(tmpl)type = *((int*)tmpl);
+ return true;
+ case CMD_GETTEXTDEF:
+ if(!SymTxt || !tmpl) return false;
+ memcpy(tmpl, SymTxt, sizeof(TextDEF));
+ return true;
+ case CMD_SYMTEXTDEF: case CMD_SETTEXTDEF:
+ if(!tmpl)return false;
+ if(SymTxt) tmptxt = SymTxt->text;
+ else tmptxt = 0L;
+ if(!SymTxt && !(SymTxt = (TextDEF *) calloc(1, sizeof(TextDEF)))) return false;
+ memcpy(SymTxt, tmpl, sizeof(TextDEF));
+ SymTxt->text = tmptxt;
+ return true;
+ case CMD_SYM_RANGETEXT: case CMD_RANGETEXT:
+ if(!data || !tmpl) return false;
+ if(!(tmptxt = (char*)malloc(500)))return false;
+ if((ac = new AccRange((char*)tmpl)) && ac->GetFirst(&c, &r)) {
+ for(i = 0, tmptxt[0] = 0; i <= idx; i++) ac->GetNext(&c, &r);
+ data->GetText(r, c, tmptxt, 500);
+ delete(ac);
+ }
+ Command(CMD_SETTEXT, tmptxt, 0L);
+ free(tmptxt);
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = GO_SYMBOL;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ o->ShowMark(&rDims, MRK_INVERT);
+ CurrGO = this;
+ return true;
}
- AddToPolygon(&cp, pts, &pn);
+ break;
+ }
+ break;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >1 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
+ return true;
}
+ break;
}
- free(y2); free(scvals);
+ return false;
}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// DataPolygon is a graphic object based on DataLine
-DataPolygon::DataPolygon(GraphObj *par, DataObj *d, char *xrange, char *yrange):
- DataLine(par, d, xrange, yrange)
-{
- lfPOINT *fp = Values;
- char *rx = ssXref;
- char *ry = ssYref;
-
- FileIO(INIT_VARS);
- Values = fp; //FileIO will just set Values to 0L !
- ssXref = rx; ssYref = ry;
- Id = GO_DATAPOLYGON;
-}
-
-DataPolygon::DataPolygon(int src):DataLine(0L, 0)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-DataPolygon::~DataPolygon()
-{
- if(Values)free(Values); Values =0L;
- if(pts) free (pts); pts = 0L;
- if(ssXref) free(ssXref); ssXref = 0L;
- if(ssYref) free(ssYref); ssYref = 0L;
- if(mo) DelBitmapClass(mo); mo = 0L;
- if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);
-}
-
-void
-DataPolygon::DoPlot(anyOutput *target)
-{
- if(!Values || nPntSet < 2) return;
- if(mo) DelBitmapClass(mo); mo = 0L;
- DataLine::DoPlot(target); //no drawing but fill pts only
- target->SetLine(&LineDef); target->SetFill(&pgFill);
- target->oPolygon(pts, cp);
-}
-
-void
-DataPolygon::DoMark(anyOutput *o, bool mark)
-{
- if(pts && cp && o){
- if(mark){
- memcpy(&mrc, &rDims, sizeof(RECT));
- IncrementMinMaxRect(&mrc, 6 + o->un2ix(LineDef.width));
- mo = GetRectBitmap(&mrc, o);
- InvertPolygon(pts, cp, &LineDef, &pgFill, &mrc, o, mark);
- }
- else RestoreRectBitmap(&mo, &mrc, o);
- }
-}
-
-bool
-DataPolygon::Command(int cmd, void *tmpl, anyOutput *o)
-{
- switch (cmd) {
- case CMD_PG_FILL:
- if(tmpl) {
- memcpy((void*)&pgFill, tmpl, sizeof(FillDEF));
- if(pgFill.hatch) memcpy((void*)&pgFillLine, (void*)pgFill.hatch, sizeof(LineDEF));
- pgFill.hatch = (LineDEF*)&pgFillLine;
- }
- return true;
- case CMD_LEGEND:
- if(tmpl && ((GraphObj*)tmpl)->Id == GO_LEGEND) {
- if(Id == GO_DATAPOLYGON) ((Legend*)tmpl)->HasFill(&LineDef, &pgFill);
- }
- break;
- default:
- return DataLine::Command(cmd, tmpl, o);
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Calculate and display a regression line
-// Ref.: "Biometry" third edition 1995 (ed. R.R. Sokal and F.J. Rohlf),
-// W.H. Freeman and Company, New York; ISBN 0-7167-2411-1; pp. 451ff
-RegLine::RegLine(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel):
- GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- type = sel;
- Id = GO_REGLINE;
- uclip.Xmin = uclip.Ymin = lim.Xmin = lim.Ymin = -1.0;
- uclip.Xmax = uclip.Ymax = lim.Xmax = lim.Ymax = 1.0;
- Recalc(values, n);
-}
-
-RegLine::RegLine(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) FileIO(FILE_READ);
-}
-
-RegLine::~RegLine()
-{
- if(pts) free(pts);
- pts = 0L;
- if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);
-}
-
-double
-RegLine::GetSize(int select)
-{
- double a, b;
-
- switch(select) {
- case SIZE_MX: return mx;
- case SIZE_MY: return my;
- case SIZE_A:
- case SIZE_B:
- switch(type & 0x07) {
- case 1: a = l2.fx; b = l2.fy; break;
- case 2: a = l3.fx; b = l3.fy; break;
- case 3: a = l4.fx; b = l4.fy; break;
- case 4: a = l5.fx; b = l5.fy; break;
- default: a = l1.fx; b = l1.fy; break;
- }
- if(select == SIZE_A) return a;
- else return b;
- }
- return 0.0;
-}
-
-void
-RegLine::DoPlot(anyOutput *o)
-{
- int i;
- POINT pn, *tmppts;
- double x, x1, y, d, a, b;
- fRECT cliprc;
- bool dValid;
-
- switch (type & 0x70) {
- case 0x20: memcpy(&cliprc, &uclip, sizeof(fRECT)); break;
- case 0x10:
- if(parent) {
- cliprc.Xmin = parent->GetSize(SIZE_BOUNDS_LEFT);
- cliprc.Xmax = parent->GetSize(SIZE_BOUNDS_RIGHT);
- cliprc.Ymin = parent->GetSize(SIZE_BOUNDS_BOTTOM);
- cliprc.Ymax = parent->GetSize(SIZE_BOUNDS_TOP);
- break;
- }
- //no parent: use default
- default: memcpy(&cliprc, &lim, sizeof(fRECT)); break;
- }
- if(cliprc.Xmax < cliprc.Xmin) {
- x = cliprc.Xmax; cliprc.Xmax = cliprc.Xmin; cliprc.Xmin = x;
- }
- if(cliprc.Ymax < cliprc.Ymin) {
- y = cliprc.Ymax; cliprc.Ymax = cliprc.Ymin; cliprc.Ymin = y;
- }
- if(cliprc.Xmin == cliprc.Xmax || cliprc.Ymin == cliprc.Ymax) return;
- if(pts) free(pts);
- if(!(pts = (POINT *)malloc(sizeof(POINT)*200)))return;
- switch(type & 0x07) {
- case 1: a = l2.fx; b = l2.fy; break;
- case 2: a = l3.fx; b = l3.fy; break;
- case 3: a = l4.fx; b = l4.fy; break;
- case 4: a = l5.fx; b = l5.fy; break;
- default: a = l1.fx; b = l1.fy; break;
- }
- x = cliprc.Xmin; d = (cliprc.Xmax - cliprc.Xmin)/200.0;
- for (cp = i = 0; i <= 200; i++){
- dValid = true;
- switch(type & 0x700) {
- case 0x100: //logarithmic x
- if(dValid = x > defs.min4log) x1 = log10(x);
- break;
- case 0x200: //reciprocal x
- if(dValid = fabs(x) > defs.min4log) x1 = 1.0/x;
- break;
- case 0x300: //square root x
- if(dValid = fabs(x) > defs.min4log) x1 = sqrt(x);
- break;
- default: x1 = x; break; //linear x
- }
- y = a + b*x1;
- if(dValid) switch(type & 0x7000) {
- case 0x1000: //logarithmic y
- y = pow(10.0, y);
- break;
- case 0x2000: //reciprocal y
- if(dValid = fabs(y) >0.0001) y = 1.0/y;
- break;
- case 0x3000: //square root y
- if(dValid = fabs(y) >0.0001) y = y*y;
- break;
- }
- if(dValid && y >= cliprc.Ymin && y <= cliprc.Ymax) {
- pn.x = o->fx2ix(x); pn.y = o->fy2iy(y);
- AddToPolygon(&cp, pts, &pn);
- }
- x += d;
- }
- if(cp < 2) return;
- o->SetLine(&LineDef);
- o->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);
- for(i = 2; i < cp; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
- i = 2*o->un2ix(LineDef.width); //increase size of rectangle for marks
- IncrementMinMaxRect(&rDims, i);
-}
-
-void
-RegLine::DoMark(anyOutput *o, bool mark)
-{
- if(pts && cp && o){
- if(mark)InvertLine(pts, cp, &LineDef, &rDims, o, mark);
- else if(parent) parent->Command(CMD_REDRAW, 0L, o);
- }
-}
-
-bool
-RegLine::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- POINT p1;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPoints <2)
- return false;
- if(IsCloseToPL(p1,pts,cp)) return o->ShowMark(CurrGO= this, MRK_GODRAW);
- }
- break;
- case CMD_SET_DATAOBJ:
- Id = GO_REGLINE;
- return true;
- case CMD_BOUNDS:
- if(tmpl) {
- memcpy(&lim, tmpl, sizeof(fRECT));
- memcpy(&uclip, tmpl, sizeof(fRECT));
- }
- return true;
- case CMD_AUTOSCALE:
- if(nPoints < 2) return false;
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds(lim.Xmin, lim.Ymin);
- ((Plot*)parent)->CheckBounds(lim.Xmax, lim.Ymax);
- return true;
- }
- return false;
- }
- return false;
-}
-
-void
-RegLine::Recalc(lfPOINT *values, long n)
-{
- double sx, sy, dx, dy, sxy, sxx, syy;
- double a, b, k;
- long ic;
-
- sx = sy = 0.0;
- if((nPoints = n)<2) return;
- for(ic = 0; ic < n; ic++) {
- sx += values[ic].fx; sy += values[ic].fy;
- }
- mx = sx /((double)nPoints); my = sy/((double)nPoints);
- sxy = sxx = syy = 0.0;
- for(ic = 0; ic < n; ic++) {
- dx = mx - values[ic].fx; dy = my - values[ic].fy;
- sxx += (dx*dx); syy += (dy*dy); sxy += (dx*dy);
- }
- l1.fy = sxy / sxx; l1.fx = my - (sxy / sxx) * mx;
- b = sxy / syy; a = mx - (sxy / syy) * my;
- l2.fy = 1.0/b; l2.fx = -a / b;
- l3.fy = (l1.fy+l2.fy)/2.0; l3.fx = (l1.fx+l2.fx)/2.0;
- l4.fy = sy/sx; l4.fx = 0.0;
- if(l5.fx == 0.0 && l5.fx == 0.0){
- l5.fy = l1.fy; l5.fx = l1.fx;
- }
- //calculate distance point from line algorithm
- //Ref: K. Thompson, 1990: Vertical Distance from a Point to a Line. In:
- // Graphic Gems (Andrew S. Glassner, ed.), Academic Press,
- // pp. 47-48; ISBN 0-12-286165-5
- k = (sqrt(1.0/(1.0+l1.fy*l1.fy))+sqrt(1.0/(1.0+l2.fy*l2.fy)))/2.0;
- b = sqrt(1.0/(k*k) -1.0);
- l3.fy = l3.fy > 0.0 ? b : -b;
- l3.fx = my - mx * l3.fy;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Calculate and display a statnard deviation (SD-) ellipse
-SDellipse::SDellipse(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel):
- GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- type = sel;
- Id = GO_SDELLIPSE;
- if(val = (lfPOINT*)malloc(n * sizeof(lfPOINT))){
- memcpy(val, values, (nPoints = n)*sizeof(lfPOINT));
- rl = new RegLine(this, data, values, n, type);
- }
-}
-
-SDellipse::SDellipse(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) FileIO(FILE_READ);
-}
-
-SDellipse::~SDellipse()
-{
- if(val) free(val);
- if(pts) free(pts);
- if(!(type & 0x10000) && parent && rl &&
- parent->Command(CMD_DROP_OBJECT, rl, 0L)) return;
- if(rl) DeleteGO(rl);
-}
-
-void
-SDellipse::DoPlot(anyOutput *o)
-{
- int i;
- double a1, b1, a2, b2, fv, k1, k2, ss1, ss2, np, x, dx, si, csi;
- lfPOINT fp, fip;
- POINT p1, *tmppts;
-
- if(!rl) return;
- if(pts) free(pts);
- if(!(pts = (POINT *)malloc(sizeof(POINT)*420)))return;
- //get line data from regression line object
- mx = rl->GetSize(SIZE_MX); my = rl->GetSize(SIZE_MY);
- a1 = rl->GetSize(SIZE_A); b1 = rl->GetSize(SIZE_B);
- b2 = -1.0/b1; a2 = my - b2 * mx;
- //calculate sine and cosine for back rotation
- fv = sqrt(1.0+b1*b1); si = b1/fv; csi = 1.0/fv;
- //calculate distance from line for each point and squared sum of distances
- //Ref: K. Thompson, 1990: Vertical Distance from a Point to a Line. In:
- // Graphic Gems (Andrew S. Glassner, ed.), Academic Press,
- // pp. 47-48; ISBN 0-12-286165-5
- k1 = sqrt(1.0/(1.0+b1*b1)); k2 = sqrt(1.0/(1.0+b2*b2));
- // y = a + b*x;
- ss1 = ss2 = 0.0;
- for(i = 0; i < nPoints; i++) {
- fv = (a1 + b1 * val[i].fx - val[i].fy) * k1; ss1 += (fv*fv);
- fv = (a2 + b2 * val[i].fx - val[i].fy) * k2; ss2 += (fv*fv);
- }
- np = ((double)(nPoints-1));
- //SD perpendicular and in direction of regression line
- sd1 = sqrt(ss1 /= np); sd2 = sqrt(ss2 /= np);
- dx = sd2/100.0;
- for(i = 0, cp = 0, x = -sd2; i < 2; i++) {
- do {
- fv = (x*x)/ss2;
- fv = fv < 0.99999 ? sqrt((1.0-fv)*ss1) : 0.0;
- fv = i ? fv : -fv;
- fp.fx = mx + x * csi - fv * si;
- fp.fy = my + x * si + fv * csi;
- switch(type & 0x700) {
- case 0x100: //logarithmic x
- fp.fx = pow(10.0, fp.fx);
- break;
- case 0x200: //reciprocal x
- if(fabs(fp.fx) > defs.min4log) fp.fx = 1.0/fp.fx;
- else fp.fx = 0.0;
- break;
- case 0x300: //square root x
- if(fabs(fp.fx) > defs.min4log) fp.fx = fp.fx*fp.fx;
- else fp.fx = 0.0;
- break;
- }
- switch(type & 0x7000) {
- case 0x1000: //logarithmic y
- fp.fy = pow(10.0, fp.fy);
- break;
- case 0x2000: //reciprocal y
- if(fabs(fp.fy) > defs.min4log) fp.fy = 1.0/fp.fy;
- else fp.fy = 0.0;
- break;
- case 0x3000: //square root y
- if(fabs(fp.fy) > defs.min4log) fp.fy = fp.fy*fp.fy;
- else fp.fy = 0.0;
- break;
- }
- o->fp2fip(&fp, &fip); p1.x = iround(fip.fx); p1.y = iround(fip.fy);
- AddToPolygon(&cp, pts, &p1);
- }while((x += dx) < sd2 && x > -sd2);
- x = sd2;
- dx *= -1.0;
- }
- o->SetLine(&LineDef);
- if(cp > 2) {
- AddToPolygon(&cp, pts, pts); //close polygon
- if(tmppts = (POINT*)realloc(pts, cp *sizeof(POINT))) pts = tmppts;
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
- for(i = 2; i < cp; i++)
- UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
- i = 3*o->un2ix(LineDef.width); //increase size of rectangle for marks
- IncrementMinMaxRect(&rDims, i);
- o->oPolyline(pts, cp);
- }
- else {
- free(pts);
- cp = 0;
- }
- if(!(type & 0x10000))rl->DoPlot(o);
-}
-
-void
-SDellipse::DoMark(anyOutput *o, bool mark)
-{
- if(pts && cp && o){
- if(mark)InvertLine(pts, cp, &LineDef, &rDims, o, mark);
- else if(parent) parent->Command(CMD_REDRAW, 0L, o);
- }
-}
-
-bool
-SDellipse::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- POINT p1;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(!(type & 0x10000) && rl && rl->Command(cmd, tmpl, o)) return true;
- if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPoints <2)
- return false;
- if(IsCloseToPL(p1,pts,cp)) return o->ShowMark(CurrGO= this, MRK_GODRAW);
- }
- break;
- case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_RMU:
- if(!(type & 0x10000) && parent && rl && parent->Command(CMD_DROP_OBJECT, rl, o)){
- rl = 0L;
- return true;
- }
- return false;
- case CMD_INIT:
- if(rl) return rl->PropertyDlg();
- break;
- case CMD_DROP_OBJECT:
- if(tmpl && ((GraphObj*)tmpl)->Id == GO_REGLINE && !rl) {
- rl = (RegLine *)tmpl;
- rl->parent = this;
- return true;
- }
- return false;
- case CMD_SET_DATAOBJ:
- Id = GO_SDELLIPSE;
- if(rl) rl->Command(cmd, tmpl, o);
- return true;
- case CMD_BOUNDS:
- if(tmpl) {
- if(rl) rl->Command(cmd, tmpl, o);
- memcpy(&lim, tmpl, sizeof(fRECT));
- }
- return true;
- case CMD_DELOBJ:
- if(tmpl && tmpl == (void*)rl) {
- Undo.ValInt(parent, &type, 0L);
- type |= 0x10000;
- if(parent) parent->Command(CMD_REDRAW, 0L, o);
- return true;
- }
- break;
- case CMD_AUTOSCALE:
- if(nPoints < 2) return false;
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds(lim.Xmin, lim.Ymin);
- ((Plot*)parent)->CheckBounds(lim.Xmax, lim.Ymax);
- return true;
- }
- break;
- }
- return false;
-}
-
-void
-SDellipse::Recalc(lfPOINT *values, long n)
-{
- if(val) free(val);
- if(val = (lfPOINT*)malloc(n * sizeof(lfPOINT)))
- memcpy(val, values, (nPoints = n)*sizeof(lfPOINT));
- if(rl) rl->Recalc(values, n);
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Error bars are simple graphic objects
-ErrorBar::ErrorBar(GraphObj *par, DataObj *d, double x, double y, double err, int which,
- int xc, int xr, int yc, int yr, int ec, int er):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- fPos.fx = x; fPos.fy = y;
- ferr = err;
- type = which;
- Id = GO_ERRBAR;
- data = d;
- if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || ec >= 0 || er >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- ssRef[2].x = ec; ssRef[2].y = er;
- cssRef = 3;
- }
- }
- Command(CMD_AUTOSCALE, 0L, 0L);
-}
-
-ErrorBar::ErrorBar(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- type = ERRBAR_VSYM;
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-ErrorBar::~ErrorBar()
-{
- if(mo) DelBitmapClass(mo); mo = 0L;
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name) free(name); name = 0L;
-}
-
-bool
-ErrorBar::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_ERRBAR:
- SizeBar = value;
- return true;
- case SIZE_ERRBAR_LINE:
- ErrLine.width = value;
- return true;
- }
- return false;
-}
-
-bool
-ErrorBar::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_ERROR_LINE:
- ErrLine.color = col;
- return true;
- }
- return false;
-}
-
-void
-ErrorBar::DoPlot(anyOutput *target)
-{
- int ie;
-
- switch (type & 0x0ff) {
- case ERRBAR_VSYM:
- case ERRBAR_VUP:
- case ERRBAR_VDOWN:
- ie = target->un2ix(SizeBar/2.0);
- break;
- default:
- ie = target->un2iy(SizeBar/2.0);
- break;
- }
- target->SetLine(&ErrLine);
- switch(type) {
- case ERRBAR_VSYM:
- ebpts[0].x = ebpts[1].x = target->fx2ix(fPos.fx);
- ebpts[0].y = target->fy2iy(fPos.fy-ferr);
- ebpts[4].y = ebpts[5].y = ebpts[1].y = target->fy2iy(fPos.fy+ferr);
- if(ebpts[1].y != ebpts[0].y) target->oSolidLine(ebpts);
- ebpts[4].x = ebpts[2].x = ebpts[0].x - ie;
- ebpts[5].x = ebpts[3].x = ebpts[1].x + ie+1;
- ebpts[2].y = ebpts[3].y = ebpts[0].y;
- if(ebpts[3].x > ebpts[2].x) {
- target->oSolidLine(ebpts+2);
- target->oSolidLine(ebpts+4);
- }
- rDims.left = ebpts[2].x; rDims.right = ebpts[3].x;
- rDims.top = ebpts[0].y; rDims.bottom = ebpts[1].y;
- break;
- case ERRBAR_VUP:
- case ERRBAR_VDOWN:
- ebpts[0].x = ebpts[1].x = target->fx2ix(fPos.fx);
- ebpts[0].y = target->fy2iy(fPos.fy);
- ebpts[2].y = ebpts[3].y = ebpts[1].y =
- target->fy2iy(type == ERRBAR_VUP ? fPos.fy+ferr : fPos.fy-ferr);
- if(ebpts[1].y != ebpts[0].y) target->oSolidLine(ebpts);
- ebpts[2].x = ebpts[0].x - ie;
- ebpts[3].x = ebpts[1].x + ie+1;
- if(ebpts[3].x > ebpts[2].x) target->oSolidLine(ebpts+2);
- rDims.left = ebpts[2].x; rDims.right = ebpts[3].x;
- rDims.top = ebpts[0].y; rDims.bottom = ebpts[1].y;
- break;
- case ERRBAR_HSYM:
- ebpts[2].x = ebpts[3].x = ebpts[0].x = target->fx2ix(fPos.fx-ferr);
- ebpts[4].x = ebpts[5].x = ebpts[1].x = target->fx2ix(fPos.fx+ferr);
- ebpts[0].y = ebpts[1].y = target->fy2iy(fPos.fy);
- if(ebpts[1].x != ebpts[0].x) target->oSolidLine(ebpts);
- ebpts[2].y = ebpts[4].y = ebpts[0].y - ie;
- ebpts[3].y = ebpts[5].y = ebpts[1].y + ie+1;
- if(ebpts[3].y >ebpts[2].y) {
- target->oSolidLine(ebpts+2);
- target->oSolidLine(ebpts+4);
- }
- rDims.left = ebpts[0].x; rDims.right = ebpts[1].x;
- rDims.top = ebpts[2].y; rDims.bottom = ebpts[3].y;
- break;
- case ERRBAR_HLEFT:
- case ERRBAR_HRIGHT:
- ebpts[0].x = target->fx2ix(fPos.fx);
- ebpts[0].y = ebpts[1].y = target->fy2iy(fPos.fy);
- ebpts[2].x = ebpts[3].x = ebpts[1].x =
- target->fx2ix(type == ERRBAR_HRIGHT ? fPos.fx+ferr : fPos.fx-ferr);
- if(ebpts[1].x != ebpts[0].x) target->oSolidLine(ebpts);
- ebpts[2].y = ebpts[0].y - ie;
- ebpts[3].y = ebpts[1].y + ie+1;
- if(ebpts[3].y > ebpts[2].y) target->oSolidLine(ebpts+2);
- rDims.left = ebpts[0].x; rDims.right = ebpts[1].x;
- rDims.top = ebpts[2].y; rDims.bottom = ebpts[3].y;
- break;
- }
- if(rDims.left > rDims.right) Swap(rDims.left, rDims.right);
- if(rDims.top > rDims.bottom) Swap(rDims.top, rDims.bottom);
- IncrementMinMaxRect(&rDims, 2);
-}
-
-void
-ErrorBar::DoMark(anyOutput *o, bool mark)
-{
- 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));
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Bubbles are graphic objects
+Bubble::Bubble(GraphObj *par, DataObj *d, double x, double y, double s, int which,
+ FillDEF *fill, LineDEF *outline, int xc, int xr, int yc, int yr, int sc,
+ int sr):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ fPos.fx = x; fPos.fy = y; fs = s;
+ type = which;
+ if(fill) {
+ memcpy(&BubbleFill,fill, sizeof(FillDEF));
+ if(BubbleFill.hatch) memcpy(&BubbleFillLine, BubbleFill.hatch, sizeof(LineDEF));
}
- else RestoreRectBitmap(&mo, &mrc, o);
-}
-
-bool
-ErrorBar::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- bool bFound;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- bFound = false;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(!IsInRect(&rDims, mev->x, mev->y) || CurrGO) return false;
- switch (type) {
- 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:
- 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) &&
- mev->y <= (ebpts[4].y + 2)) bFound = true;
- break;
- }
- if(bFound) o->ShowMark(this, MRK_GODRAW);
- }
- case CMD_SET_DATAOBJ:
- Id = GO_ERRBAR;
- data = (DataObj *) tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >2 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &ferr);
- return true;
- }
- 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;
+ BubbleFill.hatch = &BubbleFillLine;
+ if(outline)memcpy(&BubbleLine, outline, sizeof(LineDEF));
+ Id = GO_BUBBLE;
+ if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || sc >= 0 || sr >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ ssRef[2].x = sc; ssRef[2].y = sr;
+ cssRef = 3;
}
- 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;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- switch(type) {
- case ERRBAR_VSYM:
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy+ferr);
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy-ferr); break;
- case ERRBAR_VUP:
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy+ferr); break;
- case ERRBAR_VDOWN:
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy-ferr); break;
- case ERRBAR_HSYM:
- ((Plot*)parent)->CheckBounds(fPos.fx+ferr, fPos.fy);
- ((Plot*)parent)->CheckBounds(fPos.fx-ferr, fPos.fy); break;
- case ERRBAR_HLEFT:
- ((Plot*)parent)->CheckBounds(fPos.fx-ferr, fPos.fy);
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy); break;
- case ERRBAR_HRIGHT:
- ((Plot*)parent)->CheckBounds(fPos.fx+ferr, fPos.fy);
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy); break;
- }
- return true;
- }
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// arrows to data points or with absolute coordinates
-Arrow::Arrow(GraphObj * par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
- int xc1, int xr1, int yc1, int yr1, int xc2, int xr2, int yc2, int yr2):
- GraphObj(par, d)
-{
- double dx, dy;
-
- FileIO(INIT_VARS);
- memcpy(&pos1, &fp1, sizeof(lfPOINT));
- memcpy(&pos2, &fp2, sizeof(lfPOINT));
- type = which;
- if(type & ARROW_UNITS) {
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- pos1.fx -= dx; pos1.fy -= dy; pos2.fx -= dx; pos2.fy -= dy;
- }
- if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || xc2 >= 0 || xr2 >= 0 ||
- yc2 >= 0 || yr2 >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
- ssRef[0].x = xc1; ssRef[0].y = xr1;
- ssRef[1].x = yc1; ssRef[1].y = yr1;
- ssRef[2].x = xc2; ssRef[2].y = xr2;
- ssRef[3].x = yc2; ssRef[3].y = yr2;
- cssRef = 4;
- }
- }
- bModified = false;
-}
-
-Arrow::Arrow(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-Arrow::~Arrow()
-{
- Command(CMD_FLUSH, 0L, 0L);
- if(bModified) Undo.InvalidGO(this);
-}
-
-double
-Arrow::GetSize(int select)
-{
- switch(select) {
- case SIZE_XPOS: return pos1.fx;
- case SIZE_XPOS+1: return pos2.fx;
- case SIZE_YPOS: return pos1.fy;
- case SIZE_YPOS+1: return pos2.fy;
- case SIZE_GRECT_LEFT: case SIZE_GRECT_TOP:
- case SIZE_GRECT_RIGHT: case SIZE_GRECT_BOTTOM:
- if(parent) return parent->GetSize(select);
- break;
- }
- return 0.0;
-}
-
-bool
-Arrow::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_ARROW_LINE: LineDef.width = value; return true;
- case SIZE_ARROW_CAPWIDTH: cw = value; return true;
- case SIZE_ARROW_CAPLENGTH: cl = value; return true;
- case SIZE_XPOS: pos1.fx = value; return true;
- case SIZE_XPOS+1: pos2.fx = value; return true;
- case SIZE_YPOS: pos1.fy = value; return true;
- case SIZE_YPOS+1: pos2.fy = value; return true;
- }
- return false;
-}
-
-bool
-Arrow::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_ARROW:
- LineDef.color = col;
- return true;
- }
- return false;
-}
-
-void
-Arrow::DoPlot(anyOutput *o)
-{
- double si, csi, tmp, fix1, fiy1, fix2, fiy2, dx, dy;
-
- if(!o || !parent) return;
- if(type & ARROW_UNITS) {
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- fix1 = o->co2fix(pos1.fx+dx); fix2 = o->co2fix(pos2.fx+dx);
- fiy1 = o->co2fiy(pos1.fy+dy); fiy2 = o->co2fiy(pos2.fy+dy);
- }
- else {
- fix1 = o->fx2fix(pos1.fx); fix2 = o->fx2fix(pos2.fx);
- fiy1 = o->fy2fiy(pos1.fy); fiy2 = o->fy2fiy(pos2.fy);
- }
- if(fix1 == fix2 && fiy1 == fiy2) return; //zero length
- //draw arrow line
- pts[0].x = iround(fix1); pts[1].x = iround(fix2);
- pts[0].y = iround(fiy1); pts[1].y = iround(fiy2);
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
- //calculate sine and cosine for cap
- si = fiy1-fiy2;
- tmp = fix2 - fix1;
- si = si/sqrt(si*si + tmp*tmp);
- csi = fix2-fix1;
- tmp = fiy2 - fiy1;
- csi = csi/sqrt(csi*csi + tmp*tmp);
- //draw cap
- pts[2].x = pts[1].x - o->un2ix(csi*cl + si*cw/2.0);
- pts[2].y = pts[1].y + o->un2iy(si*cl - csi*cw/2.0);
- pts[3].x = pts[1].x; pts[3].y = pts[1].y;
- pts[4].x = pts[1].x - o->un2ix(csi*cl - si*cw/2.0);
- pts[4].y = pts[1].y + o->un2iy(si*cl + csi*cw/2.0);
- switch(type & 0xff) {
- case ARROW_NOCAP:
- pts[2].x = pts[3].x = pts[4].x = pts[1].x;
- pts[2].y = pts[3].y = pts[4].y = pts[1].y;
- break;
- }
- UpdateMinMaxRect(&rDims, pts[2].x, pts[2].y);
- UpdateMinMaxRect(&rDims, pts[4].x, pts[4].y);
- IncrementMinMaxRect(&rDims, 3);
- if(this == CurrGO) o->ShowMark(this, MRK_GODRAW);
- else Redraw(o);
-}
-
-void
-Arrow::DoMark(anyOutput *o, bool mark)
-{
- LineDEF OldLine;
-
- if(type & ARROW_UNITS) {
- if(!dh1) dh1 = new dragHandle(this, DH_12);
- if(!dh2) dh2 = new dragHandle(this, DH_22);
- }
- else {
- if (dh1) DeleteGO(dh1); if (dh2) DeleteGO(dh2);
- dh1 = dh2 = 0L;
- }
- memcpy(&OldLine, &LineDef, sizeof(LineDEF));
- if(mark) {
- LineDef.color = 0x00000000L;
- LineDef.width = OldLine.width *3.0;
- Redraw(o);
- LineDef.width = OldLine.width;
- LineDef.color = OldLine.color ^ 0x00ffffffL;
- Redraw(o);
- if(dh1) dh1->DoPlot(o); if(dh2) dh2->DoPlot(o);
- }
- else if(parent){
- LineDef.color = 0x00ffffffL;
- LineDef.width = OldLine.width *3.0;
- Redraw(o);
- LineDef.width = OldLine.width;
- LineDef.color = OldLine.color;
- parent->DoPlot(o);
- }
- memcpy(&LineDef, &OldLine, sizeof(LineDEF));
- o->UpdateRect(&rDims, false);
-}
-
-bool
-Arrow::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
-
- switch (cmd) {
- case CMD_SAVEPOS:
- bModified = true;
- Undo.SaveLFP(this, &pos1, 0L);
- Undo.SaveLFP(this, &pos2, UNDO_CONTINUE);
- return true;
- case CMD_FLUSH:
- if (dh1) DeleteGO(dh1); dh1 = 0L;
- if (dh2) DeleteGO(dh2); dh2 = 0L;
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name) free(name); name = 0L;
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(!CurrGO && ObjThere(mev->x, mev->y)){
- o->ShowMark(this, MRK_GODRAW);
- return true;
- }
- }
- break;
- case CMD_ARROW_ORG:
- memcpy(&pos1, tmpl, sizeof(lfPOINT));
- if(ssRef && cssRef >3)
- ssRef[0].x = ssRef[0].y = ssRef[1].x = ssRef[1].y = -1;
- return true;
- case CMD_ARROW_TYPE:
- if(tmpl) {
- type &= ~0xff; type |= (*((int*)tmpl));
- return true;
- }
- return false;
- case CMD_SET_DATAOBJ:
- Id = GO_ARROW;
- data = (DataObj *)tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >3 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &pos1.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &pos1.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &pos2.fx);
- data->GetValue(ssRef[3].y, ssRef[3].x, &pos2.fy);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds(pos1.fx, pos1.fy);
- ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy);
- return true;
- }
- break;
- case CMD_MRK_DIRTY: //from Undo ?
- case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_MOVE:
- bModified = true;
- case CMD_UNDO_MOVE:
- if(type & ARROW_UNITS) {
- if(cmd == CMD_MOVE) Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
- pos1.fx += ((lfPOINT*)tmpl)[0].fx; pos1.fy += ((lfPOINT*)tmpl)[0].fy;
- pos2.fx += ((lfPOINT*)tmpl)[0].fx; pos2.fy += ((lfPOINT*)tmpl)[0].fy;
- if(o){
- o->StartPage(); parent->DoPlot(o); o->EndPage();
- }
- return true;
- }
- break;
- }
- return false;
-}
-
-void
-Arrow::Redraw(anyOutput *o)
-{
- FillDEF FillCap;
-
- o->SetLine(&LineDef);
- o->oSolidLine(pts);
- switch(type & 0xff) {
- case ARROW_NOCAP:
- break;
- case ARROW_LINE:
- o->oSolidLine(pts+2);
- o->oSolidLine(pts+3);
- break;
- case ARROW_TRIANGLE:
- FillCap.type = FILL_NONE;
- FillCap.color = LineDef.color;
- FillCap.scale = 1.0f;
- FillCap.hatch = 0L;
- o->SetFill(&FillCap);
- o->oPolygon(pts+2, 3);
- break;
- }
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// universal boxes
-Box::Box(GraphObj * par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
- int xc1, int xr1, int yc1, int yr1, int xc2, int xr2,
- int yc2, int yr2):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- memcpy(&pos1, &fp1, sizeof(lfPOINT));
- memcpy(&pos2, &fp2, sizeof(lfPOINT));
- type = which;
- Id = GO_BOX;
- if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || xc2 >= 0 || xr2 >= 0 ||
- yc2 >= 0 || yr2 >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
- ssRef[0].x = xc1; ssRef[0].y = xr1;
- ssRef[1].x = yc1; ssRef[1].y = yr1;
- ssRef[2].x = xc2; ssRef[2].y = xr2;
- ssRef[3].x = yc2; ssRef[3].y = yr2;
- cssRef = 4;
- }
- }
-}
-
-Box::Box(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-Box::~Box()
-{
- Command(CMD_FLUSH, 0L, 0L);
-}
-
-double
-Box::GetSize(int select)
-{
- switch(select) {
- case SIZE_XPOS:
- return (pos1.fx + pos2.fx)/2.0;
- case SIZE_YPOS:
- return (pos1.fy + pos2.fy)/2.0;
- }
- return 1.0;
-}
-
-bool
-Box::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_BOX_LINE: Outline.width = value; return true;
- case SIZE_BOX: size = value; return true;
- case SIZE_XPOS: pos1.fx = value; return true;
- case SIZE_XPOS+1: pos2.fx = value; return true;
- case SIZE_YPOS: pos1.fy = value; return true;
- case SIZE_YPOS+1: pos2.fy = value; return true;
- }
- return false;
-}
-
-bool
-Box::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_BOX_LINE:
- Outline.color = col;
- return true;
- }
- return false;
-}
-
-void
-Box::DoPlot(anyOutput *o)
-{
- double si, csi, tmp, fix1, fiy1, fix2, fiy2, fsize, dx, dy;
-
- if(!parent || !o || size <= 0.001) return;
- o->SetLine(&Outline);
- o->SetFill(&Fill);
- //calculate coordinates
- fix1 = o->fx2fix(pos1.fx); fix2 = o->fx2fix(pos2.fx);
- fiy1 = o->fy2fiy(pos1.fy); fiy2 = o->fy2fiy(pos2.fy);
- //calculate sine and cosine
- si = fiy1-fiy2;
- tmp = fix2 - fix1;
- si = si/sqrt(si*si + tmp*tmp);
- csi = fix2-fix1;
- tmp = fiy2 - fiy1;
- csi = csi/sqrt(csi*csi + tmp*tmp);
- if(type & BAR_WIDTHDATA) { //use e.g. for density distribution
- dx = si * size; dy = csi * size;
- pts[0].x = o->fx2ix(pos1.fx + dx); pts[1].x = o->fx2ix(pos2.fx + dx);
- pts[2].x = o->fx2ix(pos2.fx - dx); pts[3].x = o->fx2ix(pos1.fx - dx);
- pts[0].y = o->fy2iy(pos1.fy + dy); pts[1].y = o->fy2iy(pos2.fy + dy);
- pts[2].y = o->fy2iy(pos2.fy - dy); pts[3].y = o->fy2iy(pos1.fy - dy);
- }
- else if(type & BAR_RELWIDTH) {
- if(!parent || (pos1.fy == pos2.fy && pos1.fx == pos2.fx)) return;
- fsize = parent->GetSize(pos1.fy == pos2.fy ? SIZE_BOXMINY : SIZE_BOXMINX);
- fsize = fsize * size /200.0;
- dx = si * fsize; dy = csi * fsize;
- pts[0].x = o->fx2ix(pos1.fx + dx); pts[1].x = o->fx2ix(pos2.fx + dx);
- pts[2].x = o->fx2ix(pos2.fx - dx); pts[3].x = o->fx2ix(pos1.fx - dx);
- pts[0].y = o->fy2iy(pos1.fy + dy); pts[1].y = o->fy2iy(pos2.fy + dy);
- pts[2].y = o->fy2iy(pos2.fy - dy); pts[3].y = o->fy2iy(pos1.fy - dy);
- }
- else {
- dx = o->un2fix(si*size/2.0); dy = o->un2fiy(csi*size/2.0);
- pts[0].x = iround(fix1 + dx); pts[1].x = iround(fix2 + dx);
- pts[2].x = iround(fix2 - dx); pts[3].x = iround(fix1 - dx);
- pts[0].y = iround(fiy1 + dy); pts[1].y = iround(fiy2 + dy);
- pts[2].y = iround(fiy2 - dy); pts[3].y = iround(fiy1 - dy);
- }
- pts[4].x = pts[0].x; pts[4].y = pts[0].y; //close polygon
- if(pts[0].x == pts[1].x){
- o->oRectangle(pts[3].x, pts[3].y, pts[1].x, pts[1].y, name);
- }
- else {
- o->oPolygon(pts, 5);
- }
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[2].x, pts[2].y);
- UpdateMinMaxRect(&rDims, pts[1].x, pts[1].y);
- UpdateMinMaxRect(&rDims, pts[3].x, pts[3].y);
-}
-
-void
-Box::DoMark(anyOutput *o, bool mark)
-{
- InvertPolygon(pts, 5, &Outline, &Fill, &rDims, o, mark);
-}
-
-bool
-Box::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- POINT p;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name)free(name); name = 0L;
- return true;
- case CMD_LEGEND:
- if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
- ((Legend*)tmpl)->HasFill(&Outline, &Fill);
- break;
- case CMD_MRK_DIRTY: case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- 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(CurrGO = this, MRK_GODRAW);
- return true;
- }
- else {
- p.x = mev->x; p.y = mev->y;
- if(IsInPolygon(&p, pts, 5)) {
- o->ShowMark(CurrGO = this, MRK_GODRAW);
- return true;
- }
- }
- }
- break;
- }
- return false;
- case CMD_SET_DATAOBJ:
- Id = GO_BOX;
- data = (DataObj *)tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >3 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &pos1.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &pos1.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &pos2.fx);
- data->GetValue(ssRef[3].y, ssRef[3].x, &pos2.fy);
- return true;
- }
- return false;
- case CMD_BOX_TYPE:
- if(tmpl)type = *((int*)tmpl);
- return true;
- case CMD_BOX_FILL:
- if(tmpl) {
- memcpy(&Fill, tmpl, sizeof(FillDEF));
- if(Fill.hatch) memcpy(&Hatchline, Fill.hatch, sizeof(LineDEF));
- Fill.hatch = &Hatchline;
- return true;
- }
- break;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- if(type & BAR_WIDTHDATA) {
- if(pos1.fy != pos2.fy) {
- ((Plot*)parent)->CheckBounds(pos1.fx+size, pos1.fy);
- ((Plot*)parent)->CheckBounds(pos2.fx-size, pos2.fy);
- }
- else {
- ((Plot*)parent)->CheckBounds(pos1.fx, pos1.fy+size);
- ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy-size);
- }
- }
- 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;
- }
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// whisker
-Whisker::Whisker(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
- int xc1, int xr1, int yc1, int yr1, int xc2, int xr2,
- int yc2, int yr2):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- memcpy(&pos1, &fp1, sizeof(lfPOINT));
- memcpy(&pos2, &fp2, sizeof(lfPOINT));
- type = which;
- Id = GO_WHISKER;
- if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || xc2 >= 0 || xr2 >= 0 ||
- yc2 >= 0 || yr2 >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
- ssRef[0].x = xc1; ssRef[0].y = xr1;
- ssRef[1].x = yc1; ssRef[1].y = yr1;
- ssRef[2].x = xc2; ssRef[2].y = xr2;
- ssRef[3].x = yc2; ssRef[3].y = yr2;
- cssRef = 4;
- }
- }
- Command(CMD_AUTOSCALE, 0L, 0L);
-}
-
-Whisker::Whisker(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
+ }
}
-Whisker::~Whisker()
+Bubble::Bubble(int src):GraphObj(0L, 0L)
{
- if(mo) DelBitmapClass(mo); mo = 0L;
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name) free(name); name = 0L;
-}
-
-bool
-Whisker::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_WHISKER:
- size = value;
- return true;
- case SIZE_WHISKER_LINE:
- LineDef.width = value;
- return true;
- }
- return false;
-}
-
-bool
-Whisker::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_WHISKER:
- LineDef.color = col;
- return true;
- }
- return false;
-}
-
-void
-Whisker::DoPlot(anyOutput *o)
-{
- double si, csi, tmp, fix1, fiy1, fix2, fiy2, dx, dy;
- int i;
-
- fix1 = o->fx2fix(pos1.fx); fix2 = o->fx2fix(pos2.fx);
- fiy1 = o->fy2fiy(pos1.fy); fiy2 = o->fy2fiy(pos2.fy);
- if(fix1 == fix2 && fiy1 == fiy2) return; //zero length
- pts[2].x = iround(fix1); pts[3].x = iround(fix2);
- pts[2].y = iround(fiy1); pts[3].y = iround(fiy2);
- //calculate sine and cosine
- si = fiy1-fiy2;
- tmp = fix2 - fix1;
- si = si/sqrt(si*si + tmp*tmp);
- csi = fix2-fix1;
- tmp = fiy2 - fiy1;
- csi = csi/sqrt(csi*csi + tmp*tmp);
- dx = o->un2fix(si*size/2.0);
- dy = o->un2fiy(csi*size/2.0);
- //calc cap
- pts[0].x = iround(fix1 - dx); pts[4].x = iround(fix2 - dx);
- pts[0].y = iround(fiy1 - dy); pts[4].y = iround(fiy2 - dy);
- pts[1].x = iround(fix1 + dx); pts[5].x = iround(fix2 + dx);
- pts[1].y = iround(fiy1 + dy); pts[5].y = iround(fiy2 + dy);
- //draw whisker
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
- UpdateMinMaxRect(&rDims, pts[4].x, pts[4].y);
- UpdateMinMaxRect(&rDims, pts[5].x, pts[5].y);
- IncrementMinMaxRect(&rDims, 3+(o->un2ix(LineDef.width)<<1));
- o->SetLine(&LineDef);
- switch(type & 0x0f) {
- case 2:
- pts[4].x = pts[3].x; pts[4].y = pts[3].y;
- pts[1].x = pts[2].x; pts[1].y = pts[2].y;
- case 3:
- if((type & 0x0f) == 3){
- pts[5].x = pts[3].x; pts[5].y = pts[3].y;
- pts[0].x = pts[2].x; pts[0].y = pts[2].y;
- }
- case 0:
- for(i = 0; i < 5; i+=2) o->oSolidLine(pts+i);
- break;
- case 1:
- pts[4].x = pts[5].x = pts[3].x; pts[4].y = pts[5].y = pts[3].y;
- pts[1].x = pts[0].x = pts[2].x; pts[1].y = pts[0].y = pts[2].y;
- o->oSolidLine(pts+2);
- break;
- }
-}
-
-void
-Whisker::DoMark(anyOutput *o, bool mark)
-{
- int i;
- LineDEF OldLine;
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
- 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));
+Bubble::~Bubble()
+{
+ Command(CMD_FLUSH, 0L, 0L);
+}
+
+void
+Bubble::DoPlot(anyOutput *o)
+{
+ int x1, y1, x2, y2, ix, iy, tmp;
+ double fix, fiy;
+
+ o->SetLine(&BubbleLine);
+ o->SetFill(&BubbleFill);
+ switch(type & 0x0f0) {
+ case BUBBLE_UNITS:
+ fix = o->un2fix(fs); fiy = o->un2fiy(fs);
+ break;
+ case BUBBLE_XAXIS:
+ fix = (o->fx2fix(fPos.fx+fs) - o->fx2fix(fPos.fx-fs))/2.0;
+ fiy = fix * (o->un2fiy(10.0f)/o->un2fix(10.0f)); //x and y resolution different ?
+ break;
+ case BUBBLE_YAXIS:
+ fix = (o->fy2fiy(fPos.fy-fs) - o->fy2fiy(fPos.fy+fs))/2.0;
+ fiy = fix * (o->un2fiy(10.0f)/o->un2fix(10.0f)); //x and y resolution different ?
+ break;
}
- else RestoreRectBitmap(&mo, &mrc, o);
-}
-
-bool
-Whisker::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- if(IsCloseToLine(&pts[2], &pts[3], mev->x, mev->y) ||
- IsCloseToLine(&pts[0], &pts[1], mev->x, mev->y) ||
- IsCloseToLine(&pts[4], &pts[5], mev->x, mev->y)) {
- o->ShowMark(this, MRK_GODRAW);
- return true;
- }
- }
- 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;
+ fix = fix < 0.0 ? -fix : fix; //sign must be positive
+ fiy = fiy < 0.0 ? -fiy : fiy;
+ rDims.left = rDims.right = iround(o->fx2fix(fPos.fx));
+ rDims.top = rDims.bottom = iround(o->fy2fiy(fPos.fy));
+ switch(type & 0x00f) {
+ case BUBBLE_CIRCLE:
+ ix = (int)(fix/2.0); iy = (int)(fiy/2.0);
+ tmp = iround(o->fx2fix(fPos.fx)); x1 = tmp - ix; x2 = tmp + ix;
+ tmp = iround(o->fy2fiy(fPos.fy)); y1 = tmp - iy; y2 = tmp + iy;
+ o->oCircle(x1, y1, x2, y2, name);
+ UpdateMinMaxRect(&rDims, x1, y1); UpdateMinMaxRect(&rDims, x2, y2);
+ break;
+ case BUBBLE_SQUARE:
+ if((type & 0xf00) == BUBBLE_CIRCUM) {
+ ix = iround(fix*.392699081); iy = iround(fiy*.392699081);
+ }
+ else if((type & 0xf00) == BUBBLE_AREA) {
+ ix = iround(fix*.443113462); iy = iround(fiy*.443113462);
}
+ else {
+ ix = iround(fix*.353553391); iy = iround(fiy*.353553391);
+ }
+ tmp = iround(o->fx2fix(fPos.fx)); x1 = tmp - ix; x2 = tmp + ix;
+ tmp = iround(o->fy2fiy(fPos.fy)); y1 = tmp - iy; y2 = tmp + iy;
+ o->oRectangle(x1, y1, x2, y2, name);
+ UpdateMinMaxRect(&rDims, x1, y1); UpdateMinMaxRect(&rDims, x2, y2);
break;
- case CMD_SET_DATAOBJ:
- Id = GO_WHISKER; data = (DataObj *)tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >3 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &pos1.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &pos1.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &pos2.fx);
- data->GetValue(ssRef[3].y, ssRef[3].x, &pos2.fy);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds(pos1.fx, pos1.fy);
- ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy);
- return true;
- }
- break;
- case CMD_WHISKER_STYLE:
- if(tmpl) type = *((int*)tmpl);
- return true;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// drop line
-DropLine::DropLine(GraphObj *par, DataObj *d, double x, double y, int which, int xc,
- int xr, int yc, int yr):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- fPos.fx = x;
- fPos.fy = y;
- type = which;
- Id = GO_DROPLINE;
- if(xc >= 0 && xr >= 0 && yc >= 0 && yr >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*2)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- cssRef = 2;
- }
- }
- bModified = false;
-}
-
-DropLine::DropLine(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-DropLine::~DropLine()
-{
- if(bModified) Undo.InvalidGO(this);
- if(ssRef) free(ssRef); ssRef = 0L;
-}
-
-void
-DropLine::DoPlot(anyOutput *o)
-{
- int tmp;
-
- o->RLP.fp = 0.0f; //reset line pattern start
- if(parent) {
- pts[0].x = pts[1].x = pts[2].x = pts[3].x = o->fx2ix(fPos.fx);
- pts[0].y = pts[1].y = pts[2].y = pts[3].y = o->fy2iy(fPos.fy);
- if(type & DL_LEFT) {
- tmp = o->fx2ix(parent->GetSize(SIZE_BOUNDS_LEFT));
- if(tmp < pts[0].x) pts[0].x = tmp;
- if(tmp > pts[1].x) pts[1].x = tmp;
- }
- if(type & DL_RIGHT) {
- tmp = o->fx2ix(parent->GetSize(SIZE_BOUNDS_RIGHT));
- if(tmp < pts[0].x) pts[0].x = tmp;
- if(tmp > pts[1].x) pts[1].x = tmp;
- }
- if(type & DL_YAXIS) {
- tmp = iround(parent->GetSize(SIZE_YAXISX));
- if(tmp < pts[0].x) pts[0].x = tmp;
- if(tmp > pts[1].x) pts[1].x = tmp;
- }
- if(type & DL_TOP) {
- tmp = o->fy2iy(parent->GetSize(SIZE_BOUNDS_TOP));
- if(tmp < pts[2].y) pts[2].y = tmp;
- if(tmp > pts[3].y) pts[3].y = tmp;
- }
- if(type & DL_BOTTOM) {
- tmp = o->fy2iy(parent->GetSize(SIZE_BOUNDS_BOTTOM));
- if(tmp < pts[2].y) pts[2].y = tmp;
- if(tmp > pts[3].y) pts[3].y = tmp;
- }
- if(type & DL_XAXIS) {
- tmp = iround(parent->GetSize(SIZE_XAXISY));
- if(tmp < pts[2].y) pts[2].y = tmp;
- if(tmp > pts[3].y) pts[3].y = tmp;
- }
- SetMinMaxRect(&rDims, pts[0].x, pts[2].y, pts[1].x, pts[3].y);
- IncrementMinMaxRect(&rDims, 3);
- o->SetLine(&LineDef);
- o->oPolyline(pts, 2);
- o->oPolyline(pts+2, 2);
- }
-}
-
-void
-DropLine::DoMark(anyOutput *o, bool mark)
-{
-
- InvertLine(pts, 2, &LineDef, 0L, o, mark);
- InvertLine(pts+2, 2, &LineDef, &rDims, o, mark);
-}
-
-bool
-DropLine::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- if(IsCloseToLine(&pts[0], &pts[1], mev->x, mev->y) ||
- IsCloseToLine(&pts[2], &pts[3], mev->x, mev->y)) {
- o->ShowMark(this, MRK_GODRAW);
- return true;
- }
- }
- break;
- }
- return false;
- case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_DL_LINE:
- if(tmpl) memcpy(&LineDef, tmpl, sizeof(LineDEF));
- return true;
- case CMD_DL_TYPE:
- if(tmpl)type = *((int*)tmpl);
- return true;
- case CMD_SET_DATAOBJ:
- Id = GO_DROPLINE;
- data = (DataObj *)tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >1 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
- return true;
- }
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// define a spherical scanline used for clipping spheres
-sph_scanline::sph_scanline(POINT3D *center, int radius, bool bVert):GraphObj(0, 0)
-{
- Id = GO_SPHSCANL;
- rad = radius >= 0 ? radius : -radius;
- memcpy(&p1, center, sizeof(POINT3D)); memcpy(&p2, center, sizeof(POINT3D));
- memcpy(¢, center, sizeof(POINT3D));
- if(vert = bVert) {
- p1.y -= rad; p2.y += rad;
- }
- else {
- p1.x -= rad; p2.x += rad;
- }
- if(p1.x < 1) p1.x = 1; if(p1.y < 1) p1.y = 1;
- if(p2.x < p1.x) p2.x = p1.x; if(p2.y < p1.y) p2.y = p1.y;
- bValid1 = bValid2 = true;
-}
-
-bool
-sph_scanline::Command(int cmd, void *tmpl, anyOutput *o)
-{
- switch(cmd) {
- case CMD_ADDTOLINE:
- if(bValid1 && tmpl){
- memcpy(&p2, tmpl, sizeof(POINT3D));
- bValid2 = true;
- return true;
- }
- break;
- case CMD_STARTLINE:
- if(!bValid1 && tmpl){
- memcpy(&p1, tmpl, sizeof(POINT3D));
- bValid1 = true;
- }
- break;
- return true;
- }
- return false;
-}
-
-void
-sph_scanline::DoClip(GraphObj *co)
-{
- POINT3D *pla;
- int np, i;
-
- if(!bValid1 || !bValid2) return;
- switch(co->Id){
- case GO_SPHERE:
- bValid1 = bValid2 = false;
- clip_sphline_sphere(this, &p1, &p2, ¢, rad, iround(co->GetSize(SIZE_RADIUS1)),
- iround(co->GetSize(SIZE_XPOS)), iround(co->GetSize(SIZE_YPOS)),
- iround(co->GetSize(SIZE_ZPOS)));
- break;
- case GO_PLANE:
- for(i=0; ((plane*)co)->GetPolygon(&pla, &np, i); i++) {
- bValid1 = bValid2 = false;
- clip_sphline_plane(this, &p1, &p2, ¢, rad, pla, np, ((plane*)co)->GetVec());
- }
- break;
- }
-}
-
-bool
-sph_scanline::GetPoint(POINT *p, int sel)
-{
- if(!bValid1 || !bValid2) {
- p->x = p->y = 0;
- return false;
- }
- switch(sel) {
- case 1:
- p->x = p1.x; p->y = p1.y;
- return true;
- case 2:
- p->x = p2.x; p->y = p2.y;
- return true;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Sphere: a symbol in three dimensional space
-Sphere::Sphere(GraphObj *par, DataObj *d, int sel, double x, double y, double z,
- double r, int xc, int xr, int yc, int yr, int zc, int zr, int rc, int rr)
- :GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- Id = GO_SPHERE;
- fPos.fx = x; fPos.fy = y; fPos.fz = z; size = r;
- if(xc >=0 || xr >=0 || yc >=0 || yr >=0 || zc >=0 || zr >=0 || rc >=0 || rr >=0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- ssRef[2].x = zc; ssRef[2].y = zr;
- ssRef[3].x = rc; ssRef[3].y = rr;
- cssRef = 4;
- }
- }
- type = sel;
- bModified = false;
-}
-
-Sphere::Sphere(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-Sphere::~Sphere()
-{
- if(bModified) Undo.InvalidGO(this);
- Command(CMD_FLUSH, 0L, 0L);
-}
-
-double
-Sphere::GetSize(int select)
-{
- switch(select) {
- case SIZE_MIN_X: return fip.fx - (double)rx;
- case SIZE_MAX_X: return fip.fx + (double)rx;
- case SIZE_MIN_Y: return fip.fy - (double)ry;
- case SIZE_MAX_Y: return fip.fy + (double)ry;
- case SIZE_MIN_Z: return fip.fz - (double)rx;
- case SIZE_MAX_Z: return fip.fz + (double)rx;
- case SIZE_XPOS: return fip.fx;
- case SIZE_YPOS: return fip.fy;
- case SIZE_ZPOS: return fip.fz;
- case SIZE_RADIUS1: case SIZE_RADIUS2: return (double)rx;
- case SIZE_XCENT: return fPos.fx;
- case SIZE_YCENT: return fPos.fy;
- case SIZE_ZCENT: return fPos.fz;
- case SIZE_DRADIUS: return size;
- case SIZE_SYMBOL:
- if(!type) return size;
- else return defs.GetSize(SIZE_SYMBOL);
- case SIZE_SYM_LINE: return Line.width;
- }
- return 0.0;
-}
-
-bool
-Sphere::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_SYMBOL: size = value; break;
- case SIZE_SYM_LINE: Line.width = value; break;
- }
- return true;
-}
-
-DWORD
-Sphere::GetColor(int select)
+ case BUBBLE_UPTRIA:
+ case BUBBLE_DOWNTRIA:
+ if((type & 0xf00) == BUBBLE_CIRCUM) {
+ fix *= .523598775; fiy *= .523598775;
+ }
+ else if((type & 0xf00) == BUBBLE_AREA) {
+ fix *= .673386843; fiy *= .673386843;
+ }
+ else {
+ fix *=.433012702; fiy *= .433012702;
+ }
+ ix = iround(fix); iy = iround(fiy*.57735);
+ tmp = iround(o->fx2fix(fPos.fx));
+ pts[0].x = pts[3].x = tmp - ix; pts[1].x = tmp + ix; pts[2].x = tmp;
+ tmp = iround(o->fy2fiy(fPos.fy));
+ if((type & 0x00f) == BUBBLE_UPTRIA) {
+ pts[0].y = pts[1].y = pts[3].y = tmp + iy;
+ pts[2].y = tmp - iround(fiy*1.1547);
+ }
+ else {
+ pts[0].y = pts[1].y = pts[3].y = tmp - iy;
+ pts[2].y = tmp + iround(fiy*1.1547);
+ }
+ o->oPolygon(pts, 4);
+ UpdateMinMaxRect(&rDims, pts[0].x, pts[0].y);
+ UpdateMinMaxRect(&rDims, pts[1].x, pts[2].y);
+ break;
+ }
+}
+
+void
+Bubble::DoMark(anyOutput *o, bool mark)
{
- switch(select) {
- case COL_SYM_LINE: return Line.color;
- case COL_SYM_FILL: return Fill.color;
- default: return defs.Color(select);
+ if(mark) {
+ BubbleFillLine.color ^= 0x00ffffffL;
+ BubbleFill.color ^= 0x00ffffffL;
+ DoPlot(o);
+ BubbleFill.color ^= 0x00ffffffL;
+ BubbleFillLine.color ^= 0x00ffffffL;
+ }
+ else {
+ if(parent) parent->DoPlot(o);
+ else DoPlot(o);
}
+ o->UpdateRect(&rDims, false);
}
-
-bool
-Sphere::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_SYM_LINE: Line.color = col; break;
- case COL_SYM_FILL: Fill.color = col; break;
- }
- return true;
-}
-
-void
-Sphere::DoPlot(anyOutput *o)
-{
- int i;
-
- if(size <= 0.001 || !o) return;
- if(!o->fvec2ivec(&fPos, &fip)) return;
- bDrawDone = false;
- if(scl){
- for(i = 0; i < nscl; i++) if(scl[i]) delete(scl[i]);
- free(scl);
- scl = 0L; nscl = 0;
- }
- ix = iround(fip.fx); iy = iround(fip.fy);
- switch (type) {
- case 1:
- rx = ry = iround(size * 0.5 * o->ddx); break;
- case 2:
- rx = ry = iround(size * 0.5 * o->ddy); break;
- case 3:
- rx = ry = iround(size * 0.5 * o->ddz); break;
- default:
- type = 0;
- case 5:
- rx = o->un2ix(size/2.0); ry = o->un2iy(size/2.0);
- break;
- }
- rDims.left = ix - rx; rDims.right = ix + rx;
- rDims.top = iy - ry; rDims.bottom = iy + ry;
- if(o->VPscale > 1.5 && (
- (rDims.right < defs.clipRC.left) || (rDims.left > defs.clipRC.right) ||
- (rDims.bottom < defs.clipRC.top) || (rDims.top > defs.clipRC.bottom))){
- bDrawDone = true; return;
- }
- if(parent && parent->Command(CMD_SET_GO3D, this, o)) return;
- Command(CMD_REDRAW, 0L, o);
-}
-
-bool
-Sphere::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- int i;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name) free(name); name = 0L;
- if(scl){
- for(i = 0; i < nscl; i++) if(scl[i]) delete(scl[i]);
- free(scl);
- scl = 0L; nscl = 0;
- }
- return true;
+
+bool
+Bubble::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ bool bSelected = false;
+ unsigned long n, s;
+ POINT p;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name)free(name); name = 0L;
+ return true;
+ case CMD_SCALE:
+ if(!tmpl) return false;
+ if((type & 0x0f0)== BUBBLE_UNITS) fs *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleFillLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleFillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ BubbleFill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
case CMD_LEGEND:
if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
- ((Legend*)tmpl)->HasFill(&Line, &Fill);
- break;
- case CMD_SYM_FILL:
- if(tmpl) memcpy(&Fill, tmpl, sizeof(FillDEF));
- return true;
- case CMD_MRK_DIRTY:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_SET_DATAOBJ:
- Id = GO_SPHERE;
- data = (DataObj *)tmpl;
- return true;
- case CMD_REDRAW:
- //Note: this command is issued either by Undo (no output given) or
- // by Plot3D::DoPlot after sorting all objects (output specified)
- if(!parent) return false;
- if(!o) return parent->Command(cmd, tmpl, o);
- if(bDrawDone) return false;
- bDrawDone = true;
- if(scl) DrawPG(o, 0);
- else {
- o->SetLine(&Line); o->SetFill(&Fill);
- if(Fill.type & FILL_LIGHT3D) o->oSphere(ix, iy, rx, 0L, 0, 0L);
- else o->oCircle(ix-rx, iy-ry, ix+rx+1, iy+ry+1, name);
- }
- rx--;ry--; //smaller marking rectangle
- rDims.left = ix-rx-1; rDims.right = ix+rx+1;
- rDims.top = iy-ry-1; rDims.bottom = iy+ry+1;
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- o->ShowMark(&rDims, MRK_INVERT);
- CurrGO = this;
- return true;
- }
- break;
- }
- break;
- case CMD_UPDATE:
- if(ssRef && cssRef >1 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &fPos.fz);
- if(cssRef >3) data->GetValue(ssRef[3].y, ssRef[3].x, &size);
- return true;
- }
- return false;
- case CMD_CLIP:
- if(co = (GraphObj*)tmpl){
- switch(co->Id) {
- case GO_PLANE:
- case GO_SPHERE:
- DoClip(co);
- break;
- }
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds3D(fPos.fx, fPos.fy, fPos.fz);
- return true;
- }
- break;
- }
- return false;
-}
-
-void
-Sphere::DoClip(GraphObj *co)
-{
- RECT cliprc;
- double d, d1;
- POINT3D cscl;
- int x, y, q, di, de, lim, cx, cy;
- int i;
-
- if(co && co->Id == GO_SPHERE) {
- if(co->GetSize(SIZE_ZPOS) > fip.fz) return;
- d1 = (d = co->GetSize(SIZE_XPOS) - fip.fx) * d;
- d1 += (d = co->GetSize(SIZE_YPOS) - fip.fy) * d;
- d1 = sqrt(d1 + (d = co->GetSize(SIZE_ZPOS) - fip.fz) * d);
- if(d1 >= (co->GetSize(SIZE_RADIUS1) + rx))return;
- }
- else {
- cliprc.left = iround(co->GetSize(SIZE_MIN_X));
- cliprc.right = iround(co->GetSize(SIZE_MAX_X));
- cliprc.top = iround(co->GetSize(SIZE_MIN_Y));
- cliprc.bottom = iround(co->GetSize(SIZE_MAX_Y));
- if(!OverlapRect(&rDims, &cliprc))return;
- }
- //use a list of horizontal scanlines created by a circular Bresenham's algorithm
- //Ref: C. Montani, R. Scopigno (1990) "Speres-To-Voxel Conversion", in:
- // Graphic Gems (A.S. Glassner ed.) Academic Press, Inc.;
- // ISBN 0-12-288165-5
- if(!scl && (scl = (sph_scanline**)calloc(rx*7+2, sizeof(sph_scanline*)))) {
- cscl.z = iround(fip.fz); nscl = 0;
- for(q = 0; q < 2; q++) {
- x = lim = 0; y = rx; di = 2*(1-rx);
- while( y >= lim) {
- if(di < 0) {
- de = 2*di + 2*y -1;
- if(de > 0) {
- x++; y--; di += (2*x -2*y +2);
- }
- else {
- x++; di += (2*x +1);
- }
- }
- else {
- de = 2*di -2*x -1;
- if(de > 0) {
- y--; di += (-2*y +1);
- }
- else {
- x++; y--; di += (2*x -2*y +2);
- }
- }
- switch(q) {
- case 0:
- cy = rx - y; cx = x;
- break;
- case 1:
- cy = rx + x; cx = y;
- break;
- }
- cscl.y = iround(fip.fy); cscl.x = iround(fip.fx);
- cscl.y = cscl.y - rx + cy;
- if(cx > 1) scl[nscl++] = new sph_scanline(&cscl, cx, false);
- }
- }
- }
- if(!scl) return;
- //do clip for every scanline
- for(i = 0; i < nscl; i++) if(scl[i]) scl[i]->DoClip(co);
-}
-
-void
-Sphere::DrawPG(anyOutput *o, int start)
-{
- POINT *pts, np;
- long cp = 0;
- int i = start, step = 1;
-
- if(!o || !scl ||!nscl) return;
- if((pts = (POINT*)calloc(nscl*2, sizeof(POINT)))) {
- do {
- if(scl[i]) {
- if(step > 0) scl[i]->GetPoint(&np, 1);
- else scl[i]->GetPoint(&np, 2);
- if(np.x && np.y){
- AddToPolygon(&cp, pts, &np);
- }
- else if(cp){
- if(step > 0) DrawPG(o, i); //split sphere
- step = -1;
- }
- }
- if(i == nscl && step > 0) step = -1;
- else i += step;
- }while(i > start);
- }
- o->SetLine(&Line); o->SetFill(&Fill);
- if(cp) o->oSphere(ix, iy, rx, pts, cp, name);
- free(pts);
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// plane: utility object to draw a flat plane in 3D space
-plane::plane(GraphObj *par, DataObj *d, fPOINT3D *pts, int nPts, LineDEF *line,
- FillDEF *fill):GraphObj(par, d)
-{
- int i;
- long area;
- double vlength, v1[3], v2[3], vp[3], area1;
- bool v_valid = false;
-
- nli = n_ipts = n_lines = 0;
- nldata = 0L; ldata = 0L; co = 0L; lines = 0L; PlaneVec = 0L;
- Id = GO_PLANE; totalArea = 0;
- memcpy(&Line, line, sizeof(LineDEF));
- memcpy(&Fill, fill, sizeof(FillDEF));
- rDims.left = rDims.right = rDims.top = rDims.bottom = 0;
- if(nPts > 2 && (ldata =(POINT3D**)calloc(1, sizeof(POINT3D*))) &&
- (ldata[0] = (POINT3D *)calloc(nPts+1, sizeof(POINT3D))) &&
- (nldata = (int*)calloc(1, sizeof(int))) &&
- (ipts = (POINT*)calloc(nPts, sizeof(POINT)))){
- for(i = 0; i < nPts; i++) {
- ipts[i].x = ldata[0][i].x = iround(pts[i].fx);
- ipts[i].y = ldata[0][i].y = iround(pts[i].fy);
- ldata[0][i].z = iround(pts[i].fz);
- }
- nldata[0] = nPts; nli = 1; n_ipts = nPts;
- xBounds.fx = xBounds.fy = pts[0].fx; yBounds.fx = yBounds.fy = pts[0].fy;
- zBounds.fx = zBounds.fy = pts[0].fz;
- rDims.left = rDims.right = ipts[0].x; rDims.top = rDims.bottom = ipts[0].y;
- for(i = 1; i < nPts; i++){
- UpdateMinMaxRect(&rDims, ipts[i].x, ipts[i].y);
- if(pts[i].fx < xBounds.fx) xBounds.fx = pts[i].fx;
- if(pts[i].fx > xBounds.fy) xBounds.fy = pts[i].fx;
- if(pts[i].fy < yBounds.fx) yBounds.fx = pts[i].fy;
- if(pts[i].fy > yBounds.fy) yBounds.fy = pts[i].fy;
- if(pts[i].fz < zBounds.fx) zBounds.fx = pts[i].fz;
- if(pts[i].fz > zBounds.fy) zBounds.fy = pts[i].fz;
- }
- //test if plane vertical
- area1 = (xBounds.fx - xBounds.fy) * (yBounds.fx - yBounds.fy);
- for(area = 0, i = 1; i < nPts; i++) {
- area += (ipts[i].x - ipts[i-1].x) * ((ipts[i].y + ipts[i-1].y)>>1);
- }
- totalArea= area = abs(area);
- area1 = area ? fabs(area1/area) : 101.0;
- if(area < 100 && area1 > 100.0) { //its small or vertical !
- if(lines=(line_segment**)calloc(nPts, sizeof(line_segment*))){
- for(i = 1; i < nPts; i++) {
- lines[i-1] = new line_segment(par, d, line, &ldata[0][i-1], &ldata[0][i]);
- }
- n_lines = nPts-1;
- }
- }
- else { //for a visible plane get vector perpendicular to plane
- for (i = 1; i < (nPts-1); i++) {
- v1[0] = pts[i].fx - pts[i-1].fx; v1[1] = pts[i].fy - pts[i-1].fy;
- v1[2] = pts[i].fz - pts[i-1].fz; v2[0] = pts[i+1].fx - pts[i].fx;
- v2[1] = pts[i+1].fy - pts[i].fy; v2[2] = pts[i+1].fz - pts[i].fz;
- vp[0] = v1[1]*v2[2] - v1[2]*v2[1]; vp[1] = v1[2]*v2[0] - v1[0]*v2[2];
- vp[2] = v1[0]*v2[1] - v1[1]*v2[0];
- vlength = sqrt(vp[0]*vp[0]+vp[1]*vp[1]+vp[2]*vp[2]);
- if(v_valid = (vlength > 100.0)) break;
- }
- if(v_valid && (PlaneVec = (double*)malloc(4 * sizeof(double)))) {
- PlaneVec[0] = vp[0]/vlength; PlaneVec[1] = vp[1]/vlength;
- PlaneVec[2] = -vp[2]/vlength;
- PlaneVec[3] = PlaneVec[0] * pts[i].fx + PlaneVec[1] * pts[i].fy - PlaneVec[2] * pts[i].fz;
- }
- }
- }
-}
-
-plane::~plane()
-{
- int i;
-
- if(ldata) {
- for(i = 0; i < nli; i++) if(ldata[i]) free(ldata[i]);
- free(ldata); ldata = 0L; nli = 0;
- }
- if(lines) {
- for(i = 0; i < n_lines; i++) if(lines[i]) delete(lines[i]);
- free(lines); lines = 0L; n_lines = 0;
- }
- if(nldata) free(nldata); nldata = 0L;
- if(ipts) free(ipts); ipts = 0L;
- if(PlaneVec) free(PlaneVec); PlaneVec = 0L;
-}
-
-double
-plane::GetSize(int select)
-{
- switch(select) {
- case SIZE_MIN_X: return xBounds.fx;
- case SIZE_MAX_X: return xBounds.fy;
- case SIZE_MIN_Y: return yBounds.fx;
- case SIZE_MAX_Y: return yBounds.fy;
- case SIZE_MIN_Z: return zBounds.fx;
- case SIZE_MAX_Z: return zBounds.fy;
- }
- return 0.0;
-}
-
-void
-plane::DoPlot(anyOutput *o)
-{
- int i;
-
- bDrawDone = bReqPoint = false;
- if(Fill.type & FILL_LIGHT3D){
- Fill.color = o->VecColor(PlaneVec, Fill.color2, Fill.color);
- Fill.type &= ~FILL_LIGHT3D;
- }
- if(o->VPscale > 1.5 && (
- //ignore objects outside the display ara
- (rDims.right < defs.clipRC.left) || (rDims.left > defs.clipRC.right) ||
- (rDims.bottom < defs.clipRC.top) || (rDims.top > defs.clipRC.bottom))){
- bDrawDone = true; return;
- }
- if(lines) {
- if(Line.width == 0.0) return;
- //draw line segments for vertical plane
- for(i = 0; i < n_lines; i++) if(lines[i]) lines[i]->DoPlot(o);
- bDrawDone = true; return;
- }
- if(parent && parent->Command(CMD_SET_GO3D, this, o)) return;
- Command(CMD_REDRAW, 0L, o);
-}
-
-void
-plane::DoMark(anyOutput *o, bool mark)
-{
- FillDEF tmpfill;
- LineDEF tmpline;
-
- memcpy(&tmpfill, &Fill, sizeof(FillDEF));
- memcpy(&tmpline, &Line, sizeof(LineDEF));
- if(mark){
- tmpfill.color ^= 0x00ffffffL; tmpline.color ^= 0x00ffffffL;
- }
- o->SetLine(&tmpline); o->SetFill(&tmpfill);
- o->oPolygon(ipts, n_ipts);
-}
-
-bool
-plane::Command(int cmd, void *tmpl, anyOutput *o)
-{
- POINT *pt;
- POINT3D *ap;
- int i, j;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- if(parent) return parent->Command(cmd, tmpl, o);
+ ((Legend*)tmpl)->HasFill(&BubbleLine, &BubbleFill, 0L);
break;
- case CMD_REDRAW:
- if(bDrawDone) return false;
- bDrawDone = true;
- if(o && nldata){
- if(Line.width == 0.0) Line.color = Fill.color;
- o->SetLine(&Line); o->SetFill(&Fill);
- for(i = 0; i < nli; i++){
- if(nldata[i] > 2 && (pt = (POINT*)malloc(nldata[i]*sizeof(POINT)))){
- for(j = 0; j < nldata[i]; j++) {
- pt[j].x = ldata[i][j].x; pt[j].y = ldata[i][j].y;
- }
- o->oPolygon(pt, nldata[i]);
- free(pt);
- }
- }
- }
- return true;
- case CMD_STARTLINE:
- if(ap = (POINT3D*)tmpl) {
- if(ldata && nldata && nli) {
- if(bReqPoint) {
- Command(CMD_ADDTOLINE, &ReqPoint, o);
- bReqPoint = false;
- }
- i = nli-1; j = nldata[i]-1;
- if(ldata[i][j].x == ap->x && ldata[i][j].y == ap->y && ldata[i][j].z == ap->z){
- return true;
- }
- if(IsValidPG(ldata[i], nldata[i])) {
- //close previous polygon first
- if(ldata[i][0].x != ldata[i][j].x || ldata[i][0].y != ldata[i][j].y ||
- ldata[i][0].z != ldata[i][j].z){
- j++;
- ldata[i][j].x = ldata[i][0].x; ldata[i][j].y = ldata[i][0].y;
- ldata[i][j].z = ldata[i][0].z; nldata[i]++;
- }
- ldata = (POINT3D**)realloc(ldata, sizeof(POINT3D*) * (nli+1));
- ldata[nli] = (POINT3D*)malloc(sizeof(POINT3D)*2);
- nldata = (int*)realloc(nldata, sizeof(int) * (nli+1));
- }
- else { //drop incomplete or invalid polygon
- nli--;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, p.x = mev->x, p.y = mev->y) && !CurrGO) {
+ switch(type & 0x00f) {
+ case BUBBLE_CIRCLE:
+ n = s = p.x - ((rDims.right+rDims.left)>>1);
+ s *= n;
+ n = p.y - ((rDims.bottom+rDims.top)>>1);
+ n = isqr(s += n*n) -2;
+ bSelected = ((unsigned)((rDims.right-rDims.left)>>1) > n);
+ break;
+ case BUBBLE_SQUARE:
+ bSelected = true;
+ break;
+ case BUBBLE_UPTRIA:
+ case BUBBLE_DOWNTRIA:
+ if(!(bSelected = IsInPolygon(&p, pts, 4)))
+ bSelected = IsCloseToPL(p, pts, 4);
+ break;
}
+ if(bSelected) o->ShowMark(this, MRK_GODRAW);
+ return bSelected;
}
- else {
- ldata = (POINT3D**)calloc(1, sizeof(POINT3D*));
- ldata[nli = 0] = (POINT3D*)malloc(sizeof(POINT3D));
- nldata = (int*)calloc(1, sizeof(int));
- bReqPoint = false;
- }
- if(ldata && nldata) {
- ldata[nli][0].x = ap->x; ldata[nli][0].y = ap->y;
- ldata[nli][0].z = ap->z; nldata[nli++] = 1;
- return true;
- }
- }
- break;
- case CMD_REQ_POINT:
- if(ap = (POINT3D*)tmpl) {
- ReqPoint.x = ap->x; ReqPoint.y = ap->y; ReqPoint.z = ap->z;
- bReqPoint = true;
+ break;
}
- return true;
- case CMD_ADDTOLINE:
- if((ap = (POINT3D*)tmpl) && ldata && nldata && nli) {
- i= nli-1; j=nldata[i]-1;
- if((ldata[i][j].x == ap->x && ldata[i][j].y == ap->y) ||
- (ldata[i][j].y == ap->y && ldata[i][j].z == ap->z)){
- //probably nothing to add
- ldata[i][j].x = ap->x; ldata[i][j].y = ap->y;
- return j>0 ? true : false;
- }
- ldata[i] = (POINT3D*)realloc(ldata[i], ((j=nldata[i])+2) * sizeof(POINT3D));
- ldata[i][j].x = ap->x; ldata[i][j].y = ap->y;
- ldata[i][j].z = ap->z; nldata[i]++;
- return true;
- }
- case CMD_CLIP:
- if(co = (GraphObj*)tmpl){
- switch(co->Id) {
- case GO_PLANE:
- //Clip only planes which are drawn later
- if(GetSize(SIZE_MIN_Z) < co->GetSize(SIZE_MIN_Z)) return false;
- if(nli){
- DoClip(co);
- if(nli && ldata) {
- i = nli-1; j = nldata[i]-1;
- //is last part valid ?
- if(j < 2) {
- free(ldata[i]); ldata[i] = 0L;
- nldata[i] = 0;
- nli--;
- }
- //close last polygon
- else if(ldata[i][0].x != ldata[i][j].x ||
- ldata[i][0].y != ldata[i][j].y ||
- ldata[i][0].z != ldata[i][j].z){
- j++;
- ldata[i][j].x = ldata[i][0].x;
- ldata[i][j].y = ldata[i][0].y;
- ldata[i][j].z = ldata[i][0].z;
- nldata[i]++;
- }
- }
- }
- else xBounds.fx=xBounds.fy=yBounds.fx=yBounds.fy=zBounds.fx=zBounds.fy=0.0;
- break;
- }
- }
- break;
- }
- return false;
-}
-
-void *
-plane::ObjThere(int x, int y)
-{
- POINT p1;
-
- if(bDrawDone && IsInRect(&rDims, p1.x = x, p1.y = y) &&
- (IsInPolygon(&p1, ipts, n_ipts) || IsCloseToPL(p1, ipts, n_ipts))) return this;
- return 0L;
-}
-
-bool
-plane::GetPolygon(POINT3D **pla, int *npt, int n)
-{
- if(n < nli && ldata && ldata[n]) {
- *pla = ldata[n]; *npt = nldata[n];
- return true;
- }
- return false;
-}
-
-void
-plane::DoClip(GraphObj *co)
-{
- RECT cliprc;
- int o_nli, *o_nldata = 0L;
- POINT3D **o_ldata = 0L;
- POINT3D *tpg;
- int i, j, tnpt;
- bool is_valid = false;
-
- //if two planes have the same parent it means they are part of one object
- // do not clip!
- if(co->parent == parent && co->Id == GO_PLANE) return;
- if(co->Id == GO_PLANE && (parent->parent->Id == GO_GRID3D || parent->parent->Id == GO_RIBBON)
- && co->parent->parent == parent->parent) return;
- cliprc.left = iround(co->GetSize(SIZE_MIN_X));
- cliprc.right = iround(co->GetSize(SIZE_MAX_X));
- cliprc.top = iround(co->GetSize(SIZE_MIN_Y));
- cliprc.bottom = iround(co->GetSize(SIZE_MAX_Y));
- if(OverlapRect(&rDims, &cliprc) && co != this) {
- o_nli = nli; nli = 0;
- o_nldata = nldata; nldata = 0L;
- o_ldata = ldata; ldata = 0L;
- switch(co->Id) {
- case GO_PLANE:
- //clip all parts of this plane with all from another plane
- for(i = 0; ((plane*)co)->GetPolygon(&tpg, &tnpt, i); i++){
- for(j = 0; j < o_nli; j++) {
- if(o_nldata[j] >2) clip_plane_plane(this, o_ldata[j], o_nldata[j], PlaneVec,
- tpg, tnpt, ((plane*)co)->GetVec(), ipts, n_ipts );
- }
- if(bReqPoint){
- Command(CMD_ADDTOLINE, &ReqPoint, 0L);
- bReqPoint = false;
- }
- if(nli) is_valid = true;
- if(o_ldata) {
- for(j = 0; j < o_nli; j++) if(o_ldata[j]) free(o_ldata[j]);
- free(o_ldata);
- }
- if(o_nldata) free(o_nldata);
- o_nli = nli; nli = 0;
- o_nldata = nldata; nldata = 0L;
- o_ldata = ldata; ldata = 0L;
- if(!o_nli) { //plane is completly hidden
- return;
- }
- }
- if(is_valid || i==0){
- nli = o_nli; o_nli = 0;
- nldata = o_nldata; o_nldata = 0L;
- ldata = o_ldata; o_ldata = 0L;
- }
- if(nli > 1) for(i = 1; i < nli; i++) {
- if(nldata[i] > 3 && ldata[i][nldata[i]-1].x == ldata[i-1][0].x
- && ldata[i][nldata[i]-1].y == ldata[i-1][0].y) {
- nldata[i]--; //bad vis: ignore last point
- }
- }
- break;
- default:
- nli = o_nli; o_nli = 0;
- nldata = o_nldata; o_nldata = 0L;
- ldata = o_ldata; o_ldata = 0L;
- break;
- }
- //check shape and recalc some values
- if(is_valid && nli) {
- xBounds.fx = xBounds.fy = ldata[0][0].x; yBounds.fx = yBounds.fy = ldata[0][0].y;
- zBounds.fx = zBounds.fy = ldata[0][0].z;
- rDims.left = rDims.right = ldata[0][0].x; rDims.top = rDims.bottom = ldata[0][0].y;
- for(i = 0; i < nli; i++) if(nldata[i] > 2){
- if(ldata[i][0].x != ldata[i][nldata[i]-1].x || ldata[i][0].y != ldata[i][nldata[i]-1].y
- || ldata[i][0].z != ldata[i][nldata[i]-1].z) {
- ldata[i][nldata[i]].x = ldata[i][0].x; ldata[i][nldata[i]].y = ldata[i][0].y;
- ldata[i][nldata[i]].z = ldata[i][0].z; nldata[i]++;
- }
- for(j = 0; j < (nldata[i]-1); j++) {
- UpdateMinMaxRect(&rDims, ldata[i][j].x, ldata[i][j].y);
- if(ldata[i][j].x < xBounds.fx) xBounds.fx = ldata[i][j].x;
- if(ldata[i][j].x > xBounds.fy) xBounds.fy = ldata[i][j].x;
- if(ldata[i][j].y < yBounds.fx) yBounds.fx = ldata[i][j].y;
- if(ldata[i][j].y > yBounds.fy) yBounds.fy = ldata[i][j].y;
- if(ldata[i][j].z < zBounds.fx) zBounds.fx = ldata[i][j].z;
- if(ldata[i][j].z > zBounds.fy) zBounds.fy = ldata[i][j].z;
- }
- }
- }
- }
- if(o_ldata) {
- for(i = 0; i < o_nli; i++) if(o_ldata[i]) free(o_ldata[i]);
- free(o_ldata);
- }
- if(o_nldata) free(o_nldata);
-}
-
-bool
-plane::IsValidPG(POINT3D *pg, int npg)
-{
- int i;
- long area;
-
- //a polygon must have more than 3 Points
- if(npg < 3) return false;
- //check for a reasonable size
- for(area = 0, i = 1; i < npg; i++) {
- area += (pg[i].x - pg[i-1].x) * ((pg[i].y + pg[i-1].y)>>1);
- }
- area += (pg[0].x - pg[i-1].x) * ((pg[0].y + pg[i-1].y)>>1);
- area = abs(area);
- if(area < 20) return false;
- if(totalArea/area > 100) return false;
- return true;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// a simple plane in three dimensional space
-Plane3D::Plane3D(GraphObj *par, DataObj *da, fPOINT3D *pt, long npt)
- :GraphObj(par, da)
-{
- FileIO(INIT_VARS);
- Id = GO_PLANE3D;
- dt = (fPOINT3D*) memdup(pt, sizeof(fPOINT3D)*npt, 0L);
- ndt = npt;
-}
-
-Plane3D::Plane3D(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-Plane3D::~Plane3D()
-{
- if(dt) free(dt); if(pts) free(pts);
- dt = 0L; ndt = 0L;
- if(ipl) delete (ipl); ipl = 0L;
-}
-
-bool
-Plane3D::SetSize(int select, double value)
-{
- int i;
-
- if((select & 0xfff) >= SIZE_XPOS && (select & 0xfff) <= SIZE_XPOS_LAST){
- if((i = select-SIZE_XPOS) >=0 && i <= 200 && i < (int)ndt){
- dt[i].fx = value; return true;
- }
- }
- else if((select & 0xfff) >= SIZE_YPOS && (select & 0xfff) <= SIZE_YPOS_LAST){
- if((i = select-SIZE_YPOS) >=0 && i <= 200 && i < (int)ndt){
- dt[i].fy = value; return true;
- }
- }
- else if((select & 0xfff) >= SIZE_ZPOS && (select & 0xfff) <= SIZE_ZPOS_LAST){
- if((i = select-SIZE_ZPOS) >=0 && i <= 200 && i < (int)ndt){
- dt[i].fz = value; return true;
- }
- }
- else switch(select) {
- case SIZE_SYM_LINE:
- Line.width = value;
- }
- return false;
-}
-
-bool
-Plane3D::SetColor(int select, DWORD col)
-{
- switch(select) {
- case COL_POLYLINE: Line.color = col; return true;
- case COL_POLYGON: Fill.color = col; return true;
- }
- return false;
-}
-
-void
-Plane3D::DoPlot(anyOutput *o)
-{
- int i;
-
- if(ipl) delete ipl; ipl = 0L;
- if(pts) free(pts); pts = 0L;
- o->ActualSize(&rDims);
- rDims.left = rDims.right; rDims.top = rDims.bottom;
- rDims.right = rDims.bottom = 0;
- if((pts = (fPOINT3D*)malloc(sizeof(fPOINT3D)*ndt))){
- for(i = 0; i < ndt; i++) {
- if(!o->fvec2ivec(&dt[i], &pts[i])){
- free(pts); pts = 0L; return;
- }
- UpdateMinMaxRect(&rDims, iround(pts[i].fx), iround(pts[i].fy));
- }
- if(ipl = new plane(this, data, pts, i, &Line, &Fill))ipl->DoPlot(o);
- }
- IncrementMinMaxRect(&rDims, o->un2ix(Line.width)+1);
-}
-
-void
-Plane3D::DoMark(anyOutput *o, bool mark)
-{
- if(mark){
- if(pts && ipl)ipl->DoMark(o, mark);
- o->UpdateRect(&rDims, false);
- }
- else if(parent) parent->Command(CMD_REDRAW, 0L, o);
-}
-
-bool
-Plane3D::Command(int cmd, void *tmpl, anyOutput *o)
-{
- int i;
- MouseEvent *mev;
-
- switch (cmd) {
- case CMD_SET_DATAOBJ:
- Id = GO_PLANE3D;
- data = (DataObj *)tmpl;
- return true;
- case CMD_LEGEND:
- if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
- ((Legend*)tmpl)->HasFill(&Line, &Fill);
- break;
- case CMD_MRK_DIRTY:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_SYM_FILL:
- if(tmpl) memcpy(&Fill, tmpl, sizeof(FillDEF));
- return true;
- case CMD_REDRAW:
- //Note: this command is issued either by Undo (no output given) or
- // by Plot3D::DoPlot after sorting all objects (output specified)
- if(!parent) return false;
- if(!o) return parent->Command(cmd, tmpl, o);
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- if(ipl && ipl->ObjThere(mev->x, mev->y)){
- o->ShowMark(CurrGO=this, MRK_GODRAW);
- return true;
- }
- }
- break;
- }
- break;
- case CMD_PG_FILL:
- if(tmpl) {
- memcpy((void*)&Fill, tmpl, sizeof(FillDEF));
- Fill.hatch = 0L;
- }
- break;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH && dt) {
- for(i = 0; i < ndt; i++)
- ((Plot*)parent)->CheckBounds3D(dt[i].fx, dt[i].fy, dt[i].fz);
- return true;
- }
- break;
- case CMD_SET_GO3D:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Brick: a bar in three dimensional space
-Brick::Brick(GraphObj *par, DataObj *da, double x, double y, double z,
- double d, double w, double h, DWORD flg, int xc, int xr, int yc,
- int yr, int zc, int zr, int dc, int dr, int wc, int wr, int hc,
- int hr):GraphObj(par, da)
-{
- FileIO(INIT_VARS);
- Id = GO_BRICK;
- fPos.fx = x; fPos.fy = y; fPos.fz = z;
- depth = d; width = w; height = h;
- flags = flg;
- if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || zc >= 0 || zr >= 0 ||
- dc >= 0 || dr >= 0 || wc >= 0 || wr >= 0 || hc >= 0 || hr >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*6)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- ssRef[2].x = zc; ssRef[2].y = zr;
- ssRef[3].x = dc; ssRef[3].y = dr;
- ssRef[4].x = wc; ssRef[4].y = wr;
- ssRef[5].x = hc; ssRef[5].y = hr;
- cssRef = 6;
- }
- }
- bModified = false;
-}
-
-Brick::Brick(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-Brick::~Brick()
-{
- int i;
-
- if(faces) {
- for(i = 0; i < 6; i++) if(faces[i]) delete(faces[i]);
- free(faces);
- }
- faces = 0L;
- if(mo) DelBitmapClass(mo); mo = 0L;
- Command(CMD_FLUSH, 0L, 0L);
- if(bModified) Undo.InvalidGO(this);
-}
-
-bool
-Brick::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_BAR_LINE: Line.width = value; return true;
- case SIZE_BAR_BASE: fPos.fy = value; return true;
- case SIZE_BAR: width = value; return true;
- case SIZE_BAR_DEPTH: depth = value; return true;
- }
- return false;
-}
-
-bool
-Brick::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_BAR_LINE: Line.color = col; return true;
- case COL_BAR_FILL: Fill.color = col; return true;
- }
- return false;
-}
-
-void
-Brick::DoPlot(anyOutput *o)
-{
- fPOINT3D cpt[8], fip1, fip2, tmp, itmp, *pg;
- plane *npl;
- double dtmp;
- int i;
-
- if(mo) DelBitmapClass(mo); mo = 0L;
- if(!faces || !o || !o->fvec2ivec(&fPos, &fip1)) return;
- if(!(pg = (fPOINT3D *)malloc(5*sizeof(fPOINT3D)))) return;
- for(i = 0; i < 6; i++) {
- if(faces[i]) delete(faces[i]);
- faces[i] = 0L;
- }
- if(flags & 0x800L) { //height is data
- tmp.fx = fPos.fx; tmp.fy = height;
- tmp.fz = fPos.fz; o->fvec2ivec(&tmp, &fip2);
- }
- else { //height is units
- tmp.fx = tmp.fz = 0.0; tmp.fy = height;
- o->uvec2ivec(&tmp, &fip2);
- fip2.fx += fip1.fx; fip2.fy += fip1.fy;
- fip2.fz += fip1.fz;
- }
- //calc output-device coordinates of cubic brick: 8 corners
- tmp.fx = -(width/2.0); tmp.fz = (depth/2.0); tmp.fy = 0.0;
- o->uvec2ivec(&tmp, &itmp);
- cpt[0].fx= fip1.fx+itmp.fx; cpt[0].fy= fip1.fy+itmp.fy; cpt[0].fz= fip1.fz+itmp.fz;
- cpt[2].fx= fip1.fx-itmp.fx; cpt[2].fy= fip1.fy-itmp.fy; cpt[2].fz= fip1.fz-itmp.fz;
- cpt[4].fx= fip2.fx+itmp.fx; cpt[4].fy= fip2.fy+itmp.fy; cpt[4].fz= fip2.fz+itmp.fz;
- cpt[6].fx= fip2.fx-itmp.fx; cpt[6].fy= fip2.fy-itmp.fy; cpt[6].fz= fip2.fz-itmp.fz;
- tmp.fx = (width/2.0); tmp.fz = (depth/2.0); tmp.fy = 0.0;
- o->uvec2ivec(&tmp, &itmp);
- cpt[1].fx= fip1.fx+itmp.fx; cpt[1].fy= fip1.fy+itmp.fy; cpt[1].fz= fip1.fz+itmp.fz;
- cpt[3].fx= fip1.fx-itmp.fx; cpt[3].fy= fip1.fy-itmp.fy; cpt[3].fz= fip1.fz-itmp.fz;
- cpt[5].fx= fip2.fx+itmp.fx; cpt[5].fy= fip2.fy+itmp.fy; cpt[5].fz= fip2.fz+itmp.fz;
- cpt[7].fx= fip2.fx-itmp.fx; cpt[7].fy= fip2.fy-itmp.fy; cpt[7].fz= fip2.fz-itmp.fz;
- //set up 6 faces
- pg[0].fx = pg[4].fx = cpt[0].fx; pg[1].fx = cpt[1].fx;
- pg[2].fx = cpt[2].fx; pg[3].fx = cpt[3].fx;
- pg[0].fy = pg[4].fy = cpt[0].fy; pg[1].fy = cpt[1].fy;
- pg[2].fy = cpt[2].fy; pg[3].fy = cpt[3].fy;
- pg[0].fz = pg[4].fz = cpt[0].fz; pg[1].fz = cpt[1].fz;
- pg[2].fz = cpt[2].fz; pg[3].fz = cpt[3].fz;
- faces[0] = new plane(this, data, pg, 5, &Line, &Fill);
- pg[2].fx = cpt[5].fx; pg[3].fx = cpt[4].fx;
- pg[2].fy = cpt[5].fy; pg[3].fy = cpt[4].fy;
- pg[2].fz = cpt[5].fz; pg[3].fz = cpt[4].fz;
- npl = new plane(this, data, pg, 5, &Line, &Fill);
- if(npl->GetSize(SIZE_MAX_Z) > faces[0]->GetSize(SIZE_MAX_Z)) faces[1] = npl;
- else {
- faces[1] = faces[0]; faces[0] = npl;
- }
- pg[0].fx = pg[4].fx = cpt[2].fx; pg[1].fx = cpt[6].fx;
- pg[2].fx = cpt[5].fx; pg[3].fx = cpt[1].fx;
- pg[0].fy = pg[4].fy = cpt[2].fy; pg[1].fy = cpt[6].fy;
- pg[2].fy = cpt[5].fy; pg[3].fy = cpt[1].fy;
- pg[0].fz = pg[4].fz = cpt[2].fz; pg[1].fz = cpt[6].fz;
- pg[2].fz = cpt[5].fz; pg[3].fz = cpt[1].fz;
- npl = new plane(this, data, pg, 5, &Line, &Fill);
- if((dtmp = npl->GetSize(SIZE_MAX_Z)) > faces[1]->GetSize(SIZE_MAX_Z)) faces[2] = npl;
- else {
- faces[2] = faces[1];
- if(dtmp > faces[0]->GetSize(SIZE_MAX_Z)) faces[1] = npl;
- else {
- faces[1] = faces[0]; faces[0] = npl;
- }
- }
- pg[2].fx = cpt[7].fx; pg[3].fx = cpt[3].fx;
- pg[2].fy = cpt[7].fy; pg[3].fy = cpt[3].fy;
- pg[2].fz = cpt[7].fz; pg[3].fz = cpt[3].fz;
- npl = new plane(this, data, pg, 5, &Line, &Fill);
- dtmp = npl->GetSize(SIZE_MAX_Z);
- for (i = 3; i; i--) {
- if(dtmp >faces[i-1]->GetSize(SIZE_MAX_Z)) {
- faces[i] = npl; break;
- }
- else faces[i] = faces[i-1];
- }
- if(!i) faces[0] = npl;
- pg[0].fx = pg[4].fx = cpt[4].fx; pg[1].fx = cpt[7].fx;
- pg[2].fx = cpt[3].fx; pg[3].fx = cpt[0].fx;
- pg[0].fy = pg[4].fy = cpt[4].fy; pg[1].fy = cpt[7].fy;
- pg[2].fy = cpt[3].fy; pg[3].fy = cpt[0].fy;
- pg[0].fz = pg[4].fz = cpt[4].fz; pg[1].fz = cpt[7].fz;
- pg[2].fz = cpt[3].fz; pg[3].fz = cpt[0].fz;
- npl = new plane(this, data, pg, 5, &Line, &Fill);
- dtmp = npl->GetSize(SIZE_MAX_Z);
- for (i = 4; i; i--) {
- if(dtmp >faces[i-1]->GetSize(SIZE_MAX_Z)) {
- faces[i] = npl; break;
- }
- else faces[i] = faces[i-1];
- }
- if(!i) faces[0] = npl;
- pg[2].fx = cpt[6].fx; pg[3].fx = cpt[5].fx;
- pg[2].fy = cpt[6].fy; pg[3].fy = cpt[5].fy;
- pg[2].fz = cpt[6].fz; pg[3].fz = cpt[5].fz;
- npl = new plane(this, data, pg, 5, &Line, &Fill);
- dtmp = npl->GetSize(SIZE_MAX_Z);
- for (i = 5; i; i--) {
- if(dtmp >faces[i-1]->GetSize(SIZE_MAX_Z)) {
- faces[i] = npl; break;
- }
- else faces[i] = faces[i-1];
- }
- if(!i) faces[0] = npl;
- rDims.left = rDims.right = (int)pg[0].fx;
- rDims.top = rDims.bottom = (int)pg[0].fy;
- for (i= 3; i < 6; i++) if(faces[i]) {
- faces[i]->DoPlot(o);
- UpdateMinMaxRect(&rDims, faces[i]->rDims.left, faces[i]->rDims.top);
- UpdateMinMaxRect(&rDims, faces[i]->rDims.right, faces[i]->rDims.bottom);
- }
- free(pg);
-}
-
-void
-Brick::DoMark(anyOutput *o, bool mark)
-{
- int i;
-
- if(mark){
- memcpy(&mrc, &rDims, sizeof(RECT));
- IncrementMinMaxRect(&mrc, 6 + o->un2ix(Line.width));
- mo = GetRectBitmap(&mrc, o);
- if(faces) for(i = 3; i < 6; i++)
- if(faces[i]) faces[i]->DoMark(o, mark);
- o->UpdateRect(&rDims, false);
- }
- else if(mo) RestoreRectBitmap(&mo, &mrc, o);
-}
-
-bool
-Brick::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name) free(name); name = 0L;
- return true;
- case CMD_LEGEND:
- if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
- ((Legend*)tmpl)->HasFill(&Line, &Fill);
- break;
- case CMD_BAR_FILL:
- if(tmpl) {
- memcpy(&Fill, tmpl, sizeof(FillDEF));
- Fill.hatch = 0L;
- return true;
- }
- break;
- case CMD_MRK_DIRTY:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_SET_DATAOBJ:
- Id = GO_BRICK;
- data = (DataObj *)tmpl;
- return true;
- case CMD_REDRAW:
- //Note: this command is issued either by Undo (no output given) or
- // by Plot3D::DoPlot after sorting all objects (output specified)
- if(!parent) return false;
- if(!o) return parent->Command(cmd, tmpl, o);
- //Should we ever come here ?
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- if(faces && faces[3] && faces[4] && faces[5] &&
- (faces[3]->ObjThere(mev->x, mev->y) ||
- faces[4]->ObjThere(mev->x, mev->y) ||
- faces[5]->ObjThere(mev->x, mev->y))){
- o->ShowMark(CurrGO=this, MRK_GODRAW);
- return true;
- }
- }
- break;
- }
- break;
- case CMD_UPDATE:
- if(ssRef && cssRef > 5 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &fPos.fz);
- data->GetValue(ssRef[3].y, ssRef[3].x, &depth);
- data->GetValue(ssRef[4].y, ssRef[4].x, &width);
- data->GetValue(ssRef[5].y, ssRef[5].x, &height);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds3D(fPos.fx, fPos.fy, fPos.fz);
- if(flags & 0x800L) { //height is data
- ((Plot*)parent)->CheckBounds3D(fPos.fx, height, fPos.fz);
- }
- return true;
- }
- break;
- case CMD_SET_GO3D:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// line_segment: utility object to draw a piece of a polyline in 3D space
-line_segment::line_segment(GraphObj *par, DataObj *d, LineDEF *ld, POINT3D *p1, POINT3D *p2)
- :GraphObj(par, d)
-{
- double tmp, tmp1, tmp2;
-
- nli = 0; nldata = 0L; ldata = 0L; prop = 1.0; df_go = 0L;
- fmin.fx = fmax.fx = fmin.fy = fmax.fy = fmin.fz = fmax.fz = 0.0;
- ndf_go = 0;
- if(ld) memcpy(&Line, ld, sizeof(LineDEF));
- if(p1 && p2 &&(ldata =(POINT3D**)calloc(1, sizeof(POINT3D*))) &&
- (ldata[0] = (POINT3D*)malloc(2 * sizeof(POINT3D))) &&
- (nldata = (int*)calloc(1, sizeof(int)))){
- if(Line.pattern) {
- tmp1 = (tmp = (p2->x - p1->x)) * tmp;
- tmp2 = (tmp1 += (tmp = (p2->y - p1->y)) * tmp);
- tmp1 += (tmp = (p2->z - p1->z)) * tmp;
- if(tmp1 > 1.0) prop = sqrt(tmp2)/sqrt(tmp1);
- }
- memcpy(&ldata[0][0], p1, sizeof(POINT3D));
- memcpy(&ldata[0][1], p2, sizeof(POINT3D));
- nldata[0] = 2; nli = 1;
- rDims.left = rDims.right = p1->x; rDims.top = rDims.bottom = p1->y;
- UpdateMinMaxRect(&rDims, p2->x, p2->y);
- fmin.fx = (double)rDims.left; fmin.fy = (double)rDims.top;
- fmax.fx = (double)rDims.right; fmax.fy = (double)rDims.bottom;
- if(p2->z > p1->z) {
- fmin.fz = (double)p1->z; fmax.fz = (double)p2->z;
- }
- else {
- fmin.fz = (double)p2->z; fmax.fz = (double)p1->z;
- }
- }
- Id = GO_LINESEG;
-}
-
-line_segment::~line_segment()
-{
- int i;
-
- if(ldata) {
- for(i = 0; i < nli; i++) if(ldata[i]) free(ldata[i]);
- free(ldata);
- }
- if(nldata) free(nldata); nldata = 0L;
-}
-
-double
-line_segment::GetSize(int select)
-{
- switch(select) {
- case SIZE_MIN_Z:
- return fmin.fz;
- case SIZE_MAX_Z:
- return fmax.fz;
- }
- return 0.0;
-}
-
-void
-line_segment::DoPlot(anyOutput *o)
-{
- bDrawDone = false; co = 0L;
- if(df_go) free(df_go);
- df_go = 0L; ndf_go = 0;
- if(o->VPscale > 1.5 && (
- (rDims.right < defs.clipRC.left) || (rDims.left > defs.clipRC.right) ||
- (rDims.bottom < defs.clipRC.top) || (rDims.top > defs.clipRC.bottom))){
- bDrawDone = true; return;
- }
- if(parent && parent->Command(CMD_SET_GO3D, this, o)) return;
- Command(CMD_REDRAW, 0L, o);
-}
-
-bool
-line_segment::Command(int cmd, void *tmpl, anyOutput *o)
-{
- int i, j;
- POINT pts[2];
- LineDEF cLine;
- POINT3D *ap;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- if(parent) return parent->Command(cmd, tmpl, o);
break;
- case CMD_DRAW_LATER:
- if(!co) return false;
- if(df_go){
- for(i = 0; i < ndf_go; i++) if(df_go[i] == co) return true;
- if(df_go = (GraphObj**)realloc(df_go, (ndf_go +1) * sizeof(GraphObj*))) {
- df_go[ndf_go++] = co;
- }
- }
- else {
- if(df_go = (GraphObj**)malloc(sizeof(GraphObj*))){
- df_go[0] = co; ndf_go = 1;
- }
- }
- return true;
- case CMD_REDRAW:
- if(bDrawDone) return false;
- bDrawDone = true;
- if(!nli) return false;
- if(df_go) {
- for(i = 0; i < ndf_go; i++) if(df_go[i]) df_go[i]->Command(cmd, tmpl, o);
- free(df_go); df_go = 0L; ndf_go = 0L;
- }
- if(o && ldata && nldata){
- memcpy(&cLine, &Line, sizeof(LineDEF));
- cLine.patlength *= prop;
- o->SetLine(&cLine);
- for(i = 0; i < nli; i++) for(j = 0; j < (nldata[i]-1); j++) {
- pts[0].x = ldata[i][j].x; pts[0].y = ldata[i][j].y;
- pts[1].x = ldata[i][j+1].x; pts[1].y = ldata[i][j+1].y;
- if(pts[0].x != pts[1].x || pts[0].y != pts[1].y) o->oPolyline(pts, 2);
- }
- }
- return true;
- case CMD_CLIP:
- if(co = (GraphObj*)tmpl){
- switch(co->Id) {
- case GO_PLANE:
- case GO_SPHERE:
- DoClip(co);
- break;
- }
- }
- return false;
- case CMD_STARTLINE:
- if(tmpl) {
- if(ldata && nldata) {
- ldata = (POINT3D**)realloc(ldata, sizeof(POINT3D*) * (nli+1));
- ldata[nli] = (POINT3D*)malloc(2 * sizeof(POINT3D));
- nldata = (int*)realloc(nldata, sizeof(int)*(nli+1));
- }
- else {
- ldata = (POINT3D**)calloc(1, sizeof(POINT3D*));
- ldata[nli = 0] = (POINT3D*)malloc(2 * sizeof(POINT3D));
- nldata = (int*)calloc(1, sizeof(int));
- }
- if(ldata && nldata) {
- memcpy(&ldata[nli][0], tmpl, sizeof(POINT3D));
- memcpy(&ldata[nli][1], tmpl, sizeof(POINT3D));
- nldata[nli++] = 1;
- return true;
- }
- }
- break;
- case CMD_ADDTOLINE:
- if((ap = (POINT3D*)tmpl) && ldata && nldata && nli && nldata[i =(nli-1)]) {
- j = nldata[i];
- ldata[i] = (POINT3D*)realloc(ldata[i], (nldata[i]+2) * sizeof(POINT3D));
- if(j && ldata[i][j-1].x == ap->x && ldata[i][j-1].y == ap->y &&
- ldata[i][j-1].z == ap->z) return true;
- else {
- j = (nldata[i]++);
- }
- memcpy(&ldata[i][j-1], tmpl, sizeof(POINT3D));
- return true;
- }
- break;
- }
- return false;
-}
-
-void *
-line_segment::ObjThere(int x, int y)
-{
- int i, j;
- POINT pts[2];
-
- if(ldata && nldata){
- for(i = 0; i < nli; i++) for(j = 0; j < nldata[i]; j +=2) {
- pts[0].x = ldata[i][j].x; pts[0].y = ldata[i][j].y;
- pts[1].x = ldata[i][j+1].x; pts[1].y = ldata[i][j+1].y;
- if(IsCloseToLine(&pts[0], &pts[1], x, y))return this;
- }
- }
- return 0L;
-}
-
-void
-line_segment::DoClip(GraphObj *co)
-{
- RECT cliprc;
- int o_nli, *o_nldata = 0L;
- POINT3D **o_ldata = 0L, *pts = 0L, *pla;
- int i, j, k, np, r, cx, cy, cz;
- bool is_valid = false;
-
- cliprc.left = iround(co->GetSize(SIZE_MIN_X));
- cliprc.right = iround(co->GetSize(SIZE_MAX_X));
- cliprc.top = iround(co->GetSize(SIZE_MIN_Y));
- cliprc.bottom = iround(co->GetSize(SIZE_MAX_Y));
- if(OverlapRect(&rDims, &cliprc)) {
- if(!(pts = (POINT3D*)calloc(2, sizeof(POINT3D))))return;
- o_nli = nli; nli = 0;
- o_nldata = nldata; nldata = 0L;
- o_ldata = ldata; ldata = 0L;
- switch(co->Id) {
- case GO_SPHERE:
- cx = iround(co->GetSize(SIZE_XPOS));
- cy = iround(co->GetSize(SIZE_YPOS));
- cz = iround(co->GetSize(SIZE_ZPOS));
- r = iround(co->GetSize(SIZE_RADIUS1));
- for(i = 0; i < o_nli; i++) for(j = 0; j < (o_nldata[i]-1); j ++) {
- pts[0].x = o_ldata[i][j].x; pts[0].y = o_ldata[i][j].y;
- pts[0].z = o_ldata[i][j].z; pts[1].x = o_ldata[i][j+1].x;
- pts[1].y = o_ldata[i][j+1].y; pts[1].z = o_ldata[i][j+1].z;
- clip_line_sphere(this, &pts, r, cx, cy, cz);
- }
- break;
- case GO_PLANE:
- for(i = 0; ((plane*)co)->GetPolygon(&pla, &np, i); i++){
- for(j = 0; j < o_nli; j++) {
- if(o_nldata[j] >1) for(k = 0; k < (o_nldata[j]-1); k++){
- pts[0].x = o_ldata[j][k].x; pts[0].y = o_ldata[j][k].y;
- pts[0].z = o_ldata[j][k].z; pts[1].x = o_ldata[j][k+1].x;
- pts[1].y = o_ldata[j][k+1].y; pts[1].z = o_ldata[j][k+1].z;
- if(pts[0].x != pts[1].x || pts[0].y != pts[1].y || pts[0].z != pts[1].z)
- clip_line_plane(this, &pts, pla, np, ((plane*)co)->GetVec());
- }
- }
- if(nli) is_valid = true;
- if(o_ldata) {
- for(j = 0; j < o_nli; j++) if(o_ldata[j]) free(o_ldata[j]);
- free(o_ldata);
- }
- if(o_nldata) free(o_nldata);
- o_nli = nli; nli = 0;
- o_nldata = nldata; nldata = 0L;
- o_ldata = ldata; ldata = 0L;
- if(!o_nli) return; //line is completly hidden
- }
- if(is_valid || i==0){
- nli = o_nli; o_nli = 0;
- nldata = o_nldata; o_nldata = 0L;
- ldata = o_ldata; o_ldata = 0L;
- }
- break;
- default:
- nli = o_nli; o_nli = 0;
- nldata = o_nldata; o_nldata = 0L;
- ldata = o_ldata; o_ldata = 0L;
- break;
- }
- if(pts) free(pts);
- }
- if(o_ldata) {
- for(i = 0; i < o_nli; i++) if(o_ldata[i]) free(o_ldata[i]);
- free(o_ldata);
- }
- if(o_nldata) free(o_nldata);
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// define a drop line in 3D space
-DropLine3D::DropLine3D(GraphObj *par, DataObj *d, fPOINT3D *p1, int xc,
- int xr, int yc, int yr, int zc, int zr):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- Id = GO_DROPL3D;
- memcpy(&fPos, p1, sizeof(fPOINT3D));
- if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || zc >= 0 || zr >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- ssRef[2].x = zc; ssRef[2].y = zr;
- cssRef = 3;
- }
- }
- bModified = false;
- type = 0x01;
-}
-
-DropLine3D::DropLine3D(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-DropLine3D::~DropLine3D()
-{
- if(bModified) Undo.InvalidGO(this);
- if(mo) DelBitmapClass(mo); mo = 0L;
- Command(CMD_FLUSH, 0L, 0L);
-}
-
-void
-DropLine3D::DoPlot(anyOutput *o)
-{
- fPOINT3D fip, fp, fp1;
- POINT3D p1, p2;
- int i;
-
- if(!parent || !o || !o->fvec2ivec(&fPos, &fip)) return;
- if(mo) DelBitmapClass(mo); mo = 0L;
- for(i = 0; i < 6; i++){
- if(ls[i]) delete(ls[i]);
- ls[i] = 0L;
- }
- p1.x = iround(fip.fx); p1.y = iround(fip.fy); p1.z = iround(fip.fz);
- rDims.left = rDims.right = p1.x; rDims.top = rDims.bottom = p1.y;
- for(i = 0; i < 6; i++) {
- fp.fx = fPos.fx; fp.fy = fPos.fy; fp.fz = fPos.fz;
- if(type & (1 << i)){
- switch (i) {
- case 0: fp.fy = parent->GetSize(SIZE_BOUNDS_YMIN); break;
- case 1: fp.fy = parent->GetSize(SIZE_BOUNDS_YMAX); break;
- case 2: fp.fz = parent->GetSize(SIZE_BOUNDS_ZMIN); break;
- case 3: fp.fz = parent->GetSize(SIZE_BOUNDS_ZMAX); break;
- case 4: fp.fx = parent->GetSize(SIZE_BOUNDS_XMIN); break;
- case 5: fp.fx = parent->GetSize(SIZE_BOUNDS_XMAX); break;
- }
- o->fvec2ivec(&fp, &fp1); p2.x = iround(fp1.fx);
- p2.y = iround(fp1.fy); p2.z = iround(fp1.fz);
- UpdateMinMaxRect(&rDims, p2.x, p2.y);
- if(ls[i] = new line_segment(this, data, &Line, &p1, &p2)) ls[i]->DoPlot(o);
- mpts[i][0].x = p1.x; mpts[i][0].y = p1.y;
- mpts[i][1].x = p2.x; mpts[i][1].y = p2.y;
- }
- }
- IncrementMinMaxRect(&rDims, 5);
-}
-
-void
-DropLine3D::DoMark(anyOutput *o, bool mark)
-{
- int i;
-
- if(mark) {
- memcpy(&mrc, &rDims, sizeof(RECT));
- IncrementMinMaxRect(&mrc, 6 + o->un2ix(Line.width));
- mo = GetRectBitmap(&mrc, o);
- for(i = 0; i < 6; i++) {
- if(type & (1 << i)){
- InvertLine(mpts[i], 2, &Line, 0L, o, mark);
- }
- }
- o->UpdateRect(&mrc, false);
- }
- else RestoreRectBitmap(&mo, &mrc, o);
-}
-
-bool
-DropLine3D::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- int i;
-
- switch (cmd) {
- case CMD_FLUSH:
- for(i = 0; i < 6; i++){
- if(ls[i]) delete(ls[i]);
- ls[i] = 0L;
- }
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name) free(name); name = 0L;
- return true;
- case CMD_DL_TYPE:
- if(tmpl && *((int*)tmpl)) type = *((int*)tmpl);
- return true;
- case CMD_DL_LINE:
- if(tmpl) memcpy(&Line, tmpl, sizeof(LineDEF));
- return true;
- case CMD_SET_DATAOBJ:
- Id = GO_DROPL3D;
- data = (DataObj *)tmpl;
- return true;
- case CMD_REDRAW:
- //Note: this command is issued either by Undo (no output given) or
- // by Plot3D::DoPlot after sorting all objects (output specified)
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- for(i = 0; i < 6; i++) {
- if(ls[i] && ls[i]->ObjThere(mev->x, mev->y)){
- o->ShowMark(this, MRK_GODRAW);
- return true;
- }
- }
- }
- break;
- }
- break;
- case CMD_UPDATE:
- if(ssRef && cssRef >2 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &fPos.fz);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds3D(fPos.fx, fPos.fy, fPos.fz);
- return true;
- }
- break;
- case CMD_SET_GO3D:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// define an arrow in 3D space
-Arrow3D::Arrow3D(GraphObj *par, DataObj *d, fPOINT3D *p1, fPOINT3D *p2, int xc1,
- int xr1, int yc1, int yr1, int zc1, int zr1, int xc2, int xr2, int yc2,
- int yr2, int zc2, int zr2):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- Id = GO_ARROW3D;
- memcpy(&fPos1, p1, sizeof(fPOINT3D)); memcpy(&fPos2, p2, sizeof(fPOINT3D));
- if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || zc1 >= 0 || zr1 >= 0 ||
- xc2 >= 0 || xr2 >= 0 || yc2 >= 0 || yr2 >= 0 || zc2 >= 0 || zr2 >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*6)) {
- ssRef[0].x = xc1; ssRef[0].y = xr1;
- ssRef[1].x = yc1; ssRef[1].y = yr1;
- ssRef[2].x = zc1; ssRef[2].y = zr1;
- ssRef[3].x = xc2; ssRef[3].y = xr2;
- ssRef[4].x = yc2; ssRef[4].y = yr2;
- ssRef[5].x = zc2; ssRef[5].y = zr2;
- cssRef = 6;
- }
- }
- bModified = false;
-}
-
-Arrow3D::Arrow3D(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-Arrow3D::~Arrow3D()
-{
- if(bModified) Undo.InvalidGO(this);
- Command(CMD_FLUSH, 0L, 0L);
-}
-
-bool
-Arrow3D::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_ARROW_LINE:
- Line.width = value;
- return true;
- case SIZE_ARROW_CAPWIDTH:
- cw = value;
- return true;
- case SIZE_ARROW_CAPLENGTH:
- cl = value;
- return true;
- }
- return false;
-}
-
-bool
-Arrow3D::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_ARROW:
- Line.color = col;
- return true;
- }
- return false;
-}
-
-void
-Arrow3D::DoPlot(anyOutput *o)
-{
- double si, csi, tmp, cwr, clr, d, d1, d2;
- fPOINT3D fip1, fip2, tria[3];
- POINT3D p1, p2, cp1, cp2;
- FillDEF fill;
- int i;
-
- if(!parent || !o || !o->fvec2ivec(&fPos1, &fip1) ||!o->fvec2ivec(&fPos2, &fip2)) return;
- for(i = 0; i < 3; i++){
- if(ls[i]) delete(ls[i]);
- ls[i] = 0L;
- }
- p1.x = iround(fip1.fx); p1.y = iround(fip1.fy); p1.z = iround(fip1.fz);
- p2.x = iround(fip2.fx); p2.y = iround(fip2.fy); p2.z = iround(fip2.fz);
- if(p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) return; //zero length arrow
- rDims.left = rDims.right = p1.x; rDims.top = rDims.bottom = p1.y;
- UpdateMinMaxRect(&rDims, p2.x, p2.y);
- IncrementMinMaxRect(&rDims, 5);
- if(ls[0] = new line_segment(this, data, &Line, &p1, &p2)) ls[0]->DoPlot(o);
- mpts[0][0].x = p1.x; mpts[0][0].y = p1.y; mpts[0][1].x = p2.x; mpts[0][1].y = p2.y;
- if(p1.x == p2.x && p1.y == p2.y) return; //zero length in 2D
- if((type & 0xff) == ARROW_NOCAP) return; //no cap;
- //calculate sine and cosine for cap
- si = fip1.fy-fip2.fy;
- tmp = fip2.fx - fip1.fx;
- si = si/sqrt(si*si + tmp*tmp);
- csi = fip2.fx-fip1.fx;
- tmp = fip2.fy - fip1.fy;
- csi = csi/sqrt(csi*csi + tmp*tmp);
- //cap corners
- d1 = (d = fip2.fx - fip1.fx) * d;
- d1 += ((d = fip2.fy - fip1.fy) * d);
- d2 = d1 + ((d = fip2.fz - fip1.fz) * d);
- d1 = sqrt(d1); d2 = sqrt(d2); d = d1/d2;
- cwr = cw; clr = cl*d;
- cp1.x = p2.x - o->un2ix(csi*clr + si*cwr/2.0);
- cp1.y = p2.y + o->un2iy(si*clr - csi*cwr/2.0);
- cp2.x = p2.x - o->un2ix(csi*clr - si*cwr/2.0);
- cp2.y = p2.y + o->un2iy(si*clr + csi*cwr/2.0);
- cp1.z = cp2.z = p2.z;
- mpts[1][0].x = p2.x; mpts[1][0].y = p2.y; mpts[1][1].x = cp1.x; mpts[1][1].y = cp1.y;
- mpts[2][0].x = p2.x; mpts[2][0].y = p2.y; mpts[2][1].x = cp2.x; mpts[2][1].y = cp2.y;
- if((type & 0xff) == ARROW_LINE) {
- if(ls[1] = new line_segment(this, data, &Line, &p2, &cp1)) ls[1]->DoPlot(o);
- if(ls[2] = new line_segment(this, data, &Line, &p2, &cp2)) ls[2]->DoPlot(o);
- }
- else if((type & 0xff) == ARROW_TRIANGLE) {
- fill.type = FILL_NONE; fill.color = Line.color;
- fill.scale = 1.0; fill.hatch = 0L;
- tria[0].fz = tria[1].fz = tria[2].fz = fip2.fz;
- tria[0].fx = cp1.x; tria[0].fy = cp1.y;
- tria[1].fx = fip2.fx; tria[1].fy = fip2.fy;
- tria[2].fx = cp2.x; tria[2].fy = cp2.y;
- if(cap = new plane(this, data, tria, 3, &Line, &fill))cap->DoPlot(o);
- }
-}
-
-void
-Arrow3D::DoMark(anyOutput *o, bool mark)
-{
- int i;
-
- if(mark) {
- for(i = 0; i < 3; i++) {
- if(ls[i]){
- InvertLine(mpts[i], 2, &Line, 0L, o, mark);
- }
- }
- }
- else if(parent) parent->Command(CMD_REDRAW, 0L, o);
-}
-
-bool
-Arrow3D::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- int i;
-
- switch (cmd) {
- case CMD_FLUSH:
- for(i = 0; i < 3; i++){
- if(ls[i]) delete(ls[i]);
- ls[i] = 0L;
- }
- if(cap) delete(cap); cap = 0L;
- if(ssRef) free(ssRef); ssRef = 0L;
- if(name) free(name); name = 0L;
- return true;
- case CMD_SET_DATAOBJ:
- Id = GO_ARROW3D;
- data = (DataObj *)tmpl;
- return true;
- case CMD_MRK_DIRTY: //from Undo ?
- case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
- for(i = 0; i < 3; i++) {
- if(ls[i] && ls[i]->ObjThere(mev->x, mev->y)){
- o->ShowMark(this, MRK_GODRAW);
- return true;
- }
- }
- }
- break;
- }
- break;
- case CMD_ARROW_ORG3D:
- if(tmpl) memcpy(&fPos1, tmpl, sizeof(fPOINT3D));
- return true;
- case CMD_ARROW_TYPE:
- if(tmpl) type = *((int*)tmpl);
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >5 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos2.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos2.fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &fPos2.fz);
- data->GetValue(ssRef[3].y, ssRef[3].x, &fPos1.fx);
- data->GetValue(ssRef[4].y, ssRef[4].x, &fPos1.fy);
- data->GetValue(ssRef[5].y, ssRef[5].x, &fPos1.fz);
- return true;
- }
- return false;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
- ((Plot*)parent)->CheckBounds3D(fPos1.fx, fPos1.fy, fPos1.fz);
- ((Plot*)parent)->CheckBounds3D(fPos2.fx, fPos2.fy, fPos2.fz);
- return true;
- }
- break;
- case CMD_SET_GO3D:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// a data line in 3D space
-Line3D::Line3D(GraphObj *par, DataObj *d, char *rx, char *ry, char *rz)
- :GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- if(rx && rx[0]) x_range = strdup(rx); if(ry && ry[0]) y_range = strdup(ry);
- if(rz && rz[0]) z_range = strdup(rz);
- DoUpdate();
- Id = GO_LINE3D;
- bModified = false;
-}
-
-Line3D::Line3D(GraphObj *par, DataObj *d, fPOINT3D *pt, int n_pt, int xc1, int xr1, int yc1, int yr1,
- int zc1, int zr1, int xc2, int xr2, int yc2, int yr2, int zc2, int zr2)
- :GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- if(pt && n_pt) {
- values = (fPOINT3D*)memdup(pt, n_pt * sizeof(fPOINT3D), 0L);
- nPts = n_pt;
- ls = (line_segment **)calloc(nPts-1, sizeof(line_segment*));
- }
- if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || zc1 >= 0 || zr1 >= 0 ||
- xc2 >= 0 || xr2 >= 0 || yc2 >= 0 || yr2 >= 0 || zc2 >= 0 || zr2 >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*6)) {
- ssRef[0].x = xc1; ssRef[0].y = xr1;
- ssRef[1].x = yc1; ssRef[1].y = yr1;
- ssRef[2].x = zc1; ssRef[2].y = zr1;
- ssRef[3].x = xc2; ssRef[3].y = xr2;
- ssRef[4].x = yc2; ssRef[4].y = yr2;
- ssRef[5].x = zc2; ssRef[5].y = zr2;
- cssRef = 6;
+ case CMD_SET_DATAOBJ:
+ Id = GO_BUBBLE;
+ data = (DataObj*)tmpl;
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >2 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &fs);
+ return true;
}
- }
- Id = GO_LINE3D;
- bModified = false;
-}
-
-Line3D::Line3D(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-Line3D::~Line3D()
-{
- int i;
-
- if(bModified) Undo.InvalidGO(this);
- if(ls){
- for(i = 0; i < (nPts-1); i++) if(ls[i]) delete(ls[i]);
- free(ls);
- }
- if(pts && npts) free(pts); pts = 0L; npts = 0; cssRef = 0;
- if(x_range) free(x_range); x_range = 0L;
- if(y_range) free(y_range); y_range = 0L;
- if(z_range) free(z_range); z_range = 0L;
- if(values) free(values); values = 0L;
- if(ssRef) free(ssRef); ssRef = 0L;
- if(mo) DelBitmapClass(mo); mo = 0L;
-}
-
-void
-Line3D::DoPlot(anyOutput *o)
-{
- int i, j;
- fPOINT3D fip;
- POINT3D p1, p2;
- POINT np;
-
-
- if(mo) DelBitmapClass(mo); mo = 0L;
- if(ls) {
- if(pts && npts) free(pts);
- npts = 0; if(!(pts = (POINT*)calloc(nPts, sizeof(POINT))))return;
- for(i = 0; i< nPts; i++) {
- if(!o->fvec2ivec(&values[i], &fip)) return;
- p2.x = iround(fip.fx); p2.y = iround(fip.fy); p2.z = iround(fip.fz);
- np.x = p2.x; np.y = p2.y;
- AddToPolygon(&npts, pts, &np);
- if(i) {
- UpdateMinMaxRect(&rDims, np.x, np.y);
- j = i-1;
- if(ls[j]) delete(ls[j]);
- if(ls[j] = new line_segment(this, data, &Line, &p1, &p2)) {
- ls[j]->DoPlot(o);
- }
- }
- else {
- rDims.left = rDims.right = p2.x;
- rDims.top = rDims.bottom = p2.y;
- }
- p1.x = p2.x; p1.y = p2.y; p1.z = p2.z;
- }
- IncrementMinMaxRect(&rDims, 6);
- }
-}
-
-void
-Line3D::DoMark(anyOutput *o, bool mark)
-{
- if(mark) {
- memcpy(&mrc, &rDims, sizeof(RECT));
- IncrementMinMaxRect(&mrc, 6 + o->un2ix(Line.width));
- mo = GetRectBitmap(&mrc, o);
- InvertLine(pts, npts, &Line, &rDims, o, true);
- }
- else RestoreRectBitmap(&mo, &mrc, o);
-}
-
-bool
-Line3D::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- POINT p1;
- int i;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(name) free(name); name = 0L;
- return true;
- case CMD_SET_LINE:
+ return false;
+ case CMD_BUBBLE_ATTRIB:
if(tmpl) {
- memcpy(&Line, tmpl, sizeof(LineDEF));
+ type &= ~0xff0;
+ type |= (*((int*)tmpl) & 0xff0);
return true;
}
return false;
- case CMD_SET_DATAOBJ:
- Id = GO_LINE3D;
- data = (DataObj *)tmpl;
- return true;
- case CMD_REDRAW:
- //Note: this command is issued by Undo (no output given)
- if(!parent) return false;
- if(!o) return parent->Command(cmd, tmpl, o);
- //Should we ever come here ?
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(!IsInRect(&rDims, p1.x= mev->x, p1.y=mev->y)|| CurrGO || !o || nPts <2 ||
- !IsCloseToPL(p1, pts, npts))return false;
- o->ShowMark(CurrGO=this, MRK_GODRAW);
- return true;
- }
- return false;
- case CMD_UPDATE:
- if(parent && parent->Id != GO_GRID3D) {
- Undo.DataMem(this, (void**)&values, nPts * sizeof(fPOINT3D), &nPts, UNDO_CONTINUE);
- }
- if(ssRef && cssRef >5 && data && nPts == 2) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &values[0].fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &values[0].fy);
- data->GetValue(ssRef[2].y, ssRef[2].x, &values[0].fz);
- data->GetValue(ssRef[3].y, ssRef[3].x, &values[1].fx);
- data->GetValue(ssRef[4].y, ssRef[4].x, &values[1].fy);
- data->GetValue(ssRef[5].y, ssRef[5].x, &values[1].fz);
+ case CMD_BUBBLE_TYPE:
+ if(tmpl) {
+ type &= ~0x00f;
+ type |= (*((int*)tmpl) & 0x00f);
return true;
}
- else DoUpdate();
- case CMD_AUTOSCALE:
- if(parent && parent->Id > GO_PLOT && parent->Id < GO_GRAPH){
- if(min.fx == max.fx || min.fy == max.fy){ //z's may be equal !
- min.fx = min.fy = min.fz = HUGE_VAL;
- max.fx = max.fy = max.fz = -HUGE_VAL;
- for(i = 0; i < nPts; i++) {
- if(values[i].fx < min.fx) min.fx = values[i].fx;
- if(values[i].fy < min.fy) min.fy = values[i].fy;
- if(values[i].fz < min.fz) min.fz = values[i].fz;
- if(values[i].fx > max.fx) max.fx = values[i].fx;
- if(values[i].fy > max.fy) max.fy = values[i].fy;
- if(values[i].fz > max.fz) max.fz = values[i].fz;
- }
- }
- ((Plot*)parent)->CheckBounds3D(min.fx, min.fy, min.fz);
- ((Plot*)parent)->CheckBounds3D(max.fx, max.fy, max.fz);
- return true;
- }
- return false;
- case CMD_SET_GO3D:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- }
- return false;
-}
-
-void
-Line3D::DoUpdate()
-{
- int n1 = 0, ic = 0, i, j, k, l, m, n;
- double x, y, z;
- AccRange *rX=0L, *rY=0L, *rZ=0L;
-
- if(!x_range || !y_range || !z_range) return;
- if(values) free(values); values = 0L;
- if(ls) free(ls); ls = 0L;
- rX = new AccRange(x_range);
- rY = new AccRange(y_range);
- rZ = new AccRange(z_range);
- min.fx = min.fy = min.fz = HUGE_VAL; max.fx = max.fy = max.fz = -HUGE_VAL;
- if(rX) n1 = rX->CountItems();
- if(n1 && rY && rZ && (values = (fPOINT3D*)malloc(n1 * sizeof(fPOINT3D)))){
- 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)){
- values[ic].fx = x; values[ic].fy = y; values[ic].fz = z;
- if(x < min.fx) min.fx = x; if(x > max.fx) max.fx = x;
- if(y < min.fy) min.fy = y; if(y > max.fy) max.fy = y;
- if(z < min.fz) min.fz = z; if(z > max.fz) max.fz = z;
- ic++;
- }
- }while(rX->GetNext(&i, &j) && rY->GetNext(&k, &l) && rZ->GetNext(&m, &n));
- nPts = ic;
- if(ic > 1) ls = (line_segment **)calloc(ic-1, sizeof(line_segment*));
- }
- if(rX) delete(rX); if(rY) delete(rY); if(rZ) delete(rZ);
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// the text label class
-Label::Label(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, DWORD flg,
- int xc, int xr, int yc, int yr, int tc, int tr):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- fPos.fx = x; fPos.fy = y; flags = flg;
- if(parent){
- fDist.fx = parent->GetSize(SIZE_LB_XDIST);
- fDist.fy = parent->GetSize(SIZE_LB_YDIST);
- }
- Id = GO_LABEL;
- if(td){
- memcpy(&TextDef, td, sizeof(TextDEF));
- if(td->text) TextDef.text = strdup(td->text);
- }
- if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || tc >= 0 || tr >= 0) {
- if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
- ssRef[0].x = xc; ssRef[0].y = xr;
- ssRef[1].x = yc; ssRef[1].y = yr;
- ssRef[2].x = tc; ssRef[2].y = tr;
- cssRef = 3;
- }
- }
-}
-
-Label::Label(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-Label::~Label()
-{
- Command(CMD_FLUSH, 0L, 0L);
- if(fmt_txt) delete(fmt_txt); fmt_txt = 0L;
- if(bModified)Undo.InvalidGO(this);
-}
-
-double
-Label::GetSize(int select)
-{
- switch(select){
- case SIZE_CURSORPOS:
- return (double)CursorPos;
- case SIZE_CURSOR_XMIN:
- return (double) (Cursor.right > Cursor.left ? Cursor.left : Cursor.right);
- case SIZE_CURSOR_XMAX:
- return (double) (Cursor.right > Cursor.left ? Cursor.right : Cursor.left);
- case SIZE_CURSOR_YMIN:
- return (double) (Cursor.bottom > Cursor.top ? Cursor.top : Cursor.bottom);
- case SIZE_CURSOR_YMAX:
- return (double) (Cursor.bottom > Cursor.top ? Cursor.bottom : Cursor.top);
- case SIZE_MIN_Z: case SIZE_MAX_Z: case SIZE_ZPOS:
- return curr_z;
- }
- return 0.0;
-}
-
-bool
-Label::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_LB_XDIST: fDist.fx = value; return true;
- case SIZE_LB_YDIST: fDist.fy = value; return true;
- case SIZE_XPOS: fPos.fx = value; return true;
- case SIZE_YPOS: fPos.fy = value; return true;
- case SIZE_ZPOS: curr_z = value; return is3D = true;
- }
- return false;
-}
-
-bool
-Label::SetColor(int select, DWORD col)
-{
- switch(select & 0xfff) {
- case COL_TEXT:
- if(select & UNDO_STORESET) {
- Undo.ValDword(this, &TextDef.ColTxt, UNDO_CONTINUE);
- bModified = true;
- }
- TextDef.ColTxt = col; bBGvalid = false;
+ return false;
+ case CMD_BUBBLE_FILL:
+ if(tmpl) {
+ BubbleFill.type = ((FillDEF*)tmpl)->type;
+ BubbleFill.color = ((FillDEF*)tmpl)->color;
+ BubbleFill.scale = ((FillDEF*)tmpl)->scale;
+ if(((FillDEF*)tmpl)->hatch)
+ memcpy(&BubbleFillLine, ((FillDEF*)tmpl)->hatch, sizeof(LineDEF));
+ }
return true;
- case COL_BG:
- bgcolor = col; bBGvalid = true;
- return true;
- }
- return false;
+ case CMD_BUBBLE_LINE:
+ if(tmpl) memcpy(&BubbleLine, tmpl, sizeof(LineDEF));
+ return true;
+ case CMD_AUTOSCALE:
+ return DoAutoscale(o);
+ break;
+ }
+ return false;
}
-
-void
-Label::DoPlot(anyOutput *o)
+
+bool
+Bubble::DoAutoscale(anyOutput *o)
{
- if(is3D && parent && parent->Command(CMD_SET_GO3D, this, o)) return;
- DoPlotText(o);
+ double dx, dy;
+
+ switch(type & 0x0f0) {
+ case BUBBLE_XAXIS: case BUBBLE_YAXIS:
+ dx = dy = fs/2.0; break;
+ case BUBBLE_UNITS:
+ dx = fPos.fx/20; dy = fPos.fy/20; break;
+ }
+ ((Plot*)parent)->CheckBounds(fPos.fx+dx, fPos.fy-dy);
+ ((Plot*)parent)->CheckBounds(fPos.fx-dx, fPos.fy+dy);
+ return true;
}
-void
-Label::DoMark(anyOutput *o, bool mark)
-{
- DWORD bgpix[16];
- int i, d, d1, ix, iy, dx, dy, n;
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Bars are graphic objects
+Bar::Bar(GraphObj *par, DataObj *d, double x, double y, int which,int xc, int xr,
+ int yc, int yr, char *desc):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ fPos.fx = x; fPos.fy = y; type = which;
+ if(type & BAR_RELWIDTH) size = 60.0; Id = GO_BAR;
+ if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*2)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ cssRef = 2;
+ }
+ }
+ if(desc && desc[0]) name = (char*)memdup(desc, (int)strlen(desc)+1, 0);
+}
+
+Bar::Bar(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+Bar::~Bar()
+{
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ Command(CMD_FLUSH, 0L, 0L);
+}
+
+double
+Bar::GetSize(int select)
+{
+ switch(select){
+ case SIZE_XPOS: return fPos.fx;
+ case SIZE_YPOS: return fPos.fy;
+ }
+ return 0.0;
+}
+
+bool
+Bar::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_BAR:
+ size = value;
+ return true;
+ case SIZE_BAR_LINE:
+ BarLine.width = value;
+ return true;
+ case SIZE_XBASE:
+ BarBase.fx = value;
+ return true;
+ case SIZE_YBASE:
+ BarBase.fy = value;
+ return true;
+ }
+ return false;
+}
+
+bool
+Bar::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_BAR_LINE:
+ BarLine.color = col;
+ return true;
+ case COL_BAR_FILL:
+ BarFill.color = col;
+ return true;
+ }
+ return false;
+}
+
+void
+Bar::DoPlot(anyOutput *target)
+{
+ int w;
+ double fBase, rsize;
+ POINT pts[2];
+
+ if(!parent || size <= 0.001) return;
+ target->SetLine(&BarLine); target->SetFill(&BarFill);
+ switch(type & 0xff) {
+ case BAR_VERTU: case BAR_VERTT: case BAR_VERTB:
+ switch(type & 0xff) {
+ case BAR_VERTB:
+ fBase = parent->GetSize(SIZE_BOUNDS_BOTTOM);
+ break;
+ case BAR_VERTT:
+ fBase = parent->GetSize(SIZE_BOUNDS_TOP);
+ break;
+ case BAR_VERTU:
+ fBase = BarBase.fy;
+ break;
+ }
+ if(type & BAR_RELWIDTH) {
+ rsize = size * parent->GetSize(SIZE_BARMINX)/100.0;
+ pts[0].x = iround(target->fx2fix(fPos.fx - rsize/2.0));
+ pts[1].x = iround(target->fx2fix(fPos.fx + rsize/2.0));
+ }
+ else {
+ w = target->un2ix(size);
+ pts[0].x = iround(target->fx2fix(fPos.fx)) - (w>>1);
+ pts[1].x = pts[0].x + w;
+ }
+ if(type & BAR_CENTERED) {
+ pts[0].y = iround(target->fy2fiy(fBase - (fPos.fy - fBase)));
+ pts[1].y = iround(target->fy2fiy(fBase + (fPos.fy - fBase)));
+ }
+ else {
+ pts[0].y = iround(target->fy2fiy(fBase));
+ pts[1].y = iround(target->fy2fiy(fPos.fy));
+ }
+ break;
+ case BAR_HORU: case BAR_HORR: case BAR_HORL:
+ switch(type & 0xff) {
+ case BAR_HORL:
+ fBase = parent->GetSize(SIZE_BOUNDS_LEFT);
+ break;
+ case BAR_HORR:
+ fBase = parent->GetSize(SIZE_BOUNDS_RIGHT);
+ break;
+ case BAR_HORU:
+ fBase = BarBase.fx;
+ break;
+ }
+ if(type & BAR_RELWIDTH) {
+ rsize = size * parent->GetSize(SIZE_BARMINY)/100.0;
+ pts[0].y = iround(target->fy2fiy(fPos.fy - rsize/2.0));
+ pts[1].y = iround(target->fy2fiy(fPos.fy + rsize/2.0));
+ }
+ else {
+ w = target->un2iy(size);
+ pts[0].y = target->fy2iy(fPos.fy) - w/2;
+ pts[1].y = pts[0].y+w;
+ }
+ if(type & BAR_CENTERED) {
+ pts[0].x = target->fx2ix(fBase - (fPos.fx - fBase));
+ pts[1].x = target->fx2ix(fBase + (fPos.fx - fBase));
+ }
+ else {
+ pts[0].x = target->fx2ix(fBase);
+ pts[1].x = target->fx2ix(fPos.fx);
+ }
+ break;
+ default:
+ return;
+ }
+ if(pts[0].x == pts[1].x || pts[0].y == pts[1].y) {
+ target->oSolidLine(pts);
+ }
+ else target->oRectangle(pts[0].x, pts[0].y, pts[1].x, pts[1].y, name);
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+}
+
+void
+Bar::DoMark(anyOutput *o, bool mark)
+{
+ int i;
+
+ if(mark){
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ 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);
+ }
+ else RestoreRectBitmap(&mo, &mrc, o);
+}
+
+bool
+Bar::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ FillDEF *TmpFill;
+ lfPOINT bl;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name)free(name); name = 0L;
+ return true;
+ case CMD_SCALE:
+ if(!tmpl) return false;
+ if(!(type & BAR_RELWIDTH)) size *= ((scaleINFO*)tmpl)->sy.fy;
+ BarLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ BarLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ HatchLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ HatchLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ BarFill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_LEGEND:
+ if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
+ ((Legend*)tmpl)->HasFill(&BarLine, &BarFill, name);
+ break;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ o->ShowMark(CurrGO = this, MRK_GODRAW);
+ return true;
+ }
+ break;
+ }
+ return false;
+ case CMD_BAR_FILL:
+ TmpFill = (FillDEF *)tmpl;
+ if(TmpFill) {
+ BarFill.type = TmpFill->type;
+ BarFill.color = TmpFill->color;
+ BarFill.scale = TmpFill->scale;
+ if(TmpFill->hatch) memcpy(&HatchLine, TmpFill->hatch, sizeof(LineDEF));
+ }
+ return true;
+ case CMD_BAR_TYPE:
+ if(tmpl) type = *((int*)tmpl);
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = GO_BAR;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >1 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
+ switch(type & 0xff) {
+ case BAR_VERTU:
+ case BAR_VERTT:
+ case BAR_VERTB:
+ bl.fx = fPos.fx;
+ switch (type & 0xff) {
+ case BAR_VERTU:
+ bl.fy = BarBase.fy;
+ break;
+ case BAR_VERTT:
+ case BAR_VERTB:
+ bl.fy = 0.0f; //cannot resolve
+ break;
+ }
+ if(type & BAR_CENTERED) bl.fy -= fPos.fy;
+ break;
+ case BAR_HORU:
+ case BAR_HORR:
+ case BAR_HORL:
+ bl.fy = fPos.fy;
+ switch(type & 0xff) {
+ case BAR_HORU:
+ bl.fx = BarBase.fx;
+ case BAR_HORR:
+ case BAR_HORL:
+ bl.fx = 0.0f; //cannot resolve
+ }
+ if(type & BAR_CENTERED) bl.fx -= fPos.fx;
+ break;
+ }
+ ((Plot*)parent)->CheckBounds(bl.fx, bl.fy);
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Data line is a graphic object
+DataLine::DataLine(GraphObj *par, DataObj *d, char *xrange, char *yrange, char *nam):GraphObj(par, d)
+{
+ size_t cb;
+
+ FileIO(INIT_VARS);
+ Id = GO_DATALINE;
+ if(xrange && xrange[0]) {
+ cb = strlen(xrange) +2; ssXref = (char*)malloc(cb); rlp_strcpy(ssXref, (int)cb, xrange);
+ }
+ if(yrange && yrange[0]) {
+ cb = strlen(yrange) +2; ssYref = (char*)malloc(cb); rlp_strcpy(ssYref, (int)cb, yrange);
+ }
+ if(nam && nam[0]) name = (char*)memdup(nam, (int)strlen(nam)+1, 0);
+ SetValues();
+}
+
+DataLine::DataLine(GraphObj *par, DataObj *d, lfPOINT *val, long nval, char *na):GraphObj(par, d)
+{
+ int cb;
+
+ FileIO(INIT_VARS);
+ Values = val; nPnt = nval; nPntSet = nPnt-1;
+ if(na && na[0] && (name = (char*)malloc((cb = (int)strlen(na))+2))) {
+ rlp_strcpy(name, cb+1, na);
+ }
+ Id = GO_DATALINE;
+}
+
+DataLine::DataLine(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+DataLine::~DataLine()
+{
+ if(Values)free(Values); Values = 0L;
+ if(pts) free(pts); pts = 0L;
+ if(ssXref) free(ssXref); ssXref = 0L;
+ if(ssYref) free(ssYref); ssYref = 0L;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(name) free(name); name = 0L;
+ if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);
+}
+
+bool
+DataLine::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_DATA_LINE:
+ LineDef.color = col;
+ return true;
+ }
+ return false;
+}
+
+void
+DataLine::DoPlot(anyOutput *target)
+{
+ int i;
+ lfPOINT fip;
+ POINT pn, *tmppts;
+
+ if(!Values || nPntSet < 1) return;
+ if (nPntSet >= nPnt) nPntSet = nPnt-1;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(pts) free(pts); pts = 0L;
+ if((type & 0xff) == 9 || (type & 0xff) == 10) //splines
+ pts = (POINT *)malloc(sizeof(POINT)*1000);
+ else if(type & 0xff) pts = (POINT *)malloc(sizeof(POINT)*(nPntSet+2)*2);
+ else pts = (POINT *)malloc(sizeof(POINT)*(nPntSet+2));
+ if(!pts) return;
+ if(max.fx > min.fx && max.fy > min.fy) dirty = false;
+ else if(dirty) Command(CMD_AUTOSCALE, 0L, target);
+ cp = 0;
+ switch(type & 0x0f) {
+ case 0: default:
+ for (i = 0; i <= nPntSet; i++){
+ target->fp2fip(Values+i, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ AddToPolygon(&cp, pts, &pn);
+ }
+ break;
+ case 5:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ target->fp2fip(Values+1, &fip);
+ pn.y += (pn.y -iround(fip.fy))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ case 1:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(+fip.fy);
+ for (i = 0; i <= nPntSet; i++){
+ target->fp2fip(Values+i, &fip);
+ pn.x = iround(fip.fx); AddToPolygon(&cp, pts, &pn);
+ pn.y = iround(fip.fy); AddToPolygon(&cp, pts, &pn);
+ }
+ if((type &0xf) == 5) {
+ target->fp2fip(Values+i-2, &fip);
+ pn.x += (pn.x - iround(fip.fx))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ }
+ break;
+ case 6:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ target->fp2fip(Values+1, &fip);
+ pn.x += (pn.x - iround(fip.fx))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ case 2:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ for (i = 0; i <= nPntSet; i++){
+ target->fp2fip(Values+i, &fip);
+ pn.y = iround(fip.fy); AddToPolygon(&cp, pts, &pn);
+ pn.x = iround(fip.fx); AddToPolygon(&cp, pts, &pn);
+ }
+ if((type &0xf) == 6) {
+ target->fp2fip(Values+i-2, &fip);
+ pn.y += (pn.y - iround(fip.fy))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ }
+ break;
+ case 7:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ target->fp2fip(Values+1, &fip);
+ pn.x += (pn.x - iround(fip.fx))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ case 3:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ for (i = 0; i <= nPntSet; i++){
+ target->fp2fip(Values+i, &fip);
+ pn.x = (pn.x + iround(fip.fx))>>1; AddToPolygon(&cp, pts, &pn);
+ pn.y = iround(fip.fy); AddToPolygon(&cp, pts, &pn);
+ pn.x = iround(fip.fx);
+ }
+ AddToPolygon(&cp, pts, &pn);
+ if((type &0xf) == 7) {
+ target->fp2fip(Values+i-2, &fip);
+ pn.x += (pn.x - iround(fip.fx))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ }
+ break;
+ case 8:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ target->fp2fip(Values+1, &fip);
+ pn.y += (pn.y - iround(fip.fy))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ case 4:
+ target->fp2fip(Values, &fip);
+ pn.x = iround(fip.fx); pn.y = iround(fip.fy);
+ for (i = 0; i <= nPntSet; i++){
+ target->fp2fip(Values+i, &fip);
+ pn.y = (pn.y + iround(fip.fy))>>1; AddToPolygon(&cp, pts, &pn);
+ pn.x = iround(fip.fx); AddToPolygon(&cp, pts, &pn);
+ pn.y = iround(fip.fy);
+ }
+ AddToPolygon(&cp, pts, &pn);
+ if((type &0xf) == 8) {
+ target->fp2fip(Values+i-2, &fip);
+ pn.y += (pn.y - iround(fip.fy))>>1;
+ AddToPolygon(&cp, pts, &pn);
+ }
+ break;
+ case 9: case 10:
+ DrawSpline(target);
+ break;
+ }
+ if(cp < 2) return;
+ if(isPolygon) { //for mark polygon only !!
+ AddToPolygon(&cp, pts, pts);
+ }
+ else{
+ 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);
+ for(i = 2; i < cp; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
+ i = 2*target->un2ix(LineDef.width); //increase size of rectangle for marks
+ IncrementMinMaxRect(&rDims, i);
+}
+
+void
+DataLine::DoMark(anyOutput *o, bool mark)
+{
+ if(pts && cp && o){
+ if(mark){
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ IncrementMinMaxRect(&mrc, 6 + o->un2ix(LineDef.width));
+ mo = GetRectBitmap(&mrc, o);
+ InvertLine(pts, cp, &LineDef, &mrc, o, mark);
+ }
+ else if(mo) RestoreRectBitmap(&mo, &mrc, o);
+ }
+}
+
+bool
+DataLine::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ bool bFound = false;
+ POINT p1;
+ int i;
+
+ switch (cmd) {
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPntSet <1)
+ return false;
+ if(isPolygon && IsInPolygon(&p1, pts, cp)) bFound = true;
+ if(bFound || IsCloseToPL(p1,pts,cp))
+ return o->ShowMark(this, MRK_GODRAW);
+ }
+ break;
+ case CMD_SCALE:
+ LineDef.width *= ((scaleINFO*)tmpl)->sy.fy; LineDef.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ break;
+ case CMD_SET_DATAOBJ:
+ Id = isPolygon ? GO_DATAPOLYGON : GO_DATALINE;
+ data = (DataObj*)tmpl;
+ return true;
+ case CMD_MRK_DIRTY:
+ dirty= true;
+ case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, 0L);
+ return false;
+ case CMD_LEGEND:
+ if(tmpl && ((GraphObj*)tmpl)->Id == GO_LEGEND) {
+ if(Id == GO_DATALINE) ((Legend*)tmpl)->HasFill(&LineDef, 0L, name);
+ }
+ break;
+ case CMD_SET_LINE:
+ if(tmpl) memcpy(&LineDef, tmpl, sizeof(LineDEF));
+ return true;
+ case CMD_UPDATE:
+ Undo.DataMem(this, (void**)&Values, nPnt * sizeof(lfPOINT), &nPnt, UNDO_CONTINUE);
+ Undo.ValLong(this, &nPntSet, UNDO_CONTINUE);
+ SetValues();
+ return true;
+ case CMD_AUTOSCALE:
+ if(nPntSet < 1 || !Values) return false;
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ if(dirty) {
+ min.fx = max.fx = Values[0].fx; min.fy = max.fy = Values[0].fy;
+ for (i = 1; i <= nPntSet; i++){
+ min.fx = Values[i].fx < min.fx ? Values[i].fx : min.fx;
+ max.fx = Values[i].fx > max.fx ? Values[i].fx : max.fx;
+ min.fy = Values[i].fy < min.fy ? Values[i].fy : min.fy;
+ max.fy = Values[i].fy > max.fy ? Values[i].fy : max.fy;
+ }
+ }
+ ((Plot*)parent)->CheckBounds(min.fx, min.fy);
+ ((Plot*)parent)->CheckBounds(max.fx, max.fy);
+ dirty = false;
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
+
+void
+DataLine::SetValues()
+{
+ AccRange *rX, *rY1=0L, *rY2=0L;
+ int i, j, k, l, m, n;
+ double x, y;
+ char yref1[500], yref2[500];
+ lfPOINT *tmpValues = Values;
+
+ if(!ssXref || !ssYref) return;
+ if(!rlp_strcpy(yref1, 500, ssYref)) return;
+ for(i = 0, yref2[0] = 0; yref1[i]; i++) {
+ if(yref1[i] == ';') {
+ yref1[i++] = 0;
+ while(yref1[i] && yref1[i] < 33) i++;
+ rlp_strcpy(yref2, 500, yref1+i);
+ }
+ }
+ nPnt = nPntSet = 0;
+ min.fx = min.fy = HUGE_VAL; max.fx = max.fy = -HUGE_VAL;
+ rX = new AccRange(ssXref); rY1 = new AccRange(yref1);
+ if(!rX || !rY1){
+ if(rX) delete(rX); if(rY1) delete(rY1);
+ return;
+ }
+ if(!name) name = rY1->RangeDesc(data, 1);
+ if(yref2[0] &&((nPnt = rX->CountItems()) == (rY1->CountItems()))) {
+ if(!(Values = (lfPOINT *)realloc(Values, ((nPnt*2+2) * sizeof(lfPOINT))))) return;
+ if(!(rY2 = new AccRange(yref2))) {
+ if(yref1) free(yref1); if(yref2) free(yref2);
+ if(rX) delete(rX); if(rY1) delete(rY1);
+ return;
+ }
+ if(rX->GetFirst(&i, &j) && rY1->GetFirst(&k, &l) &&
+ rX->GetNext(&i, &j) && rY1->GetNext(&k, &l) &&
+ rY2->GetFirst(&m, &n) && rY2->GetNext(&m, &n)) do {
+ if(data->GetValue(j, i, &x)){
+ if(data->GetValue(l, k, &y)){
+ Values[nPntSet].fx = x; Values[nPntSet++].fy = y;
+ }
+ if(data->GetValue(n, m, &y)){
+ Values[nPntSet].fx = x; Values[nPntSet++].fy = y;
+ }
+ }
+ }while(rX->GetNext(&i, &j) && rY1->GetNext(&k, &l) && rY2->GetNext(&m, &n));
+ }
+ else {
+ if((nPnt = rX->CountItems()) != (rY1->CountItems())) return;
+ if(!(Values = (lfPOINT *)realloc(Values, (nPnt+2) * sizeof(lfPOINT)))) return;
+ if(rX->GetFirst(&i, &j) && rY1->GetFirst(&k, &l) &&
+ rX->GetNext(&i, &j) && rY1->GetNext(&k, &l)) do {
+ if(data->GetValue(j, i, &x) && data->GetValue(l, k, &y)){
+ Values[nPntSet].fx = x; Values[nPntSet++].fy = y;
+ }
+ }while(rX->GetNext(&i, &j) && rY1->GetNext(&k, &l));
+ }
+ nPnt = nPntSet; nPntSet--; dirty = true;
+ Command(CMD_AUTOSCALE, 0L, 0L);
+ if(tmpValues && Values != tmpValues) Undo.InvalidGO(this);
+ if(rX) delete(rX); if(rY1) delete(rY1); if(rY2) delete(rY2);
+}
+
+void
+DataLine::LineData(lfPOINT *val, long nval)
+{
+ lfPOINT *ov = Values;
+
+ if(!val || nval <2) return;
+ if(nval > nPnt && nPnt > 1 && Values){
+ if(!(Values = (lfPOINT *)realloc(Values, ((nval*2+2) * sizeof(lfPOINT))))) return;
+ if(ov != Values) Undo.InvalidGO(this);
+ }
+ else if(!Undo.busy) Undo.DataMem(this, (void**)&Values, nPnt * sizeof(lfPOINT), &nPnt, UNDO_CONTINUE);
+ memcpy(Values, val, nval * sizeof(lfPOINT));
+ if(pts) free(pts); pts = 0L; dirty = true;
+ free(val); nPnt = nval; nPntSet = nPnt-1;
+}
+
+void
+DataLine::DrawCurve(anyOutput *target)
+{
+}
+
+void
+DataLine::DrawSpline(anyOutput *target)
+{
+ int i, j, k, klo, khi, ptsize = 1000;
+ double *y2, min, max, x, y, h, b, a;
+ POINT pn;
+ lfPOINT *scvals;
+
+ if(!(y2 = (double*)malloc(sizeof(double)*(nPnt)))) return;
+ if(!(scvals = (lfPOINT*)malloc(sizeof(lfPOINT)*(nPnt)))){
+ free(y2);
+ return;
+ }
+ if((type & 0x0f) == 9 || (type & 0x0f) == 10) {
+ if((type & 0x0f) == 9) for(i = 0; i < nPnt; i++) {
+ scvals[i].fx = target->fx2fix(Values[i].fx);
+ scvals[i].fy = target->fy2fiy(Values[i].fy);
+ }
+ else for(i = 0; i < nPnt; i++) {
+ scvals[i].fy = target->fx2fix(Values[i].fx);
+ scvals[i].fx = target->fy2fiy(Values[i].fy);
+ }
+ SortFpArray(nPnt, scvals);
+ min = scvals[0].fx; max = scvals[nPnt-1].fx;
+ for(i = j = 0; i < (nPnt-1); i++, j++) {
+ y = scvals[i].fy; scvals[j].fx = scvals[i].fx;
+ for(k = 1; scvals[i+1].fx == scvals[i].fx; k++) {
+ y += scvals[i+1].fy; i++;
+ }
+ scvals[j].fy = y/((double)k);
+ }
+ if(scvals[i].fx > scvals[i-1].fx) {
+ scvals[j].fx = scvals[i].fx; scvals[j].fy = scvals[i].fy;
+ j++;
+ }
+ spline(scvals, j, y2);
+ h = scvals[1].fx - scvals[0].fx; // klo and khi bracket the input value of x
+ for(x = min, klo = 0, i = khi = 1; x < max && i < j; x += 1.0) {
+ while(x > scvals[i].fx) {
+ klo++; khi++; i++;
+ h = scvals[khi].fx - scvals[klo].fx;
+ }
+ a = (scvals[khi].fx - x) / h; b = (x - scvals[klo].fx) / h;
+ y = a * scvals[klo].fy + b * scvals[khi].fy + ((a*a*a - a) * y2[klo] + (b*b*b - b) * y2[khi]) * (h*h)/6.0;
+ if((type & 0x0f) == 9) {
+ pn.x = iround(x); pn.y = iround(y);
+ }
+ else {
+ pn.x = iround(y); pn.y = iround(x);
+ }
+ if(cp >= ptsize) {
+ ptsize += 1000;
+ pts = (POINT*)realloc(pts, sizeof(POINT)*ptsize);
+ }
+ AddToPolygon(&cp, pts, &pn);
+ }
+ }
+ free(y2); free(scvals);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// DataPolygon is a graphic object based on DataLine
+DataPolygon::DataPolygon(GraphObj *par, DataObj *d, char *xrange, char *yrange, char *nam):
+ DataLine(par, d, xrange, yrange, nam)
+{
+ lfPOINT *fp = Values;
+ char *rx = ssXref;
+ char *ry = ssYref;
+
+ FileIO(INIT_VARS);
+ Values = fp; //FileIO will just set Values to 0L !
+ ssXref = rx; ssYref = ry;
+ Id = GO_DATAPOLYGON;
+}
+
+DataPolygon::DataPolygon(int src):DataLine(0L, 0)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+DataPolygon::~DataPolygon()
+{
+ if(Values)free(Values); Values =0L;
+ if(pts) free (pts); pts = 0L;
+ if(ssXref) free(ssXref); ssXref = 0L;
+ if(ssYref) free(ssYref); ssYref = 0L;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(name) free(name); name = 0;
+ if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);
+}
+
+void
+DataPolygon::DoPlot(anyOutput *target)
+{
+ if(!Values || nPntSet < 2) return;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ DataLine::DoPlot(target); //no drawing but fill pts only
+ target->SetLine(&LineDef); target->SetFill(&pgFill);
+ target->oPolygon(pts, cp);
+}
+
+void
+DataPolygon::DoMark(anyOutput *o, bool mark)
+{
+ if(pts && cp && o){
+ if(mark){
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ IncrementMinMaxRect(&mrc, 6 + o->un2ix(LineDef.width));
+ mo = GetRectBitmap(&mrc, o);
+ InvertPolygon(pts, cp, &LineDef, &pgFill, &mrc, o, mark);
+ }
+ else RestoreRectBitmap(&mo, &mrc, o);
+ }
+}
+
+bool
+DataPolygon::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ switch (cmd) {
+ case CMD_PG_FILL:
+ if(tmpl) {
+ memcpy((void*)&pgFill, tmpl, sizeof(FillDEF));
+ if(pgFill.hatch) memcpy((void*)&pgFillLine, (void*)pgFill.hatch, sizeof(LineDEF));
+ pgFill.hatch = (LineDEF*)&pgFillLine;
+ }
+ return true;
+ case CMD_SCALE:
+ LineDef.width *= ((scaleINFO*)tmpl)->sy.fy; LineDef.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ pgFillLine.width *= ((scaleINFO*)tmpl)->sy.fy; pgFillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ pgFill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ break;
+ case CMD_LEGEND:
+ if(tmpl && ((GraphObj*)tmpl)->Id == GO_LEGEND) {
+ if(Id == GO_DATAPOLYGON) ((Legend*)tmpl)->HasFill(&LineDef, &pgFill, name);
+ }
+ break;
+ default:
+ return DataLine::Command(cmd, tmpl, o);
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Calculate and display a regression line
+// Ref.: "Biometry" third edition 1995 (ed. R.R. Sokal and F.J. Rohlf),
+// W.H. Freeman and Company, New York; ISBN 0-7167-2411-1; pp. 451ff
+RegLine::RegLine(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel):
+ GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ type = sel;
+ Id = GO_REGLINE;
+ uclip.Xmin = uclip.Ymin = lim.Xmin = lim.Ymin = -1.0;
+ uclip.Xmax = uclip.Ymax = lim.Xmax = lim.Ymax = 1.0;
+ Recalc(values, n);
+}
+
+RegLine::RegLine(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) FileIO(FILE_READ);
+}
+
+RegLine::~RegLine()
+{
+ if(pts) free(pts); pts = 0L;
+ if(parent)parent->Command(CMD_MRK_DIRTY, 0L, 0L);
+}
+
+double
+RegLine::GetSize(int select)
+{
+ double a, b;
+
+ switch(select) {
+ case SIZE_MX: return mx;
+ case SIZE_MY: return my;
+ case SIZE_A:
+ case SIZE_B:
+ switch(type & 0x07) {
+ case 1: a = l2.fx; b = l2.fy; break;
+ case 2: a = l3.fx; b = l3.fy; break;
+ case 3: a = l4.fx; b = l4.fy; break;
+ case 4: a = l5.fx; b = l5.fy; break;
+ default: a = l1.fx; b = l1.fy; break;
+ }
+ if(select == SIZE_A) return a;
+ else return b;
+ }
+ return 0.0;
+}
+
+void
+RegLine::DoPlot(anyOutput *o)
+{
+ int i;
+ POINT pn;
+ double x, x1, y, d, a, b;
+ fRECT cliprc;
+ bool dValid;
+
+ switch (type & 0x70) {
+ case 0x20: memcpy(&cliprc, &uclip, sizeof(fRECT)); break;
+ case 0x10:
+ if(parent) {
+ cliprc.Xmin = parent->GetSize(SIZE_BOUNDS_LEFT);
+ cliprc.Xmax = parent->GetSize(SIZE_BOUNDS_RIGHT);
+ cliprc.Ymin = parent->GetSize(SIZE_BOUNDS_BOTTOM);
+ cliprc.Ymax = parent->GetSize(SIZE_BOUNDS_TOP);
+ break;
+ }
+ //no parent: use default
+ default: memcpy(&cliprc, &lim, sizeof(fRECT)); break;
+ }
+ if(cliprc.Xmax < cliprc.Xmin) {
+ x = cliprc.Xmax; cliprc.Xmax = cliprc.Xmin; cliprc.Xmin = x;
+ }
+ if(cliprc.Ymax < cliprc.Ymin) {
+ y = cliprc.Ymax; cliprc.Ymax = cliprc.Ymin; cliprc.Ymin = y;
+ }
+ if(cliprc.Xmin == cliprc.Xmax || cliprc.Ymin == cliprc.Ymax) return;
+ if((!pts) && (!(pts = (POINT *)malloc(sizeof(POINT)*202))))return;
+ switch(type & 0x07) {
+ case 1: a = l2.fx; b = l2.fy; break;
+ case 2: a = l3.fx; b = l3.fy; break;
+ case 3: a = l4.fx; b = l4.fy; break;
+ case 4: a = l5.fx; b = l5.fy; break;
+ default: a = l1.fx; b = l1.fy; break;
+ }
+ x = cliprc.Xmin; d = (cliprc.Xmax - cliprc.Xmin)/200.0;
+ for (cp = i = 0; i <= 200; i++){
+ dValid = true;
+ switch(type & 0x700) {
+ case 0x100: //logarithmic x
+ if(dValid = x > defs.min4log) x1 = log10(x);
+ break;
+ case 0x200: //reciprocal x
+ if(dValid = fabs(x) > defs.min4log) x1 = 1.0/x;
+ break;
+ case 0x300: //square root x
+ if(dValid = fabs(x) > defs.min4log) x1 = sqrt(x);
+ break;
+ default: x1 = x; break; //linear x
+ }
+ y = a + b*x1;
+ if(dValid) switch(type & 0x7000) {
+ case 0x1000: //logarithmic y
+ y = pow(10.0, y);
+ break;
+ case 0x2000: //reciprocal y
+ if(dValid = fabs(y) >0.0001) y = 1.0/y;
+ break;
+ case 0x3000: //square root y
+ if(dValid = fabs(y) >0.0001) y = y*y;
+ break;
+ }
+ if(dValid && y >= cliprc.Ymin && y <= cliprc.Ymax) {
+ pn.x = o->fx2ix(x); pn.y = o->fy2iy(y);
+ AddToPolygon(&cp, pts, &pn);
+ }
+ x += d;
+ }
+ if(cp < 2) return;
+ o->SetLine(&LineDef); o->oPolyline(pts, cp);
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+ for(i = 2; i < cp; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
+ i = 2*o->un2ix(LineDef.width); //increase size of rectangle for marks
+ IncrementMinMaxRect(&rDims, i);
+}
+
+void
+RegLine::DoMark(anyOutput *o, bool mark)
+{
+ if(pts && cp && o){
+ if(mark)InvertLine(pts, cp, &LineDef, &rDims, o, mark);
+ else if(parent) parent->Command(CMD_REDRAW, 0L, o);
+ }
+}
+
+bool
+RegLine::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ POINT p1;
+
+ switch (cmd) {
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPoints <2)
+ return false;
+ if(IsCloseToPL(p1,pts,cp)) return o->ShowMark(CurrGO= this, MRK_GODRAW);
+ }
+ break;
+ case CMD_SCALE:
+ LineDef.width *= ((scaleINFO*)tmpl)->sy.fy; LineDef.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ break;
+ case CMD_SET_DATAOBJ:
+ Id = GO_REGLINE;
+ return true;
+ case CMD_BOUNDS:
+ if(tmpl) {
+ memcpy(&lim, tmpl, sizeof(fRECT));
+ memcpy(&uclip, tmpl, sizeof(fRECT));
+ }
+ return true;
+ case CMD_AUTOSCALE:
+ if(nPoints < 2) return false;
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds(lim.Xmin, lim.Ymin);
+ ((Plot*)parent)->CheckBounds(lim.Xmax, lim.Ymax);
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
+
+void
+RegLine::Recalc(lfPOINT *values, long n)
+{
+ double sx, sy, dx, dy, sxy, sxx, syy;
+ double a, b, k;
+ long ic;
+
+ sx = sy = 0.0;
+ if((nPoints = n)<2) return;
+ for(ic = 0; ic < n; ic++) {
+ sx += values[ic].fx; sy += values[ic].fy;
+ }
+ mx = sx /((double)nPoints); my = sy/((double)nPoints);
+ sxy = sxx = syy = 0.0;
+ for(ic = 0; ic < n; ic++) {
+ dx = mx - values[ic].fx; dy = my - values[ic].fy;
+ sxx += (dx*dx); syy += (dy*dy); sxy += (dx*dy);
+ }
+ l1.fy = sxy / sxx; l1.fx = my - (sxy / sxx) * mx;
+ b = sxy / syy; a = mx - (sxy / syy) * my;
+ l2.fy = 1.0/b; l2.fx = -a / b;
+ l3.fy = (l1.fy+l2.fy)/2.0; l3.fx = (l1.fx+l2.fx)/2.0;
+ l4.fy = sy/sx; l4.fx = 0.0;
+ if(l5.fx == 0.0 && l5.fx == 0.0){
+ l5.fy = l1.fy; l5.fx = l1.fx;
+ }
+ //calculate distance point from line algorithm
+ //Ref: K. Thompson, 1990: Vertical Distance from a Point to a Line. In:
+ // Graphic Gems (Andrew S. Glassner, ed.), Academic Press,
+ // pp. 47-48; ISBN 0-12-286165-5
+ k = (sqrt(1.0/(1.0+l1.fy*l1.fy))+sqrt(1.0/(1.0+l2.fy*l2.fy)))/2.0;
+ b = sqrt(1.0/(k*k) -1.0);
+ l3.fy = l3.fy > 0.0 ? b : -b;
+ l3.fx = my - mx * l3.fy;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Calculate and display a statnard deviation (SD-) ellipse
+SDellipse::SDellipse(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel):
+ GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ type = sel;
+ Id = GO_SDELLIPSE;
+ if(val = (lfPOINT*)malloc(n * sizeof(lfPOINT))){
+ memcpy(val, values, (nPoints = n)*sizeof(lfPOINT));
+ rl = new RegLine(this, data, values, n, type);
+ }
+}
+
+SDellipse::SDellipse(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) FileIO(FILE_READ);
+}
+
+SDellipse::~SDellipse()
+{
+ if(val) free(val);
+ if(pts) free(pts);
+ if(!(type & 0x10000) && parent && rl &&
+ parent->Command(CMD_DROP_OBJECT, rl, 0L)) return;
+ if(rl) DeleteGO(rl);
+}
+
+void
+SDellipse::DoPlot(anyOutput *o)
+{
+ int i;
+ double a1, b1, a2, b2, fv, k1, k2, ss1, ss2, np, x, dx, si, csi;
+ lfPOINT fp, fip;
+ POINT p1, *tmppts;
+
+ if(!rl) return;
+ if(pts) free(pts);
+ if(!(pts = (POINT *)malloc(sizeof(POINT)*420)))return;
+ //get line data from regression line object
+ mx = rl->GetSize(SIZE_MX); my = rl->GetSize(SIZE_MY);
+ a1 = rl->GetSize(SIZE_A); b1 = rl->GetSize(SIZE_B);
+ b2 = -1.0/b1; a2 = my - b2 * mx;
+ //calculate sine and cosine for back rotation
+ fv = sqrt(1.0+b1*b1); si = b1/fv; csi = 1.0/fv;
+ //calculate distance from line for each point and squared sum of distances
+ //Ref: K. Thompson, 1990: Vertical Distance from a Point to a Line. In:
+ // Graphic Gems (Andrew S. Glassner, ed.), Academic Press,
+ // pp. 47-48; ISBN 0-12-286165-5
+ k1 = sqrt(1.0/(1.0+b1*b1)); k2 = sqrt(1.0/(1.0+b2*b2));
+ // y = a + b*x;
+ ss1 = ss2 = 0.0;
+ for(i = 0; i < nPoints; i++) {
+ fv = (a1 + b1 * val[i].fx - val[i].fy) * k1; ss1 += (fv*fv);
+ fv = (a2 + b2 * val[i].fx - val[i].fy) * k2; ss2 += (fv*fv);
+ }
+ np = ((double)(nPoints-1));
+ //SD perpendicular and in direction of regression line
+ sd1 = sqrt(ss1 /= np); sd2 = sqrt(ss2 /= np);
+ dx = sd2/100.0;
+ for(i = 0, cp = 0, x = -sd2; i < 2; i++) {
+ do {
+ fv = (x*x)/ss2;
+ fv = fv < 0.99999 ? sqrt((1.0-fv)*ss1) : 0.0;
+ fv = i ? fv : -fv;
+ fp.fx = mx + x * csi - fv * si;
+ fp.fy = my + x * si + fv * csi;
+ switch(type & 0x700) {
+ case 0x100: //logarithmic x
+ fp.fx = pow(10.0, fp.fx);
+ break;
+ case 0x200: //reciprocal x
+ if(fabs(fp.fx) > defs.min4log) fp.fx = 1.0/fp.fx;
+ else fp.fx = 0.0;
+ break;
+ case 0x300: //square root x
+ if(fabs(fp.fx) > defs.min4log) fp.fx = fp.fx*fp.fx;
+ else fp.fx = 0.0;
+ break;
+ }
+ switch(type & 0x7000) {
+ case 0x1000: //logarithmic y
+ fp.fy = pow(10.0, fp.fy);
+ break;
+ case 0x2000: //reciprocal y
+ if(fabs(fp.fy) > defs.min4log) fp.fy = 1.0/fp.fy;
+ else fp.fy = 0.0;
+ break;
+ case 0x3000: //square root y
+ if(fabs(fp.fy) > defs.min4log) fp.fy = fp.fy*fp.fy;
+ else fp.fy = 0.0;
+ break;
+ }
+ o->fp2fip(&fp, &fip); p1.x = iround(fip.fx); p1.y = iround(fip.fy);
+ AddToPolygon(&cp, pts, &p1);
+ }while((x += dx) < sd2 && x > -sd2);
+ x = sd2;
+ dx *= -1.0;
+ }
+ o->SetLine(&LineDef);
+ if(cp > 2) {
+ AddToPolygon(&cp, pts, pts); //close polygon
+ if(tmppts = (POINT*)realloc(pts, cp *sizeof(POINT))) pts = tmppts;
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+ for(i = 2; i < cp; i++)
+ UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
+ i = 3*o->un2ix(LineDef.width); //increase size of rectangle for marks
+ IncrementMinMaxRect(&rDims, i);
+ o->oPolyline(pts, cp);
+ }
+ else {
+ free(pts);
+ cp = 0;
+ }
+ if(!(type & 0x10000))rl->DoPlot(o);
+}
+
+void
+SDellipse::DoMark(anyOutput *o, bool mark)
+{
+ if(pts && cp && o){
+ if(mark)InvertLine(pts, cp, &LineDef, &rDims, o, mark);
+ else if(parent) parent->Command(CMD_REDRAW, 0L, o);
+ }
+}
+
+bool
+SDellipse::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ POINT p1;
+
+ switch (cmd) {
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(!(type & 0x10000) && rl && rl->Command(cmd, tmpl, o)) return true;
+ if(!IsInRect(&rDims, p1.x= mev->x, p1.y= mev->y) || CurrGO || !o || nPoints <2)
+ return false;
+ if(IsCloseToPL(p1,pts,cp)) return o->ShowMark(CurrGO= this, MRK_GODRAW);
+ }
+ break;
+ case CMD_SCALE:
+ LineDef.width *= ((scaleINFO*)tmpl)->sy.fy; LineDef.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ if(rl) rl->Command(cmd, tmpl, o);
+ break;
+ case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_RMU:
+ if(!(type & 0x10000) && parent && rl && parent->Command(CMD_DROP_OBJECT, rl, o)){
+ rl = 0L;
+ return true;
+ }
+ return false;
+ case CMD_INIT:
+ if(rl) return rl->PropertyDlg();
+ break;
+ case CMD_DROP_OBJECT:
+ if(tmpl && ((GraphObj*)tmpl)->Id == GO_REGLINE && !rl) {
+ rl = (RegLine *)tmpl;
+ rl->parent = this;
+ return true;
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_SDELLIPSE;
+ if(rl) rl->Command(cmd, tmpl, o);
+ return true;
+ case CMD_BOUNDS:
+ if(tmpl) {
+ if(rl) rl->Command(cmd, tmpl, o);
+ memcpy(&lim, tmpl, sizeof(fRECT));
+ }
+ return true;
+ case CMD_DELOBJ:
+ if(tmpl && tmpl == (void*)rl) {
+ Undo.ValInt(parent, &type, 0L);
+ type |= 0x10000;
+ if(parent) parent->Command(CMD_REDRAW, 0L, o);
+ return true;
+ }
+ break;
+ case CMD_AUTOSCALE:
+ if(nPoints < 2) return false;
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds(lim.Xmin, lim.Ymin);
+ ((Plot*)parent)->CheckBounds(lim.Xmax, lim.Ymax);
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+void
+SDellipse::Recalc(lfPOINT *values, long n)
+{
+ if(val) free(val);
+ if(val = (lfPOINT*)malloc(n * sizeof(lfPOINT)))
+ memcpy(val, values, (nPoints = n)*sizeof(lfPOINT));
+ if(rl) rl->Recalc(values, n);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Error bars are simple graphic objects
+ErrorBar::ErrorBar(GraphObj *par, DataObj *d, double x, double y, double err, int which,
+ int xc, int xr, int yc, int yr, int ec, int er):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ fPos.fx = x; fPos.fy = y;
+ ferr = err;
+ type = which;
+ Id = GO_ERRBAR;
+ data = d;
+ if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || ec >= 0 || er >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ ssRef[2].x = ec; ssRef[2].y = er;
+ cssRef = 3;
+ }
+ }
+ Command(CMD_AUTOSCALE, 0L, 0L);
+}
+
+ErrorBar::ErrorBar(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ type = ERRBAR_VSYM;
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+ErrorBar::~ErrorBar()
+{
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
+}
+
+bool
+ErrorBar::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_ERRBAR:
+ SizeBar = value;
+ return true;
+ case SIZE_ERRBAR_LINE:
+ ErrLine.width = value;
+ return true;
+ }
+ return false;
+}
+
+bool
+ErrorBar::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_ERROR_LINE:
+ ErrLine.color = col;
+ return true;
+ }
+ return false;
+}
+
+void
+ErrorBar::DoPlot(anyOutput *target)
+{
+ int ie;
+
+ switch (type & 0x0ff) {
+ case ERRBAR_VSYM:
+ case ERRBAR_VUP:
+ case ERRBAR_VDOWN:
+ ie = target->un2ix(SizeBar/2.0);
+ break;
+ default:
+ ie = target->un2iy(SizeBar/2.0);
+ break;
+ }
+ target->SetLine(&ErrLine);
+ switch(type) {
+ case ERRBAR_VSYM:
+ ebpts[0].x = ebpts[1].x = target->fx2ix(fPos.fx);
+ ebpts[0].y = target->fy2iy(fPos.fy-ferr);
+ ebpts[4].y = ebpts[5].y = ebpts[1].y = target->fy2iy(fPos.fy+ferr);
+ if(ebpts[1].y != ebpts[0].y) target->oSolidLine(ebpts);
+ ebpts[4].x = ebpts[2].x = ebpts[0].x - ie;
+ ebpts[5].x = ebpts[3].x = ebpts[1].x + ie+1;
+ ebpts[2].y = ebpts[3].y = ebpts[0].y;
+ if(ebpts[3].x > ebpts[2].x) {
+ target->oSolidLine(ebpts+2);
+ target->oSolidLine(ebpts+4);
+ }
+ rDims.left = ebpts[2].x; rDims.right = ebpts[3].x;
+ rDims.top = ebpts[0].y; rDims.bottom = ebpts[1].y;
+ break;
+ case ERRBAR_VUP:
+ case ERRBAR_VDOWN:
+ ebpts[0].x = ebpts[1].x = target->fx2ix(fPos.fx);
+ ebpts[0].y = target->fy2iy(fPos.fy);
+ ebpts[2].y = ebpts[3].y = ebpts[1].y =
+ target->fy2iy(type == ERRBAR_VUP ? fPos.fy+ferr : fPos.fy-ferr);
+ if(ebpts[1].y != ebpts[0].y) target->oSolidLine(ebpts);
+ ebpts[2].x = ebpts[0].x - ie;
+ ebpts[3].x = ebpts[1].x + ie+1;
+ if(ebpts[3].x > ebpts[2].x) target->oSolidLine(ebpts+2);
+ rDims.left = ebpts[2].x; rDims.right = ebpts[3].x;
+ rDims.top = ebpts[0].y; rDims.bottom = ebpts[1].y;
+ break;
+ case ERRBAR_HSYM:
+ ebpts[2].x = ebpts[3].x = ebpts[0].x = target->fx2ix(fPos.fx-ferr);
+ ebpts[4].x = ebpts[5].x = ebpts[1].x = target->fx2ix(fPos.fx+ferr);
+ ebpts[0].y = ebpts[1].y = target->fy2iy(fPos.fy);
+ if(ebpts[1].x != ebpts[0].x) target->oSolidLine(ebpts);
+ ebpts[2].y = ebpts[4].y = ebpts[0].y - ie;
+ ebpts[3].y = ebpts[5].y = ebpts[1].y + ie+1;
+ if(ebpts[3].y >ebpts[2].y) {
+ target->oSolidLine(ebpts+2);
+ target->oSolidLine(ebpts+4);
+ }
+ rDims.left = ebpts[0].x; rDims.right = ebpts[1].x;
+ rDims.top = ebpts[2].y; rDims.bottom = ebpts[3].y;
+ break;
+ case ERRBAR_HLEFT:
+ case ERRBAR_HRIGHT:
+ ebpts[0].x = target->fx2ix(fPos.fx);
+ ebpts[0].y = ebpts[1].y = target->fy2iy(fPos.fy);
+ ebpts[2].x = ebpts[3].x = ebpts[1].x =
+ target->fx2ix(type == ERRBAR_HRIGHT ? fPos.fx+ferr : fPos.fx-ferr);
+ if(ebpts[1].x != ebpts[0].x) target->oSolidLine(ebpts);
+ ebpts[2].y = ebpts[0].y - ie;
+ ebpts[3].y = ebpts[1].y + ie+1;
+ if(ebpts[3].y > ebpts[2].y) target->oSolidLine(ebpts+2);
+ rDims.left = ebpts[0].x; rDims.right = ebpts[1].x;
+ rDims.top = ebpts[2].y; rDims.bottom = ebpts[3].y;
+ break;
+ }
+ if(rDims.left > rDims.right) Swap(rDims.left, rDims.right);
+ if(rDims.top > rDims.bottom) Swap(rDims.top, rDims.bottom);
+ IncrementMinMaxRect(&rDims, 2);
+}
+
+void
+ErrorBar::DoMark(anyOutput *o, bool mark)
+{
+ 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
+ErrorBar::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ bool bFound;
+ int cb;
+
+ switch (cmd) {
+ case CMD_SCALE:
+ ErrLine.width *= ((scaleINFO*)tmpl)->sy.fy; ErrLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ SizeBar *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ bFound = false;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(!IsInRect(&rDims, mev->x, mev->y) || CurrGO) return false;
+ switch (type) {
+ 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:
+ 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) &&
+ mev->y <= (ebpts[4].y + 2)) bFound = true;
+ break;
+ }
+ if(bFound) o->ShowMark(this, MRK_GODRAW);
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_ERRBAR;
+ data = (DataObj *) tmpl;
+ return true;
+ case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >2 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &ferr);
+ return true;
+ }
+ 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(tmpl && *((char *)tmpl)){
+ cb = (int)strlen((char*)tmpl)+2;
+ if(name = (char*)realloc(name, cb)) rlp_strcpy(name, cb, (char*)tmpl);
+ return true;
+ }
+ return false;
+ case CMD_ERR_TYPE:
+ if(tmpl) type = *((int*)tmpl);
+ return true;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ switch(type) {
+ case ERRBAR_VSYM:
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy+ferr);
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy-ferr); break;
+ case ERRBAR_VUP:
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy+ferr); break;
+ case ERRBAR_VDOWN:
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy-ferr); break;
+ case ERRBAR_HSYM:
+ ((Plot*)parent)->CheckBounds(fPos.fx+ferr, fPos.fy);
+ ((Plot*)parent)->CheckBounds(fPos.fx-ferr, fPos.fy); break;
+ case ERRBAR_HLEFT:
+ ((Plot*)parent)->CheckBounds(fPos.fx-ferr, fPos.fy);
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy); break;
+ case ERRBAR_HRIGHT:
+ ((Plot*)parent)->CheckBounds(fPos.fx+ferr, fPos.fy);
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy); break;
+ }
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// arrows to data points or with absolute coordinates
+Arrow::Arrow(GraphObj * par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
+ int xc1, int xr1, int yc1, int yr1, int xc2, int xr2, int yc2, int yr2):
+ GraphObj(par, d)
+{
+ double dx, dy;
+
+ FileIO(INIT_VARS);
+ memcpy(&pos1, &fp1, sizeof(lfPOINT));
+ memcpy(&pos2, &fp2, sizeof(lfPOINT));
+ type = which;
+ if(type & ARROW_UNITS) {
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ pos1.fx -= dx; pos1.fy -= dy; pos2.fx -= dx; pos2.fy -= dy;
+ }
+ if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || xc2 >= 0 || xr2 >= 0 ||
+ yc2 >= 0 || yr2 >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
+ ssRef[0].x = xc1; ssRef[0].y = xr1;
+ ssRef[1].x = yc1; ssRef[1].y = yr1;
+ ssRef[2].x = xc2; ssRef[2].y = xr2;
+ ssRef[3].x = yc2; ssRef[3].y = yr2;
+ cssRef = 4;
+ }
+ }
+ bModified = false;
+}
+
+Arrow::Arrow(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+Arrow::~Arrow()
+{
+ Command(CMD_FLUSH, 0L, 0L);
+ if(bModified) Undo.InvalidGO(this);
+}
+
+double
+Arrow::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_XPOS: return pos1.fx;
+ case SIZE_XPOS+1: return pos2.fx;
+ case SIZE_YPOS: return pos1.fy;
+ case SIZE_YPOS+1: return pos2.fy;
+ case SIZE_GRECT_LEFT: case SIZE_GRECT_TOP:
+ case SIZE_GRECT_RIGHT: case SIZE_GRECT_BOTTOM:
+ if(parent) return parent->GetSize(select);
+ break;
+ }
+ return 0.0;
+}
+
+bool
+Arrow::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_ARROW_LINE: LineDef.width = value; return true;
+ case SIZE_ARROW_CAPWIDTH: cw = value; return true;
+ case SIZE_ARROW_CAPLENGTH: cl = value; return true;
+ case SIZE_XPOS: pos1.fx = value; return true;
+ case SIZE_XPOS+1: pos2.fx = value; return true;
+ case SIZE_YPOS: pos1.fy = value; return true;
+ case SIZE_YPOS+1: pos2.fy = value; return true;
+ }
+ return false;
+}
+
+bool
+Arrow::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_ARROW:
+ LineDef.color = col;
+ return true;
+ }
+ return false;
+}
+
+void
+Arrow::DoPlot(anyOutput *o)
+{
+ double si, csi, tmp, fix1, fiy1, fix2, fiy2, dx, dy;
+
+ if(!o || !parent) return;
+ if(type & ARROW_UNITS) {
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ fix1 = o->co2fix(pos1.fx+dx); fix2 = o->co2fix(pos2.fx+dx);
+ fiy1 = o->co2fiy(pos1.fy+dy); fiy2 = o->co2fiy(pos2.fy+dy);
+ }
+ else {
+ fix1 = o->fx2fix(pos1.fx); fix2 = o->fx2fix(pos2.fx);
+ fiy1 = o->fy2fiy(pos1.fy); fiy2 = o->fy2fiy(pos2.fy);
+ }
+ if(fix1 == fix2 && fiy1 == fiy2) return; //zero length
+ //draw arrow line
+ pts[0].x = iround(fix1); pts[1].x = iround(fix2);
+ pts[0].y = iround(fiy1); pts[1].y = iround(fiy2);
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+ //calculate sine and cosine for cap
+ si = fiy1-fiy2;
+ tmp = fix2 - fix1;
+ si = si/sqrt(si*si + tmp*tmp);
+ csi = fix2-fix1;
+ tmp = fiy2 - fiy1;
+ csi = csi/sqrt(csi*csi + tmp*tmp);
+ //draw cap
+ pts[2].x = pts[1].x - o->un2ix(csi*cl + si*cw/2.0);
+ pts[2].y = pts[1].y + o->un2iy(si*cl - csi*cw/2.0);
+ pts[3].x = pts[1].x; pts[3].y = pts[1].y;
+ pts[4].x = pts[1].x - o->un2ix(csi*cl - si*cw/2.0);
+ pts[4].y = pts[1].y + o->un2iy(si*cl + csi*cw/2.0);
+ switch(type & 0xff) {
+ case ARROW_NOCAP:
+ pts[2].x = pts[3].x = pts[4].x = pts[1].x;
+ pts[2].y = pts[3].y = pts[4].y = pts[1].y;
+ break;
+ }
+ UpdateMinMaxRect(&rDims, pts[2].x, pts[2].y);
+ UpdateMinMaxRect(&rDims, pts[4].x, pts[4].y);
+ IncrementMinMaxRect(&rDims, 3);
+ if(this == CurrGO) o->ShowMark(this, MRK_GODRAW);
+ else Redraw(o);
+}
+
+void
+Arrow::DoMark(anyOutput *o, bool mark)
+{
+ LineDEF OldLine;
+
+ if(type & ARROW_UNITS) {
+ if(!dh1) dh1 = new dragHandle(this, DH_12);
+ if(!dh2) dh2 = new dragHandle(this, DH_22);
+ }
+ else {
+ if (dh1) DeleteGO(dh1); if (dh2) DeleteGO(dh2);
+ dh1 = dh2 = 0L;
+ }
+ memcpy(&OldLine, &LineDef, sizeof(LineDEF));
+ if(mark) {
+ LineDef.color = 0x00000000L;
+ LineDef.width = OldLine.width *3.0;
+ Redraw(o);
+ LineDef.width = OldLine.width;
+ LineDef.color = OldLine.color ^ 0x00ffffffL;
+ Redraw(o);
+ if(dh1) dh1->DoPlot(o); if(dh2) dh2->DoPlot(o);
+ }
+ else if(parent){
+ LineDef.color = 0x00ffffffL;
+ LineDef.width = OldLine.width *3.0;
+ Redraw(o);
+ LineDef.width = OldLine.width;
+ LineDef.color = OldLine.color;
+ parent->DoPlot(o);
+ }
+ memcpy(&LineDef, &OldLine, sizeof(LineDEF));
+ o->UpdateRect(&rDims, false);
+}
+
+bool
+Arrow::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+
+ switch (cmd) {
+ case CMD_SAVEPOS:
+ bModified = true;
+ Undo.SaveLFP(this, &pos1, 0L);
+ Undo.SaveLFP(this, &pos2, UNDO_CONTINUE);
+ return true;
+ case CMD_SCALE:
+ LineDef.width *= ((scaleINFO*)tmpl)->sy.fy; LineDef.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ cw *= ((scaleINFO*)tmpl)->sy.fy; cl *= ((scaleINFO*)tmpl)->sy.fy;
+ if(type & ARROW_UNITS) {
+ pos1.fx = ((scaleINFO*)tmpl)->sx.fx + pos1.fx * ((scaleINFO*)tmpl)->sx.fy;
+ pos1.fy = ((scaleINFO*)tmpl)->sy.fx + pos1.fy * ((scaleINFO*)tmpl)->sy.fy;
+ pos2.fx = ((scaleINFO*)tmpl)->sx.fx + pos2.fx * ((scaleINFO*)tmpl)->sx.fy;
+ pos2.fy = ((scaleINFO*)tmpl)->sy.fx + pos2.fy * ((scaleINFO*)tmpl)->sy.fy;
+ }
+ return true;
+ case CMD_FLUSH:
+ if (dh1) DeleteGO(dh1); dh1 = 0L;
+ if (dh2) DeleteGO(dh2); dh2 = 0L;
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(!CurrGO && ObjThere(mev->x, mev->y)){
+ o->ShowMark(this, MRK_GODRAW);
+ return true;
+ }
+ }
+ break;
+ case CMD_ARROW_ORG:
+ memcpy(&pos1, tmpl, sizeof(lfPOINT));
+ if(ssRef && cssRef >3)
+ ssRef[0].x = ssRef[0].y = ssRef[1].x = ssRef[1].y = -1;
+ return true;
+ case CMD_ARROW_TYPE:
+ if(tmpl) {
+ type &= ~0xff; type |= (*((int*)tmpl));
+ return true;
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_ARROW;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >3 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &pos1.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &pos1.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &pos2.fx);
+ data->GetValue(ssRef[3].y, ssRef[3].x, &pos2.fy);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds(pos1.fx, pos1.fy);
+ ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy);
+ return true;
+ }
+ break;
+ case CMD_MRK_DIRTY: //from Undo ?
+ case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_MOVE:
+ bModified = true;
+ case CMD_UNDO_MOVE:
+ if(type & ARROW_UNITS) {
+ if(cmd == CMD_MOVE) Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ pos1.fx += ((lfPOINT*)tmpl)[0].fx; pos1.fy += ((lfPOINT*)tmpl)[0].fy;
+ pos2.fx += ((lfPOINT*)tmpl)[0].fx; pos2.fy += ((lfPOINT*)tmpl)[0].fy;
+ if(o){
+ o->StartPage(); parent->DoPlot(o); o->EndPage();
+ }
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+void
+Arrow::Redraw(anyOutput *o)
+{
+ FillDEF FillCap;
+
+ o->SetLine(&LineDef);
+ o->oSolidLine(pts);
+ switch(type & 0xff) {
+ case ARROW_NOCAP:
+ break;
+ case ARROW_LINE:
+ o->oSolidLine(pts+2);
+ o->oSolidLine(pts+3);
+ break;
+ case ARROW_TRIANGLE:
+ FillCap.type = FILL_NONE;
+ FillCap.color = LineDef.color;
+ FillCap.scale = 1.0f;
+ FillCap.hatch = 0L;
+ o->SetFill(&FillCap);
+ o->oPolygon(pts+2, 3);
+ break;
+ }
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// universal boxes
+Box::Box(GraphObj * par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
+ int xc1, int xr1, int yc1, int yr1, int xc2, int xr2,
+ int yc2, int yr2):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ memcpy(&pos1, &fp1, sizeof(lfPOINT));
+ memcpy(&pos2, &fp2, sizeof(lfPOINT));
+ type = which;
+ Id = GO_BOX;
+ if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || xc2 >= 0 || xr2 >= 0 ||
+ yc2 >= 0 || yr2 >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
+ ssRef[0].x = xc1; ssRef[0].y = xr1;
+ ssRef[1].x = yc1; ssRef[1].y = yr1;
+ ssRef[2].x = xc2; ssRef[2].y = xr2;
+ ssRef[3].x = yc2; ssRef[3].y = yr2;
+ cssRef = 4;
+ }
+ }
+}
+
+Box::Box(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+Box::~Box()
+{
+ Command(CMD_FLUSH, 0L, 0L);
+}
+
+double
+Box::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_XPOS:
+ return (pos1.fx + pos2.fx)/2.0;
+ case SIZE_YPOS:
+ return (pos1.fy + pos2.fy)/2.0;
+ }
+ return 1.0;
+}
+
+bool
+Box::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_BOX_LINE: Outline.width = value; return true;
+ case SIZE_BOX: size = value; return true;
+ case SIZE_XPOS: pos1.fx = value; return true;
+ case SIZE_XPOS+1: pos2.fx = value; return true;
+ case SIZE_YPOS: pos1.fy = value; return true;
+ case SIZE_YPOS+1: pos2.fy = value; return true;
+ }
+ return false;
+}
+
+bool
+Box::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_BOX_LINE:
+ Outline.color = col;
+ return true;
+ }
+ return false;
+}
+
+void
+Box::DoPlot(anyOutput *o)
+{
+ double si, csi, tmp, fix1, fiy1, fix2, fiy2, fsize, dx, dy;
+
+ if(!parent || !o || size <= 0.001) return;
+ o->SetLine(&Outline);
+ o->SetFill(&Fill);
+ //calculate coordinates
+ fix1 = o->fx2fix(pos1.fx); fix2 = o->fx2fix(pos2.fx);
+ fiy1 = o->fy2fiy(pos1.fy); fiy2 = o->fy2fiy(pos2.fy);
+ //calculate sine and cosine
+ si = fiy1-fiy2;
+ tmp = fix2 - fix1;
+ si = si/sqrt(si*si + tmp*tmp);
+ csi = fix2-fix1;
+ tmp = fiy2 - fiy1;
+ csi = csi/sqrt(csi*csi + tmp*tmp);
+ if(type & BAR_WIDTHDATA) { //use e.g. for density distribution
+ dx = si * size; dy = csi * size;
+ pts[0].x = o->fx2ix(pos1.fx + dx); pts[1].x = o->fx2ix(pos2.fx + dx);
+ pts[2].x = o->fx2ix(pos2.fx - dx); pts[3].x = o->fx2ix(pos1.fx - dx);
+ pts[0].y = o->fy2iy(pos1.fy + dy); pts[1].y = o->fy2iy(pos2.fy + dy);
+ pts[2].y = o->fy2iy(pos2.fy - dy); pts[3].y = o->fy2iy(pos1.fy - dy);
+ }
+ else if(type & BAR_RELWIDTH) {
+ if(!parent || (pos1.fy == pos2.fy && pos1.fx == pos2.fx)) return;
+ fsize = parent->GetSize(pos1.fy == pos2.fy ? SIZE_BOXMINY : SIZE_BOXMINX);
+ fsize = fsize * size /200.0;
+ dx = si * fsize; dy = csi * fsize;
+ pts[0].x = o->fx2ix(pos1.fx + dx); pts[1].x = o->fx2ix(pos2.fx + dx);
+ pts[2].x = o->fx2ix(pos2.fx - dx); pts[3].x = o->fx2ix(pos1.fx - dx);
+ pts[0].y = o->fy2iy(pos1.fy + dy); pts[1].y = o->fy2iy(pos2.fy + dy);
+ pts[2].y = o->fy2iy(pos2.fy - dy); pts[3].y = o->fy2iy(pos1.fy - dy);
+ }
+ else {
+ dx = o->un2fix(si*size/2.0); dy = o->un2fiy(csi*size/2.0);
+ pts[0].x = iround(fix1 + dx); pts[1].x = iround(fix2 + dx);
+ pts[2].x = iround(fix2 - dx); pts[3].x = iround(fix1 - dx);
+ pts[0].y = iround(fiy1 + dy); pts[1].y = iround(fiy2 + dy);
+ pts[2].y = iround(fiy2 - dy); pts[3].y = iround(fiy1 - dy);
+ }
+ pts[4].x = pts[0].x; pts[4].y = pts[0].y; //close polygon
+ if(pts[0].x == pts[1].x){
+ o->oRectangle(pts[3].x, pts[3].y, pts[1].x, pts[1].y, name);
+ }
+ else {
+ o->oPolygon(pts, 5);
+ }
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[2].x, pts[2].y);
+ UpdateMinMaxRect(&rDims, pts[1].x, pts[1].y);
+ UpdateMinMaxRect(&rDims, pts[3].x, pts[3].y);
+}
+
+void
+Box::DoMark(anyOutput *o, bool mark)
+{
+ InvertPolygon(pts, 5, &Outline, &Fill, &rDims, o, mark);
+}
+
+bool
+Box::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ POINT p;
+
+ switch (cmd) {
+ case CMD_SCALE:
+ Outline.width *= ((scaleINFO*)tmpl)->sy.fy;
+ Hatchline.width *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ if(!(type & BAR_RELWIDTH) && parent->Id!= GO_DENSDISP)size *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_FLUSH:
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name)free(name); name = 0L;
+ return true;
+ case CMD_LEGEND:
+ if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
+ ((Legend*)tmpl)->HasFill(&Outline, &Fill, name);
+ break;
+ case CMD_MRK_DIRTY: case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ 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(CurrGO = this, MRK_GODRAW);
+ return true;
+ }
+ else {
+ p.x = mev->x; p.y = mev->y;
+ if(IsInPolygon(&p, pts, 5)) {
+ o->ShowMark(CurrGO = this, MRK_GODRAW);
+ return true;
+ }
+ }
+ }
+ break;
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_BOX;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >3 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &pos1.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &pos1.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &pos2.fx);
+ data->GetValue(ssRef[3].y, ssRef[3].x, &pos2.fy);
+ return true;
+ }
+ return false;
+ case CMD_BOX_TYPE:
+ if(tmpl)type = *((int*)tmpl);
+ return true;
+ case CMD_BOX_FILL:
+ if(tmpl) {
+ memcpy(&Fill, tmpl, sizeof(FillDEF));
+ if(Fill.hatch) memcpy(&Hatchline, Fill.hatch, sizeof(LineDEF));
+ Fill.hatch = &Hatchline;
+ return true;
+ }
+ break;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ if(type & BAR_WIDTHDATA) {
+ if(pos1.fy != pos2.fy) {
+ ((Plot*)parent)->CheckBounds(pos1.fx+size, pos1.fy);
+ ((Plot*)parent)->CheckBounds(pos2.fx-size, pos2.fy);
+ }
+ else {
+ ((Plot*)parent)->CheckBounds(pos1.fx, pos1.fy+size);
+ ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy-size);
+ }
+ }
+ 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;
+ }
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// whisker
+Whisker::Whisker(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which,
+ int xc1, int xr1, int yc1, int yr1, int xc2, int xr2,
+ int yc2, int yr2):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ memcpy(&pos1, &fp1, sizeof(lfPOINT));
+ memcpy(&pos2, &fp2, sizeof(lfPOINT));
+ type = which;
+ Id = GO_WHISKER;
+ if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || xc2 >= 0 || xr2 >= 0 ||
+ yc2 >= 0 || yr2 >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
+ ssRef[0].x = xc1; ssRef[0].y = xr1;
+ ssRef[1].x = yc1; ssRef[1].y = yr1;
+ ssRef[2].x = xc2; ssRef[2].y = xr2;
+ ssRef[3].x = yc2; ssRef[3].y = yr2;
+ cssRef = 4;
+ }
+ }
+ Command(CMD_AUTOSCALE, 0L, 0L);
+}
+
+Whisker::Whisker(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ 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
+Whisker::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_WHISKER:
+ size = value;
+ return true;
+ case SIZE_WHISKER_LINE:
+ LineDef.width = value;
+ return true;
+ }
+ return false;
+}
+
+bool
+Whisker::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_WHISKER:
+ LineDef.color = col;
+ return true;
+ }
+ return false;
+}
+
+void
+Whisker::DoPlot(anyOutput *o)
+{
+ double si, csi, tmp, fix1, fiy1, fix2, fiy2, dx, dy;
+ int i;
+
+ fix1 = o->fx2fix(pos1.fx); fix2 = o->fx2fix(pos2.fx);
+ fiy1 = o->fy2fiy(pos1.fy); fiy2 = o->fy2fiy(pos2.fy);
+ if(fix1 == fix2 && fiy1 == fiy2) return; //zero length
+ pts[2].x = iround(fix1); pts[3].x = iround(fix2);
+ pts[2].y = iround(fiy1); pts[3].y = iround(fiy2);
+ //calculate sine and cosine
+ si = fiy1-fiy2;
+ tmp = fix2 - fix1;
+ si = si/sqrt(si*si + tmp*tmp);
+ csi = fix2-fix1;
+ tmp = fiy2 - fiy1;
+ csi = csi/sqrt(csi*csi + tmp*tmp);
+ dx = o->un2fix(si*size/2.0);
+ dy = o->un2fiy(csi*size/2.0);
+ //calc cap
+ pts[0].x = iround(fix1 - dx); pts[4].x = iround(fix2 - dx);
+ pts[0].y = iround(fiy1 - dy); pts[4].y = iround(fiy2 - dy);
+ pts[1].x = iround(fix1 + dx); pts[5].x = iround(fix2 + dx);
+ pts[1].y = iround(fiy1 + dy); pts[5].y = iround(fiy2 + dy);
+ //draw whisker
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+ UpdateMinMaxRect(&rDims, pts[4].x, pts[4].y);
+ UpdateMinMaxRect(&rDims, pts[5].x, pts[5].y);
+ IncrementMinMaxRect(&rDims, 3+(o->un2ix(LineDef.width)<<1));
+ o->SetLine(&LineDef);
+ switch(type & 0x0f) {
+ case 2:
+ pts[4].x = pts[3].x; pts[4].y = pts[3].y;
+ pts[1].x = pts[2].x; pts[1].y = pts[2].y;
+ case 3:
+ if((type & 0x0f) == 3){
+ pts[5].x = pts[3].x; pts[5].y = pts[3].y;
+ pts[0].x = pts[2].x; pts[0].y = pts[2].y;
+ }
+ case 0:
+ for(i = 0; i < 5; i+=2) o->oSolidLine(pts+i);
+ break;
+ case 1:
+ pts[4].x = pts[5].x = pts[3].x; pts[4].y = pts[5].y = pts[3].y;
+ pts[1].x = pts[0].x = pts[2].x; pts[1].y = pts[0].y = pts[2].y;
+ o->oSolidLine(pts+2);
+ break;
+ }
+}
+
+void
+Whisker::DoMark(anyOutput *o, bool mark)
+{
+ 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
+Whisker::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ int cb;
+
+ switch (cmd) {
+ case CMD_SCALE:
+ size *= ((scaleINFO*)tmpl)->sy.fy;
+ LineDef.width *= ((scaleINFO*)tmpl)->sy.fy;
+ LineDef.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ if(IsCloseToLine(&pts[2], &pts[3], mev->x, mev->y) ||
+ IsCloseToLine(&pts[0], &pts[1], mev->x, mev->y) ||
+ IsCloseToLine(&pts[4], &pts[5], mev->x, mev->y)) {
+ o->ShowMark(this, MRK_GODRAW);
+ return true;
+ }
+ }
+ break;
+ }
+ return false;
+ case CMD_ERRDESC:
+ if(tmpl && *((char*)tmpl)) {
+ cb = (int)strlen((char*)tmpl)+2;
+ if(name = (char*)realloc(name, cb)) rlp_strcpy(name, cb, (char*)tmpl);
+ return true;
+ }
+ return false;
+ 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;
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >3 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &pos1.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &pos1.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &pos2.fx);
+ data->GetValue(ssRef[3].y, ssRef[3].x, &pos2.fy);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds(pos1.fx, pos1.fy);
+ ((Plot*)parent)->CheckBounds(pos2.fx, pos2.fy);
+ return true;
+ }
+ break;
+ case CMD_WHISKER_STYLE:
+ if(tmpl) type = *((int*)tmpl);
+ return true;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// drop line
+DropLine::DropLine(GraphObj *par, DataObj *d, double x, double y, int which, int xc,
+ int xr, int yc, int yr):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ fPos.fx = x;
+ fPos.fy = y;
+ type = which;
+ Id = GO_DROPLINE;
+ if(xc >= 0 && xr >= 0 && yc >= 0 && yr >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*2)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ cssRef = 2;
+ }
+ }
+ bModified = false;
+}
+
+DropLine::DropLine(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+DropLine::~DropLine()
+{
+ if(bModified) Undo.InvalidGO(this);
+ if(ssRef) free(ssRef); ssRef = 0L;
+}
+
+void
+DropLine::DoPlot(anyOutput *o)
+{
+ int tmp;
+
+ o->RLP.fp = 0.0f; //reset line pattern start
+ if(parent) {
+ pts[0].x = pts[1].x = pts[2].x = pts[3].x = o->fx2ix(fPos.fx);
+ pts[0].y = pts[1].y = pts[2].y = pts[3].y = o->fy2iy(fPos.fy);
+ if(type & DL_LEFT) {
+ tmp = o->fx2ix(parent->GetSize(SIZE_BOUNDS_LEFT));
+ if(tmp < pts[0].x) pts[0].x = tmp;
+ if(tmp > pts[1].x) pts[1].x = tmp;
+ }
+ if(type & DL_RIGHT) {
+ tmp = o->fx2ix(parent->GetSize(SIZE_BOUNDS_RIGHT));
+ if(tmp < pts[0].x) pts[0].x = tmp;
+ if(tmp > pts[1].x) pts[1].x = tmp;
+ }
+ if(type & DL_YAXIS) {
+ tmp = iround(parent->GetSize(SIZE_YAXISX));
+ if(tmp < pts[0].x) pts[0].x = tmp;
+ if(tmp > pts[1].x) pts[1].x = tmp;
+ }
+ if(type & DL_TOP) {
+ tmp = o->fy2iy(parent->GetSize(SIZE_BOUNDS_TOP));
+ if(tmp < pts[2].y) pts[2].y = tmp;
+ if(tmp > pts[3].y) pts[3].y = tmp;
+ }
+ if(type & DL_BOTTOM) {
+ tmp = o->fy2iy(parent->GetSize(SIZE_BOUNDS_BOTTOM));
+ if(tmp < pts[2].y) pts[2].y = tmp;
+ if(tmp > pts[3].y) pts[3].y = tmp;
+ }
+ if(type & DL_XAXIS) {
+ tmp = iround(parent->GetSize(SIZE_XAXISY));
+ if(tmp < pts[2].y) pts[2].y = tmp;
+ if(tmp > pts[3].y) pts[3].y = tmp;
+ }
+ SetMinMaxRect(&rDims, pts[0].x, pts[2].y, pts[1].x, pts[3].y);
+ IncrementMinMaxRect(&rDims, 3);
+ o->SetLine(&LineDef);
+ o->oPolyline(pts, 2);
+ o->oPolyline(pts+2, 2);
+ }
+}
+
+void
+DropLine::DoMark(anyOutput *o, bool mark)
+{
+
+ InvertLine(pts, 2, &LineDef, 0L, o, mark);
+ InvertLine(pts+2, 2, &LineDef, &rDims, o, mark);
+}
+
+bool
+DropLine::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+
+ switch (cmd) {
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ if(IsCloseToLine(&pts[0], &pts[1], mev->x, mev->y) ||
+ IsCloseToLine(&pts[2], &pts[3], mev->x, mev->y)) {
+ o->ShowMark(this, MRK_GODRAW);
+ return true;
+ }
+ }
+ break;
+ }
+ return false;
+ case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_DL_LINE:
+ if(tmpl) memcpy(&LineDef, tmpl, sizeof(LineDEF));
+ return true;
+ case CMD_DL_TYPE:
+ if(tmpl)type = *((int*)tmpl);
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = GO_DROPLINE;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >1 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// define a spherical scanline used for clipping spheres
+sph_scanline::sph_scanline(POINT3D *center, int radius, bool bVert):GraphObj(0, 0)
+{
+ Id = GO_SPHSCANL;
+ rad = radius >= 0 ? radius : -radius;
+ memcpy(&p1, center, sizeof(POINT3D)); memcpy(&p2, center, sizeof(POINT3D));
+ memcpy(¢, center, sizeof(POINT3D));
+ if(vert = bVert) {
+ p1.y -= rad; p2.y += rad;
+ }
+ else {
+ p1.x -= rad; p2.x += rad;
+ }
+ if(p1.x < 1) p1.x = 1; if(p1.y < 1) p1.y = 1;
+ if(p2.x < p1.x) p2.x = p1.x; if(p2.y < p1.y) p2.y = p1.y;
+ bValid1 = bValid2 = true;
+}
+
+bool
+sph_scanline::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ switch(cmd) {
+ case CMD_ADDTOLINE:
+ if(bValid1 && tmpl){
+ memcpy(&p2, tmpl, sizeof(POINT3D));
+ bValid2 = true;
+ return true;
+ }
+ break;
+ case CMD_STARTLINE:
+ if(!bValid1 && tmpl){
+ memcpy(&p1, tmpl, sizeof(POINT3D));
+ bValid1 = true;
+ }
+ break;
+ return true;
+ }
+ return false;
+}
+
+void
+sph_scanline::DoClip(GraphObj *co)
+{
+ POINT3D *pla;
+ int np, i;
+
+ if(!bValid1 || !bValid2) return;
+ switch(co->Id){
+ case GO_SPHERE:
+ bValid1 = bValid2 = false;
+ clip_sphline_sphere(this, &p1, &p2, ¢, rad, iround(co->GetSize(SIZE_RADIUS1)),
+ iround(co->GetSize(SIZE_XPOS)), iround(co->GetSize(SIZE_YPOS)),
+ iround(co->GetSize(SIZE_ZPOS)));
+ break;
+ case GO_PLANE:
+ for(i=0; ((plane*)co)->GetPolygon(&pla, &np, i); i++) {
+ bValid1 = bValid2 = false;
+ clip_sphline_plane(this, &p1, &p2, ¢, rad, pla, np, ((plane*)co)->GetVec());
+ }
+ break;
+ }
+}
+
+bool
+sph_scanline::GetPoint(POINT *p, int sel)
+{
+ if(!bValid1 || !bValid2) {
+ p->x = p->y = 0;
+ return false;
+ }
+ switch(sel) {
+ case 1:
+ p->x = p1.x; p->y = p1.y;
+ return true;
+ case 2:
+ p->x = p2.x; p->y = p2.y;
+ return true;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Sphere: a symbol in three dimensional space
+Sphere::Sphere(GraphObj *par, DataObj *d, int sel, double x, double y, double z,
+ double r, int xc, int xr, int yc, int yr, int zc, int zr, int rc, int rr)
+ :GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ Id = GO_SPHERE;
+ fPos.fx = x; fPos.fy = y; fPos.fz = z; size = r;
+ if(xc >=0 || xr >=0 || yc >=0 || yr >=0 || zc >=0 || zr >=0 || rc >=0 || rr >=0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*4)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ ssRef[2].x = zc; ssRef[2].y = zr;
+ ssRef[3].x = rc; ssRef[3].y = rr;
+ cssRef = 4;
+ }
+ }
+ type = sel;
+ bModified = false;
+}
+
+Sphere::Sphere(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+Sphere::~Sphere()
+{
+ if(bModified) Undo.InvalidGO(this);
+ Command(CMD_FLUSH, 0L, 0L);
+}
+
+double
+Sphere::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_MIN_X: return fip.fx - (double)rx;
+ case SIZE_MAX_X: return fip.fx + (double)rx;
+ case SIZE_MIN_Y: return fip.fy - (double)ry;
+ case SIZE_MAX_Y: return fip.fy + (double)ry;
+ case SIZE_MIN_Z: return fip.fz - (double)rx;
+ case SIZE_MAX_Z: return fip.fz + (double)rx;
+ case SIZE_XPOS: return fip.fx;
+ case SIZE_YPOS: return fip.fy;
+ case SIZE_ZPOS: return fip.fz;
+ case SIZE_RADIUS1: case SIZE_RADIUS2: return (double)rx;
+ case SIZE_XCENT: return fPos.fx;
+ case SIZE_YCENT: return fPos.fy;
+ case SIZE_ZCENT: return fPos.fz;
+ case SIZE_DRADIUS: return size;
+ case SIZE_SYMBOL:
+ if(!type) return size;
+ else return DefSize(SIZE_SYMBOL);
+ case SIZE_SYM_LINE: return Line.width;
+ }
+ return 0.0;
+}
+
+bool
+Sphere::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_SYMBOL: size = value; break;
+ case SIZE_SYM_LINE: Line.width = value; break;
+ }
+ return true;
+}
+
+DWORD
+Sphere::GetColor(int select)
+{
+ switch(select) {
+ case COL_SYM_LINE: return Line.color;
+ case COL_SYM_FILL: return Fill.color;
+ default: return defs.Color(select);
+ }
+}
+
+bool
+Sphere::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_SYM_LINE: Line.color = col; break;
+ case COL_SYM_FILL: Fill.color = col; break;
+ }
+ return true;
+}
+
+void
+Sphere::DoPlot(anyOutput *o)
+{
+ int i;
+
+ if(size <= 0.001 || !o) return;
+ if(!o->fvec2ivec(&fPos, &fip)) return;
+ bDrawDone = false;
+ if(scl){
+ for(i = 0; i < nscl; i++) if(scl[i]) delete(scl[i]);
+ free(scl);
+ scl = 0L; nscl = 0;
+ }
+ ix = iround(fip.fx); iy = iround(fip.fy);
+ switch (type) {
+ case 1:
+ rx = ry = iround(size * 0.5 * o->ddx); break;
+ case 2:
+ rx = ry = iround(size * 0.5 * o->ddy); break;
+ case 3:
+ rx = ry = iround(size * 0.5 * o->ddz); break;
+ default:
+ type = 0;
+ case 5:
+ rx = o->un2ix(size/2.0); ry = o->un2iy(size/2.0);
+ break;
+ }
+ rDims.left = ix - rx; rDims.right = ix + rx;
+ rDims.top = iy - ry; rDims.bottom = iy + ry;
+ if(o->VPscale > 1.5 && (
+ (rDims.right < defs.clipRC.left) || (rDims.left > defs.clipRC.right) ||
+ (rDims.bottom < defs.clipRC.top) || (rDims.top > defs.clipRC.bottom))){
+ bDrawDone = true; return;
+ }
+ if(parent && parent->Command(CMD_SET_GO3D, this, o)) return;
+ Command(CMD_REDRAW, 0L, o);
+}
+
+bool
+Sphere::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ int i;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
+ if(scl){
+ for(i = 0; i < nscl; i++) if(scl[i]) delete(scl[i]);
+ free(scl);
+ scl = 0L; nscl = 0;
+ }
+ return true;
+ case CMD_SCALE:
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ if(!type || type == 5)size *= ((scaleINFO*)tmpl)->sy.fy;;
+ return true;
+ case CMD_LEGEND:
+ if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
+ ((Legend*)tmpl)->HasFill(&Line, &Fill, 0L);
+ break;
+ case CMD_SYM_FILL:
+ if(tmpl) memcpy(&Fill, tmpl, sizeof(FillDEF));
+ return true;
+ case CMD_MRK_DIRTY:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_SET_DATAOBJ:
+ Id = GO_SPHERE;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_REDRAW:
+ //Note: this command is issued either by Undo (no output given) or
+ // by Plot3D::DoPlot after sorting all objects (output specified)
+ if(!parent) return false;
+ if(!o) return parent->Command(cmd, tmpl, o);
+ if(bDrawDone) return false;
+ bDrawDone = true;
+ if(scl) DrawPG(o, 0);
+ else {
+ o->SetLine(&Line); o->SetFill(&Fill);
+ if(Fill.type & FILL_LIGHT3D) o->oSphere(ix, iy, rx, 0L, 0, 0L);
+ else o->oCircle(ix-rx, iy-ry, ix+rx+1, iy+ry+1, name);
+ }
+ rx--;ry--; //smaller marking rectangle
+ rDims.left = ix-rx-1; rDims.right = ix+rx+1;
+ rDims.top = iy-ry-1; rDims.bottom = iy+ry+1;
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ o->ShowMark(&rDims, MRK_INVERT);
+ CurrGO = this;
+ return true;
+ }
+ break;
+ }
+ break;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >1 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &fPos.fz);
+ if(cssRef >3) data->GetValue(ssRef[3].y, ssRef[3].x, &size);
+ return true;
+ }
+ return false;
+ case CMD_CLIP:
+ if(co = (GraphObj*)tmpl){
+ switch(co->Id) {
+ case GO_PLANE:
+ case GO_SPHERE:
+ DoClip(co);
+ break;
+ }
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds3D(fPos.fx, fPos.fy, fPos.fz);
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+void
+Sphere::DoClip(GraphObj *co)
+{
+ RECT cliprc;
+ double d, d1;
+ POINT3D cscl;
+ int x, y, q, di, de, lim, cx, cy;
+ int i;
+
+ if(co && co->Id == GO_SPHERE) {
+ if(co->GetSize(SIZE_ZPOS) > fip.fz) return;
+ d1 = (d = co->GetSize(SIZE_XPOS) - fip.fx) * d;
+ d1 += (d = co->GetSize(SIZE_YPOS) - fip.fy) * d;
+ d1 = sqrt(d1 + (d = co->GetSize(SIZE_ZPOS) - fip.fz) * d);
+ if(d1 >= (co->GetSize(SIZE_RADIUS1) + rx))return;
+ }
+ else {
+ cliprc.left = iround(co->GetSize(SIZE_MIN_X));
+ cliprc.right = iround(co->GetSize(SIZE_MAX_X));
+ cliprc.top = iround(co->GetSize(SIZE_MIN_Y));
+ cliprc.bottom = iround(co->GetSize(SIZE_MAX_Y));
+ if(!OverlapRect(&rDims, &cliprc))return;
+ }
+ //use a list of horizontal scanlines created by a circular Bresenham's algorithm
+ //Ref: C. Montani, R. Scopigno (1990) "Speres-To-Voxel Conversion", in:
+ // Graphic Gems (A.S. Glassner ed.) Academic Press, Inc.;
+ // ISBN 0-12-288165-5
+ if(!scl && (scl = (sph_scanline**)calloc(rx*7+2, sizeof(sph_scanline*)))) {
+ cscl.z = iround(fip.fz); nscl = 0;
+ for(q = 0; q < 2; q++) {
+ x = lim = 0; y = rx; di = 2*(1-rx);
+ while( y >= lim) {
+ if(di < 0) {
+ de = 2*di + 2*y -1;
+ if(de > 0) {
+ x++; y--; di += (2*x -2*y +2);
+ }
+ else {
+ x++; di += (2*x +1);
+ }
+ }
+ else {
+ de = 2*di -2*x -1;
+ if(de > 0) {
+ y--; di += (-2*y +1);
+ }
+ else {
+ x++; y--; di += (2*x -2*y +2);
+ }
+ }
+ switch(q) {
+ case 0:
+ cy = rx - y; cx = x;
+ break;
+ case 1:
+ cy = rx + x; cx = y;
+ break;
+ }
+ cscl.y = iround(fip.fy); cscl.x = iround(fip.fx);
+ cscl.y = cscl.y - rx + cy;
+ if(cx > 1) scl[nscl++] = new sph_scanline(&cscl, cx, false);
+ }
+ }
+ }
+ if(!scl) return;
+ //do clip for every scanline
+ for(i = 0; i < nscl; i++) if(scl[i]) scl[i]->DoClip(co);
+}
+
+void
+Sphere::DrawPG(anyOutput *o, int start)
+{
+ POINT *pts, np;
+ long cp = 0;
+ int i = start, step = 1;
+
+ if(!o || !scl ||!nscl) return;
+ if((pts = (POINT*)calloc(nscl*2, sizeof(POINT)))) {
+ do {
+ if(scl[i]) {
+ if(step > 0) scl[i]->GetPoint(&np, 1);
+ else scl[i]->GetPoint(&np, 2);
+ if(np.x && np.y){
+ AddToPolygon(&cp, pts, &np);
+ }
+ else if(cp){
+ if(step > 0) DrawPG(o, i); //split sphere
+ step = -1;
+ }
+ }
+ if(i == nscl && step > 0) step = -1;
+ else i += step;
+ }while(i > start);
+ }
+ o->SetLine(&Line); o->SetFill(&Fill);
+ if(cp) o->oSphere(ix, iy, rx, pts, cp, name);
+ free(pts);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// plane: utility object to draw a flat plane in 3D space
+plane::plane(GraphObj *par, DataObj *d, fPOINT3D *pts, int nPts, LineDEF *line,
+ FillDEF *fill):GraphObj(par, d)
+{
+ int i;
+ long area;
+ double vlength, v1[3], v2[3], vp[3], area1;
+ bool v_valid = false;
+
+ nli = n_ipts = n_lines = 0;
+ nldata = 0L; ldata = 0L; co = 0L; lines = 0L; PlaneVec = 0L;
+ Id = GO_PLANE; totalArea = 0;
+ memcpy(&Line, line, sizeof(LineDEF));
+ memcpy(&Fill, fill, sizeof(FillDEF));
+ rDims.left = rDims.right = rDims.top = rDims.bottom = 0;
+ if(nPts > 2 && (ldata =(POINT3D**)calloc(1, sizeof(POINT3D*))) &&
+ (ldata[0] = (POINT3D *)calloc(nPts+1, sizeof(POINT3D))) &&
+ (nldata = (int*)calloc(1, sizeof(int))) &&
+ (ipts = (POINT*)calloc(nPts, sizeof(POINT)))){
+ for(i = 0; i < nPts; i++) {
+ ipts[i].x = ldata[0][i].x = iround(pts[i].fx);
+ ipts[i].y = ldata[0][i].y = iround(pts[i].fy);
+ ldata[0][i].z = iround(pts[i].fz);
+ }
+ nldata[0] = nPts; nli = 1; n_ipts = nPts;
+ xBounds.fx = xBounds.fy = pts[0].fx; yBounds.fx = yBounds.fy = pts[0].fy;
+ zBounds.fx = zBounds.fy = pts[0].fz;
+ rDims.left = rDims.right = ipts[0].x; rDims.top = rDims.bottom = ipts[0].y;
+ for(i = 1; i < nPts; i++){
+ UpdateMinMaxRect(&rDims, ipts[i].x, ipts[i].y);
+ if(pts[i].fx < xBounds.fx) xBounds.fx = pts[i].fx;
+ if(pts[i].fx > xBounds.fy) xBounds.fy = pts[i].fx;
+ if(pts[i].fy < yBounds.fx) yBounds.fx = pts[i].fy;
+ if(pts[i].fy > yBounds.fy) yBounds.fy = pts[i].fy;
+ if(pts[i].fz < zBounds.fx) zBounds.fx = pts[i].fz;
+ if(pts[i].fz > zBounds.fy) zBounds.fy = pts[i].fz;
+ }
+ //test if plane vertical
+ area1 = (xBounds.fx - xBounds.fy) * (yBounds.fx - yBounds.fy);
+ for(area = 0, i = 1; i < nPts; i++) {
+ area += (ipts[i].x - ipts[i-1].x) * ((ipts[i].y + ipts[i-1].y)>>1);
+ }
+ totalArea= area = abs(area);
+ area1 = area ? fabs(area1/area) : 101.0;
+ if(area < 100 && area1 > 100.0) { //its small or vertical !
+ if(lines=(line_segment**)calloc(nPts, sizeof(line_segment*))){
+ for(i = 1; i < nPts; i++) {
+ lines[i-1] = new line_segment(par, d, line, &ldata[0][i-1], &ldata[0][i]);
+ }
+ n_lines = nPts-1;
+ }
+ }
+ else { //for a visible plane get vector perpendicular to plane
+ for (i = 1; i < (nPts-1); i++) {
+ v1[0] = pts[i].fx - pts[i-1].fx; v1[1] = pts[i].fy - pts[i-1].fy;
+ v1[2] = pts[i].fz - pts[i-1].fz; v2[0] = pts[i+1].fx - pts[i].fx;
+ v2[1] = pts[i+1].fy - pts[i].fy; v2[2] = pts[i+1].fz - pts[i].fz;
+ vp[0] = v1[1]*v2[2] - v1[2]*v2[1]; vp[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ vp[2] = v1[0]*v2[1] - v1[1]*v2[0];
+ vlength = sqrt(vp[0]*vp[0]+vp[1]*vp[1]+vp[2]*vp[2]);
+ if(v_valid = (vlength > 100.0)) break;
+ }
+ if(v_valid && (PlaneVec = (double*)malloc(4 * sizeof(double)))) {
+ PlaneVec[0] = vp[0]/vlength; PlaneVec[1] = vp[1]/vlength;
+ PlaneVec[2] = -vp[2]/vlength;
+ PlaneVec[3] = PlaneVec[0] * pts[i].fx + PlaneVec[1] * pts[i].fy - PlaneVec[2] * pts[i].fz;
+ }
+ }
+ }
+}
+
+plane::~plane()
+{
+ int i;
+
+ if(ldata) {
+ for(i = 0; i < nli; i++) if(ldata[i]) free(ldata[i]);
+ free(ldata); ldata = 0L; nli = 0;
+ }
+ if(lines) {
+ for(i = 0; i < n_lines; i++) if(lines[i]) delete(lines[i]);
+ free(lines); lines = 0L; n_lines = 0;
+ }
+ if(nldata) free(nldata); nldata = 0L;
+ if(ipts) free(ipts); ipts = 0L;
+ if(PlaneVec) free(PlaneVec); PlaneVec = 0L;
+}
+
+double
+plane::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_MIN_X: return xBounds.fx;
+ case SIZE_MAX_X: return xBounds.fy;
+ case SIZE_MIN_Y: return yBounds.fx;
+ case SIZE_MAX_Y: return yBounds.fy;
+ case SIZE_MIN_Z: return zBounds.fx;
+ case SIZE_MAX_Z: return zBounds.fy;
+ }
+ return 0.0;
+}
+
+void
+plane::DoPlot(anyOutput *o)
+{
+ int i;
+
+ bDrawDone = bReqPoint = false;
+ if(Fill.type & FILL_LIGHT3D){
+ Fill.color = o->VecColor(PlaneVec, Fill.color2, Fill.color);
+ Fill.type &= ~FILL_LIGHT3D;
+ }
+ if(o->VPscale > 1.5 && (
+ //ignore objects outside the display ara
+ (rDims.right < defs.clipRC.left) || (rDims.left > defs.clipRC.right) ||
+ (rDims.bottom < defs.clipRC.top) || (rDims.top > defs.clipRC.bottom))){
+ bDrawDone = true; return;
+ }
+ if(lines) {
+ if(Line.width == 0.0) return;
+ //draw line segments for vertical plane
+ for(i = 0; i < n_lines; i++) if(lines[i]) lines[i]->DoPlot(o);
+ bDrawDone = true; return;
+ }
+ if(parent && parent->Command(CMD_SET_GO3D, this, o)) return;
+ Command(CMD_REDRAW, 0L, o);
+}
+
+void
+plane::DoMark(anyOutput *o, bool mark)
+{
+ FillDEF tmpfill;
+ LineDEF tmpline;
+
+ memcpy(&tmpfill, &Fill, sizeof(FillDEF));
+ memcpy(&tmpline, &Line, sizeof(LineDEF));
+ if(mark){
+ tmpfill.color ^= 0x00ffffffL; tmpline.color ^= 0x00ffffffL;
+ }
+ o->SetLine(&tmpline); o->SetFill(&tmpfill);
+ o->oPolygon(ipts, n_ipts);
+}
+
+bool
+plane::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ POINT *pt;
+ POINT3D *ap;
+ int i, j;
+
+ switch (cmd) {
+ case CMD_MOUSE_EVENT:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_REDRAW:
+ if(bDrawDone) return false;
+ bDrawDone = true;
+ if(o && nldata){
+ if(Line.width == 0.0) Line.color = Fill.color;
+ o->SetLine(&Line); o->SetFill(&Fill);
+ for(i = 0; i < nli; i++){
+ if(nldata[i] > 2 && (pt = (POINT*)malloc(nldata[i]*sizeof(POINT)))){
+ for(j = 0; j < nldata[i]; j++) {
+ pt[j].x = ldata[i][j].x; pt[j].y = ldata[i][j].y;
+ }
+ o->oPolygon(pt, nldata[i]);
+ free(pt);
+ }
+ }
+ }
+ return true;
+ case CMD_STARTLINE:
+ if(ap = (POINT3D*)tmpl) {
+ if(ldata && nldata && nli) {
+ if(bReqPoint) {
+ Command(CMD_ADDTOLINE, &ReqPoint, o);
+ bReqPoint = false;
+ }
+ i = nli-1; j = nldata[i]-1;
+ if(ldata[i][j].x == ap->x && ldata[i][j].y == ap->y && ldata[i][j].z == ap->z){
+ return true;
+ }
+ if(IsValidPG(ldata[i], nldata[i])) {
+ //close previous polygon first
+ if(ldata[i][0].x != ldata[i][j].x || ldata[i][0].y != ldata[i][j].y ||
+ ldata[i][0].z != ldata[i][j].z){
+ j++;
+ ldata[i][j].x = ldata[i][0].x; ldata[i][j].y = ldata[i][0].y;
+ ldata[i][j].z = ldata[i][0].z; nldata[i]++;
+ }
+ ldata = (POINT3D**)realloc(ldata, sizeof(POINT3D*) * (nli+1));
+ ldata[nli] = (POINT3D*)malloc(sizeof(POINT3D)*2);
+ nldata = (int*)realloc(nldata, sizeof(int) * (nli+1));
+ }
+ else { //drop incomplete or invalid polygon
+ nli--;
+ }
+ }
+ else {
+ ldata = (POINT3D**)calloc(1, sizeof(POINT3D*));
+ ldata[nli = 0] = (POINT3D*)malloc(sizeof(POINT3D));
+ nldata = (int*)calloc(1, sizeof(int));
+ bReqPoint = false;
+ }
+ if(ldata && nldata) {
+ ldata[nli][0].x = ap->x; ldata[nli][0].y = ap->y;
+ ldata[nli][0].z = ap->z; nldata[nli++] = 1;
+ return true;
+ }
+ }
+ break;
+ case CMD_REQ_POINT:
+ if(ap = (POINT3D*)tmpl) {
+ ReqPoint.x = ap->x; ReqPoint.y = ap->y; ReqPoint.z = ap->z;
+ bReqPoint = true;
+ }
+ return true;
+ case CMD_ADDTOLINE:
+ if((ap = (POINT3D*)tmpl) && ldata && nldata && nli) {
+ i= nli-1; j=nldata[i]-1;
+ if((ldata[i][j].x == ap->x && ldata[i][j].y == ap->y) ||
+ (ldata[i][j].y == ap->y && ldata[i][j].z == ap->z)){
+ //probably nothing to add
+ ldata[i][j].x = ap->x; ldata[i][j].y = ap->y;
+ return j>0 ? true : false;
+ }
+ ldata[i] = (POINT3D*)realloc(ldata[i], ((j=nldata[i])+2) * sizeof(POINT3D));
+ ldata[i][j].x = ap->x; ldata[i][j].y = ap->y;
+ ldata[i][j].z = ap->z; nldata[i]++;
+ return true;
+ }
+ case CMD_CLIP:
+ if(co = (GraphObj*)tmpl){
+ switch(co->Id) {
+ case GO_PLANE:
+ //Clip only planes which are drawn later
+ if(GetSize(SIZE_MIN_Z) < co->GetSize(SIZE_MIN_Z)) return false;
+ if(nli){
+ DoClip(co);
+ if(nli && ldata) {
+ i = nli-1; j = nldata[i]-1;
+ //is last part valid ?
+ if(j < 2) {
+ free(ldata[i]); ldata[i] = 0L;
+ nldata[i] = 0;
+ nli--;
+ }
+ //close last polygon
+ else if(ldata[i][0].x != ldata[i][j].x ||
+ ldata[i][0].y != ldata[i][j].y ||
+ ldata[i][0].z != ldata[i][j].z){
+ j++;
+ ldata[i][j].x = ldata[i][0].x;
+ ldata[i][j].y = ldata[i][0].y;
+ ldata[i][j].z = ldata[i][0].z;
+ nldata[i]++;
+ }
+ }
+ }
+ else xBounds.fx=xBounds.fy=yBounds.fx=yBounds.fy=zBounds.fx=zBounds.fy=0.0;
+ break;
+ }
+ }
+ break;
+ }
+ return false;
+}
+
+void *
+plane::ObjThere(int x, int y)
+{
+ POINT p1;
+
+ if(bDrawDone && IsInRect(&rDims, p1.x = x, p1.y = y) &&
+ (IsInPolygon(&p1, ipts, n_ipts) || IsCloseToPL(p1, ipts, n_ipts))) return this;
+ return 0L;
+}
+
+bool
+plane::GetPolygon(POINT3D **pla, int *npt, int n)
+{
+ if(n < nli && ldata && ldata[n]) {
+ *pla = ldata[n]; *npt = nldata[n];
+ return true;
+ }
+ return false;
+}
+
+void
+plane::DoClip(GraphObj *co)
+{
+ RECT cliprc;
+ int o_nli, *o_nldata = 0L;
+ POINT3D **o_ldata = 0L;
+ POINT3D *tpg;
+ int i, j, tnpt;
+ bool is_valid = false;
+
+ //if two planes have the same parent it means they are part of one object
+ // do not clip!
+ if(co->parent == parent && co->Id == GO_PLANE) return;
+ if(co->Id == GO_PLANE && (parent->parent->Id == GO_GRID3D || parent->parent->Id == GO_RIBBON)
+ && co->parent->parent == parent->parent) return;
+ cliprc.left = iround(co->GetSize(SIZE_MIN_X));
+ cliprc.right = iround(co->GetSize(SIZE_MAX_X));
+ cliprc.top = iround(co->GetSize(SIZE_MIN_Y));
+ cliprc.bottom = iround(co->GetSize(SIZE_MAX_Y));
+ if(OverlapRect(&rDims, &cliprc) && co != this) {
+ o_nli = nli; nli = 0;
+ o_nldata = nldata; nldata = 0L;
+ o_ldata = ldata; ldata = 0L;
+ switch(co->Id) {
+ case GO_PLANE:
+ //clip all parts of this plane with all from another plane
+ for(i = 0; ((plane*)co)->GetPolygon(&tpg, &tnpt, i); i++){
+ for(j = 0; j < o_nli; j++) {
+ if(o_nldata[j] >2) clip_plane_plane(this, o_ldata[j], o_nldata[j], PlaneVec,
+ tpg, tnpt, ((plane*)co)->GetVec(), ipts, n_ipts );
+ }
+ if(bReqPoint){
+ Command(CMD_ADDTOLINE, &ReqPoint, 0L);
+ bReqPoint = false;
+ }
+ if(nli) is_valid = true;
+ if(o_ldata) {
+ for(j = 0; j < o_nli; j++) if(o_ldata[j]) free(o_ldata[j]);
+ free(o_ldata);
+ }
+ if(o_nldata) free(o_nldata);
+ o_nli = nli; nli = 0;
+ o_nldata = nldata; nldata = 0L;
+ o_ldata = ldata; ldata = 0L;
+ if(!o_nli) { //plane is completly hidden
+ return;
+ }
+ }
+ if(is_valid || i==0){
+ nli = o_nli; o_nli = 0;
+ nldata = o_nldata; o_nldata = 0L;
+ ldata = o_ldata; o_ldata = 0L;
+ }
+ if(nli > 1) for(i = 1; i < nli; i++) {
+ if(nldata[i] > 3 && ldata[i][nldata[i]-1].x == ldata[i-1][0].x
+ && ldata[i][nldata[i]-1].y == ldata[i-1][0].y) {
+ nldata[i]--; //bad vis: ignore last point
+ }
+ }
+ break;
+ default:
+ nli = o_nli; o_nli = 0;
+ nldata = o_nldata; o_nldata = 0L;
+ ldata = o_ldata; o_ldata = 0L;
+ break;
+ }
+ //check shape and recalc some values
+ if(is_valid && nli) {
+ xBounds.fx = xBounds.fy = ldata[0][0].x; yBounds.fx = yBounds.fy = ldata[0][0].y;
+ zBounds.fx = zBounds.fy = ldata[0][0].z;
+ rDims.left = rDims.right = ldata[0][0].x; rDims.top = rDims.bottom = ldata[0][0].y;
+ for(i = 0; i < nli; i++) if(nldata[i] > 2){
+ if(ldata[i][0].x != ldata[i][nldata[i]-1].x || ldata[i][0].y != ldata[i][nldata[i]-1].y
+ || ldata[i][0].z != ldata[i][nldata[i]-1].z) {
+ ldata[i][nldata[i]].x = ldata[i][0].x; ldata[i][nldata[i]].y = ldata[i][0].y;
+ ldata[i][nldata[i]].z = ldata[i][0].z; nldata[i]++;
+ }
+ for(j = 0; j < (nldata[i]-1); j++) {
+ UpdateMinMaxRect(&rDims, ldata[i][j].x, ldata[i][j].y);
+ if(ldata[i][j].x < xBounds.fx) xBounds.fx = ldata[i][j].x;
+ if(ldata[i][j].x > xBounds.fy) xBounds.fy = ldata[i][j].x;
+ if(ldata[i][j].y < yBounds.fx) yBounds.fx = ldata[i][j].y;
+ if(ldata[i][j].y > yBounds.fy) yBounds.fy = ldata[i][j].y;
+ if(ldata[i][j].z < zBounds.fx) zBounds.fx = ldata[i][j].z;
+ if(ldata[i][j].z > zBounds.fy) zBounds.fy = ldata[i][j].z;
+ }
+ }
+ }
+ }
+ if(o_ldata) {
+ for(i = 0; i < o_nli; i++) if(o_ldata[i]) free(o_ldata[i]);
+ free(o_ldata);
+ }
+ if(o_nldata) free(o_nldata);
+}
+
+bool
+plane::IsValidPG(POINT3D *pg, int npg)
+{
+ int i;
+ long area;
+
+ //a polygon must have more than 3 Points
+ if(npg < 3) return false;
+ //check for a reasonable size
+ for(area = 0, i = 1; i < npg; i++) {
+ area += (pg[i].x - pg[i-1].x) * ((pg[i].y + pg[i-1].y)>>1);
+ }
+ area += (pg[0].x - pg[i-1].x) * ((pg[0].y + pg[i-1].y)>>1);
+ area = abs(area);
+ if(area < 20) return false;
+ if(totalArea/area > 100) return false;
+ return true;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// a simple plane in three dimensional space
+Plane3D::Plane3D(GraphObj *par, DataObj *da, fPOINT3D *pt, long npt)
+ :GraphObj(par, da)
+{
+ FileIO(INIT_VARS);
+ Id = GO_PLANE3D;
+ dt = (fPOINT3D*) memdup(pt, sizeof(fPOINT3D)*npt, 0L);
+ ndt = npt;
+}
+
+Plane3D::Plane3D(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+Plane3D::~Plane3D()
+{
+ if(dt) free(dt); if(pts) free(pts);
+ dt = 0L; ndt = 0L;
+ if(ipl) delete (ipl); ipl = 0L;
+}
+
+bool
+Plane3D::SetSize(int select, double value)
+{
+ int i;
+
+ if((select & 0xfff) >= SIZE_XPOS && (select & 0xfff) <= SIZE_XPOS_LAST){
+ if((i = select-SIZE_XPOS) >=0 && i <= 200 && i < (int)ndt){
+ dt[i].fx = value; return true;
+ }
+ }
+ else if((select & 0xfff) >= SIZE_YPOS && (select & 0xfff) <= SIZE_YPOS_LAST){
+ if((i = select-SIZE_YPOS) >=0 && i <= 200 && i < (int)ndt){
+ dt[i].fy = value; return true;
+ }
+ }
+ else if((select & 0xfff) >= SIZE_ZPOS && (select & 0xfff) <= SIZE_ZPOS_LAST){
+ if((i = select-SIZE_ZPOS) >=0 && i <= 200 && i < (int)ndt){
+ dt[i].fz = value; return true;
+ }
+ }
+ else switch(select) {
+ case SIZE_SYM_LINE:
+ Line.width = value;
+ }
+ return false;
+}
+
+bool
+Plane3D::SetColor(int select, DWORD col)
+{
+ switch(select) {
+ case COL_POLYLINE: Line.color = col; return true;
+ case COL_POLYGON: Fill.color = col; return true;
+ }
+ return false;
+}
+
+void
+Plane3D::DoPlot(anyOutput *o)
+{
+ int i;
+
+ if(ipl) delete ipl; ipl = 0L;
+ if(pts) free(pts); pts = 0L;
+ o->ActualSize(&rDims);
+ rDims.left = rDims.right; rDims.top = rDims.bottom;
+ rDims.right = rDims.bottom = 0;
+ if((pts = (fPOINT3D*)malloc(sizeof(fPOINT3D)*ndt))){
+ for(i = 0; i < ndt; i++) {
+ if(!o->fvec2ivec(&dt[i], &pts[i])){
+ free(pts); pts = 0L; return;
+ }
+ UpdateMinMaxRect(&rDims, iround(pts[i].fx), iround(pts[i].fy));
+ }
+ if(ipl = new plane(this, data, pts, i, &Line, &Fill))ipl->DoPlot(o);
+ }
+ IncrementMinMaxRect(&rDims, o->un2ix(Line.width)+1);
+}
+
+void
+Plane3D::DoMark(anyOutput *o, bool mark)
+{
+ if(mark){
+ if(pts && ipl)ipl->DoMark(o, mark);
+ o->UpdateRect(&rDims, false);
+ }
+ else if(parent) parent->Command(CMD_REDRAW, 0L, o);
+}
+
+bool
+Plane3D::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ int i;
+ MouseEvent *mev;
+
+ switch (cmd) {
+ case CMD_SET_DATAOBJ:
+ Id = GO_PLANE3D;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_SCALE:
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_LEGEND:
+ if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
+ ((Legend*)tmpl)->HasFill(&Line, &Fill, 0L);
+ break;
+ case CMD_MRK_DIRTY:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_SYM_FILL:
+ if(tmpl) memcpy(&Fill, tmpl, sizeof(FillDEF));
+ return true;
+ case CMD_REDRAW:
+ //Note: this command is issued either by Undo (no output given) or
+ // by Plot3D::DoPlot after sorting all objects (output specified)
+ if(!parent) return false;
+ if(!o) return parent->Command(cmd, tmpl, o);
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ if(ipl && ipl->ObjThere(mev->x, mev->y)){
+ o->ShowMark(CurrGO=this, MRK_GODRAW);
+ return true;
+ }
+ }
+ break;
+ }
+ break;
+ case CMD_PG_FILL:
+ if(tmpl) {
+ memcpy((void*)&Fill, tmpl, sizeof(FillDEF));
+ Fill.hatch = 0L;
+ }
+ break;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH && dt) {
+ for(i = 0; i < ndt; i++)
+ ((Plot*)parent)->CheckBounds3D(dt[i].fx, dt[i].fy, dt[i].fz);
+ return true;
+ }
+ break;
+ case CMD_SET_GO3D:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Brick: a bar in three dimensional space
+Brick::Brick(GraphObj *par, DataObj *da, double x, double y, double z,
+ double d, double w, double h, DWORD flg, int xc, int xr, int yc,
+ int yr, int zc, int zr, int dc, int dr, int wc, int wr, int hc,
+ int hr):GraphObj(par, da)
+{
+ FileIO(INIT_VARS);
+ Id = GO_BRICK;
+ fPos.fx = x; fPos.fy = y; fPos.fz = z;
+ depth = d; width = w; height = h;
+ flags = flg;
+ if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || zc >= 0 || zr >= 0 ||
+ dc >= 0 || dr >= 0 || wc >= 0 || wr >= 0 || hc >= 0 || hr >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*6)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ ssRef[2].x = zc; ssRef[2].y = zr;
+ ssRef[3].x = dc; ssRef[3].y = dr;
+ ssRef[4].x = wc; ssRef[4].y = wr;
+ ssRef[5].x = hc; ssRef[5].y = hr;
+ cssRef = 6;
+ }
+ }
+ bModified = false;
+}
+
+Brick::Brick(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+Brick::~Brick()
+{
+ int i;
+
+ if(faces) {
+ for(i = 0; i < 6; i++) if(faces[i]) delete(faces[i]);
+ free(faces);
+ }
+ faces = 0L;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ Command(CMD_FLUSH, 0L, 0L);
+ if(bModified) Undo.InvalidGO(this);
+}
+
+bool
+Brick::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_BAR_LINE: Line.width = value; return true;
+ case SIZE_BAR_BASE: fPos.fy = value; return true;
+ case SIZE_BAR: width = value; return true;
+ case SIZE_BAR_DEPTH: depth = value; return true;
+ }
+ return false;
+}
+
+bool
+Brick::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_BAR_LINE: Line.color = col; return true;
+ case COL_BAR_FILL: Fill.color = col; return true;
+ }
+ return false;
+}
+
+void
+Brick::DoPlot(anyOutput *o)
+{
+ fPOINT3D cpt[8], fip1, fip2, tmp, itmp, *pg;
+ plane *npl;
+ double dtmp;
+ int i;
+
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(!faces || !o || !o->fvec2ivec(&fPos, &fip1)) return;
+ if(!(pg = (fPOINT3D *)malloc(5*sizeof(fPOINT3D)))) return;
+ for(i = 0; i < 6; i++) {
+ if(faces[i]) delete(faces[i]);
+ faces[i] = 0L;
+ }
+ if(flags & 0x800L) { //height is data
+ tmp.fx = fPos.fx; tmp.fy = height;
+ tmp.fz = fPos.fz; o->fvec2ivec(&tmp, &fip2);
+ }
+ else { //height is units
+ tmp.fx = tmp.fz = 0.0; tmp.fy = height;
+ o->uvec2ivec(&tmp, &fip2);
+ fip2.fx += fip1.fx; fip2.fy += fip1.fy;
+ fip2.fz += fip1.fz;
+ }
+ //calc output-device coordinates of cubic brick: 8 corners
+ tmp.fx = -(width/2.0); tmp.fz = (depth/2.0); tmp.fy = 0.0;
+ o->uvec2ivec(&tmp, &itmp);
+ cpt[0].fx= fip1.fx+itmp.fx; cpt[0].fy= fip1.fy+itmp.fy; cpt[0].fz= fip1.fz+itmp.fz;
+ cpt[2].fx= fip1.fx-itmp.fx; cpt[2].fy= fip1.fy-itmp.fy; cpt[2].fz= fip1.fz-itmp.fz;
+ cpt[4].fx= fip2.fx+itmp.fx; cpt[4].fy= fip2.fy+itmp.fy; cpt[4].fz= fip2.fz+itmp.fz;
+ cpt[6].fx= fip2.fx-itmp.fx; cpt[6].fy= fip2.fy-itmp.fy; cpt[6].fz= fip2.fz-itmp.fz;
+ tmp.fx = (width/2.0); tmp.fz = (depth/2.0); tmp.fy = 0.0;
+ o->uvec2ivec(&tmp, &itmp);
+ cpt[1].fx= fip1.fx+itmp.fx; cpt[1].fy= fip1.fy+itmp.fy; cpt[1].fz= fip1.fz+itmp.fz;
+ cpt[3].fx= fip1.fx-itmp.fx; cpt[3].fy= fip1.fy-itmp.fy; cpt[3].fz= fip1.fz-itmp.fz;
+ cpt[5].fx= fip2.fx+itmp.fx; cpt[5].fy= fip2.fy+itmp.fy; cpt[5].fz= fip2.fz+itmp.fz;
+ cpt[7].fx= fip2.fx-itmp.fx; cpt[7].fy= fip2.fy-itmp.fy; cpt[7].fz= fip2.fz-itmp.fz;
+ //set up 6 faces
+ pg[0].fx = pg[4].fx = cpt[0].fx; pg[1].fx = cpt[1].fx;
+ pg[2].fx = cpt[2].fx; pg[3].fx = cpt[3].fx;
+ pg[0].fy = pg[4].fy = cpt[0].fy; pg[1].fy = cpt[1].fy;
+ pg[2].fy = cpt[2].fy; pg[3].fy = cpt[3].fy;
+ pg[0].fz = pg[4].fz = cpt[0].fz; pg[1].fz = cpt[1].fz;
+ pg[2].fz = cpt[2].fz; pg[3].fz = cpt[3].fz;
+ faces[0] = new plane(this, data, pg, 5, &Line, &Fill);
+ pg[2].fx = cpt[5].fx; pg[3].fx = cpt[4].fx;
+ pg[2].fy = cpt[5].fy; pg[3].fy = cpt[4].fy;
+ pg[2].fz = cpt[5].fz; pg[3].fz = cpt[4].fz;
+ npl = new plane(this, data, pg, 5, &Line, &Fill);
+ if(npl->GetSize(SIZE_MAX_Z) > faces[0]->GetSize(SIZE_MAX_Z)) faces[1] = npl;
+ else {
+ faces[1] = faces[0]; faces[0] = npl;
+ }
+ pg[0].fx = pg[4].fx = cpt[2].fx; pg[1].fx = cpt[6].fx;
+ pg[2].fx = cpt[5].fx; pg[3].fx = cpt[1].fx;
+ pg[0].fy = pg[4].fy = cpt[2].fy; pg[1].fy = cpt[6].fy;
+ pg[2].fy = cpt[5].fy; pg[3].fy = cpt[1].fy;
+ pg[0].fz = pg[4].fz = cpt[2].fz; pg[1].fz = cpt[6].fz;
+ pg[2].fz = cpt[5].fz; pg[3].fz = cpt[1].fz;
+ npl = new plane(this, data, pg, 5, &Line, &Fill);
+ if((dtmp = npl->GetSize(SIZE_MAX_Z)) > faces[1]->GetSize(SIZE_MAX_Z)) faces[2] = npl;
+ else {
+ faces[2] = faces[1];
+ if(dtmp > faces[0]->GetSize(SIZE_MAX_Z)) faces[1] = npl;
+ else {
+ faces[1] = faces[0]; faces[0] = npl;
+ }
+ }
+ pg[2].fx = cpt[7].fx; pg[3].fx = cpt[3].fx;
+ pg[2].fy = cpt[7].fy; pg[3].fy = cpt[3].fy;
+ pg[2].fz = cpt[7].fz; pg[3].fz = cpt[3].fz;
+ npl = new plane(this, data, pg, 5, &Line, &Fill);
+ dtmp = npl->GetSize(SIZE_MAX_Z);
+ for (i = 3; i; i--) {
+ if(dtmp >faces[i-1]->GetSize(SIZE_MAX_Z)) {
+ faces[i] = npl; break;
+ }
+ else faces[i] = faces[i-1];
+ }
+ if(!i) faces[0] = npl;
+ pg[0].fx = pg[4].fx = cpt[4].fx; pg[1].fx = cpt[7].fx;
+ pg[2].fx = cpt[3].fx; pg[3].fx = cpt[0].fx;
+ pg[0].fy = pg[4].fy = cpt[4].fy; pg[1].fy = cpt[7].fy;
+ pg[2].fy = cpt[3].fy; pg[3].fy = cpt[0].fy;
+ pg[0].fz = pg[4].fz = cpt[4].fz; pg[1].fz = cpt[7].fz;
+ pg[2].fz = cpt[3].fz; pg[3].fz = cpt[0].fz;
+ npl = new plane(this, data, pg, 5, &Line, &Fill);
+ dtmp = npl->GetSize(SIZE_MAX_Z);
+ for (i = 4; i; i--) {
+ if(dtmp >faces[i-1]->GetSize(SIZE_MAX_Z)) {
+ faces[i] = npl; break;
+ }
+ else faces[i] = faces[i-1];
+ }
+ if(!i) faces[0] = npl;
+ pg[2].fx = cpt[6].fx; pg[3].fx = cpt[5].fx;
+ pg[2].fy = cpt[6].fy; pg[3].fy = cpt[5].fy;
+ pg[2].fz = cpt[6].fz; pg[3].fz = cpt[5].fz;
+ npl = new plane(this, data, pg, 5, &Line, &Fill);
+ dtmp = npl->GetSize(SIZE_MAX_Z);
+ for (i = 5; i; i--) {
+ if(dtmp >faces[i-1]->GetSize(SIZE_MAX_Z)) {
+ faces[i] = npl; break;
+ }
+ else faces[i] = faces[i-1];
+ }
+ if(!i) faces[0] = npl;
+ rDims.left = rDims.right = (int)pg[0].fx;
+ rDims.top = rDims.bottom = (int)pg[0].fy;
+ for (i= 3; i < 6; i++) if(faces[i]) {
+ faces[i]->DoPlot(o);
+ UpdateMinMaxRect(&rDims, faces[i]->rDims.left, faces[i]->rDims.top);
+ UpdateMinMaxRect(&rDims, faces[i]->rDims.right, faces[i]->rDims.bottom);
+ }
+ free(pg);
+}
+
+void
+Brick::DoMark(anyOutput *o, bool mark)
+{
+ int i;
+
+ if(mark){
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ IncrementMinMaxRect(&mrc, 6 + o->un2ix(Line.width));
+ mo = GetRectBitmap(&mrc, o);
+ if(faces) for(i = 3; i < 6; i++)
+ if(faces[i]) faces[i]->DoMark(o, mark);
+ o->UpdateRect(&rDims, false);
+ }
+ else if(mo) RestoreRectBitmap(&mo, &mrc, o);
+}
+
+bool
+Brick::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
+ return true;
+ case CMD_SCALE:
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy; depth *= ((scaleINFO*)tmpl)->sz.fy;
+ width *= ((scaleINFO*)tmpl)->sx.fy; if(!(flags & 0x800L)) height *= ((scaleINFO*)tmpl)->sx.fy;
+ return true;
+ case CMD_LEGEND:
+ if(!tmpl || ((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
+ ((Legend*)tmpl)->HasFill(&Line, &Fill, 0L);
+ break;
+ case CMD_BAR_FILL:
+ if(tmpl) {
+ memcpy(&Fill, tmpl, sizeof(FillDEF));
+ Fill.hatch = 0L;
+ return true;
+ }
+ break;
+ case CMD_MRK_DIRTY:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_SET_DATAOBJ:
+ Id = GO_BRICK;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_REDRAW:
+ //Note: this command is issued either by Undo (no output given) or
+ // by Plot3D::DoPlot after sorting all objects (output specified)
+ if(!parent) return false;
+ if(!o) return parent->Command(cmd, tmpl, o);
+ //Should we ever come here ?
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ if(faces && faces[3] && faces[4] && faces[5] &&
+ (faces[3]->ObjThere(mev->x, mev->y) ||
+ faces[4]->ObjThere(mev->x, mev->y) ||
+ faces[5]->ObjThere(mev->x, mev->y))){
+ o->ShowMark(CurrGO=this, MRK_GODRAW);
+ return true;
+ }
+ }
+ break;
+ }
+ break;
+ case CMD_UPDATE:
+ if(ssRef && cssRef > 5 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &fPos.fz);
+ data->GetValue(ssRef[3].y, ssRef[3].x, &depth);
+ data->GetValue(ssRef[4].y, ssRef[4].x, &width);
+ data->GetValue(ssRef[5].y, ssRef[5].x, &height);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds3D(fPos.fx, fPos.fy, fPos.fz);
+ if(flags & 0x800L) { //height is data
+ ((Plot*)parent)->CheckBounds3D(fPos.fx, height, fPos.fz);
+ }
+ return true;
+ }
+ break;
+ case CMD_SET_GO3D:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// line_segment: utility object to draw a piece of a polyline in 3D space
+line_segment::line_segment(GraphObj *par, DataObj *d, LineDEF *ld, POINT3D *p1, POINT3D *p2)
+ :GraphObj(par, d)
+{
+ double tmp, tmp1, tmp2;
+
+ nli = 0; nldata = 0L; ldata = 0L; prop = 1.0; df_go = 0L;
+ fmin.fx = fmax.fx = fmin.fy = fmax.fy = fmin.fz = fmax.fz = 0.0;
+ ndf_go = 0;
+ if(ld) memcpy(&Line, ld, sizeof(LineDEF));
+ if(p1 && p2 &&(ldata =(POINT3D**)calloc(1, sizeof(POINT3D*))) &&
+ (ldata[0] = (POINT3D*)malloc(2 * sizeof(POINT3D))) &&
+ (nldata = (int*)calloc(1, sizeof(int)))){
+ if(Line.pattern) {
+ tmp1 = (tmp = (p2->x - p1->x)) * tmp;
+ tmp2 = (tmp1 += (tmp = (p2->y - p1->y)) * tmp);
+ tmp1 += (tmp = (p2->z - p1->z)) * tmp;
+ if(tmp1 > 1.0) prop = sqrt(tmp2)/sqrt(tmp1);
+ }
+ memcpy(&ldata[0][0], p1, sizeof(POINT3D));
+ memcpy(&ldata[0][1], p2, sizeof(POINT3D));
+ nldata[0] = 2; nli = 1;
+ rDims.left = rDims.right = p1->x; rDims.top = rDims.bottom = p1->y;
+ UpdateMinMaxRect(&rDims, p2->x, p2->y);
+ fmin.fx = (double)rDims.left; fmin.fy = (double)rDims.top;
+ fmax.fx = (double)rDims.right; fmax.fy = (double)rDims.bottom;
+ if(p2->z > p1->z) {
+ fmin.fz = (double)p1->z; fmax.fz = (double)p2->z;
+ }
+ else {
+ fmin.fz = (double)p2->z; fmax.fz = (double)p1->z;
+ }
+ }
+ Id = GO_LINESEG;
+}
+
+line_segment::~line_segment()
+{
+ int i;
+
+ if(ldata) {
+ for(i = 0; i < nli; i++) if(ldata[i]) free(ldata[i]);
+ free(ldata);
+ }
+ if(nldata) free(nldata); nldata = 0L;
+}
+
+double
+line_segment::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_MIN_Z:
+ return fmin.fz;
+ case SIZE_MAX_Z:
+ return fmax.fz;
+ }
+ return 0.0;
+}
+
+void
+line_segment::DoPlot(anyOutput *o)
+{
+ bDrawDone = false; co = 0L;
+ if(df_go) free(df_go);
+ df_go = 0L; ndf_go = 0;
+ if(o->VPscale > 1.5 && (
+ (rDims.right < defs.clipRC.left) || (rDims.left > defs.clipRC.right) ||
+ (rDims.bottom < defs.clipRC.top) || (rDims.top > defs.clipRC.bottom))){
+ bDrawDone = true; return;
+ }
+ if(parent && parent->Command(CMD_SET_GO3D, this, o)) return;
+ Command(CMD_REDRAW, 0L, o);
+}
+
+bool
+line_segment::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ int i, j;
+ POINT pts[2];
+ LineDEF cLine;
+ POINT3D *ap;
+
+ switch (cmd) {
+ case CMD_MOUSE_EVENT:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_DRAW_LATER:
+ if(!co) return false;
+ if(df_go){
+ for(i = 0; i < ndf_go; i++) if(df_go[i] == co) return true;
+ if(df_go = (GraphObj**)realloc(df_go, (ndf_go +1) * sizeof(GraphObj*))) {
+ df_go[ndf_go++] = co;
+ }
+ }
+ else {
+ if(df_go = (GraphObj**)malloc(sizeof(GraphObj*))){
+ df_go[0] = co; ndf_go = 1;
+ }
+ }
+ return true;
+ case CMD_REDRAW:
+ if(bDrawDone) return false;
+ bDrawDone = true;
+ if(!nli) return false;
+ if(df_go) {
+ for(i = 0; i < ndf_go; i++) if(df_go[i]) df_go[i]->Command(cmd, tmpl, o);
+ free(df_go); df_go = 0L; ndf_go = 0L;
+ }
+ if(o && ldata && nldata){
+ memcpy(&cLine, &Line, sizeof(LineDEF));
+ cLine.patlength *= prop;
+ o->SetLine(&cLine);
+ for(i = 0; i < nli; i++) for(j = 0; j < (nldata[i]-1); j++) {
+ pts[0].x = ldata[i][j].x; pts[0].y = ldata[i][j].y;
+ pts[1].x = ldata[i][j+1].x; pts[1].y = ldata[i][j+1].y;
+ if(pts[0].x != pts[1].x || pts[0].y != pts[1].y) o->oPolyline(pts, 2);
+ }
+ }
+ return true;
+ case CMD_CLIP:
+ if(co = (GraphObj*)tmpl){
+ switch(co->Id) {
+ case GO_PLANE:
+ case GO_SPHERE:
+ DoClip(co);
+ break;
+ }
+ }
+ return false;
+ case CMD_STARTLINE:
+ if(tmpl) {
+ if(ldata && nldata) {
+ ldata = (POINT3D**)realloc(ldata, sizeof(POINT3D*) * (nli+1));
+ ldata[nli] = (POINT3D*)malloc(2 * sizeof(POINT3D));
+ nldata = (int*)realloc(nldata, sizeof(int)*(nli+1));
+ }
+ else {
+ ldata = (POINT3D**)calloc(1, sizeof(POINT3D*));
+ ldata[nli = 0] = (POINT3D*)malloc(2 * sizeof(POINT3D));
+ nldata = (int*)calloc(1, sizeof(int));
+ }
+ if(ldata && nldata) {
+ memcpy(&ldata[nli][0], tmpl, sizeof(POINT3D));
+ memcpy(&ldata[nli][1], tmpl, sizeof(POINT3D));
+ nldata[nli++] = 1;
+ return true;
+ }
+ }
+ break;
+ case CMD_ADDTOLINE:
+ if((ap = (POINT3D*)tmpl) && ldata && nldata && nli && nldata[i =(nli-1)]) {
+ j = nldata[i];
+ ldata[i] = (POINT3D*)realloc(ldata[i], (nldata[i]+2) * sizeof(POINT3D));
+ if(j && ldata[i][j-1].x == ap->x && ldata[i][j-1].y == ap->y &&
+ ldata[i][j-1].z == ap->z) return true;
+ else {
+ j = (nldata[i]++);
+ }
+ memcpy(&ldata[i][j-1], tmpl, sizeof(POINT3D));
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+void *
+line_segment::ObjThere(int x, int y)
+{
+ int i, j;
+ POINT pts[2];
+
+ if(ldata && nldata){
+ for(i = 0; i < nli; i++) for(j = 0; j < nldata[i]; j +=2) {
+ pts[0].x = ldata[i][j].x; pts[0].y = ldata[i][j].y;
+ pts[1].x = ldata[i][j+1].x; pts[1].y = ldata[i][j+1].y;
+ if(IsCloseToLine(&pts[0], &pts[1], x, y))return this;
+ }
+ }
+ return 0L;
+}
+
+void
+line_segment::DoClip(GraphObj *co)
+{
+ RECT cliprc;
+ int o_nli, *o_nldata = 0L;
+ POINT3D **o_ldata = 0L, *pts = 0L, *pla;
+ int i, j, k, np, r, cx, cy, cz;
+ bool is_valid = false;
+
+ cliprc.left = iround(co->GetSize(SIZE_MIN_X));
+ cliprc.right = iround(co->GetSize(SIZE_MAX_X));
+ cliprc.top = iround(co->GetSize(SIZE_MIN_Y));
+ cliprc.bottom = iround(co->GetSize(SIZE_MAX_Y));
+ if(OverlapRect(&rDims, &cliprc)) {
+ if(!(pts = (POINT3D*)calloc(2, sizeof(POINT3D))))return;
+ o_nli = nli; nli = 0;
+ o_nldata = nldata; nldata = 0L;
+ o_ldata = ldata; ldata = 0L;
+ switch(co->Id) {
+ case GO_SPHERE:
+ cx = iround(co->GetSize(SIZE_XPOS));
+ cy = iround(co->GetSize(SIZE_YPOS));
+ cz = iround(co->GetSize(SIZE_ZPOS));
+ r = iround(co->GetSize(SIZE_RADIUS1));
+ for(i = 0; i < o_nli; i++) for(j = 0; j < (o_nldata[i]-1); j ++) {
+ pts[0].x = o_ldata[i][j].x; pts[0].y = o_ldata[i][j].y;
+ pts[0].z = o_ldata[i][j].z; pts[1].x = o_ldata[i][j+1].x;
+ pts[1].y = o_ldata[i][j+1].y; pts[1].z = o_ldata[i][j+1].z;
+ clip_line_sphere(this, &pts, r, cx, cy, cz);
+ }
+ break;
+ case GO_PLANE:
+ for(i = 0; ((plane*)co)->GetPolygon(&pla, &np, i); i++){
+ for(j = 0; j < o_nli; j++) {
+ if(o_nldata[j] >1) for(k = 0; k < (o_nldata[j]-1); k++){
+ pts[0].x = o_ldata[j][k].x; pts[0].y = o_ldata[j][k].y;
+ pts[0].z = o_ldata[j][k].z; pts[1].x = o_ldata[j][k+1].x;
+ pts[1].y = o_ldata[j][k+1].y; pts[1].z = o_ldata[j][k+1].z;
+ if(pts[0].x != pts[1].x || pts[0].y != pts[1].y || pts[0].z != pts[1].z)
+ clip_line_plane(this, &pts, pla, np, ((plane*)co)->GetVec());
+ }
+ }
+ if(nli) is_valid = true;
+ if(o_ldata) {
+ for(j = 0; j < o_nli; j++) if(o_ldata[j]) free(o_ldata[j]);
+ free(o_ldata);
+ }
+ if(o_nldata) free(o_nldata);
+ o_nli = nli; nli = 0;
+ o_nldata = nldata; nldata = 0L;
+ o_ldata = ldata; ldata = 0L;
+ if(!o_nli) return; //line is completly hidden
+ }
+ if(is_valid || i==0){
+ nli = o_nli; o_nli = 0;
+ nldata = o_nldata; o_nldata = 0L;
+ ldata = o_ldata; o_ldata = 0L;
+ }
+ break;
+ default:
+ nli = o_nli; o_nli = 0;
+ nldata = o_nldata; o_nldata = 0L;
+ ldata = o_ldata; o_ldata = 0L;
+ break;
+ }
+ if(pts) free(pts);
+ }
+ if(o_ldata) {
+ for(i = 0; i < o_nli; i++) if(o_ldata[i]) free(o_ldata[i]);
+ free(o_ldata);
+ }
+ if(o_nldata) free(o_nldata);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// define a drop line in 3D space
+DropLine3D::DropLine3D(GraphObj *par, DataObj *d, fPOINT3D *p1, int xc,
+ int xr, int yc, int yr, int zc, int zr):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ Id = GO_DROPL3D;
+ memcpy(&fPos, p1, sizeof(fPOINT3D));
+ if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || zc >= 0 || zr >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ ssRef[2].x = zc; ssRef[2].y = zr;
+ cssRef = 3;
+ }
+ }
+ bModified = false;
+ type = 0x01;
+}
+
+DropLine3D::DropLine3D(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+DropLine3D::~DropLine3D()
+{
+ if(bModified) Undo.InvalidGO(this);
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ Command(CMD_FLUSH, 0L, 0L);
+}
+
+void
+DropLine3D::DoPlot(anyOutput *o)
+{
+ fPOINT3D fip, fp, fp1;
+ POINT3D p1, p2;
+ int i;
+
+ if(!parent || !o || !o->fvec2ivec(&fPos, &fip)) return;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ for(i = 0; i < 6; i++){
+ if(ls[i]) delete(ls[i]);
+ ls[i] = 0L;
+ }
+ p1.x = iround(fip.fx); p1.y = iround(fip.fy); p1.z = iround(fip.fz);
+ rDims.left = rDims.right = p1.x; rDims.top = rDims.bottom = p1.y;
+ for(i = 0; i < 6; i++) {
+ fp.fx = fPos.fx; fp.fy = fPos.fy; fp.fz = fPos.fz;
+ if(type & (1 << i)){
+ switch (i) {
+ case 0: fp.fy = parent->GetSize(SIZE_BOUNDS_YMIN); break;
+ case 1: fp.fy = parent->GetSize(SIZE_BOUNDS_YMAX); break;
+ case 2: fp.fz = parent->GetSize(SIZE_BOUNDS_ZMIN); break;
+ case 3: fp.fz = parent->GetSize(SIZE_BOUNDS_ZMAX); break;
+ case 4: fp.fx = parent->GetSize(SIZE_BOUNDS_XMIN); break;
+ case 5: fp.fx = parent->GetSize(SIZE_BOUNDS_XMAX); break;
+ }
+ o->fvec2ivec(&fp, &fp1); p2.x = iround(fp1.fx);
+ p2.y = iround(fp1.fy); p2.z = iround(fp1.fz);
+ UpdateMinMaxRect(&rDims, p2.x, p2.y);
+ if(ls[i] = new line_segment(this, data, &Line, &p1, &p2)) ls[i]->DoPlot(o);
+ mpts[i][0].x = p1.x; mpts[i][0].y = p1.y;
+ mpts[i][1].x = p2.x; mpts[i][1].y = p2.y;
+ }
+ }
+ IncrementMinMaxRect(&rDims, 5);
+}
+
+void
+DropLine3D::DoMark(anyOutput *o, bool mark)
+{
+ int i;
+
+ if(mark) {
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ IncrementMinMaxRect(&mrc, 6 + o->un2ix(Line.width));
+ mo = GetRectBitmap(&mrc, o);
+ for(i = 0; i < 6; i++) {
+ if(type & (1 << i)){
+ InvertLine(mpts[i], 2, &Line, 0L, o, mark);
+ }
+ }
+ o->UpdateRect(&mrc, false);
+ }
+ else RestoreRectBitmap(&mo, &mrc, o);
+}
+
+bool
+DropLine3D::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ int i;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ for(i = 0; i < 6; i++){
+ if(ls[i]) delete(ls[i]);
+ ls[i] = 0L;
+ }
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
+ return true;
+ case CMD_SCALE:
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_DL_TYPE:
+ if(tmpl && *((int*)tmpl)) type = *((int*)tmpl);
+ return true;
+ case CMD_DL_LINE:
+ if(tmpl) memcpy(&Line, tmpl, sizeof(LineDEF));
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = GO_DROPL3D;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_REDRAW:
+ //Note: this command is issued either by Undo (no output given) or
+ // by Plot3D::DoPlot after sorting all objects (output specified)
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ for(i = 0; i < 6; i++) {
+ if(ls[i] && ls[i]->ObjThere(mev->x, mev->y)){
+ o->ShowMark(this, MRK_GODRAW);
+ return true;
+ }
+ }
+ }
+ break;
+ }
+ break;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >2 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &fPos.fz);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds3D(fPos.fx, fPos.fy, fPos.fz);
+ return true;
+ }
+ break;
+ case CMD_SET_GO3D:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// define an arrow in 3D space
+Arrow3D::Arrow3D(GraphObj *par, DataObj *d, fPOINT3D *p1, fPOINT3D *p2, int xc1,
+ int xr1, int yc1, int yr1, int zc1, int zr1, int xc2, int xr2, int yc2,
+ int yr2, int zc2, int zr2):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ Id = GO_ARROW3D;
+ memcpy(&fPos1, p1, sizeof(fPOINT3D)); memcpy(&fPos2, p2, sizeof(fPOINT3D));
+ if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || zc1 >= 0 || zr1 >= 0 ||
+ xc2 >= 0 || xr2 >= 0 || yc2 >= 0 || yr2 >= 0 || zc2 >= 0 || zr2 >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*6)) {
+ ssRef[0].x = xc1; ssRef[0].y = xr1;
+ ssRef[1].x = yc1; ssRef[1].y = yr1;
+ ssRef[2].x = zc1; ssRef[2].y = zr1;
+ ssRef[3].x = xc2; ssRef[3].y = xr2;
+ ssRef[4].x = yc2; ssRef[4].y = yr2;
+ ssRef[5].x = zc2; ssRef[5].y = zr2;
+ cssRef = 6;
+ }
+ }
+ bModified = false;
+}
+
+Arrow3D::Arrow3D(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+Arrow3D::~Arrow3D()
+{
+ if(bModified) Undo.InvalidGO(this);
+ Command(CMD_FLUSH, 0L, 0L);
+}
+
+bool
+Arrow3D::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_ARROW_LINE:
+ Line.width = value;
+ return true;
+ case SIZE_ARROW_CAPWIDTH:
+ cw = value;
+ return true;
+ case SIZE_ARROW_CAPLENGTH:
+ cl = value;
+ return true;
+ }
+ return false;
+}
+
+bool
+Arrow3D::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_ARROW:
+ Line.color = col;
+ return true;
+ }
+ return false;
+}
+
+void
+Arrow3D::DoPlot(anyOutput *o)
+{
+ double si, csi, tmp, cwr, clr, d, d1, d2;
+ fPOINT3D fip1, fip2, tria[3];
+ POINT3D p1, p2, cp1, cp2;
+ FillDEF fill;
+ int i;
+
+ if(!parent || !o || !o->fvec2ivec(&fPos1, &fip1) ||!o->fvec2ivec(&fPos2, &fip2)) return;
+ for(i = 0; i < 3; i++){
+ if(ls[i]) delete(ls[i]);
+ ls[i] = 0L;
+ }
+ p1.x = iround(fip1.fx); p1.y = iround(fip1.fy); p1.z = iround(fip1.fz);
+ p2.x = iround(fip2.fx); p2.y = iround(fip2.fy); p2.z = iround(fip2.fz);
+ if(p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) return; //zero length arrow
+ rDims.left = rDims.right = p1.x; rDims.top = rDims.bottom = p1.y;
+ UpdateMinMaxRect(&rDims, p2.x, p2.y);
+ IncrementMinMaxRect(&rDims, 5);
+ if(ls[0] = new line_segment(this, data, &Line, &p1, &p2)) ls[0]->DoPlot(o);
+ mpts[0][0].x = p1.x; mpts[0][0].y = p1.y; mpts[0][1].x = p2.x; mpts[0][1].y = p2.y;
+ if(p1.x == p2.x && p1.y == p2.y) return; //zero length in 2D
+ if((type & 0xff) == ARROW_NOCAP) return; //no cap;
+ //calculate sine and cosine for cap
+ si = fip1.fy-fip2.fy;
+ tmp = fip2.fx - fip1.fx;
+ si = si/sqrt(si*si + tmp*tmp);
+ csi = fip2.fx-fip1.fx;
+ tmp = fip2.fy - fip1.fy;
+ csi = csi/sqrt(csi*csi + tmp*tmp);
+ //cap corners
+ d1 = (d = fip2.fx - fip1.fx) * d;
+ d1 += ((d = fip2.fy - fip1.fy) * d);
+ d2 = d1 + ((d = fip2.fz - fip1.fz) * d);
+ d1 = sqrt(d1); d2 = sqrt(d2); d = d1/d2;
+ cwr = cw; clr = cl*d;
+ cp1.x = p2.x - o->un2ix(csi*clr + si*cwr/2.0);
+ cp1.y = p2.y + o->un2iy(si*clr - csi*cwr/2.0);
+ cp2.x = p2.x - o->un2ix(csi*clr - si*cwr/2.0);
+ cp2.y = p2.y + o->un2iy(si*clr + csi*cwr/2.0);
+ cp1.z = cp2.z = p2.z;
+ mpts[1][0].x = p2.x; mpts[1][0].y = p2.y; mpts[1][1].x = cp1.x; mpts[1][1].y = cp1.y;
+ mpts[2][0].x = p2.x; mpts[2][0].y = p2.y; mpts[2][1].x = cp2.x; mpts[2][1].y = cp2.y;
+ if((type & 0xff) == ARROW_LINE) {
+ if(ls[1] = new line_segment(this, data, &Line, &p2, &cp1)) ls[1]->DoPlot(o);
+ if(ls[2] = new line_segment(this, data, &Line, &p2, &cp2)) ls[2]->DoPlot(o);
+ }
+ else if((type & 0xff) == ARROW_TRIANGLE) {
+ fill.type = FILL_NONE; fill.color = Line.color;
+ fill.scale = 1.0; fill.hatch = 0L;
+ tria[0].fz = tria[1].fz = tria[2].fz = fip2.fz;
+ tria[0].fx = cp1.x; tria[0].fy = cp1.y;
+ tria[1].fx = fip2.fx; tria[1].fy = fip2.fy;
+ tria[2].fx = cp2.x; tria[2].fy = cp2.y;
+ if(cap = new plane(this, data, tria, 3, &Line, &fill))cap->DoPlot(o);
+ }
+}
+
+void
+Arrow3D::DoMark(anyOutput *o, bool mark)
+{
+ int i;
+
+ if(mark) {
+ for(i = 0; i < 3; i++) {
+ if(ls[i]){
+ InvertLine(mpts[i], 2, &Line, 0L, o, mark);
+ }
+ }
+ }
+ else if(parent) parent->Command(CMD_REDRAW, 0L, o);
+}
+
+bool
+Arrow3D::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ int i;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ for(i = 0; i < 3; i++){
+ if(ls[i]) delete(ls[i]);
+ ls[i] = 0L;
+ }
+ if(cap) delete(cap); cap = 0L;
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(name) free(name); name = 0L;
+ return true;
+ case CMD_SCALE:
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ cw *= ((scaleINFO*)tmpl)->sy.fy; cl *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = GO_ARROW3D;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_MRK_DIRTY: //from Undo ?
+ case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !CurrGO) {
+ for(i = 0; i < 3; i++) {
+ if(ls[i] && ls[i]->ObjThere(mev->x, mev->y)){
+ o->ShowMark(this, MRK_GODRAW);
+ return true;
+ }
+ }
+ }
+ break;
+ }
+ break;
+ case CMD_ARROW_ORG3D:
+ if(tmpl) memcpy(&fPos1, tmpl, sizeof(fPOINT3D));
+ return true;
+ case CMD_ARROW_TYPE:
+ if(tmpl) type = *((int*)tmpl);
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >5 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos2.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos2.fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &fPos2.fz);
+ data->GetValue(ssRef[3].y, ssRef[3].x, &fPos1.fx);
+ data->GetValue(ssRef[4].y, ssRef[4].x, &fPos1.fy);
+ data->GetValue(ssRef[5].y, ssRef[5].x, &fPos1.fz);
+ return true;
+ }
+ return false;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH) {
+ ((Plot*)parent)->CheckBounds3D(fPos1.fx, fPos1.fy, fPos1.fz);
+ ((Plot*)parent)->CheckBounds3D(fPos2.fx, fPos2.fy, fPos2.fz);
+ return true;
+ }
+ break;
+ case CMD_SET_GO3D:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// a data line in 3D space
+Line3D::Line3D(GraphObj *par, DataObj *d, char *rx, char *ry, char *rz)
+ :GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ if(rx && rx[0]) x_range = (char*)memdup(rx, (int)strlen(rx)+2, 0L);
+ if(ry && ry[0]) y_range = (char*)memdup(ry, (int)strlen(ry)+2, 0L);
+ if(rz && rz[0]) z_range = (char*)memdup(rz, (int)strlen(rz)+2, 0L);
+ DoUpdate();
+ Id = GO_LINE3D;
+ bModified = false;
+}
+
+Line3D::Line3D(GraphObj *par, DataObj *d, fPOINT3D *pt, int n_pt, int xc1, int xr1, int yc1, int yr1,
+ int zc1, int zr1, int xc2, int xr2, int yc2, int yr2, int zc2, int zr2)
+ :GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ if(pt && n_pt) {
+ values = (fPOINT3D*)memdup(pt, n_pt * sizeof(fPOINT3D), 0L);
+ nPts = n_pt;
+ ls = (line_segment **)calloc(nPts-1, sizeof(line_segment*));
+ }
+ if(xc1 >= 0 || xr1 >= 0 || yc1 >= 0 || yr1 >= 0 || zc1 >= 0 || zr1 >= 0 ||
+ xc2 >= 0 || xr2 >= 0 || yc2 >= 0 || yr2 >= 0 || zc2 >= 0 || zr2 >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*6)) {
+ ssRef[0].x = xc1; ssRef[0].y = xr1;
+ ssRef[1].x = yc1; ssRef[1].y = yr1;
+ ssRef[2].x = zc1; ssRef[2].y = zr1;
+ ssRef[3].x = xc2; ssRef[3].y = xr2;
+ ssRef[4].x = yc2; ssRef[4].y = yr2;
+ ssRef[5].x = zc2; ssRef[5].y = zr2;
+ cssRef = 6;
+ }
+ }
+ Id = GO_LINE3D;
+ bModified = false;
+}
+
+Line3D::Line3D(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+Line3D::~Line3D()
+{
+ int i;
+
+ if(bModified) Undo.InvalidGO(this);
+ if(ls){
+ for(i = 0; i < (nPts-1); i++) if(ls[i]) delete(ls[i]);
+ free(ls);
+ }
+ if(pts && npts) free(pts); pts = 0L; npts = 0; cssRef = 0;
+ if(x_range) free(x_range); x_range = 0L;
+ if(y_range) free(y_range); y_range = 0L;
+ if(z_range) free(z_range); z_range = 0L;
+ if(values) free(values); values = 0L;
+ if(ssRef) free(ssRef); ssRef = 0L;
+ if(mo) DelBitmapClass(mo); mo = 0L;
+}
+
+void
+Line3D::DoPlot(anyOutput *o)
+{
+ int i, j;
+ fPOINT3D fip;
+ POINT3D p1, p2;
+ POINT np;
+
+
+ if(mo) DelBitmapClass(mo); mo = 0L;
+ if(ls) {
+ if(pts && npts) free(pts);
+ npts = 0; if(!(pts = (POINT*)calloc(nPts, sizeof(POINT))))return;
+ for(i = 0; i< nPts; i++) {
+ if(!o->fvec2ivec(&values[i], &fip)) return;
+ p2.x = iround(fip.fx); p2.y = iround(fip.fy); p2.z = iround(fip.fz);
+ np.x = p2.x; np.y = p2.y;
+ AddToPolygon(&npts, pts, &np);
+ if(i) {
+ UpdateMinMaxRect(&rDims, np.x, np.y);
+ j = i-1;
+ if(ls[j]) delete(ls[j]);
+ if(ls[j] = new line_segment(this, data, &Line, &p1, &p2)) {
+ ls[j]->DoPlot(o);
+ }
+ }
+ else {
+ rDims.left = rDims.right = p2.x;
+ rDims.top = rDims.bottom = p2.y;
+ }
+ p1.x = p2.x; p1.y = p2.y; p1.z = p2.z;
+ }
+ IncrementMinMaxRect(&rDims, 6);
+ }
+}
+
+void
+Line3D::DoMark(anyOutput *o, bool mark)
+{
+ if(mark) {
+ memcpy(&mrc, &rDims, sizeof(RECT));
+ IncrementMinMaxRect(&mrc, 6 + o->un2ix(Line.width));
+ mo = GetRectBitmap(&mrc, o);
+ InvertLine(pts, npts, &Line, &rDims, o, true);
+ }
+ else RestoreRectBitmap(&mo, &mrc, o);
+}
+
+bool
+Line3D::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ POINT p1;
+ int i;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ if(name) free(name); name = 0L;
+ return true;
+ case CMD_SCALE:
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_SET_LINE:
+ if(tmpl) {
+ memcpy(&Line, tmpl, sizeof(LineDEF));
+ return true;
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_LINE3D;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_REDRAW:
+ //Note: this command is issued by Undo (no output given)
+ if(!parent) return false;
+ if(!o) return parent->Command(cmd, tmpl, o);
+ //Should we ever come here ?
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(!IsInRect(&rDims, p1.x= mev->x, p1.y=mev->y)|| CurrGO || !o || nPts <2 ||
+ !IsCloseToPL(p1, pts, npts))return false;
+ o->ShowMark(CurrGO=this, MRK_GODRAW);
+ return true;
+ }
+ return false;
+ case CMD_UPDATE:
+ if(parent && parent->Id != GO_GRID3D) {
+ Undo.DataMem(this, (void**)&values, nPts * sizeof(fPOINT3D), &nPts, UNDO_CONTINUE);
+ }
+ if(ssRef && cssRef >5 && data && nPts == 2) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &values[0].fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &values[0].fy);
+ data->GetValue(ssRef[2].y, ssRef[2].x, &values[0].fz);
+ data->GetValue(ssRef[3].y, ssRef[3].x, &values[1].fx);
+ data->GetValue(ssRef[4].y, ssRef[4].x, &values[1].fy);
+ data->GetValue(ssRef[5].y, ssRef[5].x, &values[1].fz);
+ return true;
+ }
+ else DoUpdate();
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id > GO_PLOT && parent->Id < GO_GRAPH){
+ if(min.fx == max.fx || min.fy == max.fy){ //z's may be equal !
+ min.fx = min.fy = min.fz = HUGE_VAL;
+ max.fx = max.fy = max.fz = -HUGE_VAL;
+ for(i = 0; i < nPts; i++) {
+ if(values[i].fx < min.fx) min.fx = values[i].fx;
+ if(values[i].fy < min.fy) min.fy = values[i].fy;
+ if(values[i].fz < min.fz) min.fz = values[i].fz;
+ if(values[i].fx > max.fx) max.fx = values[i].fx;
+ if(values[i].fy > max.fy) max.fy = values[i].fy;
+ if(values[i].fz > max.fz) max.fz = values[i].fz;
+ }
+ }
+ ((Plot*)parent)->CheckBounds3D(min.fx, min.fy, min.fz);
+ ((Plot*)parent)->CheckBounds3D(max.fx, max.fy, max.fz);
+ return true;
+ }
+ return false;
+ case CMD_SET_GO3D:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ }
+ return false;
+}
+
+void
+Line3D::DoUpdate()
+{
+ int n1 = 0, ic = 0, i, j, k, l, m, n;
+ double x, y, z;
+ AccRange *rX=0L, *rY=0L, *rZ=0L;
+
+ if(!x_range || !y_range || !z_range) return;
+ if(values) free(values); values = 0L;
+ if(ls) free(ls); ls = 0L;
+ rX = new AccRange(x_range);
+ rY = new AccRange(y_range);
+ rZ = new AccRange(z_range);
+ min.fx = min.fy = min.fz = HUGE_VAL; max.fx = max.fy = max.fz = -HUGE_VAL;
+ if(rX) n1 = rX->CountItems();
+ if(n1 && rY && rZ && (values = (fPOINT3D*)malloc(n1 * sizeof(fPOINT3D)))){
+ 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)){
+ values[ic].fx = x; values[ic].fy = y; values[ic].fz = z;
+ if(x < min.fx) min.fx = x; if(x > max.fx) max.fx = x;
+ if(y < min.fy) min.fy = y; if(y > max.fy) max.fy = y;
+ if(z < min.fz) min.fz = z; if(z > max.fz) max.fz = z;
+ ic++;
+ }
+ }while(rX->GetNext(&i, &j) && rY->GetNext(&k, &l) && rZ->GetNext(&m, &n));
+ nPts = ic;
+ if(ic > 1) ls = (line_segment **)calloc(ic-1, sizeof(line_segment*));
+ }
+ if(rX) delete(rX); if(rY) delete(rY); if(rZ) delete(rZ);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// the text label class
+Label::Label(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, DWORD flg,
+ int xc, int xr, int yc, int yr, int tc, int tr):GraphObj(par, d)
+{
+ int cb;
+
+ FileIO(INIT_VARS);
+ fPos.fx = x; fPos.fy = y; flags = flg;
+ if(parent){
+ fDist.fx = parent->GetSize(SIZE_LB_XDIST);
+ fDist.fy = parent->GetSize(SIZE_LB_YDIST);
+ }
+ Id = GO_LABEL;
+ if(td){
+ memcpy(&TextDef, td, sizeof(TextDEF));
+ if(td->text && td->text[0]) {
+ cb = (int)strlen(td->text)+1; if(cb < 20) cb = 20;
+ TextDef.text = (char*)malloc(cb *sizeof(char));
+ rlp_strcpy(TextDef.text, cb, td->text);
+ }
+ }
+ if(xc >= 0 || xr >= 0 || yc >= 0 || yr >= 0 || tc >= 0 || tr >= 0) {
+ if(ssRef = (POINT*)malloc(sizeof(POINT)*3)) {
+ ssRef[0].x = xc; ssRef[0].y = xr;
+ ssRef[1].x = yc; ssRef[1].y = yr;
+ ssRef[2].x = tc; ssRef[2].y = tr;
+ cssRef = 3;
+ }
+ }
+}
+
+Label::Label(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+Label::~Label()
+{
+ HideTextCursor();
+ Command(CMD_FLUSH, 0L, 0L);
+ if(fmt_txt) delete(fmt_txt); fmt_txt = 0L;
+ if(bModified)Undo.InvalidGO(this);
+}
+
+double
+Label::GetSize(int select)
+{
+ switch(select){
+ case SIZE_CURSORPOS:
+ return (double)CursorPos;
+ case SIZE_CURSOR_XMIN:
+ return (double) (Cursor.right > Cursor.left ? Cursor.left : Cursor.right);
+ case SIZE_CURSOR_XMAX:
+ return (double) (Cursor.right > Cursor.left ? Cursor.right : Cursor.left);
+ case SIZE_CURSOR_YMIN:
+ return (double) (Cursor.bottom > Cursor.top ? Cursor.top : Cursor.bottom);
+ case SIZE_CURSOR_YMAX:
+ return (double) (Cursor.bottom > Cursor.top ? Cursor.bottom : Cursor.top);
+ case SIZE_MIN_Z: case SIZE_MAX_Z: case SIZE_ZPOS:
+ return curr_z;
+ }
+ return 0.0;
+}
+
+bool
+Label::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_LB_XDIST: fDist.fx = value; return true;
+ case SIZE_LB_YDIST: fDist.fy = value; return true;
+ case SIZE_XPOS: fPos.fx = value; return true;
+ case SIZE_YPOS: fPos.fy = value; return true;
+ case SIZE_ZPOS: curr_z = value; return is3D = true;
+ }
+ return false;
+}
+
+bool
+Label::SetColor(int select, DWORD col)
+{
+ switch(select & 0xfff) {
+ case COL_TEXT:
+ if(select & UNDO_STORESET) {
+ Undo.ValDword(this, &TextDef.ColTxt, UNDO_CONTINUE);
+ bModified = true;
+ }
+ TextDef.ColTxt = col; bBGvalid = false;
+ return true;
+ case COL_BG:
+ bgcolor = col; bBGvalid = true;
+ return true;
+ }
+ return false;
+}
+
+void
+Label::DoPlot(anyOutput *o)
+{
+ if(is3D && parent && parent->Command(CMD_SET_GO3D, this, o)) return;
+ DoPlotText(o);
+}
+
+void
+Label::DoMark(anyOutput *o, bool mark)
+{
+ DWORD bgpix[16];
+ int i, d, d1, ix, iy, dx, dy, n;
RECT mrc;
- anyOutput *mo;
-
- if(mark) {
+ anyOutput *mo;
+
+ if(mark) {
//find color with maximum contrast to text
if(!bBGvalid) {
mrc.left = rDims.left; mrc.right = rDims.right;
@@ -5126,1198 +5250,2013 @@ Label::DoMark(anyOutput *o, bool mark)
i++;
}
}
- DelBitmapClass(mo); n = i;
- }
- bgcolor = bgpix[0];
- d = ColDiff(bgcolor, TextDef.ColTxt);
- for(i = 1; i < n; i++) {
- if(d < (d1 = ColDiff(bgpix[i], TextDef.ColTxt))) {
- d = d1; bgcolor = bgpix[i];
- }
- }
- if(!d) bgcolor = TextDef.ColTxt ^ 0x00ffffffL;
- bBGvalid = true;
- }
- //in dialogs parent has no parent
- if(parent && parent->parent) o->ShowLine(pts, 5, TextDef.ColTxt);
- ShowCursor(o); CurrGO = this; CurrLabel = this;
- }
- else {
- HideTextCursor();
- bgLine.color = bgcolor; o->SetLine(&bgLine);
- //in dialogs parent has no parent
- if(parent && parent->parent) o->oPolyline(pts, 5);
- IncrementMinMaxRect(&rDims, 3);
- o->UpdateRect(&rDims, false); IncrementMinMaxRect(&rDims, -3);
- if(CurrLabel == this) CurrLabel = 0L;
- if(parent && parent->Id != GO_MLABEL && (!TextDef.text || !TextDef.text[0]))
- parent->Command(CMD_DELOBJ, (void*)this, o);
- }
-}
-
-bool
-Label::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- char *tmptxt;
-
- if(cmd != CMD_SET_DATAOBJ && !parent) return false;
- switch (cmd) {
- case CMD_FLUSH:
- if(CurrLabel == this) CurrLabel = 0L;
- if(TextDef.text) free(TextDef.text); TextDef.text = 0L;
- if(ssRef) free(ssRef); ssRef = 0L;
- return true;
- case CMD_POS_FIRST: case CMD_POS_LAST:
- Undo.ValInt(this, &CursorPos, 0L);
- bModified = true;
- if(o && TextDef.text) {
- CursorPos = (cmd == CMD_POS_LAST) ? strlen(TextDef.text) : 0;
- ShowCursor(o);
- return true;
- }
- return false;
- case CMD_CURRLEFT:
- if(o && CursorPos >0 && TextDef.text && fmt_txt) {
- Undo.ValInt(this, &CursorPos, 0L);
- bModified = true; fmt_txt->cur_left(&CursorPos); ShowCursor(o);
- return true;
- }
- return false;
- case CMD_CURRIGHT:
- if(o && TextDef.text && CursorPos < (int)strlen(TextDef.text) && fmt_txt) {
- Undo.ValInt(this, &CursorPos, 0L);
- bModified = true; fmt_txt->cur_right(&CursorPos); ShowCursor(o);
- return true;
- }
- return false;
- case CMD_ADDCHAR:
- SetModified();
- if(tmpl && 8 != *((int*)tmpl)) return AddChar(*((int*)tmpl), o);
- //value 8 == backspace
- case CMD_BACKSP:
- SetModified();
- if(CursorPos <=0 && o) {
- if(parent->Id == GO_MLABEL) {
- parent->Command(CMD_SETFOCUS, this, o);
- return parent->Command(CMD_BACKSP, tmpl, o);
- }
- RedrawEdit(o);
- return true;
- }
- Undo.ValInt(this, &CursorPos, 0L);
- CursorPos--; //continue as if delete
- case CMD_DELETE:
- SetModified();
- if(cmd == CMD_DELETE) Undo.ValInt(this, &CursorPos, 0L);
- if(TextDef.text && TextDef.text[CursorPos]) {
- Undo.String(this, &TextDef.text, UNDO_CONTINUE);
- strcpy(TextDef.text + CursorPos, TextDef.text + CursorPos + 1);
- if(o)RedrawEdit(o);
- }
- else if(TextDef.text && parent->Id == GO_MLABEL) {
- parent->Command(CMD_SETFOCUS, this, o);
- return parent->Command(CMD_DELETE, tmpl, o);
- }
- else o->HideMark();
- break;
- case CMD_GETTEXT:
- if(TextDef.text && tmpl) {
- strcpy((char*)tmpl, TextDef.text);
- return true;
- }
- return false;
- case CMD_SETTEXT:
- if(TextDef.text) free(TextDef.text);
- if(tmpl) TextDef.text = strdup((char*)tmpl);
- else TextDef.text = 0L;
- return true;
- case CMD_GETTEXTDEF:
- if(!tmpl) return false;
- memcpy(tmpl, &TextDef, sizeof(TextDEF));
- return true;
- case CMD_SETTEXTDEF:
- if(!tmpl)return false;
- tmptxt = TextDef.text;
- memcpy(&TextDef, tmpl, sizeof(TextDEF));
- if(!TextDef.text){
- TextDef.text = tmptxt;
- tmptxt = 0L;
- }
- else if(((TextDEF*)tmpl)->text) TextDef.text = strdup(((TextDEF*)tmpl)->text);
- if(tmptxt) free(tmptxt);
- return true;
- case CMD_SET_DATAOBJ:
- Id = GO_LABEL;
- data = (DataObj*)tmpl;
- return true;
- case CMD_UPDATE:
- if(ssRef && cssRef >2 && data) {
- data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
- data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
- if(data->GetText(ssRef[2].y, ssRef[2].x, TmpTxt, TMP_TXT_SIZE)) {
- Undo.String(this, &TextDef.text, UNDO_CONTINUE);
- TextDef.text = (char*)realloc(TextDef.text, strlen(TmpTxt)+2);
- if(TmpTxt[0]) strcpy(TextDef.text, TmpTxt);
- else TextDef.text[0] = 0;
- }
- return true;
- }
- return false;
- case CMD_SELECT:
- if(!o || !tmpl) return false;
- CalcCursorPos(((POINT*)tmpl)->x, ((POINT*)tmpl)->y, o);
- o->ShowMark(this, MRK_GODRAW);
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(ObjThere(mev->x, mev->y)) {
- if(parent && parent->Id == GO_MLABEL) parent->Command(CMD_SETFOCUS, this, o);
- CalcCursorPos(mev->x, mev->y, o);
- o->ShowMark(this, MRK_GODRAW);
- return true;
- }
- break;
- }
- break;
- case CMD_AUTOSCALE:
- if(parent->Id >= GO_PLOT && parent->Id < GO_GRAPH
- && (flags & LB_X_DATA) && (flags & LB_Y_DATA)) {
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
- return true;
- }
- break;
+ DelBitmapClass(mo); n = i;
+ }
+ bgcolor = bgpix[0];
+ d = ColDiff(bgcolor, TextDef.ColTxt);
+ for(i = 1; i < n; i++) {
+ if(d < (d1 = ColDiff(bgpix[i], TextDef.ColTxt))) {
+ d = d1; bgcolor = bgpix[i];
+ }
+ }
+ if(!d) bgcolor = TextDef.ColTxt ^ 0x00ffffffL;
+ bBGvalid = true;
+ }
+ //in dialogs parent has no parent
+ if(parent && parent->parent) o->ShowLine(pts, 5, TextDef.ColTxt);
+ ShowCursor(o); CurrGO = this; CurrLabel = this;
+ }
+ else {
+ HideTextCursor();
+ bgLine.color = bgcolor; o->SetLine(&bgLine);
+ //in dialogs parent has no parent
+ if(parent && parent->parent) o->oPolyline(pts, 5);
+ IncrementMinMaxRect(&rDims, 3);
+ o->UpdateRect(&rDims, false); IncrementMinMaxRect(&rDims, -3);
+ if(CurrLabel == this) CurrLabel = 0L;
+ if(parent && parent->Id != GO_MLABEL && (!TextDef.text || !TextDef.text[0]))
+ parent->Command(CMD_DELOBJ, (void*)this, o);
+ }
+}
+
+bool
+Label::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ scaleINFO *scale;
+ int cb;
+
+ if(cmd != CMD_SET_DATAOBJ && !parent) return false;
+ switch (cmd) {
+ case CMD_SCALE:
+ scale = (scaleINFO*)tmpl;
+ if((flags & 0x03)!= LB_X_DATA) fPos.fx *= scale->sx.fy;
+ if((flags & 0x30)!= LB_Y_DATA) fPos.fy *= scale->sy.fy;
+ fDist.fx *= scale->sx.fy; fDist.fy *= scale->sy.fy;
+ TextDef.fSize *= scale->sx.fy; TextDef.iSize = 0;
+ return true;
+ case CMD_FLUSH:
+ if(CurrLabel == this) CurrLabel = 0L;
+ if(TextDef.text) free(TextDef.text); TextDef.text = 0L;
+ if(ssRef) free(ssRef); ssRef = 0L;
+ return true;
+ case CMD_POS_FIRST: case CMD_POS_LAST:
+ Undo.ValInt(this, &CursorPos, 0L);
+ bModified = true;
+ if(o && TextDef.text) {
+ CursorPos = (cmd == CMD_POS_LAST) ? (int)strlen(TextDef.text) : 0;
+ ShowCursor(o);
+ return true;
+ }
+ return false;
+ case CMD_CURRLEFT:
+ if(o && CursorPos >0 && TextDef.text && fmt_txt) {
+ Undo.ValInt(this, &CursorPos, 0L);
+ bModified = true; fmt_txt->cur_left(&CursorPos); ShowCursor(o);
+ return true;
+ }
+ return false;
+ case CMD_CURRIGHT:
+ if(o && TextDef.text && CursorPos < (int)strlen(TextDef.text) && fmt_txt) {
+ Undo.ValInt(this, &CursorPos, 0L);
+ bModified = true; fmt_txt->cur_right(&CursorPos); ShowCursor(o);
+ return true;
+ }
+ return false;
+ case CMD_ADDCHAR:
+ SetModified();
+ if(tmpl && 8 != *((int*)tmpl)) return AddChar(*((int*)tmpl), o);
+ //value 8 == backspace
+ case CMD_BACKSP:
+ SetModified();
+ if(CursorPos <=0 && o) {
+ if(parent->Id == GO_MLABEL) {
+ parent->Command(CMD_SETFOCUS, this, o);
+ return parent->Command(CMD_BACKSP, tmpl, o);
+ }
+ RedrawEdit(o);
+ return true;
+ }
+ Undo.ValInt(this, &CursorPos, 0L);
+ CursorPos--; //continue as if delete
+ case CMD_DELETE:
+ SetModified();
+ if(cmd == CMD_DELETE) Undo.ValInt(this, &CursorPos, 0L);
+ if(TextDef.text && TextDef.text[CursorPos]) {
+ Undo.String(this, &TextDef.text, UNDO_CONTINUE);
+ rlp_strcpy(TextDef.text + CursorPos, TMP_TXT_SIZE, TextDef.text + CursorPos + 1);
+ if(o)RedrawEdit(o);
+ }
+ else if(TextDef.text && parent->Id == GO_MLABEL) {
+ parent->Command(CMD_SETFOCUS, this, o);
+ return parent->Command(CMD_DELETE, tmpl, o);
+ }
+ else o->HideMark();
+ break;
+ case CMD_GETTEXT:
+ if(TextDef.text && TextDef.text[0] && tmpl) {
+ rlp_strcpy((char*)tmpl, TMP_TXT_SIZE, TextDef.text);
+ return true;
+ }
+ return false;
+ case CMD_SETTEXT:
+ if(TextDef.text) free(TextDef.text); TextDef.text = 0L;
+ if(tmpl && *((char*)tmpl)) {
+ TextDef.text = (char*)memdup(tmpl, (int)strlen((char*)tmpl)+1, 0);
+ }
+ return true;
+ case CMD_GETTEXTDEF:
+ if(!tmpl) return false;
+ memcpy(tmpl, &TextDef, sizeof(TextDEF));
+ return true;
+ case CMD_SETTEXTDEF:
+ if(!tmpl)return false;
+ memcpy(&TextDef, tmpl, sizeof(TextDEF)-sizeof(char*));
+ if(((TextDEF*)tmpl)->text) Command(CMD_SETTEXT, tmpl, o);
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = GO_LABEL;
+ data = (DataObj*)tmpl;
+ return true;
+ case CMD_UPDATE:
+ if(ssRef && cssRef >2 && data) {
+ data->GetValue(ssRef[0].y, ssRef[0].x, &fPos.fx);
+ data->GetValue(ssRef[1].y, ssRef[1].x, &fPos.fy);
+ if(data->GetText(ssRef[2].y, ssRef[2].x, TmpTxt, TMP_TXT_SIZE)) {
+ Undo.String(this, &TextDef.text, UNDO_CONTINUE);
+ TextDef.text = (char*)realloc(TextDef.text, cb = (int)strlen(TmpTxt)+2);
+ if(TmpTxt[0]) rlp_strcpy(TextDef.text, cb, TmpTxt);
+ else TextDef.text[0] = 0;
+ }
+ return true;
+ }
+ return false;
+ case CMD_SELECT:
+ if(!o || !tmpl) return false;
+ CalcCursorPos(((POINT*)tmpl)->x, ((POINT*)tmpl)->y, o);
+ o->ShowMark(this, MRK_GODRAW);
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(ObjThere(mev->x, mev->y)) {
+ if(parent && parent->Id == GO_MLABEL) parent->Command(CMD_SETFOCUS, this, o);
+ CalcCursorPos(mev->x, mev->y, o);
+ o->ShowMark(this, MRK_GODRAW);
+ return true;
+ }
+ break;
+ }
+ break;
+ case CMD_AUTOSCALE:
+ if(parent->Id >= GO_PLOT && parent->Id < GO_GRAPH
+ && (flags & LB_X_DATA) && (flags & LB_Y_DATA)) {
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
+ return true;
+ }
+ break;
+ case CMD_REDRAW:
+ if(is3D && o) {
+ DoPlotText(o);
+ is3D = false; //enable edit
+ }
+ else if(CurrGO == this) {
+ if(parent && parent->parent) RedrawEdit(defDisp); //not a dialog
+ else ShowCursor(defDisp); //dialog !
+ }
+ else return parent->Command(cmd, tmpl, o);
+ return true;
+ case CMD_MOVE:
+ if(parent && (parent->Id == GO_MLABEL || parent->Id == GO_LEGITEM))
+ return parent->Command(cmd, tmpl, o);
+ Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ case CMD_UNDO_MOVE:
+ if(fmt_txt) delete(fmt_txt); fmt_txt = 0L;
+ if(!(flags & 0x03)) fPos.fx += ((lfPOINT*)tmpl)[0].fx;
+ if(!(flags & 0x30)) fPos.fy += ((lfPOINT*)tmpl)[0].fy;
+ if(o){
+ o->StartPage(); parent->DoPlot(o); o->EndPage();
+ }
+ return bModified = true;
+ }
+ return false;
+}
+
+void *
+Label::ObjThere(int x, int y)
+{
+ POINT p1;
+
+ if(IsInRect(&rDims, p1.x = x, p1.y = y) && IsInPolygon(&p1, pts, 5))
+ return this;
+ return 0L;
+}
+
+void
+Label::Track(POINT *p, anyOutput *o)
+{
+ POINT *tpts;
+ RECT old_rc;
+ int i;
+
+ if(!parent) return;
+ if(parent->Id == GO_MLABEL || parent->Id == GO_LEGITEM){
+ parent->Track(p, o);
+ return;
+ }
+ if(o && (tpts = (POINT*)malloc(5*sizeof(POINT)))){
+ memcpy(&old_rc, &rDims, sizeof(rDims));
+ //note: mLabel set Id to zero upon trackking
+ // thus rectangle is not updated if parent is a mLabel
+ if(parent->Id) o->UpdateRect(&rDims, false);
+ for(i = 0; i < 5; i++) {
+ tpts[i].x = pts[i].x+p->x; tpts[i].y = pts[i].y+p->y;
+ UpdateMinMaxRect(&rDims, tpts[i].x, tpts[i].y);
+ }
+ o->ShowLine(tpts, 5, TextDef.ColTxt);
+ if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
+ rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
+ free(tpts);
+ }
+}
+
+bool
+Label::CalcRect(anyOutput *o)
+{
+ int rx1, rx, ry;
+ fRECT rc, rcc;
+
+ if(parent && parent->Id != GO_MLABEL) o->SetTextSpec(&TextDef);
+ if(fmt_txt && TextDef.text && TextDef.text[0]) {
+ fmt_txt->SetText(0L, TextDef.text, &ix, &iy);
+ if(!(fmt_txt->oGetTextExtent(o, &rx, &ry, 0))) return false;
+ rx++;
+ }
+ else {
+ if(!(o->oGetTextExtent("A", 1, &rx, &ry))) return false;
+ rx = 1;
+ }
+ rx += 4; rc.Xmin = -2.0f; rc.Ymin = 0.0f; rc.Xmax = rx; rc.Ymax = ry;
+ si = sin(TextDef.RotBL *0.01745329252); csi = cos(TextDef.RotBL *0.01745329252);
+ if(TextDef.Align & TXA_HCENTER) {
+ rc.Xmin -= rx/2.0-1.0; rc.Xmax -= rx/2.0-1.0;
+ }
+ else if(TextDef.Align & TXA_HRIGHT) {
+ rc.Xmin -= rx-2.0; rc.Xmax -= rx-2.0;
+ }
+ if(TextDef.Align & TXA_VCENTER) {
+ rc.Ymin -= ry/2.0; rc.Ymax -= ry/2.0;
+ }
+ else if(TextDef.Align & TXA_VBOTTOM) {
+ rc.Ymin -= ry; rc.Ymax -= ry;
+ }
+ if(fmt_txt && fmt_txt->oGetTextExtent(o, &rx1, &ry, CursorPos)){
+ rx = CursorPos ? (int)rx1 : 0;
+ }
+ else rx = 0;
+ rcc.Xmax = rc.Xmin + (double)rx+2.0; rcc.Ymin = rc.Ymin+2.0;
+ rcc.Xmin = rc.Xmin; rcc.Ymax = rc.Ymax-2.0;
+ pts[0].x = iround(rc.Xmin*csi + rc.Ymin*si)+ix;
+ pts[0].y = iround(rc.Ymin*csi - rc.Xmin*si)+iy;
+ pts[1].x = iround(rc.Xmax*csi + rc.Ymin*si)+ix;
+ pts[1].y = iround(rc.Ymin*csi - rc.Xmax*si)+iy;
+ pts[2].x = iround(rc.Xmax*csi + rc.Ymax*si)+ix;
+ pts[2].y = iround(rc.Ymax*csi - rc.Xmax*si)+iy;
+ pts[3].x = iround(rc.Xmin*csi + rc.Ymax*si)+ix;
+ pts[3].y = iround(rc.Ymax*csi - rc.Xmin*si)+iy;
+ pts[4].x = pts[0].x; pts[4].y = pts[0].y;
+ Cursor.left = iround(rcc.Xmax*csi + rcc.Ymin*si)+ix;
+ Cursor.top = iround(rcc.Ymin*csi - rcc.Xmax*si)+iy;
+ Cursor.right = iround(rcc.Xmax*csi + rcc.Ymax*si)+ix;
+ Cursor.bottom = iround(rcc.Ymax*csi - rcc.Xmax*si)+iy;
+ return true;
+}
+
+void
+Label::RedrawEdit(anyOutput *o)
+{
+ FillDEF bgFill = {FILL_NONE, bgcolor, 1.0, 0L, bgcolor};
+
+ if(!o || !parent) return;
+ bgLine.color = bgcolor; o->SetLine(&bgLine); o->SetFill(&bgFill);
+ o->oPolygon(pts, 5); IncrementMinMaxRect(&rDims, 3);
+ o->UpdateRect(&rDims, false);
+ CalcRect(o); bgLine.color ^= 0x00ffffffL;
+ o->SetLine(&bgLine); o->oPolygon(pts, 5);
+ if(parent->Id == GO_MLABEL) {
+ if(parent->parent && parent->parent->Id == GO_LEGITEM && parent->parent->parent)
+ parent->parent->parent->DoPlot(o);
+ else parent->DoPlot(o);
+ }
+ else if(parent->Id == GO_LEGITEM && parent->parent) parent->parent->DoPlot(o);
+ else DoPlot(o);
+ o->UpdateRect(&rDims, false);
+ DoMark(o, true); ShowCursor(o);
+}
+
+void
+Label::SetModified()
+{
+ AxisDEF *adef;
+
+ bModified = true;
+ if(parent && parent->Id==GO_TICK && parent->parent && parent->parent->Id==GO_AXIS){
+ adef = ((Axis*)(parent->parent))->GetAxis();
+ adef->flags &= ~AXIS_AUTOSCALE;
+ }
+}
+
+void
+Label::DoPlotText(anyOutput *o)
+{
+ if(!parent || !o) return;
+ defDisp = o;
+ if(parent && parent->Id == GO_MLABEL) parent->Command(CMD_SETFOCUS, this, o);
+ switch(flags & 0x03) {
+ case LB_X_DATA: ix = o->fx2ix(fPos.fx); break;
+ case LB_X_PARENT:
+ ix = iround(parent->GetSize(SIZE_LB_XPOS));
+ break;
+ default:
+ ix = o->co2ix(fPos.fx + parent->GetSize(SIZE_GRECT_LEFT));
+ break;
+ }
+ switch(flags & 0x30) {
+ case LB_Y_DATA: iy = o->fy2iy(fPos.fy); break;
+ case LB_Y_PARENT:
+ iy = iround(parent->GetSize(SIZE_LB_YPOS));
+ break;
+ default:
+ iy = o->co2iy(fPos.fy +parent->GetSize(SIZE_GRECT_TOP));
+ break;
+ }
+ ix += o->un2ix(fDist.fx); iy += o->un2iy(fDist.fy);
+ TextDef.iSize = o->un2iy(TextDef.fSize);
+ o->SetTextSpec(&TextDef);
+ if(TextDef.text && TextDef.text[0]){
+ if(fmt_txt) fmt_txt->SetText(o, TextDef.text, &ix, &iy);
+ else fmt_txt = new fmtText(o, ix, iy, TextDef.text);
+ }
+ if(!(CalcRect(o))) return;
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+ UpdateMinMaxRect(&rDims, pts[2].x, pts[2].y);
+ UpdateMinMaxRect(&rDims, pts[3].x, pts[3].y);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// a multiline label consists of several Label objects
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+mLabel::mLabel(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, char *txt,
+ int cp, DWORD flg):GraphObj(par, d)
+{
+ int i;
+
+ memcpy(&TextDef, td, sizeof(TextDEF));
+ TextDef.text = 0L; fPos.fx = x; fPos.fy = y;
+ Lines = 0L; flags = flg; lspc = 1.0;
+ fDist.fx = 0.0; fDist.fy = 0.0;
+ CurrGO = CurrLabel = 0L;
+ if(txt && (Lines = (Label**)calloc(2, sizeof(Label*)))) {
+ for(i = 0; i < cp && txt[i]; i ++) TmpTxt[i] = txt[i];
+ TmpTxt[i] = 0;
+ if(Lines[0] = new Label(this, d, x, y, &TextDef, LB_X_PARENT | LB_Y_PARENT))
+ Lines[0]->Command(CMD_SETTEXT, TmpTxt, 0L);
+ if(Lines[1] = new Label(this, d, x, y, &TextDef, LB_X_PARENT | LB_Y_PARENT)){
+ Lines[1]->Command(CMD_SETTEXT, txt+cp, 0L);
+ CurrGO = CurrLabel = Lines[1];
+ }
+ nLines = 2; cli = 1;
+ }
+ Id = GO_MLABEL;
+}
+
+mLabel::mLabel(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, char *txt)
+ :GraphObj(par, d)
+{
+ int i, nll;
+ char **llist;
+
+ memcpy(&TextDef, td, sizeof(TextDEF));
+ TextDef.text = 0L; fPos.fx = x; fPos.fy = y;
+ Lines = 0L; flags = 0L; Id = GO_MLABEL;
+ fDist.fx = 0.0; fDist.fy = 0.0; lspc = 1.0;
+ CurrGO = CurrLabel = 0L;
+ if(txt){
+ if((llist=split(txt,'\n',&nll)) && nll && (Lines=(Label**)calloc(nll, sizeof(Label*)))){
+ for(i = 0; i < nll; i++) {
+ if(llist[i]){
+ Lines[i] = new Label(this, d, x, y, &TextDef, LB_X_PARENT | LB_Y_PARENT);
+ Lines[i]->Command(CMD_SETTEXT, llist[i], 0L);
+ free(llist[i]);
+ }
+ }
+ free(llist); nLines = nll; cli = 0;
+ }
+ }
+}
+
+mLabel::mLabel(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+}
+
+mLabel::~mLabel()
+{
+ int i;
+
+ Undo.InvalidGO(this);
+ if(Lines){
+ for(i = 0; i < nLines; i++) if(Lines[i]) DeleteGO(Lines[i]);
+ free(Lines);
+ }
+}
+
+double
+mLabel::GetSize(int select)
+{
+ switch(select){
+ case SIZE_LB_XPOS: return cPos1.fx;
+ case SIZE_LB_YPOS: return cPos1.fy;
+ case SIZE_GRECT_TOP:
+ if (parent) return parent->GetSize(select);
+ break;
+ case SIZE_MIN_Z: case SIZE_MAX_Z: case SIZE_ZPOS:
+ return curr_z;
+ case SIZE_LSPC:
+ return lspc;
+ }
+ return 0.0;
+}
+
+bool
+mLabel::SetSize(int select, double value)
+{
+ int i;
+
+ switch(select & 0xfff) {
+ case SIZE_LB_XDIST:
+ undo_flags = CheckNewFloat(&fDist.fx, fDist.fx, value, this, undo_flags);
+ return true;
+ case SIZE_LB_YDIST:
+ undo_flags = CheckNewFloat(&fDist.fy, fDist.fy, value, this, undo_flags);
+ return true;
+ case SIZE_XPOS:
+ undo_flags = CheckNewFloat(&fPos.fx, fPos.fx, value, this, undo_flags);
+ return true;
+ case SIZE_YPOS:
+ undo_flags = CheckNewFloat(&fPos.fy, fPos.fy, value, this, undo_flags);
+ return true;
+ case SIZE_ZPOS:
+ curr_z = value;
+ if(Lines) for(i = 0; i < nLines; i++) if(Lines[i]){
+ Lines[i]->SetSize(select, value);
+ }
+ return is3D = true;
+ case SIZE_LSPC:
+ undo_flags = CheckNewFloat(&lspc, lspc, value, this, undo_flags);
+ return true;
+ }
+ return false;
+}
+
+void
+mLabel::DoPlot(anyOutput *o)
+{
+ int i;
+ double dh, dx, dy;
+
+ if(!o || !Lines) return;
+ undo_flags = 0L;
+ if(parent){ //if this object is part of a dialog we dont have a parent
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ }
+ else dx = dy = 0.0;
+ cPos.fx = cPos.fy = 0.0;
+ TextDef.iSize = o->un2iy(TextDef.fSize);
+ switch(flags & 0x03) {
+ case LB_X_DATA: cPos.fx = o->fx2fix(fPos.fx); break;
+ case LB_X_PARENT: if(parent) cPos.fx = parent->GetSize(SIZE_LB_XPOS); break;
+ default:
+ //if no parent its a dialog
+ cPos.fx = parent ? o->co2fix(fPos.fx + dx) : fPos.fx;
+ break;
+ }
+ switch(flags & 0x30) {
+ case LB_Y_DATA: cPos.fy = o->fy2fiy(fPos.fy); break;
+ case LB_Y_PARENT: if(parent) cPos.fy = parent->GetSize(SIZE_LB_YPOS); break;
+ default:
+ //if no parent its a dialog
+ cPos.fy = parent ? o->co2fiy(fPos.fy + dy) : fPos.fy;
+ break;
+ }
+ si = sin(TextDef.RotBL *0.01745329252f); csi = cos(TextDef.RotBL *0.01745329252f);
+ if(TextDef.Align & TXA_VBOTTOM) dh = (double)(nLines-1);
+ else if(TextDef.Align & TXA_VCENTER) dh = ((double)(nLines-1))/2.0;
+ else dh = 0.0; dh *= TextDef.fSize;
+ cPos.fx -= o->un2fix(dh*si); cPos.fy -= o->un2fiy(dh*csi);
+ memcpy(&cPos1, &cPos, sizeof(lfPOINT));
+ if(lspc < 0.5 || lspc > 5) lspc = 1.0;
+#ifdef _WINDOWS
+ dist.fx = floor(o->un2fix(TextDef.fSize * si * lspc));
+ dist.fy = floor(o->un2fiy(TextDef.fSize * csi * lspc));
+#else
+ dist.fx = floor(o->un2fix(TextDef.fSize * si * 1.2 * lspc));
+ dist.fy = floor(o->un2fiy(TextDef.fSize * csi * 1.2 * lspc));
+#endif
+ o->SetTextSpec(&TextDef);
+ rDims.left = rDims.top = rDims.right = rDims.bottom = 0;
+ for(i = 0; i < nLines; i++) if(Lines[i]){
+ Lines[i]->Command(CMD_SETTEXTDEF, &TextDef, o);
+ Lines[i]->SetSize(SIZE_LB_XDIST, fDist.fx); Lines[i]->SetSize(SIZE_LB_YDIST, fDist.fy);
+ Lines[i]->SetSize(SIZE_XPOS, fPos.fx); Lines[i]->SetSize(SIZE_YPOS, fPos.fy);
+ Lines[i]->moveable = moveable; Lines[i]->DoPlot(o);
+ UpdateMinMaxRect(&rDims, Lines[i]->rDims.left, Lines[i]->rDims.top);
+ UpdateMinMaxRect(&rDims, Lines[i]->rDims.right, Lines[i]->rDims.bottom);
+ }
+ if(CurrLabel && o && Command(CMD_SETFOCUS, CurrLabel, o))
+ Lines[cli]->ShowCursor(o);
+}
+
+bool
+mLabel::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ int i, j, k;
+ fRECT t_cur;
+ MouseEvent mev;
+ scaleINFO *scale;
+
+ switch (cmd) {
+ case CMD_MOUSE_EVENT:
+ if(Lines && tmpl && IsInRect(&rDims, ((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y))
+ for(i = 0; i<nLines; i++) if(Lines[i] && Lines[i]->Command(cmd, tmpl, o)) return true;
+ break;
+ case CMD_HIDE_MARK:
+ if(Lines && o && tmpl) for(i = 0; i< nLines; i++)
+ if(Lines[i] && tmpl == (void*)Lines[i]){
+ Lines[i]->DoMark(o, false);
+ return true;
+ }
+ return false;
+ case CMD_ADDCHAR:
+ if(!tmpl || 13 != *((int*)tmpl)) return false;
+ if(!Lines[cli] || !Lines[cli]->Command(CMD_GETTEXT, &TmpTxt, o)) return false;
+ k = iround(Lines[cli]->GetSize(SIZE_CURSORPOS));
+ if(parent)Undo.ObjConf(this, 0L);
+ if(tmpl && Lines && (Lines = (Label**)realloc(Lines, (nLines+1) * sizeof(Label*)))) {
+ for(i = nLines-1, j = nLines; i >= cli; i--, j-- ) {
+ Lines[j] = Lines[i];
+ }
+ i++, j++;
+ if(Lines[j]) DeleteGO(Lines[j]); Lines[i] = Lines[j] = 0L; nLines++;
+ if(Lines[j] = new Label(this, data, fPos.fx, fPos.fy, &TextDef, LB_X_PARENT | LB_Y_PARENT)){
+ Lines[j]->Command(CMD_SETTEXT, TmpTxt+k, o);
+ Lines[j]->Command(CMD_POS_FIRST, 0L, o);
+ CurrGO = CurrLabel = Lines[j];
+ TmpTxt[k] = 0;
+ }
+ if(Lines[i] = new Label(this, data, fPos.fx, fPos.fy, &TextDef, LB_X_PARENT | LB_Y_PARENT))
+ Lines[i]->Command(CMD_SETTEXT, TmpTxt, 0L);
+ Command(CMD_SETFOCUS, CurrGO, o);
+ if(parent) return parent->Command(CMD_REDRAW, 0L, o);
+ else if(o) DoPlot(o);
+ }
+ break;
+ case CMD_SETFOCUS:
+ for(i = 0; i< nLines; i++) if(Lines[i] == (Label*)tmpl) {
+ cli = i;
+ cPos1.fx = cPos.fx + dist.fx*i;
+ cPos1.fy = cPos.fy + dist.fy*i;
+ return true;
+ }
+ break;
+ case CMD_GETTEXT:
+ if(tmpl && Lines && nLines && Lines[0]) return Lines[0]->Command(CMD_GETTEXT, tmpl, o);
+ break;
+ case CMD_ALLTEXT: //used e.g from dialog text boxes
+ if(tmpl && Lines && nLines){
+ for(i = j = 0; i < nLines; i++) {
+ if(Lines[i] && Lines[i]->Command(CMD_GETTEXT, TmpTxt+500, o) && TmpTxt[500]){
+ j += rlp_strcpy((char*)tmpl+j, 500-j, TmpTxt+500);
+ ((char*)tmpl)[j++] = '\n';
+ }
+ ((char*)tmpl)[j] = 0;
+ }
+ if(j >2) return true;
+ }
+ return false;
+ case CMD_DELETE:
+ cli++;
+ //fall through
+ case CMD_BACKSP:
+ if(cli > 0 && cli < nLines && Lines && Lines[cli] && Lines[cli-1]) {
+ Lines[cli-1]->Command(CMD_POS_LAST, 0L, o);
+ TmpTxt[0] = 0;
+ Lines[cli-1]->Command(CMD_GETTEXT, TmpTxt, o);
+ Lines[cli]->Command(CMD_GETTEXT, TmpTxt+strlen(TmpTxt), o);
+ Lines[cli-1]->Command(CMD_SETTEXT, TmpTxt, o);
+ DeleteGO(Lines[cli]); Lines[cli] = 0L;
+ for(i = cli+1; i < nLines; i++){
+ Lines[i-1] = Lines[i], Lines[i]= 0L;
+ }
+ nLines--;
+ CurrGO = CurrLabel = Lines[cli-1];
+ if(parent) parent->Command(CMD_REDRAW, 0L, o);
+ if(CurrLabel) CurrLabel->RedrawEdit(o);
+ return true;
+ }
+ return false;
+ case CMD_GETTEXTDEF:
+ if(!tmpl) return false;
+ memcpy(tmpl, &TextDef, sizeof(TextDEF));
+ return true;
+ case CMD_SETTEXTDEF:
+ if(!tmpl)return false;
+ if(parent)Undo.TextDef(this, &TextDef, undo_flags);
+ undo_flags |= UNDO_CONTINUE;
+ memcpy(&TextDef, tmpl, sizeof(TextDEF));
+ TextDef.text = 0L;
+ return true;
+ case CMD_SET_DATAOBJ:
+ if(Lines) {
+ for(i = 0; i< nLines; i++) if(Lines[i]) Lines[i]->Command(cmd, tmpl, o);
+ }
+ Id = GO_MLABEL;
+ data = (DataObj*)tmpl;
+ return true;
+ case CMD_AUTOSCALE:
+ if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH
+ && (flags & LB_X_DATA) && (flags & LB_Y_DATA)) {
+ ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
+ return true;
+ }
+ break;
+ case CMD_CURRUP: case CMD_CURRDOWN:
+ if(!o) return false;
+ o->SetTextSpec(&TextDef);
+ Command(CMD_SETFOCUS, CurrGO, o);
+ if(cli >= 0 && cli < nLines && Lines && Lines[cli]) {
+ t_cur.Xmin = Lines[cli]->GetSize(SIZE_CURSOR_XMIN);
+ t_cur.Xmax = Lines[cli]->GetSize(SIZE_CURSOR_XMAX);
+ t_cur.Ymin = Lines[cli]->GetSize(SIZE_CURSOR_YMIN);
+ t_cur.Ymax = Lines[cli]->GetSize(SIZE_CURSOR_YMAX);
+ mev.StateFlags = 0; mev.Action = MOUSE_LBUP;
+ mev.x = iround((t_cur.Xmax+t_cur.Xmin)/2.0);
+ mev.y = iround((t_cur.Ymax+t_cur.Ymin)/2.0);
+ i = o->un2ix(TextDef.fSize*si); j = o->un2iy(TextDef.fSize*csi);
+ if(cmd == CMD_CURRUP && cli > 0 && Lines[cli-1]) {
+ Lines[cli-1]->CalcCursorPos(mev.x -= i, mev.y -= j, o);
+ o->ShowMark(CurrGO = CurrLabel = Lines[cli-=1], MRK_GODRAW);
+ return Command(CMD_SETFOCUS, Lines[cli], o);
+ }
+ if(cmd == CMD_CURRDOWN && cli < (nLines-1) && Lines[cli+1]) {
+ Lines[cli+1]->CalcCursorPos(mev.x += i, mev.y += j, o);
+ o->ShowMark(CurrGO = CurrLabel = Lines[cli+=1], MRK_GODRAW);
+ return Command(CMD_SETFOCUS, Lines[cli], o);
+ }
+ }
+ else return false;
+ break;
+ case CMD_SCALE:
+ scale = (scaleINFO*)tmpl;
+ if((flags & 0x03)!= LB_X_DATA) fPos.fx *= scale->sx.fy;
+ if((flags & 0x30)!= LB_Y_DATA) fPos.fy *= scale->sy.fy;
+ fDist.fx *= scale->sx.fy; fDist.fy *= scale->sy.fy;
+ TextDef.fSize *= scale->sx.fy; TextDef.iSize = 0;
+ return true;
+ case CMD_SELECT:
+ if(o && tmpl) for(i = 0; i < nLines; i++){
+ o->SetTextSpec(&TextDef);
+ if(Lines[i] && ((POINT*)tmpl)->y > Lines[i]->rDims.top && ((POINT*)tmpl)->y <
+ Lines[i]->rDims.bottom) return Lines[i]->Command(cmd, tmpl, o);
+ }
+ break;
+ case CMD_DELOBJ:
+ if(parent && Lines) for(i = 0; i< nLines; i++)
+ if(Lines[i] && Lines[i] == (Label*)tmpl) return parent->Command(cmd, this, o);
+ break;
+ case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ else if(o) DoPlot(o);
+ break;
+ case CMD_MOVE:
+ if(parent && parent->Id == GO_LEGITEM) return parent->Command(cmd, tmpl, o);
+ Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ case CMD_UNDO_MOVE:
+ if(!(flags & 0x03)) fPos.fx += ((lfPOINT*)tmpl)[0].fx;
+ if(!(flags & 0x30)) fPos.fy += ((lfPOINT*)tmpl)[0].fy;
+ if(o && parent){
+ o->StartPage(); parent->DoPlot(o); o->EndPage();
+ }
+ return true;
+ }
+ return false;
+}
+
+void
+mLabel::Track(POINT *p, anyOutput *o)
+{
+ int i;
+
+ if(!parent) return;
+ if(parent->Id == GO_LEGITEM){
+ parent->Track(p, o);
+ return;
+ }
+ for(i = 0; i < nLines; i++) if(Lines[i]){
+ if(!i) memcpy(&rDims, &Lines[i]->rDims, sizeof(RECT));
+ else {
+ UpdateMinMaxRect(&rDims, Lines[i]->rDims.left, Lines[i]->rDims.top);
+ UpdateMinMaxRect(&rDims, Lines[i]->rDims.right, Lines[i]->rDims.bottom);
+ }
+ }
+ o->UpdateRect(&rDims, false);
+ Id = 0L; //disable reentrance from Label objects
+ for(i = 0; i < nLines; i++) if(Lines[i]) Lines[i]->Track(p, o);
+ Id = GO_MLABEL; //enable entrance from Label objects
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// a rectangular range to accept any text
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+TextFrame::TextFrame(GraphObj *parent, DataObj *data, lfPOINT *p1, lfPOINT *p2, char *txt)
+ :GraphObj(parent, data)
+{
+ FileIO(INIT_VARS); lspc = 1.0;
+ pos1.fx = p1->fx; pos1.fy = p1->fy; pos2.fx = p2->fx; pos2.fy = p2->fy;
+ if(txt && txt[0]) {
+ text = (unsigned char*)memdup(txt, (int)strlen(txt)+1, 0);
+ }
+ else if(lines = (unsigned char**)malloc(sizeof(char*))){
+ if(lines[0] = (unsigned char*)malloc(TF_MAXLINE))lines[0][0] = 0;
+ nlines = 1;
+ }
+ Id = GO_TEXTFRAME;
+}
+
+TextFrame::TextFrame(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ moveable = 1; bModified = false;
+}
+
+TextFrame::~TextFrame()
+{
+ int i;
+
+ if(text)free(text); text = 0L;
+ if(drc) delete(drc); drc = 0L;
+ if(tm_rec) free(tm_rec); tm_rec = 0L;
+ if(lines) {
+ for(i = 0; i < nlines; i++) if(lines[i]) free(lines[i]);
+ free(lines); lines = 0L;
+ }
+ HideTextCursor();
+}
+double
+TextFrame::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_XPOS: return pos1.fx;
+ case SIZE_XPOS+1: return pos2.fx;
+ case SIZE_YPOS: return pos1.fy;
+ case SIZE_YPOS+1: return pos2.fy;
+ case SIZE_GRECT_LEFT: case SIZE_GRECT_TOP:
+ case SIZE_GRECT_RIGHT: case SIZE_GRECT_BOTTOM:
+ if(parent) return parent->GetSize(select);
+ break;
+ }
+ return 0.0;
+}
+
+bool
+TextFrame::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_XPOS: pos1.fx = value; return bResize = true;
+ case SIZE_XPOS+1: pos2.fx = value; return bResize = true;
+ case SIZE_YPOS: pos1.fy = value; return bResize = true;
+ case SIZE_YPOS+1: pos2.fy = value; return bResize = true;
+ }
+ return false;
+}
+
+void
+TextFrame::DoMark(anyOutput *o, bool mark)
+{
+ RECT upd;
+
+ if(has_m1 && has_m2) TextMark(o, 3);
+ has_m1 = has_m2 = false;
+ if(!drc) drc = new dragRect(this, 0);
+ memcpy(&upd, &rDims, sizeof(RECT));
+ if(mark){
+ if(drc) drc->DoPlot(o); ShowCursor(o);
+ }
+ else if(parent) parent->DoPlot(o);
+ IncrementMinMaxRect(&upd, 6);
+ o->UpdateRect(&upd, false);
+}
+
+void
+TextFrame::DoPlot(anyOutput *o)
+{
+ int i, j, x1, y1, x2, y2;
+ double tmp, dx, dy;
+
+ if(!o) return;
+ if(parent){ //if this object is part of a dialog we dont have a parent
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ x1 = o->co2ix(pos1.fx+dx); y1 = o->co2iy(pos1.fy+dy);
+ x2 = o->co2ix(pos2.fx+dx); y2 = o->co2iy(pos2.fy+dy);
+ ipad.left = o->un2ix(pad.Xmin); ipad.right = o->un2ix(pad.Xmax);
+ ipad.top = o->un2iy(pad.Ymin); ipad.bottom = o->un2iy(pad.Ymax);
+ }
+ else {
+ dx = dy = 0.0;
+ x1 = (int)pos1.fx; y1 = (int)pos1.fy; x2 = (int)pos2.fx; y2 = (int)pos2.fy;
+ ipad.left = ipad.right = ipad.top = ipad.bottom = 4;
+ fmt_txt.EditMode(true);
+ }
+ if(pos1.fx > pos2.fx) {
+ tmp = pos2.fx; pos2.fx = pos1.fx; pos1.fx = tmp;
+ }
+ if(pos1.fy > pos2.fy) {
+ tmp = pos2.fy; pos2.fy = pos1.fy; pos1.fy = tmp;
+ }
+ o->SetLine(&Line); o->SetFill(&Fill);
+ o->oRectangle(x1, y1, x2, y2, name);
+ SetMinMaxRect(&rDims, x1, y1, x2, y2);
+ x1 += ipad.left; y1 += ipad.top;
+ TextDef.iSize = o->un2iy(TextDef.fSize);
+#ifdef _WINDOWS
+ linc = o->un2iy(TextDef.fSize*lspc);
+#else
+ linc = o->un2iy(TextDef.fSize*lspc*1.2);
+#endif
+ o->SetTextSpec(&TextDef); y1 += linc;
+ if(text && text[0] && !(lines)) text2lines(o);
+ else if(bResize && lines) {
+ c_char = lines[cur_pos.y][cur_pos.x]; lines[cur_pos.y][cur_pos.x] = 0x01;
+ if(!c_char) lines[cur_pos.y][cur_pos.x+1] = 0x00;
+ lines2text(); text2lines(o); bResize = false;
+ o->ShowMark(this, MRK_GODRAW);
+ return;
+ }
+ if(has_m1 && has_m2) TextMark(o, 1);
+ for(i = 0; i < nlines; i++) {
+ if(lines[i] && lines[i][0]){
+ j = (int)strlen((char*)lines[i]);
+ if(lines[i][j-1] == '\n') {
+ lines[i][j-1] = 0;
+ fmt_txt.SetText(o, (char*)lines[i], &x1, &y1);
+ lines[i][j-1] = '\n';
+ }
+ else fmt_txt.SetText(o, (char*)lines[i], &x1, &y1);
+ }
+ y1 += linc;
+ }
+ if(has_m1 && has_m2) TextMark(o, 2);
+ bModified = bResize = false;
+}
+
+bool
+TextFrame::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ int i;
+
+ switch (cmd) {
+ case CMD_SELECT:
+ if(!o || !tmpl) return false;
+ CalcCursorPos(((POINT*)tmpl)->x, ((POINT*)tmpl)->y, o);
+ if(parent)o->ShowMark(this, MRK_GODRAW); ShowCursor(o);
+ return true;
+ case CMD_COPY:
+ return CopyText(o, false);
+ case CMD_SAVEPOS:
+ bModified = true;
+ Undo.SaveLFP(this, &pos1, 0L);
+ Undo.SaveLFP(this, &pos2, UNDO_CONTINUE);
+ return true;
+ case CMD_SCALE:
+ if(tmpl) {
+ pos1.fx = ((scaleINFO*)tmpl)->sx.fx + pos1.fx * ((scaleINFO*)tmpl)->sx.fy;
+ pos1.fy = ((scaleINFO*)tmpl)->sy.fx + pos1.fy * ((scaleINFO*)tmpl)->sy.fy;
+ pos2.fx = ((scaleINFO*)tmpl)->sx.fx + pos2.fx * ((scaleINFO*)tmpl)->sx.fy;
+ pos2.fy = ((scaleINFO*)tmpl)->sy.fx + pos2.fy * ((scaleINFO*)tmpl)->sy.fy;
+ TextDef.fSize *= ((scaleINFO*)tmpl)->sy.fy; TextDef.iSize = 0;
+ pad.Xmax *= ((scaleINFO*)tmpl)->sx.fy; pad.Xmin *= ((scaleINFO*)tmpl)->sx.fy;
+ pad.Ymax *= ((scaleINFO*)tmpl)->sy.fy; pad.Ymin *= ((scaleINFO*)tmpl)->sy.fy;
+ Line.width *= ((scaleINFO*)tmpl)->sy.fy; Line.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ FillLine.width *= ((scaleINFO*)tmpl)->sy.fy; FillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ }
+ return true;
+ case CMD_GETTEXT: case CMD_ALLTEXT:
+ if(lines && lines[0] && lines[0][0] && nlines) {
+ lines2text(); i = rlp_strcpy((char*)tmpl, TMP_TXT_SIZE-2, (char*)text);
+ while(i && ((char*)tmpl)[i-1] == '\n') i--;
+ ((char*)tmpl)[i++] = '\n'; ((char*)tmpl)[i] = 0;
+ return true;
+ }
+ return false;
+ case CMD_ADDCHAR:
+ if(tmpl && o) AddChar(o, *((unsigned char*)tmpl));
+ return true;
+ case CMD_DELETE:
+ if(o) DelChar(o);
+ return true;
+ case CMD_SHIFTLEFT:
+ if(!has_m1) {
+ m1_pos.x = cur_pos.x; m1_pos.y = cur_pos.y;
+ }
+ has_m1 = has_m2 = true;
+ case CMD_CURRLEFT:
+ if(!(lines[cur_pos.y]))return false;
+ if(cmd == CMD_CURRLEFT && has_m1 && has_m2) TextMark(o, 3);
+ if(cur_pos.x > 0) {
+ i = 0; fmt_txt.SetText(0L,(char*)lines[cur_pos.y], &i, &i);
+ i = cur_pos.x; fmt_txt.cur_left(&i);
+ cur_pos.x = i;
+ }
+ else if(cur_pos.y) {
+ cur_pos.y--; cur_pos.x = (int)strlen((char*)lines[cur_pos.y]);
+ }
+ if(cmd == CMD_SHIFTLEFT){
+ m2_pos.x = cur_pos.x; m2_pos.y = cur_pos.y;
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ }
+ ShowCursor(o);
+ return false;
+ case CMD_SHIFTRIGHT:
+ if(!has_m1) {
+ m1_pos.x = cur_pos.x; m1_pos.y = cur_pos.y;
+ }
+ has_m1 = has_m2 = true;
+ case CMD_CURRIGHT:
+ if(!(lines[cur_pos.y]))return false;
+ if(cmd == CMD_CURRIGHT && has_m1 && has_m2) TextMark(o, 3);
+ if(cur_pos.x >= (int)strlen((char*)lines[cur_pos.y])) {
+ if(cur_pos.y < (nlines-1)) {
+ cur_pos.y++; cur_pos.x = 0;
+ }
+ else if(cur_pos.y == (nlines-1) && lines[cur_pos.y][0]) {
+ if(!(lines = (unsigned char**)realloc(lines, (nlines+1)*sizeof(char*))))return false;
+ if(!(lines[cur_pos.y+1] = (unsigned char*)malloc(TF_MAXLINE))) return false;
+ cur_pos.y++; cur_pos.x = 0; nlines++;
+ lines[cur_pos.y][0] = 0;
+ }
+ }
+ else {
+ i = 0; fmt_txt.SetText(0L,(char*)lines[cur_pos.y], &i, &i);
+ i = cur_pos.x; fmt_txt.cur_right(&i);
+ cur_pos.x = i;
+ }
+ if(cmd == CMD_SHIFTRIGHT){
+ m2_pos.x = cur_pos.x; m2_pos.y = cur_pos.y;
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ }
+ ShowCursor(o);
+ return false;
+ case CMD_SHIFTUP:
+ if(!has_m1) {
+ m1_pos.x = cur_pos.x; m1_pos.y = cur_pos.y;
+ }
+ has_m1 = has_m2 = true;
+ case CMD_CURRUP:
+ if(cmd == CMD_CURRUP && has_m1 && has_m2) TextMark(o, 3);
+ if(cur_pos.y && o) {
+ i = ((Cursor.bottom + Cursor.top)>>1)-linc;
+ CalcCursorPos(Cursor.left, i, o);
+ if(cmd == CMD_SHIFTUP){
+ m2_pos.x = cur_pos.x; m2_pos.y = cur_pos.y;
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ }
+ ShowCursor(o);
+ return true;
+ }
+ return false;
+ case CMD_SHIFTDOWN:
+ if(!has_m1) {
+ m1_pos.x = cur_pos.x; m1_pos.y = cur_pos.y;
+ }
+ has_m1 = has_m2 = true;
+ case CMD_CURRDOWN:
+ if(cmd == CMD_CURRDOWN && has_m1 && has_m2) TextMark(o, 3);
+ if(cur_pos.y < (nlines-1) && o && lines[cur_pos.y][0]) {
+ i = ((Cursor.bottom + Cursor.top)>>1)+linc;
+ if(i >= (rDims.bottom-ipad.bottom)) return false;
+ CalcCursorPos(Cursor.left, i, o);
+ if(cmd == CMD_SHIFTDOWN){
+ m2_pos.x = cur_pos.x; m2_pos.y = cur_pos.y;
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ }
+ ShowCursor(o);
+ return true;
+ }
+ return false;
+ case CMD_POS_FIRST:
+ if(has_m1 && has_m2) TextMark(o, 3);
+ cur_pos.x = 0; ShowCursor(o);
+ return true;
+ case CMD_POS_LAST:
+ if(has_m1 && has_m2) TextMark(o, 3);
+ cur_pos.x = (int)strlen((char*)lines[cur_pos.y]);
+ ShowCursor(o);
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && (!(CurrGO) || !has_m2) && o){
+ CalcCursorPos(mev->x, mev->y, o);
+ if(has_m1 && has_m2) {
+ if(o)DoPlot(o); o->UpdateRect(&rDims, false);
+ CurrGO = this; ShowCursor(o);
+ return true;
+ }
+ return o->ShowMark(this, MRK_GODRAW);
+ }
+ else if(CurrGO == this && o){
+ ShowCursor(o);
+ return IsInRect(&rDims, mev->x, mev->y);
+ }
+ break;
+ case MOUSE_LBDOWN:
+ if(has_m1 && has_m2) {
+ has_m1 = has_m2 = false;
+ if(o)DoPlot(o); o->UpdateRect(&rDims, false);
+ }
+ has_m1 = has_m2 = false;
+ case MOUSE_MOVE:
+ if(!(mev->StateFlags & 0x1)) return false;
+ if(!IsInRect(&rDims, mev->x, mev->y))return false;
+ if(!CurrGO) CurrGO = this;
+ CalcCursorPos(mev->x, mev->y, o);
+ if(!has_m1) {
+ m1_pos.x = m2_pos.x = cur_pos.x; m1_pos.y = m2_pos.y = cur_pos.y;
+ return has_m1 = true;
+ }
+ else if(cur_pos.x != m2_pos.x || cur_pos.y != m2_pos.y) {
+ m2_pos.x = cur_pos.x; m2_pos.y = cur_pos.y;
+ has_m2 = true;
+ if(o)DoPlot(o); o->UpdateRect(&rDims, false);
+ return true;
+ }
+ return true;
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_TEXTFRAME;
+ return true;
+ case CMD_PASTE:
+ return DoPaste(o);
+ case CMD_MOVE:
+ bModified = true;
+ Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ case CMD_UNDO_MOVE:
+ pos1.fx += ((lfPOINT*)tmpl)[0].fx; pos1.fy += ((lfPOINT*)tmpl)[0].fy;
+ pos2.fx += ((lfPOINT*)tmpl)[0].fx; pos2.fy += ((lfPOINT*)tmpl)[0].fy;
+ CurrGO = this;
+ case CMD_REDRAW:
+ if(parent){
+ if(o && cmd == CMD_REDRAW) DoPlot(o); //trickle down ?
+ if(!o && cmd == CMD_REDRAW) {
+ //coming from Undo
+ bModified = true;
+ if(lines) {
+ for(i = 0; i < nlines; i++) if(lines[i]) free(lines[i]);
+ free(lines); lines = 0L;
+ }
+ HideTextCursor(); cur_pos.x = cur_pos.y = 0;
+ parent->Command(CMD_REDRAW, tmpl, o);
+ }
+ else parent->Command(CMD_REDRAW, tmpl, o);
+ }
+ return true;
+ case CMD_SETSCROLL:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ case CMD_GETTEXTDEF:
+ if(!tmpl) return false;
+ memcpy(tmpl, &TextDef, sizeof(TextDEF));
+ return true;
+ case CMD_SETTEXTDEF:
+ if(!tmpl)return false;
+ memcpy(&TextDef, tmpl, sizeof(TextDEF));
+ TextDef.text = 0L;
+ return true;
+ case CMD_SETTEXT:
+ if(lines) {
+ for(i = 0; i < nlines; i++) if(lines[i]) free(lines[i]);
+ free(lines); lines = 0L;
+ }
+ if(text) free(text); text = 0L;
+ if(tmpl && *((char*)tmpl)) text = (unsigned char*)memdup(tmpl, (int)strlen(((char*)tmpl))+1, 0);
+ return true;
+ }
+ return false;
+}
+
+void
+TextFrame::Track(POINT *p, anyOutput *o)
+{
+ POINT tpts[5];
+ RECT old_rc;
+ double dx, dy;
+
+ if(o && parent){
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ memcpy(&old_rc, &rDims, sizeof(rDims));
+ o->UpdateRect(&rDims, false);
+ tpts[0].x = tpts[1].x = tpts[4].x = o->co2ix(pos1.fx+dx)+p->x;
+ tpts[0].y = tpts[3].y = tpts[4].y = o->co2iy(pos1.fy+dy)+p->y;
+ tpts[1].y = tpts[2].y = o->co2iy(pos2.fy+dy)+p->y;
+ tpts[2].x = tpts[3].x = o->co2ix(pos2.fx+dx)+p->x;
+ UpdateMinMaxRect(&rDims, tpts[0].x, tpts[0].y);
+ UpdateMinMaxRect(&rDims, tpts[2].x, tpts[2].y);
+ if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
+ rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
+ o->ShowLine(tpts, 5, Line.color);
+ }
+}
+
+void *
+TextFrame::ObjThere(int x, int y)
+{
+ if(drc) return drc->ObjThere(x, y);
+ return 0L;
+}
+
+void
+TextFrame::text2lines(anyOutput *o)
+{
+ int i, j, w, h, cl, maxlines, maxw;
+ char tmp_line[TF_MAXLINE];
+ bool hasMark = false;
+
+ if(lines) {
+ for(i = 0; i < nlines; i++) if(lines[i]) free(lines[i]);
+ free(lines); lines = 0L;
+ }
+ has_m1 = has_m2 = false;
+ nlines = 0;
+ if(!text || !text[0]) return;
+ maxlines = (rDims.bottom -rDims.top)/linc +1;
+ maxw = rDims.right - rDims.left - ipad.left - ipad.right;
+ lines = (unsigned char**)calloc(maxlines, sizeof(char*));
+ for(cl = cpos = w = h = 0; cl < maxlines && text[cpos]; cl++) {
+ if(!(lines[cl] = (unsigned char*)malloc(TF_MAXLINE))) return;
+ for(i = 0; text[cpos] && i < TF_MAXLINE; i++) {
+ tmp_line[i] = text[cpos++]; tmp_line[i+1] = 0;
+ fmt_txt.SetText(0L, tmp_line, &w, &h);
+ if(!(fmt_txt.oGetTextExtent(o, &w, &h, i))) break;
+ if(tmp_line[i] == '\n'){
+ break; //new line character found
+ }
+ if(tmp_line[i] < ' ') switch(tmp_line[i]) {
+ case 0x01:
+ if(c_char == 0 && text[cpos]) c_char = text[cpos++]; //cursor at end of line
+ hasMark = true; break;
+ case 0x02: case 0x03:
+ hasMark = true; break;
+ }
+ else if(w >= maxw){
+ for(j = i; j > (i>>1); j--) {
+ if(tmp_line[j] == ' ' || tmp_line[j] == '-' || tmp_line[j] < ' ') break;
+ }
+ if(j == (i>>1)) {
+ cpos--; tmp_line[i] = 0;
+ }
+ else {
+ for(tmp_line[j+1] = 0; j < i; j++, cpos--);
+ }
+ break;
+ }
+ }
+ if(i || tmp_line[i] == '\n') rlp_strcpy((char*)lines[cl], TF_MAXLINE, tmp_line);
+ else lines[cl][0] = 0;
+ }
+ nlines = cl;
+ if(hasMark)procTokens();
+}
+
+void
+TextFrame::lines2text()
+{
+ int i;
+
+ if(text) free(text); cpos = 0;
+ text = (unsigned char*)malloc(csize = 1000);
+ for(i = 0; i < nlines; i++) {
+ if(lines[i] && lines[i][0]) add_to_buff((char**)&text, &cpos, &csize, (char*)lines[i], 0);
+ }
+}
+
+void
+TextFrame::AddChar(anyOutput *o, unsigned char c)
+{
+ int i, j, h, w, maxw;
+
+ if(cur_pos.y >= nlines) return;
+ if(!lines || !lines[cur_pos.y]) return;
+ if(c == '\r') c = '\n';
+ if(has_m1 && has_m2){
+ TmpTxt[0] = c; TmpTxt[1] = 0;
+ if(c == 8) ReplMark(o, "");
+ else if(c >= 32 || c == '\n') ReplMark(o, TmpTxt);
+ return;
+ }
+ else if(!text) {
+ lines2text();
+ Undo.TextBuffer(this, &csize, &cpos, &text, 0L, o);
+ }
+ maxw = rDims.right - rDims.left - ipad.left - ipad.right;
+ i = j = (int)strlen((char*)lines[cur_pos.y])+1;
+ has_m1 = has_m2 = false;
+ if(c >= 32 || c == '\n') {
+ while(j) {
+ lines[cur_pos.y][j] = lines[cur_pos.y][j-1]; j--;
+ if(j == cur_pos.x){
+ lines[cur_pos.y][j] = c; j = 0;
+ cur_pos.x++;
+ }
+ }
+ fmt_txt.SetText(0L, (char*)lines[cur_pos.y], &j, &j);
+ fmt_txt.oGetTextExtent(o, &w, &h, i);
+ if(w >= maxw || c == '\n' || (c == ' ' && w >=(maxw>>1))) {
+ c_char = lines[cur_pos.y][cur_pos.x]; lines[cur_pos.y][cur_pos.x] = 0x01;
+ if(!c_char) lines[cur_pos.y][cur_pos.x+1] = 0x00;
+ lines2text(); Undo.TextBuffer(this, &csize, &cpos, &text, 0L, o); text2lines(o);
+ }
+ }
+ else if(c == 8 && (cur_pos.x || cur_pos.y)) { //Backspace
+ if(!cur_pos.x) Command(CMD_CURRLEFT, 0L, o);
+ Command(CMD_CURRLEFT, 0L, o); DelChar(o);
+ return;
+ }
+ else return;
+ DoPlot(o); o->UpdateRect(&rDims, false); ShowCursor(o);
+}
+
+void
+TextFrame::DelChar(anyOutput *o)
+{
+ int i;
+ if(has_m1 && has_m2){
+ ReplMark(o, ""); return;
+ }
+ if(lines[cur_pos.y][cur_pos.x]) {
+ lines2text(); Undo.TextBuffer(this, &csize, &cpos, &text, 0L, o);
+ for(i = cur_pos.x; ; i++) {
+ if(!(lines[cur_pos.y][i] = lines[cur_pos.y][i+1])) break;
+ }
+ c_char = lines[cur_pos.y][cur_pos.x]; lines[cur_pos.y][cur_pos.x] = 0x01;
+ if(!c_char) lines[cur_pos.y][cur_pos.x+1] = 0x00;
+ lines2text(); text2lines(o);
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ ShowCursor(o); return;
+ }
+ else if(cur_pos.y < (nlines-1)){
+ cur_pos.y++; cur_pos.x = 0;
+ DelChar(o); return;
+ }
+}
+
+void
+TextFrame::ReplMark(anyOutput *o, char *ntext)
+{
+ int i, j;
+
+ if(!has_m1 || !has_m2 || !o || !ntext) return;
+ lines2text();
+ Undo.TextBuffer(this, &csize, &cpos, &text, 0L, o);
+ for(i = cpos = 0; i < nlines && i < m1_cpos.y; i++) {
+ if(lines[i] && lines[i][0]) add_to_buff((char**)&text, &cpos, &csize, (char*)lines[i], 0);
+ }
+ if(m1_cpos.x)add_to_buff((char**)&text, &cpos, &csize, (char*)lines[i], m1_cpos.x);
+ add_to_buff((char**)&text, &cpos, &csize, ntext, 0); j = cpos;
+ if(m1_cpos.y == m2_cpos.y)add_to_buff((char**)&text, &cpos, &csize, (char*)(lines[i]+m2_cpos.x), 0);
+ for( ; i < nlines && i < m2_cpos.y; i++);
+ if(i == m2_cpos.y && m2_cpos.y > m1_cpos.y)add_to_buff((char**)&text, &cpos, &csize, (char*)(lines[i]+m2_cpos.x), 0);
+ for(i++; i < nlines; i++) {
+ if(lines[i] && lines[i][0]) add_to_buff((char**)&text, &cpos, &csize, (char*)lines[i], 0);
+ }
+ if(tm_rec)free(tm_rec); tm_rec = 0L; has_m1 = has_m2 = false;
+ if(text[j]) {
+ c_char = text[j]; text[j] = 0x01;
+ }
+ else if(i < (nlines-1) && lines[i+1] && lines[i+1][0]) {
+ c_char = lines[i+1][0]; lines[i+1][0] = 0x01;
+ }
+ else if(j == cpos){
+ c_char = 0; text[cpos++] = 0x01; text[cpos] = 0;
+ }
+ else cur_pos.x = cur_pos.y = 0;
+ text2lines(o); DoPlot(o); o->UpdateRect(&rDims, false);
+ ShowCursor(o);
+}
+
+void
+TextFrame::procTokens()
+{
+ int i, j;
+
+ for(i = 0; i < nlines; i++) {
+ if(lines[i] && lines[i][0]){
+ for(j = 0; lines[i][j]; j++) switch(lines[i][j]) {
+ case 0x01:
+ cur_pos.y = i; cur_pos.x = j;
+ lines[i][j] = c_char; c_char = '?';
+ break;
+ case 0x02:
+ m1_pos.y = i; m1_pos.x = j;
+ if(m1_char == 0x01) {
+ lines[i][j] = c_char; c_char = '?';
+ cur_pos.y = i; cur_pos.x = j;
+ }
+ else lines[i][j] = m1_char;
+ has_m1 = true; m1_char = '?';
+ break;
+ case 0x03:
+ m2_pos.y = i; m2_pos.x = j;
+ if(m2_char == 0x01) {
+ lines[i][j] = c_char; c_char = '?';
+ cur_pos.y = i; cur_pos.x = j;
+ }
+ else lines[i][j] = m2_char;
+ has_m2 = true; m2_char = '?';
+ break;
+ }
+ }
+ }
+}
+
+bool
+TextFrame::DoPaste(anyOutput *o)
+{
+ int i, j, k;
+ char *ntxt;
+ unsigned char *ptxt;
+
+ if((ptxt = PasteText()) && ptxt[0]) {
+ lines2text(); Undo.TextBuffer(this, &csize, &cpos, &text, 0L, o);
+ if(!(ntxt = (char*)malloc(strlen((char*)ptxt)+1))) return false;
+ for(i = j = cpos = 0; ptxt[i]; i++) {
+ if(ptxt[i] >= ' ' || ptxt[i] == '\n') ntxt[j++] = ptxt[i];
+ else if(ptxt[i] == 9)ntxt[j++] = ' '; //convert tab->space
+ }
+ ntxt[j] = 0;
+ if(!ntxt[0]) {
+ free(ntxt); return false;
+ }
+ if(has_m1 && has_m2) {
+ ReplMark(o, ntxt); free(ntxt);
+ return true;
+ }
+ m1_char = ntxt[0]; ntxt[0] = 0x02;
+ ntxt[j] = 0; if(text) free(text);
+ if(!(text = (unsigned char*)malloc(csize = 1000)))return false;
+ for(i = k = 0, text[0] = 0; i < nlines; i++) {
+ if(lines[i] && lines[i][0]){
+ if(i == cur_pos.y) {
+ if(cur_pos.x) add_to_buff((char**)&text, &cpos, &csize, (char*)lines[i], cur_pos.x);
+ add_to_buff((char**)&text, &cpos, &csize, ntxt, 0); k = cpos;
+ add_to_buff((char**)&text, &cpos, &csize, (char*)lines[i]+cur_pos.x, 0);
+ free(ntxt); ntxt = 0L;
+ }
+ else add_to_buff((char**)&text, &cpos, &csize, (char*)lines[i], 0);
+ }
+ }
+ if(ntxt) {
+ add_to_buff((char**)&text, &cpos, &csize, ntxt, 0); k = cpos;
+ }
+ m2_char = 0x01;
+ if(text[k]) {
+ c_char = text[k]; text[k] = 0x03;
+ }
+ else if(i < (nlines-1) && lines[i+1] && lines[i+1][0]) {
+ c_char = lines[i+1][0]; lines[i+1][0] = 0x03;
+ }
+ else if(k == cpos){
+ c_char = 0; text[cpos++] = 0x03; text[cpos] = 0;
+ }
+ text2lines(o); DoPlot(o);
+ o->UpdateRect(&rDims, false);
+ ShowCursor(o); if(ntxt) free(ntxt);
+ }
+ return false;
+}
+void
+TextFrame::TextMark(anyOutput *o, int mode)
+{
+ int i, j, w, h;
+ LineDEF ld;
+ FillDEF fd;
+
+ if(m1_pos.y > m2_pos.y) {
+ m1_cpos.y = m2_pos.y; m1_cpos.x = m2_pos.x;
+ m2_cpos.y = m1_pos.y; m2_cpos.x = m1_pos.x;
+ }
+ else if(m1_pos.y == m2_pos.y && m1_pos.x > m2_pos.x) {
+ m1_cpos.x = m2_pos.x; m2_cpos.x = m1_pos.x;
+ m1_cpos.y = m2_cpos.y = m1_pos.y;
+ }
+ else {
+ m1_cpos.y = m1_pos.y; m1_cpos.x = m1_pos.x;
+ m2_cpos.y = m2_pos.y; m2_cpos.x = m2_pos.x;
+ }
+ if(!has_m1 || !has_m2 || !o) return;
+ if(m1_pos.y == m2_pos.y && m1_pos.x == m2_pos.x) return;
+ if(mode == 1){ //create background mark
+ if(tm_rec)free(tm_rec); tm_rec = 0L;
+ if((tm_c = m2_cpos.y - m1_cpos.y +1)<1) return;
+ if(!(tm_rec = (RECT*)malloc(tm_c * sizeof(RECT))))return;
+ for(i = w = 0, j = m1_cpos.y; j <= m2_cpos.y; i++, j++) {
+ h = TextDef.iSize;
+ if(j == m1_cpos.y) {
+ fmt_txt.SetText(0L, (char*)lines[j], 0L, 0L);
+ if(m1_cpos.x) fmt_txt.oGetTextExtent(o, &w, &h, m1_cpos.x);
+ else w = 0;
+ tm_rec[0].left = w + rDims.left + ipad.left + 1;
+ fmt_txt.SetText(0L, (char*)(lines[j]+m1_cpos.x), 0L, 0L);
+ fmt_txt.oGetTextExtent(o, &w, &h, 0);
+ tm_rec[0].right = tm_rec[0].left + w;
+ }
+ if(j == m2_cpos.y) {
+ fmt_txt.SetText(0L, (char*)lines[j], 0L, 0L);
+ if(m2_cpos.x) fmt_txt.oGetTextExtent(o, &w, &h, m2_cpos.x);
+ else w = 0;
+ tm_rec[i].right = w + rDims.left + ipad.left - 1;
+ if(m2_cpos.y > m1_cpos.y) {
+ tm_rec[i].left = rDims.left + ipad.left;
+ }
+ }
+ else if(j < m2_cpos.y && j > m1_cpos.y) {
+ tm_rec[i].left = rDims.left + ipad.left;
+ tm_rec[i].top = j * linc + rDims.top + ipad.top;
+ fmt_txt.SetText(0L, (char*)lines[j], 0L, 0L);
+ fmt_txt.oGetTextExtent(o, &w, &h, 0);
+ tm_rec[i].right = w + rDims.left + ipad.left;
+ }
+ tm_rec[i].top = j * linc + rDims.top + ipad.top;
+ tm_rec[i].bottom = tm_rec[i].top + linc;
+ }
+ ld.color = 0x0000ffff; ld.patlength = 1.0;
+ ld.pattern = 0x0L; ld.width = 0;
+ fd.color = fd.color2 = ld.color; fd.hatch = 0L;
+ fd.scale = 1.0; fd.type = 0;
+ o->SetLine(&ld); o->SetFill(&fd);
+ for(i = 0; i < tm_c; i++) {
+ o->oRectangle(tm_rec[i].left, tm_rec[i].top, tm_rec[i].right, tm_rec[i].bottom, 0L);
+ }
+ }
+ if(mode == 2){ //invert rectangles
+ if(tm_rec) for(i = 0; i < tm_c; i++) {
+ o->CopyBitmap(tm_rec[i].left, tm_rec[i].top, o, tm_rec[i].left, tm_rec[i].top,
+ tm_rec[i].right - tm_rec[i].left, tm_rec[i].bottom - tm_rec[i].top, true);
+ }
+ }
+ if(mode == 3){ //clear mark
+ if(tm_rec)free(tm_rec); tm_rec = 0L;
+ tm_c = 0; has_m1 = has_m2 = false;
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ }
+}
+
+bool
+TextFrame::CopyText(anyOutput *o, bool b_cut)
+{
+ int i, csize, pos = 0;
+ char *ntxt;
+
+ if(!lines || !lines[0][0] || !o) return false;
+ if(!has_m1 || !has_m2) {
+ m1_pos.x = m1_pos.y = 0; m2_pos.y = nlines-1;
+ if(lines[nlines-1]) m2_pos.x = (int)strlen((char*)lines[nlines-1]);
+ else m2_pos.x = 0; has_m1 = has_m2 = true;
+ DoPlot(o); o->UpdateRect(&rDims, false);
+ return CopyText(o, false);
+ }
+ if(!(ntxt = (char*)malloc(csize = 1000))) return false;
+ if(m1_cpos.y == m2_cpos.y) {
+ add_to_buff(&ntxt, &pos, &csize, (char*)(lines[m1_cpos.y]) + m1_cpos.x, m2_cpos.x - m1_cpos.x);
+ ::CopyText(ntxt, pos); free(ntxt);
+ }
+ else if(m1_cpos.y < m2_cpos.y){
+ add_to_buff(&ntxt, &pos, &csize, (char*)(lines[m1_cpos.y]) + m1_cpos.x, 0);
+ for(i = m1_cpos.y; i < m2_cpos.y; i++) {
+ add_to_buff(&ntxt, &pos, &csize, (char*)(lines[i]), 0);
+ }
+ add_to_buff(&ntxt, &pos, &csize, (char*)(lines[i]), m2_pos.x);
+ ::CopyText(ntxt, pos); free(ntxt);
+ }
+ else {
+ free(ntxt); return false;
+ }
+ if(b_cut) ReplMark(o, "");
+ return true;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The segment object is either a pie slice or a ring segment
+//
+segment::segment(GraphObj *par, DataObj *d, lfPOINT *c, double r1, double r2,
+ double a1, double a2):GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ segFill.hatch = &segFillLine;
+ segFill.color = 0x00c0c0c0L;
+ fCent.fx = c->fx; fCent.fy = c->fy;
+ radius1 = r1; radius2 = r2;
+ angle1 = a1; angle2 = a2;
+ Id = GO_SEGMENT;
+ bModified = false;
+}
+
+segment::segment(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+segment::~segment()
+{
+ if(pts && nPts) free(pts);
+ if(bModified) Undo.InvalidGO(this);
+}
+
+bool
+segment::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_XPOS: fCent.fx = value; break;
+ case SIZE_YPOS: fCent.fy = value; break;
+ case SIZE_RADIUS1: radius1 = value; break;
+ case SIZE_RADIUS2: radius2 = value; break;
+ case SIZE_ANGLE1: angle1 = value; break;
+ case SIZE_ANGLE2: angle2 = value; break;
+ default: return false;
+ }
+ return true;
+}
+
+void
+segment::DoPlot(anyOutput *o)
+{
+ double dsize, dpt, frx1, frx2, dtmp, da, dda, sia, csia;
+ int i, n, npt = 12;
+ POINT np, of, cp, *tmppts;
+
+ if(!o || angle1 == angle2) return;
+ dsize = angle1 > angle2 ? angle1 -angle2 : (angle1+360.0)-angle2;
+ dpt = dsize*0.01745329252; //degrees to rad
+ frx1 = (double)o->un2fix(radius1);
+ frx2 = (double)o->un2fix(radius2);
+ dtmp = frx1*dpt;
+ npt += (int)(dtmp < dsize ? dtmp : dsize);
+ dtmp = frx2*dpt;
+ npt += (int)(dtmp < dsize ? dtmp : dsize);
+ if(!(pts = (POINT*)malloc(npt*sizeof(POINT))))return;
+ nPts = 0;
+ n = (dtmp < dsize) ? (int)dtmp : (int)dsize;
+ while (n<2) n++;
+ da = angle1*0.01745329252;
+ dda = (dsize*0.01745329252)/(double)n;
+ sia = sin(0.5*((angle2 < angle1 ? angle1 : angle1 +360) + angle2) * 0.01745329252);
+ csia = cos(0.5*((angle2 < angle1 ? angle1 : angle1 +360) + angle2) * 0.01745329252);
+ of.x = o->un2ix(shift * csia);
+ of.y = - (o->un2iy(shift * sia));
+ cp.x = o->co2ix(fCent.fx + (parent ? parent->GetSize(SIZE_GRECT_LEFT): 0.0));
+ cp.y = o->co2iy(fCent.fy + (parent ? parent->GetSize(SIZE_GRECT_TOP): 0.0));
+ for(i = 0; i < n; i++) {
+ sia = sin(da); csia = cos(da);
+ np.x = of.x + cp.x; np.y = of.y + cp.y;
+ np.x += o->un2ix(csia*radius2); np.y -= o->un2iy(sia*radius2);
+ AddToPolygon(&nPts, pts, &np);
+ da -= dda;
+ }
+ sia = sin(angle2 *0.01745329252);
+ csia = cos(angle2 *0.01745329252);
+ np.x = of.x + cp.x; np.y = of.y + cp.y;
+ np.x += o->un2ix(csia*radius2); np.y -= o->un2iy(sia*radius2);
+ AddToPolygon(&nPts, pts, &np);
+ dtmp = frx1*dpt;
+ n = dtmp < dsize ? (int)dtmp : (int)dsize;
+ da = angle2*0.01745329252;
+ if(n>1)dda = (dsize*0.01745329252)/(double)n;
+ else dda = 0.0;
+ for(i = 0; i < n; i++) {
+ sia = sin(da); csia = cos(da);
+ np.x = of.x + cp.x; np.y = of.y + cp.y;
+ np.x += o->un2ix(csia*radius1); np.y -= o->un2iy(sia*radius1);
+ AddToPolygon(&nPts, pts, &np);
+ da += dda;
+ }
+ sia = sin(angle1 *0.01745329252); csia = cos(angle1 *0.01745329252);
+ np.x = of.x + cp.x; np.y = of.y + cp.y;
+ np.x += o->un2ix(csia*radius1); np.y -= o->un2iy(sia*radius1);
+ AddToPolygon(&nPts, pts, &np);
+ if(nPts <3) return;
+ AddToPolygon(&nPts, pts, &pts[0]); //close polygon
+ o->SetLine(&segLine); o->SetFill(&segFill);
+ o->oPolygon(pts, nPts);
+ if(tmppts = (POINT*)realloc(pts, nPts *sizeof(POINT))) pts = tmppts;
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+ for(i = 2; i < nPts; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
+ i = 3*o->un2ix(segLine.width); //increase size of rectangle for marks
+ IncrementMinMaxRect(&rDims, i+6);
+}
+
+void
+segment::DoMark(anyOutput *o, bool mark)
+{
+ if(mark)InvertPolygon(pts, nPts, &segLine, &segFill, &rDims, o, mark);
+ else if(parent) {
+ parent->DoPlot(o);
+ o->UpdateRect(&rDims, false);
+ }
+}
+
+bool
+segment::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ FillDEF *TmpFill;
+ LegItem *leg;
+
+ switch (cmd) {
+ case CMD_SCALE:
+ fCent.fx *= ((scaleINFO*)tmpl)->sx.fy; fCent.fy *= ((scaleINFO*)tmpl)->sx.fy;
+ radius1 *= ((scaleINFO*)tmpl)->sx.fy; radius2 *= ((scaleINFO*)tmpl)->sx.fy;
+ segLine.width *= ((scaleINFO*)tmpl)->sx.fy; segLine.patlength *= ((scaleINFO*)tmpl)->sx.fy;
+ segFillLine.width *= ((scaleINFO*)tmpl)->sx.fy; segFillLine.patlength *= ((scaleINFO*)tmpl)->sx.fy;
+ segFill.scale *= ((scaleINFO*)tmpl)->sx.fy; shift *= ((scaleINFO*)tmpl)->sx.fy;
+ return true;
+ case CMD_LEGEND:
+ if(tmpl) {
+ leg = new LegItem(this, data, 0L, &segLine, &segFill, 0L);
+ if(!((Legend*)tmpl)->Command(CMD_DROP_OBJECT, leg, o)) DeleteGO(leg);
+ }
+ return true;
+ case CMD_MOUSE_EVENT:
+ switch (((MouseEvent*)tmpl)->Action) {
+ case MOUSE_LBUP:
+ if(ObjThere(((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y))
+ return o->ShowMark(CurrGO=this, MRK_GODRAW);
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ Id = GO_SEGMENT;
+ return true;
case CMD_REDRAW:
- if(is3D && o) {
- DoPlotText(o);
- is3D = false; //enable edit
- }
- else if(CurrGO == this) {
- if(parent && parent->parent) RedrawEdit(defDisp); //not a dialog
- else ShowCursor(defDisp); //dialog !
- }
- else return parent->Command(cmd, tmpl, o);
- return true;
- case CMD_MOVE:
- if(parent && (parent->Id == GO_MLABEL || parent->Id == GO_LEGITEM))
- return parent->Command(cmd, tmpl, o);
- Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
- case CMD_UNDO_MOVE:
- if(fmt_txt) delete(fmt_txt); fmt_txt = 0L;
- if(!(flags & 0x03)) fPos.fx += ((lfPOINT*)tmpl)[0].fx;
- if(!(flags & 0x30)) fPos.fy += ((lfPOINT*)tmpl)[0].fy;
- if(o){
- o->StartPage(); parent->DoPlot(o); o->EndPage();
- }
- return bModified = true;
- }
- return false;
-}
-
-void *
-Label::ObjThere(int x, int y)
-{
- POINT p1;
-
- if(IsInRect(&rDims, p1.x = x, p1.y = y) && IsInPolygon(&p1, pts, 5))
- return this;
- return 0L;
-}
-
-void
-Label::Track(POINT *p, anyOutput *o)
-{
- POINT *tpts;
- RECT old_rc;
- int i;
-
- if(!parent) return;
- if(parent->Id == GO_MLABEL || parent->Id == GO_LEGITEM){
- parent->Track(p, o);
- return;
- }
- if(o && (tpts = (POINT*)malloc(5*sizeof(POINT)))){
- memcpy(&old_rc, &rDims, sizeof(rDims));
- //note: mLabel set Id to zero upon trackking
- // thus rectangle is not updated if parent is a mLabel
- if(parent->Id) o->UpdateRect(&rDims, false);
- for(i = 0; i < 5; i++) {
- tpts[i].x = pts[i].x+p->x; tpts[i].y = pts[i].y+p->y;
- UpdateMinMaxRect(&rDims, tpts[i].x, tpts[i].y);
- }
- o->ShowLine(tpts, 5, TextDef.ColTxt);
- if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
- rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
- free(tpts);
- }
-}
-
-bool
-Label::CalcRect(anyOutput *o)
-{
- int rx1, rx, ry;
- fRECT rc, rcc;
-
- if(parent && parent->Id != GO_MLABEL) o->SetTextSpec(&TextDef);
- if(fmt_txt && TextDef.text && TextDef.text[0]) {
- fmt_txt->SetText(0L, TextDef.text, &ix, &iy);
- if(!(fmt_txt->oGetTextExtent(o, &rx, &ry, 0))) return false;
- rx++;
- }
- else {
- if(!(o->oGetTextExtent("A", 1, &rx, &ry))) return false;
- rx = 1;
- }
- rx += 4; rc.Xmin = -2.0f; rc.Ymin = 0.0f; rc.Xmax = rx; rc.Ymax = ry;
- si = sin(TextDef.RotBL *0.01745329252); csi = cos(TextDef.RotBL *0.01745329252);
- if(TextDef.Align & TXA_HCENTER) {
- rc.Xmin -= rx/2.0-1.0; rc.Xmax -= rx/2.0-1.0;
- }
- else if(TextDef.Align & TXA_HRIGHT) {
- rc.Xmin -= rx-2.0; rc.Xmax -= rx-2.0;
- }
- if(TextDef.Align & TXA_VCENTER) {
- rc.Ymin -= ry/2.0; rc.Ymax -= ry/2.0;
- }
- else if(TextDef.Align & TXA_VBOTTOM) {
- rc.Ymin -= ry; rc.Ymax -= ry;
- }
- if(fmt_txt && fmt_txt->oGetTextExtent(o, &rx1, &ry, CursorPos)){
- rx = CursorPos ? (int)rx1 : 0;
- }
- else rx = 0;
- rcc.Xmax = rc.Xmin + (double)rx+2.0; rcc.Ymin = rc.Ymin+2.0;
- rcc.Xmin = rc.Xmin; rcc.Ymax = rc.Ymax-2.0;
- pts[0].x = iround(rc.Xmin*csi + rc.Ymin*si)+ix;
- pts[0].y = iround(rc.Ymin*csi - rc.Xmin*si)+iy;
- pts[1].x = iround(rc.Xmax*csi + rc.Ymin*si)+ix;
- pts[1].y = iround(rc.Ymin*csi - rc.Xmax*si)+iy;
- pts[2].x = iround(rc.Xmax*csi + rc.Ymax*si)+ix;
- pts[2].y = iround(rc.Ymax*csi - rc.Xmax*si)+iy;
- pts[3].x = iround(rc.Xmin*csi + rc.Ymax*si)+ix;
- pts[3].y = iround(rc.Ymax*csi - rc.Xmin*si)+iy;
- pts[4].x = pts[0].x; pts[4].y = pts[0].y;
- Cursor.left = iround(rcc.Xmax*csi + rcc.Ymin*si)+ix;
- Cursor.top = iround(rcc.Ymin*csi - rcc.Xmax*si)+iy;
- Cursor.right = iround(rcc.Xmax*csi + rcc.Ymax*si)+ix;
- Cursor.bottom = iround(rcc.Ymax*csi - rcc.Xmax*si)+iy;
- return true;
-}
-
-void
-Label::RedrawEdit(anyOutput *o)
-{
- FillDEF bgFill = {FILL_NONE, bgcolor, 1.0, 0L, bgcolor};
-
- if(!o || !parent) return;
- bgLine.color = bgcolor; o->SetLine(&bgLine); o->SetFill(&bgFill);
- o->oPolygon(pts, 5); IncrementMinMaxRect(&rDims, 3);
- o->UpdateRect(&rDims, false);
- CalcRect(o); bgLine.color ^= 0x00ffffffL;
- o->SetLine(&bgLine); o->oPolygon(pts, 5);
- if(parent->Id == GO_MLABEL) {
- if(parent->parent && parent->parent->Id == GO_LEGITEM && parent->parent->parent)
- parent->parent->parent->DoPlot(o);
- else parent->DoPlot(o);
- }
- else if(parent->Id == GO_LEGITEM && parent->parent) parent->parent->DoPlot(o);
- else DoPlot(o);
- o->UpdateRect(&rDims, false);
- DoMark(o, true); ShowCursor(o);
-}
-
-void
-Label::SetModified()
-{
- AxisDEF *adef;
-
- bModified = true;
- if(parent && parent->Id==GO_TICK && parent->parent && parent->parent->Id==GO_AXIS){
- adef = ((Axis*)(parent->parent))->GetAxis();
- adef->flags &= ~AXIS_AUTOSCALE;
- }
-}
+ return parent ? parent->Command(cmd, tmpl, o) : false;
+ case CMD_SEG_FILL:
+ TmpFill = (FillDEF *)tmpl;
+ if(TmpFill) {
+ segFill.type = TmpFill->type; segFill.color = TmpFill->color;
+ segFill.scale = TmpFill->scale;
+ if(TmpFill->hatch) memcpy(&segFillLine, TmpFill->hatch, sizeof(LineDEF));
+ }
+ return true;
+ case CMD_SEG_LINE:
+ if(tmpl) memcpy(&segLine, tmpl, sizeof(LineDEF));
+ return true;
+ case CMD_SEG_MOVEABLE:
+ if(tmpl) moveable = *((int*)tmpl);
+ return true;
+ case CMD_SHIFT_OUT:
+ if(tmpl) shift = *((double*)tmpl);
+ return true;
+ case CMD_MOVE:
+ bModified = true;
+ Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ case CMD_UNDO_MOVE:
+ fCent.fx += ((lfPOINT*)tmpl)[0].fx; fCent.fy += ((lfPOINT*)tmpl)[0].fy;
+ if(parent)parent->Command(CMD_REDRAW, 0L, o);
+ return true;
+ }
+ return false;
+}
+
+void *
+segment::ObjThere(int x, int y)
+{
+ bool bFound = false;
+ POINT p1;
+
+ if(IsInRect(&rDims, p1.x = x, p1.y = y)) {
+ bFound = IsInPolygon(&p1, pts, nPts);
+ if(bFound || IsCloseToPL(p1, pts, nPts)) return this;
+ }
+ return 0L;
+}
+
+void
+segment::Track(POINT *p, anyOutput *o)
+{
+ POINT *tpts;
+ RECT old_rc;
+ int i;
+
+ if(o && (tpts = (POINT*)malloc(nPts*sizeof(POINT)))){
+ memcpy(&old_rc, &rDims, sizeof(rDims));
+ o->UpdateRect(&rDims, false);
+ for(i = 0; i < nPts; i++) {
+ tpts[i].x = pts[i].x+p->x; tpts[i].y = pts[i].y+p->y;
+ UpdateMinMaxRect(&rDims, tpts[i].x, tpts[i].y);
+ }
+ o->ShowLine(tpts, nPts, segLine.color);
+ if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
+ rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
+ free(tpts);
+ }
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// the polyline object
+//
+polyline::polyline(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts):
+ GraphObj(par, d)
+{
+ double dx = 0.0, dy = 0.0;
+ int i;
+
+ FileIO(INIT_VARS);
+ if(parent){
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ }
+ 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;
+ }
+ }
+ Id = GO_POLYLINE;
+ bModified = false;
+}
+
+polyline::polyline(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ bModified = false;
+}
+
+polyline::~polyline()
+{
+ Command(CMD_FLUSH, 0L, 0L);
+ if(this == CurrGO) CurrGO = 0L;
+ if(bModified) Undo.InvalidGO(this);
+}
+
+double
+polyline::GetSize(int select)
+{
+ int i;
+
+ if(select >= SIZE_XPOS && select <= SIZE_XPOS_LAST){
+ if((i = select-SIZE_XPOS) >=0 && i <= 200)
+ return i < nPoints ? Values[i].fx : Values[nPoints-2].fx;
+ }
+ if(select >= SIZE_YPOS && select <= SIZE_YPOS_LAST){
+ if((i = select-SIZE_YPOS) >=0 && i <= 200)
+ return i < nPoints ? Values[i].fy : Values[nPoints-2].fy;
+ }
+ return parent ? parent->GetSize(select) : 0.0;
+}
+
+DWORD
+polyline::GetColor(int select)
+{
+ return pgLine.color;
+}
+
+bool
+polyline::SetSize(int select, double value)
+{
+ int i;
+
+ if((select & 0xfff) >= SIZE_XPOS && (select & 0xfff) <= SIZE_XPOS_LAST){
+ if((i = select-SIZE_XPOS) >=0 && i <= 200 && i < (int)nPoints){
+ Values[i].fx = value;
+ return true;
+ }
+ }
+ if((select & 0xfff) >= SIZE_YPOS && (select & 0xfff) <= SIZE_YPOS_LAST){
+ if((i = select-SIZE_YPOS) >=0 && i <= 200 && i < (int)nPoints){
+ Values[i].fy = value;
+ return true;
+ }
+ }
+ return false;
+}
+
+void
+polyline::DoPlot(anyOutput *o)
+{
+ POINT np, *tmppts;
+ double dx, dy;
+ int i;
+
+ if(!Values || !nPoints || !o || !parent) return;
+ if(pts) free(pts);
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ if(!(pts = (POINT*)malloc((nPoints+2)*sizeof(POINT))))return;
+ for(i = nPts = 0; i < nPoints; i++){
+ np.x = o->co2ix(Values[i].fx + dx); np.y = o->co2iy(Values[i].fy + dy);
+ AddToPolygon(&nPts, pts, &np);
+ }
+ if(type == 1) AddToPolygon(&nPts, pts, &pts[0]); //close polygon
+ if(tmppts = (POINT*)realloc(pts, nPts *sizeof(POINT))) pts = tmppts;
+ SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
+ 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);
+ if(this == CurrGO) o->ShowMark(this, MRK_GODRAW);
+ else switch(type) {
+ case 0: //line
+ o->SetLine(&pgLine); o->oPolyline(pts, nPts);
+ break;
+ case 1: //polygon
+ o->SetLine(&pgLine); o->SetFill(&pgFill); o->oPolygon(pts, nPts);
+ break;
+ }
+}
+
+void
+polyline::DoMark(anyOutput *o, bool mark)
+{
+ RECT upd;
+
+ memcpy(&upd, &rDims, sizeof(RECT));
+ IncrementMinMaxRect(&upd, 6 + o->un2ix(pgLine.width)*4);
+ if(mark) {
+ o->SetLine(&pgLine);
+ if(nPoints < 200){
+ switch(type) {
+ case 0: //line
+ o->oPolyline(pts, nPts);
+ break;
+ case 1: //polygon
+ 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);
+ }
+}
+
+bool
+polyline::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ POINT p1;
+ bool bFound = false;
+ int i;
+
+ 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_SCALE:
+ if(Values) for(i = 0; i < nPoints; i++){
+ Values[i].fx = ((scaleINFO*)tmpl)->sx.fx + Values[i].fx * ((scaleINFO*)tmpl)->sx.fy;
+ Values[i].fy = ((scaleINFO*)tmpl)->sy.fx + Values[i].fy * ((scaleINFO*)tmpl)->sy.fy;
+ }
+ pgLine.patlength *= ((scaleINFO*)tmpl)->sy.fy; pgLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ pgFillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy; pgFillLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ pgFill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(!ObjThere(p1.x= mev->x, p1.y=mev->y)|| CurrGO || !o || nPoints <2)return false;
+ return o->ShowMark(CurrGO=this, MRK_GODRAW);
+ }
+ return false;
+ case CMD_DELOBJ:
+ if(pHandles && tmpl && tmpl == (void*)CurrHandle) {
+ for(i = 0; i < nPoints; i++) if(pHandles[i] == CurrHandle) {
+ Undo.DataMem(this, (void**)&Values, nPoints * sizeof(lfPOINT), &nPoints, 0L);
+ for( ; i < nPoints-1; i++) {
+ Values[i].fx = Values[i+1].fx; Values[i].fy = Values[i+1].fy;
+ }
+ nPoints--;
+ if(pHandles[nPoints])delete(pHandles[nPoints]);
+ pHandles[nPoints] = 0L; CurrHandle = 0L;
+ CurrGO = this; bModified = true;
+ return true;
+ }
+ }
+ return false;
+ case CMD_SAVEPOS:
+ if(tmpl && Values) {
+ bModified = true;
+ i = *(int*)tmpl;
+ if(i >= 0 && i < nPoints) Undo.SaveLFP(this, Values + i, 0L);
+ }
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = type == 1 ? GO_POLYGON : GO_POLYLINE;
+ return true;
+ case CMD_SETSCROLL: case CMD_REDRAW:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ return false;
+ case CMD_MOVE:
+ bModified = true;
+ Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ case CMD_UNDO_MOVE:
+ for(i = 0; i < nPoints; i++) {
+ Values[i].fx += ((lfPOINT*)tmpl)[0].fx;
+ Values[i].fy += ((lfPOINT*)tmpl)[0].fy;
+ }
+ if(o) {
+ o->StartPage(); parent->DoPlot(o); o->EndPage();
+ }
+ return true;
+ }
+ return false;
+}
-void
-Label::DoPlotText(anyOutput *o)
+void *
+polyline::ObjThere(int x, int y)
{
- if(!parent || !o) return;
- defDisp = o;
- if(parent && parent->Id == GO_MLABEL) parent->Command(CMD_SETFOCUS, this, o);
- switch(flags & 0x03) {
- case LB_X_DATA: ix = o->fx2ix(fPos.fx); break;
- case LB_X_PARENT:
- ix = iround(parent->GetSize(SIZE_LB_XPOS));
- break;
- default:
- ix = o->co2ix(fPos.fx + parent->GetSize(SIZE_GRECT_LEFT));
- break;
- }
- switch(flags & 0x30) {
- case LB_Y_DATA: iy = o->fy2iy(fPos.fy); break;
- case LB_Y_PARENT:
- iy = iround(parent->GetSize(SIZE_LB_YPOS));
- break;
- default:
- iy = o->co2iy(fPos.fy +parent->GetSize(SIZE_GRECT_TOP));
- break;
- }
- ix += o->un2ix(fDist.fx); iy += o->un2iy(fDist.fy);
- TextDef.iSize = o->un2iy(TextDef.fSize);
- o->SetTextSpec(&TextDef);
- if(TextDef.text && TextDef.text[0]){
- if(fmt_txt) fmt_txt->SetText(o, TextDef.text, &ix, &iy);
- else fmt_txt = new fmtText(o, ix, iy, TextDef.text);
+ bool bFound = false;
+ POINT p1;
+ int i;
+ 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(type == 1) bFound = IsInPolygon(&p1, pts, nPts);
+ if(bFound || IsCloseToPL(p1,pts,nPts)) return this;
}
- if(!(CalcRect(o))) return;
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
- UpdateMinMaxRect(&rDims, pts[2].x, pts[2].y);
- UpdateMinMaxRect(&rDims, pts[3].x, pts[3].y);
+ return 0L;
}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// a multiline label consists of several Label objects
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-mLabel::mLabel(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, char *txt,
- int cp, DWORD flg):GraphObj(par, d)
-{
- int i;
-
- memcpy(&TextDef, td, sizeof(TextDEF));
- TextDef.text = 0L; fPos.fx = x; fPos.fy = y;
- Lines = 0L; flags = flg; lspc = 1.0;
- fDist.fx = 0.0; fDist.fy = 0.0;
- CurrGO = CurrLabel = 0L;
- if(txt && (Lines = (Label**)calloc(2, sizeof(Label*)))) {
- for(i = 0; i < cp && txt[i]; i ++) TmpTxt[i] = txt[i];
- TmpTxt[i] = 0;
- if(Lines[0] = new Label(this, d, x, y, &TextDef, LB_X_PARENT | LB_Y_PARENT))
- Lines[0]->Command(CMD_SETTEXT, TmpTxt, 0L);
- if(Lines[1] = new Label(this, d, x, y, &TextDef, LB_X_PARENT | LB_Y_PARENT)){
- Lines[1]->Command(CMD_SETTEXT, txt+cp, 0L);
- CurrGO = CurrLabel = Lines[1];
- }
- nLines = 2; cli = 1;
- }
- Id = GO_MLABEL;
-}
-
-mLabel::mLabel(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, char *txt)
- :GraphObj(par, d)
-{
- int i, nll;
- char **llist;
-
- memcpy(&TextDef, td, sizeof(TextDEF));
- TextDef.text = 0L; fPos.fx = x; fPos.fy = y;
- Lines = 0L; flags = 0L; Id = GO_MLABEL;
- fDist.fx = 0.0; fDist.fy = 0.0; lspc = 1.0;
- CurrGO = CurrLabel = 0L;
- if(txt){
- if((llist=split(txt,'\n',&nll)) && nll && (Lines=(Label**)calloc(nll, sizeof(Label*)))){
- for(i = 0; i < nll; i++) {
- if(llist[i]){
- Lines[i] = new Label(this, d, x, y, &TextDef, LB_X_PARENT | LB_Y_PARENT);
- Lines[i]->Command(CMD_SETTEXT, llist[i], 0L);
- free(llist[i]);
- }
- }
- free(llist); nLines = nll; cli = 0;
- }
- }
-}
-
-mLabel::mLabel(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
-}
-
-mLabel::~mLabel()
-{
- int i;
-
- Undo.InvalidGO(this);
- if(Lines){
- for(i = 0; i < nLines; i++) if(Lines[i]) DeleteGO(Lines[i]);
- free(Lines);
- }
-}
-
-double
-mLabel::GetSize(int select)
-{
- switch(select){
- case SIZE_LB_XPOS: return cPos1.fx;
- case SIZE_LB_YPOS: return cPos1.fy;
- case SIZE_GRECT_TOP:
- if (parent) return parent->GetSize(select);
- break;
- case SIZE_MIN_Z: case SIZE_MAX_Z: case SIZE_ZPOS:
- return curr_z;
- case SIZE_LSPC:
- return lspc;
- }
- return 0.0;
-}
-
-bool
-mLabel::SetSize(int select, double value)
+
+void
+polyline::Track(POINT *p, anyOutput *o)
{
+ POINT *tpts;
+ RECT old_rc;
int i;
-
- switch(select & 0xfff) {
- case SIZE_LB_XDIST:
- undo_flags = CheckNewFloat(&fDist.fx, fDist.fx, value, this, undo_flags);
- return true;
- case SIZE_LB_YDIST:
- undo_flags = CheckNewFloat(&fDist.fy, fDist.fy, value, this, undo_flags);
- return true;
- case SIZE_XPOS:
- undo_flags = CheckNewFloat(&fPos.fx, fPos.fx, value, this, undo_flags);
- return true;
- case SIZE_YPOS:
- undo_flags = CheckNewFloat(&fPos.fy, fPos.fy, value, this, undo_flags);
- return true;
- case SIZE_ZPOS:
- curr_z = value;
- if(Lines) for(i = 0; i < nLines; i++) if(Lines[i]){
- Lines[i]->SetSize(select, value);
+
+ if(o && (tpts = (POINT*)malloc(nPts*sizeof(POINT)))){
+ memcpy(&old_rc, &rDims, sizeof(rDims));
+ o->UpdateRect(&rDims, false);
+ for(i = 0; i < nPts; i++) {
+ tpts[i].x = pts[i].x+p->x;
+ tpts[i].y = pts[i].y+p->y;
+ UpdateMinMaxRect(&rDims, tpts[i].x, tpts[i].y);
}
- return is3D = true;
- case SIZE_LSPC:
- undo_flags = CheckNewFloat(&lspc, lspc, value, this, undo_flags);
- return true;
- }
- return false;
-}
-
-void
-mLabel::DoPlot(anyOutput *o)
-{
- int i;
- double dh, dx, dy;
-
- if(!o || !Lines) return;
- undo_flags = 0L;
- if(parent){ //if this object is part of a dialog we dont have a parent
- dx = parent->GetSize(SIZE_GRECT_LEFT);
- dy = parent->GetSize(SIZE_GRECT_TOP);
- }
- else dx = dy = 0.0;
- cPos.fx = cPos.fy = 0.0;
- TextDef.iSize = o->un2iy(TextDef.fSize);
- switch(flags & 0x03) {
- case LB_X_DATA: cPos.fx = o->fx2fix(fPos.fx); break;
- case LB_X_PARENT: if(parent) cPos.fx = parent->GetSize(SIZE_LB_XPOS); break;
- default:
- //if no parent its a dialog
- cPos.fx = parent ? o->co2fix(fPos.fx + dx) : fPos.fx;
- break;
- }
- switch(flags & 0x30) {
- case LB_Y_DATA: cPos.fy = o->fy2fiy(fPos.fy); break;
- case LB_Y_PARENT: if(parent) cPos.fy = parent->GetSize(SIZE_LB_YPOS); break;
- default:
- //if no parent its a dialog
- cPos.fy = parent ? o->co2fiy(fPos.fy + dy) : fPos.fy;
- break;
- }
- si = sin(TextDef.RotBL *0.01745329252f); csi = cos(TextDef.RotBL *0.01745329252f);
- if(TextDef.Align & TXA_VBOTTOM) dh = (double)(nLines-1);
- else if(TextDef.Align & TXA_VCENTER) dh = ((double)(nLines-1))/2.0;
- else dh = 0.0; dh *= TextDef.fSize;
- cPos.fx -= o->un2fix(dh*si); cPos.fy -= o->un2fiy(dh*csi);
- memcpy(&cPos1, &cPos, sizeof(lfPOINT));
- if(lspc < 0.5 || lspc > 5) lspc = 1.0;
- dist.fx = floor(o->un2fix(TextDef.fSize * si * 1.1 * lspc));
- dist.fy = floor(o->un2fiy(TextDef.fSize * csi * 1.1 * lspc));
- o->SetTextSpec(&TextDef);
- rDims.left = rDims.top = rDims.right = rDims.bottom = 0;
- for(i = 0; i < nLines; i++) if(Lines[i]){
- Lines[i]->Command(CMD_SETTEXTDEF, &TextDef, o);
- Lines[i]->SetSize(SIZE_LB_XDIST, fDist.fx); Lines[i]->SetSize(SIZE_LB_YDIST, fDist.fy);
- Lines[i]->SetSize(SIZE_XPOS, fPos.fx); Lines[i]->SetSize(SIZE_YPOS, fPos.fy);
- Lines[i]->moveable = moveable; Lines[i]->DoPlot(o);
- UpdateMinMaxRect(&rDims, Lines[i]->rDims.left, Lines[i]->rDims.top);
- UpdateMinMaxRect(&rDims, Lines[i]->rDims.right, Lines[i]->rDims.bottom);
- }
- if(CurrLabel && o && Command(CMD_SETFOCUS, CurrLabel, o))
- Lines[cli]->ShowCursor(o);
-}
-
-bool
-mLabel::Command(int cmd, void *tmpl, anyOutput *o)
-{
- int i, j, k;
- fRECT t_cur;
- MouseEvent mev;
-
- switch (cmd) {
- case CMD_MOUSE_EVENT:
- if(Lines && tmpl && IsInRect(&rDims, ((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y))
- for(i = 0; i<nLines; i++) if(Lines[i] && Lines[i]->Command(cmd, tmpl, o)) return true;
- break;
- case CMD_HIDE_MARK:
- if(Lines && o && tmpl) for(i = 0; i< nLines; i++)
- if(Lines[i] && tmpl == (void*)Lines[i]){
- Lines[i]->DoMark(o, false);
- return true;
- }
- return false;
- case CMD_ADDCHAR:
- if(!tmpl || 13 != *((int*)tmpl)) return false;
- if(!Lines[cli] || !Lines[cli]->Command(CMD_GETTEXT, &TmpTxt, o)) return false;
- k = iround(Lines[cli]->GetSize(SIZE_CURSORPOS));
- if(parent)Undo.ObjConf(this, 0L);
- if(tmpl && Lines && (Lines = (Label**)realloc(Lines, (nLines+1) * sizeof(Label*)))) {
- for(i = nLines-1, j = nLines; i >= cli; i--, j-- ) {
- Lines[j] = Lines[i];
- }
- i++, j++;
- if(Lines[j]) DeleteGO(Lines[j]); Lines[i] = Lines[j] = 0L; nLines++;
- if(Lines[j] = new Label(this, data, fPos.fx, fPos.fy, &TextDef, LB_X_PARENT | LB_Y_PARENT)){
- Lines[j]->Command(CMD_SETTEXT, TmpTxt+k, o);
- Lines[j]->Command(CMD_POS_FIRST, 0L, o);
- CurrGO = CurrLabel = Lines[j];
- TmpTxt[k] = 0;
- }
- if(Lines[i] = new Label(this, data, fPos.fx, fPos.fy, &TextDef, LB_X_PARENT | LB_Y_PARENT))
- Lines[i]->Command(CMD_SETTEXT, TmpTxt, 0L);
- Command(CMD_SETFOCUS, CurrGO, o);
- if(parent) return parent->Command(CMD_REDRAW, 0L, o);
- else if(o) DoPlot(o);
- }
- break;
- case CMD_SETFOCUS:
- for(i = 0; i< nLines; i++) if(Lines[i] == (Label*)tmpl) {
- cli = i;
- cPos1.fx = cPos.fx + dist.fx*i;
- cPos1.fy = cPos.fy + dist.fy*i;
- return true;
- }
- break;
- case CMD_GETTEXT:
- if(tmpl && Lines && nLines && Lines[0]) return Lines[0]->Command(CMD_GETTEXT, tmpl, o);
- break;
- case CMD_ALLTEXT:
- if(tmpl && Lines && nLines){
- for(i = 0, j = 500; i < nLines; i++) {
- if(Lines[i] && Lines[i]->Command(CMD_GETTEXT, TmpTxt, o) && TmpTxt[0]){
- j += sprintf(TmpTxt+j, "%s\n", TmpTxt);
- }
- }
- strcpy((char*)tmpl, TmpTxt+500);
- return true;
- }
- break;
- case CMD_DELETE:
- cli++;
- //fall through
- case CMD_BACKSP:
- if(cli > 0 && cli < nLines && Lines && Lines[cli] && Lines[cli-1]) {
- Lines[cli-1]->Command(CMD_POS_LAST, 0L, o);
- TmpTxt[0] = 0;
- Lines[cli-1]->Command(CMD_GETTEXT, TmpTxt, o);
- Lines[cli]->Command(CMD_GETTEXT, TmpTxt+strlen(TmpTxt), o);
- Lines[cli-1]->Command(CMD_SETTEXT, TmpTxt, o);
- DeleteGO(Lines[cli]); Lines[cli] = 0L;
- for(i = cli+1; i < nLines; i++){
- Lines[i-1] = Lines[i], Lines[i]= 0L;
- }
- nLines--;
- CurrGO = CurrLabel = Lines[cli-1];
- if(parent) parent->Command(CMD_REDRAW, 0L, o);
- if(CurrLabel) CurrLabel->RedrawEdit(o);
- return true;
- }
- return false;
- case CMD_GETTEXTDEF:
- if(!tmpl) return false;
- memcpy(tmpl, &TextDef, sizeof(TextDEF));
- return true;
- case CMD_SETTEXTDEF:
- if(!tmpl)return false;
- Undo.TextDef(this, &TextDef, undo_flags);
- undo_flags |= UNDO_CONTINUE;
- memcpy(&TextDef, tmpl, sizeof(TextDEF));
- TextDef.text = 0L;
- return true;
- case CMD_SET_DATAOBJ:
- if(Lines) {
- for(i = 0; i< nLines; i++) if(Lines[i]) Lines[i]->Command(cmd, tmpl, o);
- }
- Id = GO_MLABEL;
- data = (DataObj*)tmpl;
- return true;
- case CMD_AUTOSCALE:
- if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH
- && (flags & LB_X_DATA) && (flags & LB_Y_DATA)) {
- ((Plot*)parent)->CheckBounds(fPos.fx, fPos.fy);
- return true;
- }
- break;
- case CMD_CURRUP: case CMD_CURRDOWN:
- if(!o) return false;
- o->SetTextSpec(&TextDef);
- Command(CMD_SETFOCUS, CurrGO, o);
- if(cli >= 0 && cli < nLines && Lines && Lines[cli]) {
- t_cur.Xmin = Lines[cli]->GetSize(SIZE_CURSOR_XMIN);
- t_cur.Xmax = Lines[cli]->GetSize(SIZE_CURSOR_XMAX);
- t_cur.Ymin = Lines[cli]->GetSize(SIZE_CURSOR_YMIN);
- t_cur.Ymax = Lines[cli]->GetSize(SIZE_CURSOR_YMAX);
- mev.StateFlags = 0; mev.Action = MOUSE_LBUP;
- mev.x = iround((t_cur.Xmax+t_cur.Xmin)/2.0);
- mev.y = iround((t_cur.Ymax+t_cur.Ymin)/2.0);
- i = o->un2ix(TextDef.fSize*si); j = o->un2iy(TextDef.fSize*csi);
- if(cmd == CMD_CURRUP && cli > 0 && Lines[cli-1]) {
- Lines[cli-1]->CalcCursorPos(mev.x -= i, mev.y -= j, o);
- o->ShowMark(CurrGO = CurrLabel = Lines[cli-=1], MRK_GODRAW);
- return Command(CMD_SETFOCUS, Lines[cli], o);
- }
- if(cmd == CMD_CURRDOWN && cli < (nLines-1) && Lines[cli+1]) {
- Lines[cli+1]->CalcCursorPos(mev.x += i, mev.y += j, o);
- o->ShowMark(CurrGO = CurrLabel = Lines[cli+=1], MRK_GODRAW);
- return Command(CMD_SETFOCUS, Lines[cli], o);
- }
- }
- else return false;
- break;
- case CMD_SELECT:
- if(o && tmpl) for(i = 0; i < nLines; i++){
- o->SetTextSpec(&TextDef);
- if(Lines[i] && ((POINT*)tmpl)->y > Lines[i]->rDims.top && ((POINT*)tmpl)->y <
- Lines[i]->rDims.bottom) return Lines[i]->Command(cmd, tmpl, o);
- }
- break;
- case CMD_DELOBJ:
- if(parent && Lines) for(i = 0; i< nLines; i++)
- if(Lines[i] && Lines[i] == (Label*)tmpl) return parent->Command(cmd, this, o);
- break;
- case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, o);
- else if(o) DoPlot(o);
- break;
- case CMD_MOVE:
- if(parent && parent->Id == GO_LEGITEM) return parent->Command(cmd, tmpl, o);
- Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
- case CMD_UNDO_MOVE:
- if(!(flags & 0x03)) fPos.fx += ((lfPOINT*)tmpl)[0].fx;
- if(!(flags & 0x30)) fPos.fy += ((lfPOINT*)tmpl)[0].fy;
- if(o && parent){
- o->StartPage(); parent->DoPlot(o); o->EndPage();
- }
- return true;
- }
- return false;
-}
-
-void
-mLabel::Track(POINT *p, anyOutput *o)
-{
- int i;
-
- if(!parent) return;
- if(parent->Id == GO_LEGITEM){
- parent->Track(p, o);
- return;
- }
- for(i = 0; i < nLines; i++) if(Lines[i]){
- if(!i) memcpy(&rDims, &Lines[i]->rDims, sizeof(RECT));
- else {
- UpdateMinMaxRect(&rDims, Lines[i]->rDims.left, Lines[i]->rDims.top);
- UpdateMinMaxRect(&rDims, Lines[i]->rDims.right, Lines[i]->rDims.bottom);
- }
- }
- o->UpdateRect(&rDims, false);
- Id = 0L; //disable reentrance from Label objects
- for(i = 0; i < nLines; i++) if(Lines[i]) Lines[i]->Track(p, o);
- Id = GO_MLABEL; //enable entrance from Label objects
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// The following GOs use absolute coordinates
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// The segment object is either a pie slice or a ring segment
-//
-segment::segment(GraphObj *par, DataObj *d, lfPOINT *c, double r1, double r2,
- double a1, double a2):GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- segFill.hatch = &segFillLine;
- segFill.color = 0x00c0c0c0L;
- fCent.fx = c->fx; fCent.fy = c->fy;
- radius1 = r1; radius2 = r2;
- angle1 = a1; angle2 = a2;
- Id = GO_SEGMENT;
- bModified = false;
-}
-
-segment::segment(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-segment::~segment()
-{
- if(pts && nPts) free(pts);
- if(bModified) Undo.InvalidGO(this);
-}
-
-bool
-segment::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_XPOS: fCent.fx = value; break;
- case SIZE_YPOS: fCent.fy = value; break;
- case SIZE_RADIUS1: radius1 = value; break;
- case SIZE_RADIUS2: radius2 = value; break;
- case SIZE_ANGLE1: angle1 = value; break;
- case SIZE_ANGLE2: angle2 = value; break;
- default: return false;
- }
- return true;
-}
-
-void
-segment::DoPlot(anyOutput *o)
-{
- double dsize, dpt, frx1, frx2, dtmp, da, dda, sia, csia;
- int i, n, npt = 12;
- POINT np, of, cp, *tmppts;
-
- if(!o || angle1 == angle2) return;
- dsize = angle1 > angle2 ? angle1 -angle2 : (angle1+360.0)-angle2;
- dpt = dsize*0.01745329252; //degrees to rad
- frx1 = (double)o->un2fix(radius1);
- frx2 = (double)o->un2fix(radius2);
- dtmp = frx1*dpt;
- npt += (int)(dtmp < dsize ? dtmp : dsize);
- dtmp = frx2*dpt;
- npt += (int)(dtmp < dsize ? dtmp : dsize);
- if(!(pts = (POINT*)malloc(npt*sizeof(POINT))))return;
- nPts = 0;
- n = (dtmp < dsize) ? (int)dtmp : (int)dsize;
- while (n<2) n++;
- da = angle1*0.01745329252;
- dda = (dsize*0.01745329252)/(double)n;
- sia = sin(0.5*((angle2 < angle1 ? angle1 : angle1 +360) + angle2) * 0.01745329252);
- csia = cos(0.5*((angle2 < angle1 ? angle1 : angle1 +360) + angle2) * 0.01745329252);
- of.x = o->un2ix(shift * csia);
- of.y = - (o->un2iy(shift * sia));
- cp.x = o->co2ix(fCent.fx + (parent ? parent->GetSize(SIZE_GRECT_LEFT): 0.0));
- cp.y = o->co2iy(fCent.fy + (parent ? parent->GetSize(SIZE_GRECT_TOP): 0.0));
- for(i = 0; i < n; i++) {
- sia = sin(da); csia = cos(da);
- np.x = of.x + cp.x; np.y = of.y + cp.y;
- np.x += o->un2ix(csia*radius2); np.y -= o->un2iy(sia*radius2);
- AddToPolygon(&nPts, pts, &np);
- da -= dda;
- }
- sia = sin(angle2 *0.01745329252);
- csia = cos(angle2 *0.01745329252);
- np.x = of.x + cp.x; np.y = of.y + cp.y;
- np.x += o->un2ix(csia*radius2); np.y -= o->un2iy(sia*radius2);
- AddToPolygon(&nPts, pts, &np);
- dtmp = frx1*dpt;
- n = dtmp < dsize ? (int)dtmp : (int)dsize;
- da = angle2*0.01745329252;
- if(n>1)dda = (dsize*0.01745329252)/(double)n;
- else dda = 0.0;
- for(i = 0; i < n; i++) {
- sia = sin(da); csia = cos(da);
- np.x = of.x + cp.x; np.y = of.y + cp.y;
- np.x += o->un2ix(csia*radius1); np.y -= o->un2iy(sia*radius1);
- AddToPolygon(&nPts, pts, &np);
- da += dda;
- }
- sia = sin(angle1 *0.01745329252); csia = cos(angle1 *0.01745329252);
- np.x = of.x + cp.x; np.y = of.y + cp.y;
- np.x += o->un2ix(csia*radius1); np.y -= o->un2iy(sia*radius1);
- AddToPolygon(&nPts, pts, &np);
- if(nPts <3) return;
- AddToPolygon(&nPts, pts, &pts[0]); //close polygon
- o->SetLine(&segLine); o->SetFill(&segFill);
- o->oPolygon(pts, nPts);
- if(tmppts = (POINT*)realloc(pts, nPts *sizeof(POINT))) pts = tmppts;
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
- for(i = 2; i < nPts; i++) UpdateMinMaxRect(&rDims, pts[i].x, pts[i].y);
- i = 3*o->un2ix(segLine.width); //increase size of rectangle for marks
- IncrementMinMaxRect(&rDims, i+6);
-}
-
-void
-segment::DoMark(anyOutput *o, bool mark)
-{
- if(mark)InvertPolygon(pts, nPts, &segLine, &segFill, &rDims, o, mark);
- else if(parent) {
- parent->DoPlot(o);
- o->UpdateRect(&rDims, false);
- }
-}
-
-bool
-segment::Command(int cmd, void *tmpl, anyOutput *o)
-{
- FillDEF *TmpFill;
- LegItem *leg;
-
- switch (cmd) {
- case CMD_LEGEND:
- if(tmpl) {
- leg = new LegItem(this, data, 0L, &segLine, &segFill);
- if(!((Legend*)tmpl)->Command(CMD_DROP_OBJECT, leg, o)) DeleteGO(leg);
- }
- return true;
- case CMD_MOUSE_EVENT:
- switch (((MouseEvent*)tmpl)->Action) {
- case MOUSE_LBUP:
- if(ObjThere(((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y))
- return o->ShowMark(CurrGO=this, MRK_GODRAW);
- }
- return false;
- case CMD_SET_DATAOBJ:
- Id = GO_SEGMENT;
- return true;
- case CMD_REDRAW:
- return parent ? parent->Command(cmd, tmpl, o) : false;
- case CMD_SEG_FILL:
- TmpFill = (FillDEF *)tmpl;
- if(TmpFill) {
- segFill.type = TmpFill->type; segFill.color = TmpFill->color;
- segFill.scale = TmpFill->scale;
- if(TmpFill->hatch) memcpy(&segFillLine, TmpFill->hatch, sizeof(LineDEF));
- }
- return true;
- case CMD_SEG_LINE:
- if(tmpl) memcpy(&segLine, tmpl, sizeof(LineDEF));
- return true;
- case CMD_SEG_MOVEABLE:
- if(tmpl) moveable = *((int*)tmpl);
- return true;
- case CMD_SHIFT_OUT:
- if(tmpl) shift = *((double*)tmpl);
- return true;
- case CMD_MOVE:
- bModified = true;
- Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
- case CMD_UNDO_MOVE:
- fCent.fx += ((lfPOINT*)tmpl)[0].fx; fCent.fy += ((lfPOINT*)tmpl)[0].fy;
- if(parent)parent->Command(CMD_REDRAW, 0L, o);
- return true;
- }
- return false;
-}
-
-void *
-segment::ObjThere(int x, int y)
-{
- bool bFound = false;
- POINT p1;
-
- if(IsInRect(&rDims, p1.x = x, p1.y = y)) {
- bFound = IsInPolygon(&p1, pts, nPts);
- if(bFound || IsCloseToPL(p1, pts, nPts)) return this;
- }
- return 0L;
-}
-
-void
-segment::Track(POINT *p, anyOutput *o)
-{
- POINT *tpts;
- RECT old_rc;
- int i;
-
- if(o && (tpts = (POINT*)malloc(nPts*sizeof(POINT)))){
- memcpy(&old_rc, &rDims, sizeof(rDims));
- o->UpdateRect(&rDims, false);
- for(i = 0; i < nPts; i++) {
- tpts[i].x = pts[i].x+p->x; tpts[i].y = pts[i].y+p->y;
- UpdateMinMaxRect(&rDims, tpts[i].x, tpts[i].y);
- }
- o->ShowLine(tpts, nPts, segLine.color);
- if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
- rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
- free(tpts);
- }
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// the polyline object
-//
-polyline::polyline(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts):
- GraphObj(par, d)
-{
- double dx = 0.0, dy = 0.0;
- int i;
-
- FileIO(INIT_VARS);
- if(parent){
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- }
- 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;
- }
- }
- Id = GO_POLYLINE;
- bModified = false;
-}
-
-polyline::polyline(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- bModified = false;
-}
-
-polyline::~polyline()
-{
- Command(CMD_FLUSH, 0L, 0L);
- if(this == CurrGO) CurrGO = 0L;
- if(bModified) Undo.InvalidGO(this);
-}
-
-double
-polyline::GetSize(int select)
-{
- int i;
-
- if(select >= SIZE_XPOS && select <= SIZE_XPOS_LAST){
- if((i = select-SIZE_XPOS) >=0 && i <= 200)
- return i < nPoints ? Values[i].fx : Values[nPoints-2].fx;
- }
- if(select >= SIZE_YPOS && select <= SIZE_YPOS_LAST){
- if((i = select-SIZE_YPOS) >=0 && i <= 200)
- return i < nPoints ? Values[i].fy : Values[nPoints-2].fy;
- }
- return parent ? parent->GetSize(select) : 0.0;
-}
-
-DWORD
-polyline::GetColor(int select)
-{
- return pgLine.color;
-}
-
-bool
-polyline::SetSize(int select, double value)
-{
- int i;
-
- if((select & 0xfff) >= SIZE_XPOS && (select & 0xfff) <= SIZE_XPOS_LAST){
- if((i = select-SIZE_XPOS) >=0 && i <= 200 && i < (int)nPoints){
- Values[i].fx = value;
- return true;
- }
- }
- if((select & 0xfff) >= SIZE_YPOS && (select & 0xfff) <= SIZE_YPOS_LAST){
- if((i = select-SIZE_YPOS) >=0 && i <= 200 && i < (int)nPoints){
- Values[i].fy = value;
- return true;
- }
- }
- return false;
-}
-
-void
-polyline::DoPlot(anyOutput *o)
-{
- POINT np, *tmppts;
- double dx, dy;
- int i;
-
- if(!Values || !nPoints || !o || !parent) return;
- if(pts) free(pts);
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- if(!(pts = (POINT*)malloc((nPoints+2)*sizeof(POINT))))return;
- for(i = nPts = 0; i < nPoints; i++){
- np.x = o->co2ix(Values[i].fx + dx); np.y = o->co2iy(Values[i].fy + dy);
- AddToPolygon(&nPts, pts, &np);
- }
- if(type == 1) AddToPolygon(&nPts, pts, &pts[0]); //close polygon
- if(tmppts = (POINT*)realloc(pts, nPts *sizeof(POINT))) pts = tmppts;
- SetMinMaxRect(&rDims, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
- 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);
- if(this == CurrGO) o->ShowMark(this, MRK_GODRAW);
- else switch(type) {
- case 0: //line
- o->SetLine(&pgLine); o->oPolyline(pts, nPts);
- break;
- case 1: //polygon
- o->SetLine(&pgLine); o->SetFill(&pgFill); o->oPolygon(pts, nPts);
- break;
- }
-}
-
-void
-polyline::DoMark(anyOutput *o, bool mark)
-{
- RECT upd;
-
- memcpy(&upd, &rDims, sizeof(RECT));
- IncrementMinMaxRect(&upd, 6 + o->un2ix(pgLine.width)*4);
- if(mark) {
- o->SetLine(&pgLine);
- if(nPoints < 200){
- switch(type) {
- case 0: //line
- o->oPolyline(pts, nPts);
- break;
- case 1: //polygon
- 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);
- }
-}
-
-bool
-polyline::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- POINT p1;
- bool bFound = false;
- int i;
-
- 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_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(!ObjThere(p1.x= mev->x, p1.y=mev->y)|| CurrGO || !o || nPoints <2)return false;
- return o->ShowMark(CurrGO=this, MRK_GODRAW);
- }
- return false;
- case CMD_DELOBJ:
- if(pHandles && tmpl && tmpl == (void*)CurrHandle) {
- for(i = 0; i < nPoints; i++) if(pHandles[i] == CurrHandle) {
- Undo.DataMem(this, (void**)&Values, nPoints * sizeof(lfPOINT), &nPoints, 0L);
- for( ; i < nPoints-1; i++) {
- Values[i].fx = Values[i+1].fx; Values[i].fy = Values[i+1].fy;
- }
- nPoints--;
- if(pHandles[nPoints])delete(pHandles[nPoints]);
- pHandles[nPoints] = 0L; CurrHandle = 0L;
- CurrGO = this; bModified = true;
- return true;
- }
- }
- return false;
- case CMD_SAVEPOS:
- if(tmpl && Values) {
- bModified = true;
- i = *(int*)tmpl;
- if(i >= 0 && i < nPoints) Undo.SaveLFP(this, Values + i, 0L);
- }
- return true;
- case CMD_SET_DATAOBJ:
- Id = type == 1 ? GO_POLYGON : GO_POLYLINE;
- return true;
- case CMD_SETSCROLL: case CMD_REDRAW:
- if(parent) return parent->Command(cmd, tmpl, o);
- return false;
- case CMD_MOVE:
- bModified = true;
- Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
- case CMD_UNDO_MOVE:
- for(i = 0; i < nPoints; i++) {
- Values[i].fx += ((lfPOINT*)tmpl)[0].fx;
- Values[i].fy += ((lfPOINT*)tmpl)[0].fy;
- }
- if(o) {
- o->StartPage(); parent->DoPlot(o); o->EndPage();
- }
- return true;
- }
- return false;
-}
-
-void *
-polyline::ObjThere(int x, int y)
-{
- bool bFound = false;
- POINT p1;
- int i;
- 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(type == 1) bFound = IsInPolygon(&p1, pts, nPts);
- if(bFound || IsCloseToPL(p1,pts,nPts)) return this;
- }
- return 0L;
-}
-
-void
-polyline::Track(POINT *p, anyOutput *o)
-{
- POINT *tpts;
- RECT old_rc;
- int i;
-
- if(o && (tpts = (POINT*)malloc(nPts*sizeof(POINT)))){
- memcpy(&old_rc, &rDims, sizeof(rDims));
- o->UpdateRect(&rDims, false);
- for(i = 0; i < nPts; i++) {
- tpts[i].x = pts[i].x+p->x;
- tpts[i].y = pts[i].y+p->y;
- UpdateMinMaxRect(&rDims, tpts[i].x, tpts[i].y);
- }
- o->ShowLine(tpts, nPts, pgLine.color);
- if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
- rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
- free(tpts);
- }
-}
-
-void
-polyline::ShowPoints(anyOutput *o)
-{
+ o->ShowLine(tpts, nPts, pgLine.color);
+ if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
+ rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
+ free(tpts);
+ }
+}
+
+void
+polyline::ShowPoints(anyOutput *o)
+{
int i;
double dx, dy;
POINT hpts[3];
- LineDEF gl = {0.0, 1.0, 0x00c0c0c0, 0};
-
- 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);
- }
+ LineDEF gl = {0.0, 1.0, 0x00c0c0c0, 0};
+
+ 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);
+ }
if(!pHandles) return;
if(Id == GO_BEZIER && parent && nPoints > 3) {
dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
@@ -6334,10 +7273,10 @@ polyline::ShowPoints(anyOutput *o)
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):
@@ -6494,24 +7433,26 @@ Bezier::FitCurve(lfPOINT *d, int npt, double error)
void
Bezier::RemovePoint(lfPOINT *d, int sel)
{
- long o_nPoints;
- double len;
- lfPOINT ndata[3], tHat1, tHat2;
+ lfPOINT 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;
+ d[sel] = d[sel+3];
+ IpolBez(d+sel-3, tHat1, tHat2);
+}
+
+//heuristic interpolation: other methods failed
+void
+Bezier::IpolBez(lfPOINT *d, lfPOINT tHat1, lfPOINT tHat2)
+{
+ double b0, b1, b2; //temp variables
+
+ b1 = d[3].fx - d[0].fx; b2 = d[3].fy - d[0].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);
+ d[1].fx = d[0].fx + tHat1.fx * b1; d[1].fy = d[0].fy + tHat1.fy * b1;
+ d[2].fx = d[3].fx + tHat2.fx * b2; d[2].fy = d[3].fy + tHat2.fy * b2;
}
//Fit a Bezier curve to a (sub)set of digitized points
@@ -6519,24 +7460,16 @@ void
Bezier::FitCubic(lfPOINT *d, int first, int last, lfPOINT tHat1, lfPOINT tHat2, double error)
{
lfPOINT bezCurve[4];
- double *u, *uPrime, maxError, iterationError;
+ double *u, *uPrime, maxError, iterationError, len;
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;
+ IpolBez(bezCurve, tHat1, tHat2);
AddPoints(3, bezCurve);
return;
}
@@ -6544,6 +7477,9 @@ Bezier::FitCubic(lfPOINT *d, int first, int last, lfPOINT tHat1, lfPOINT tHat2,
GenerateBezier(d, first, last, u, tHat1, tHat2, bezCurve);
maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
if(maxError < error) {
+ if(maxError < 0.0) { //Failure fitting curve
+ IpolBez(bezCurve, tHat1, tHat2);
+ }
AddPoints(3, bezCurve); return;
}
if(maxError < iterationError) {
@@ -6552,6 +7488,7 @@ Bezier::FitCubic(lfPOINT *d, int first, int last, lfPOINT tHat1, lfPOINT tHat2,
GenerateBezier(d, first, last, uPrime, tHat1, tHat2, bezCurve);
maxError = ComputeMaxError(d, first, last, bezCurve, uPrime, &splitPoint);
if (maxError < error) {
+ if(maxError < 0.0) IpolBez(bezCurve, tHat1, tHat2);
AddPoints(3, bezCurve); return;
}
free(u); u = uPrime;
@@ -6702,363 +7639,373 @@ Bezier::ChordLengthParameterize(lfPOINT *d, int first, int last)
for(i = first +1; i <= last; i++) {
u[i-first] = u[i-first] / u[last-first];
}
- return u;
+ 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 = -1.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):
+ polyline(par, d, fpts, cpts)
+{
+ Id = GO_POLYGON;
+ memcpy(&pgLine, defs.pgLineDEF(0L), sizeof(LineDEF));
+ type = 1;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// rectangle with absolute coordinates
+rectangle::rectangle(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2):
+ GraphObj(par, d)
+{
+ double dx = 0.0, dy = 0.0;
+
+ FileIO(INIT_VARS);
+ if(parent){
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ }
+ memcpy(&fp1, p1, sizeof(lfPOINT)); memcpy(&fp2, p2, sizeof(lfPOINT));
+ fp1.fx -= dx; fp1.fy -= dy; fp2.fx -= dx; fp2.fy -= dy;
+ type = 0;
+ Id = GO_RECTANGLE;
+ bModified = false;
+}
+
+rectangle::rectangle(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ type = 0;
+ bModified = false;
+}
+
+rectangle::~rectangle()
+{
+ Command(CMD_FLUSH, 0L, 0L);
+ if(bModified) Undo.InvalidGO(this);
+ if(drc) delete(drc); drc = 0L;
+}
+
+double
+rectangle::GetSize(int select)
+{
+ if(parent && parent->Id== GO_GROUP){
+ switch(select) {
+ case SIZE_XPOS: return fp1.fx + parent->GetSize(SIZE_XPOS);
+ case SIZE_XPOS+1: return fp2.fx + parent->GetSize(SIZE_XPOS);
+ case SIZE_YPOS: return fp1.fy + parent->GetSize(SIZE_YPOS);
+ case SIZE_YPOS+1: return fp2.fy + parent->GetSize(SIZE_YPOS);
+ case SIZE_GRECT_LEFT: case SIZE_GRECT_TOP:
+ case SIZE_GRECT_RIGHT: case SIZE_GRECT_BOTTOM:
+ return parent->GetSize(select);
+ }
+ return 0.0;
+ }
+ switch(select) {
+ case SIZE_XPOS: return fp1.fx;
+ case SIZE_XPOS+1: return fp2.fx;
+ case SIZE_YPOS: return fp1.fy;
+ case SIZE_YPOS+1: return fp2.fy;
+ case SIZE_GRECT_LEFT: case SIZE_GRECT_TOP:
+ case SIZE_GRECT_RIGHT: case SIZE_GRECT_BOTTOM:
+ if(parent) return parent->GetSize(select);
+ break;
+ }
+ return 0.0;
+}
+
+bool
+rectangle::SetSize(int select, double value)
+{
+ switch(select & 0xfff) {
+ case SIZE_XPOS: fp1.fx = value; return true;
+ case SIZE_XPOS+1: fp2.fx = value; return true;
+ case SIZE_YPOS: fp1.fy = value; return true;
+ case SIZE_YPOS+1: fp2.fy = value; return true;
+ }
+ return false;
+}
+
+void
+rectangle::DoMark(anyOutput *o, bool mark)
+{
+ RECT upd;
+
+ if(!drc) drc = new dragRect(this, 0);
+ memcpy(&upd, &rDims, sizeof(RECT));
+ if(mark){
+ if(drc) drc->DoPlot(o);
+ }
+ else if(parent) parent->DoPlot(o);
+ IncrementMinMaxRect(&upd, 6);
+ o->UpdateRect(&upd, false);
+}
+
+void
+rectangle::DoPlot(anyOutput *o)
+{
+ int x1, y1, x2, y2;
+ double tmp, dx, dy;
+
+ if(!parent || !o) return;
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ if(fp1.fx > fp2.fx) {
+ tmp = fp2.fx; fp2.fx = fp1.fx; fp1.fx = tmp;
+ }
+ if(fp1.fy > fp2.fy) {
+ tmp = fp2.fy; fp2.fy = fp1.fy; fp1.fy = tmp;
+ }
+ if(type == 2) PlotRoundRect(o);
+ else {
+ x1 = o->co2ix(fp1.fx+dx); y1 = o->co2iy(fp1.fy+dy);
+ x2 = o->co2ix(fp2.fx+dx); y2 = o->co2iy(fp2.fy+dy);
+ o->SetLine(&Line); o->SetFill(&Fill);
+ if(type == 1) o->oCircle(x1, y1, x2, y2, name);
+ else o->oRectangle(x1, y1, x2, y2, name);
+ SetMinMaxRect(&rDims, x1, y1, x2, y2);
+ }
+ o->MrkMode = MRK_NONE;
+ if(CurrGO == this) o->ShowMark(this, MRK_GODRAW);
+}
+
+bool
+rectangle::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+
+ switch (cmd) {
+ case CMD_FLUSH:
+ if(pts) free(pts); pts = 0L;
+ if(name) free(name); name = 0L;
+ return true;
+ case CMD_SCALE:
+ fp1.fx = ((scaleINFO*)tmpl)->sx.fx + fp1.fx * ((scaleINFO*)tmpl)->sx.fy;
+ fp2.fx = ((scaleINFO*)tmpl)->sx.fx + fp2.fx * ((scaleINFO*)tmpl)->sx.fy;
+ fp1.fy = ((scaleINFO*)tmpl)->sy.fx + fp1.fy * ((scaleINFO*)tmpl)->sy.fy;
+ fp2.fy = ((scaleINFO*)tmpl)->sy.fx + fp2.fy * ((scaleINFO*)tmpl)->sy.fy;
+ Line.patlength *= ((scaleINFO*)tmpl)->sy.fy; Line.width *= ((scaleINFO*)tmpl)->sy.fy;
+ FillLine.patlength *= ((scaleINFO*)tmpl)->sy.fy; FillLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy; rad *= ((scaleINFO*)tmpl)->sy.fy;
+ return true;
+ case CMD_SAVEPOS:
+ bModified = true;
+ Undo.SaveLFP(this, &fp1, 0L);
+ Undo.SaveLFP(this, &fp2, UNDO_CONTINUE);
+ return true;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ switch (mev->Action) {
+ case MOUSE_LBUP:
+ if(IsInRect(&rDims, mev->x, mev->y) && !(CurrGO) && (o)){
+ return o->ShowMark(this, MRK_GODRAW);
+ }
+ }
+ return false;
+ case CMD_SET_DATAOBJ:
+ switch (type) {
+ case 1: Id = GO_ELLIPSE; break;
+ case 2: Id = GO_ROUNDREC; break;
+ default: Id = GO_RECTANGLE; break;
+ }
+ return true;
+ case CMD_MOVE:
+ bModified = true;
+ Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ case CMD_UNDO_MOVE:
+ fp1.fx += ((lfPOINT*)tmpl)[0].fx; fp1.fy += ((lfPOINT*)tmpl)[0].fy;
+ fp2.fx += ((lfPOINT*)tmpl)[0].fx; fp2.fy += ((lfPOINT*)tmpl)[0].fy;
+ CurrGO = this;
+ case CMD_REDRAW:
+ if(parent && cmd != CMD_UNDO_MOVE){
+ parent->Command(CMD_REDRAW, tmpl, o);
+ }
+ return true;
+ case CMD_SETSCROLL:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ }
+ return false;
+}
+
+void
+rectangle::Track(POINT *p, anyOutput *o)
+{
+ POINT tpts[5];
+ RECT old_rc;
+ double dx, dy;
+
+ if(o && parent){
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ memcpy(&old_rc, &rDims, sizeof(rDims));
+ o->UpdateRect(&rDims, false);
+ tpts[0].x = tpts[1].x = tpts[4].x = o->co2ix(fp1.fx+dx)+p->x;
+ tpts[0].y = tpts[3].y = tpts[4].y = o->co2iy(fp1.fy+dy)+p->y;
+ tpts[1].y = tpts[2].y = o->co2iy(fp2.fy+dy)+p->y;
+ tpts[2].x = tpts[3].x = o->co2ix(fp2.fx+dx)+p->x;
+ UpdateMinMaxRect(&rDims, tpts[0].x, tpts[0].y);
+ UpdateMinMaxRect(&rDims, tpts[2].x, tpts[2].y);
+ if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
+ rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
+ o->ShowLine(tpts, 5, Line.color);
+ if(type == 1) o->ShowEllipse(tpts[0], tpts[2], Line.color);
+ }
+}
+
+void *
+rectangle::ObjThere(int x, int y)
+{
+ if(drc) return drc->ObjThere(x, y);
+ return 0L;
+}
+
+//use circular Bresenham's algorithm to draw rounded rectangles
+//Ref: C. Montani, R. Scopigno (1990) "Speres-To-Voxel Conversion", in:
+// Graphic Gems (A.S. Glassner ed.) Academic Press, Inc.;
+// ISBN 0-12-288165-5
+void
+rectangle::PlotRoundRect(anyOutput *o)
+{
+ int i, m, x, y, di, de, lim, ir, x1, x2, y1, y2;
+ double dx, dy;
+ POINT np;
+
+ dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
+ ir = o->un2ix(rad);
+ x1 = o->co2ix(fp1.fx+dx); y1 = o->co2iy(fp1.fy+dy);
+ x2 = o->co2ix(fp2.fx+dx); y2 = o->co2iy(fp2.fy+dy);
+ if (x1 > x2) Swap(x1, x2); if(y1 > y2) Swap(y1, y2);
+ if(pts) free(pts); nPts = 0;
+ m = ir*4+10;
+ if(!(pts = (POINT*)malloc(m*sizeof(POINT))))return;
+ for(i = 0; i < 4; i++) {
+ x = lim = 0; y = ir; di = 2*(1-ir);
+ while (y >= lim){
+ if(di < 0) {
+ de = 2*di + 2*y -1;
+ if(de > 0) {
+ x++; y--; di += (2*x -2*y +2);
+ }
+ else {
+ x++; di += (2*x +1);
+ }
+ }
+ else {
+ de = 2*di -2*x -1;
+ if(de > 0) {
+ y--; di += (-2*y +1);
+ }
+ else {
+ x++; y--; di += (2*x -2*y +2);
+ }
+ }
+ switch(i) {
+ case 0:
+ np.x = x2-ir+x; np.y = y2-ir+y;
+ break;
+ case 1:
+ np.x = x2-ir+y; np.y = y1+ir-x;
+ break;
+ case 2:
+ np.x = x1+ir-x; np.y = y1+ir-y;
+ break;
+ case 3:
+ np.x = x1+ir-y; np.y = y2-ir+x;
+ break;
+ }
+ AddToPolygon(&nPts, pts, &np);
+ }
+ }
+ AddToPolygon(&nPts, pts, pts); //close polygon
+ o->SetLine(&Line); o->SetFill(&Fill);
+ o->oPolygon(pts, nPts, name);
+ SetMinMaxRect(&rDims, x1, y1, x2, y2);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ellipse with absolute coordinates
+ellipse::ellipse(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2)
+ :rectangle(par, d, p1, p2)
+{
+ type = 1;
+ Id = GO_ELLIPSE;
+}
+
+ellipse::ellipse(int src)
+ :rectangle(src)
+{
+ type = 1;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// rounded rectangle
+roundrec::roundrec(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2)
+ :rectangle(par, d, p1, p2)
+{
+ type = 2;
+ Id = GO_ROUNDREC;
+}
+
+roundrec::roundrec(int src)
+ :rectangle(src)
+{
+ type = 2;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Add a legend to the graph
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, LineDEF *lf, FillDEF *fd, char *desc)
+ :GraphObj(par, d)
+{
+ FileIO(INIT_VARS);
+ if(!ld && !fd && lf) ld = lf;
+ if(ld) {
+ memcpy(&DataLine, ld, sizeof(LineDEF));
+ flags |= 0x01;
+ }
+ if(lf) memcpy(&OutLine, lf, sizeof(LineDEF));
+ if(fd) {
+ if(fd->hatch) memcpy(&HatchLine, fd->hatch, sizeof(LineDEF));
+ memcpy(&Fill, fd, sizeof(FillDEF));
+ Fill.hatch = &HatchLine;
+ flags |= 0x02;
+ }
+ DefDesc(desc); Id = GO_LEGITEM; moveable = 1;
}
-double
-Bezier::ComputeMaxError(lfPOINT *d, int first, int last, lfPOINT *bezCurve, double *u, int *splitPoint)
+LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, Symbol *sy)
+ :GraphObj(par, d)
{
- 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;
- }
+ FileIO(INIT_VARS);
+ if(ld) {
+ memcpy(&DataLine, ld, sizeof(LineDEF)); flags |= 0x01;
}
- return maxDist;
+ if(sy) {
+ Sym = sy; Sym->parent = this; flags |= 0x04;
+ }
+ DefDesc(sy ? sy->name : 0L); Id = GO_LEGITEM; moveable = 1;
}
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// polygons are based on the polyline object
-polygon::polygon(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts):
- polyline(par, d, fpts, cpts)
-{
- Id = GO_POLYGON;
- memcpy(&pgLine, defs.pgLineDEF(0L), sizeof(LineDEF));
- type = 1;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// rectangle with absolute coordinates
-rectangle::rectangle(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2):
- GraphObj(par, d)
-{
- double dx = 0.0, dy = 0.0;
-
- FileIO(INIT_VARS);
- if(parent){
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- }
- memcpy(&fp1, p1, sizeof(lfPOINT)); memcpy(&fp2, p2, sizeof(lfPOINT));
- fp1.fx -= dx; fp1.fy -= dy; fp2.fx -= dx; fp2.fy -= dy;
- type = 0;
- Id = GO_RECTANGLE;
- bModified = false;
-}
-
-rectangle::rectangle(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- type = 0;
- bModified = false;
-}
-
-rectangle::~rectangle()
-{
- Command(CMD_FLUSH, 0L, 0L);
- if(bModified) Undo.InvalidGO(this);
-}
-
-double
-rectangle::GetSize(int select)
-{
- if(parent && parent->Id== GO_GROUP){
- switch(select) {
- case SIZE_XPOS: return fp1.fx + parent->GetSize(SIZE_XPOS);
- case SIZE_XPOS+1: return fp2.fx + parent->GetSize(SIZE_XPOS);
- case SIZE_YPOS: return fp1.fy + parent->GetSize(SIZE_YPOS);
- case SIZE_YPOS+1: return fp2.fy + parent->GetSize(SIZE_YPOS);
- case SIZE_GRECT_LEFT: case SIZE_GRECT_TOP:
- case SIZE_GRECT_RIGHT: case SIZE_GRECT_BOTTOM:
- return parent->GetSize(select);
- }
- return 0.0;
- }
- switch(select) {
- case SIZE_XPOS: return fp1.fx;
- case SIZE_XPOS+1: return fp2.fx;
- case SIZE_YPOS: return fp1.fy;
- case SIZE_YPOS+1: return fp2.fy;
- case SIZE_GRECT_LEFT: case SIZE_GRECT_TOP:
- case SIZE_GRECT_RIGHT: case SIZE_GRECT_BOTTOM:
- if(parent) return parent->GetSize(select);
- break;
- }
- return 0.0;
-}
-
-bool
-rectangle::SetSize(int select, double value)
-{
- switch(select & 0xfff) {
- case SIZE_XPOS: fp1.fx = value; return true;
- case SIZE_XPOS+1: fp2.fx = value; return true;
- case SIZE_YPOS: fp1.fy = value; return true;
- case SIZE_YPOS+1: fp2.fy = value; return true;
- }
- return false;
-}
-
-void
-rectangle::DoMark(anyOutput *o, bool mark)
-{
- RECT upd;
-
- if(!drc) drc = new dragRect(this, 0);
- memcpy(&upd, &rDims, sizeof(RECT));
- if(mark){
- if(drc) drc->DoPlot(o);
- }
- else if(parent) parent->DoPlot(o);
- IncrementMinMaxRect(&upd, 6);
- o->UpdateRect(&upd, false);
-}
-
-void
-rectangle::DoPlot(anyOutput *o)
-{
- int x1, y1, x2, y2;
- double tmp, dx, dy;
-
- if(!parent || !o) return;
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- if(fp1.fx > fp2.fx) {
- tmp = fp2.fx; fp2.fx = fp1.fx; fp1.fx = tmp;
- }
- if(fp1.fy > fp2.fy) {
- tmp = fp2.fy; fp2.fy = fp1.fy; fp1.fy = tmp;
- }
- if(type == 2) PlotRoundRect(o);
- else {
- x1 = o->co2ix(fp1.fx+dx); y1 = o->co2iy(fp1.fy+dy);
- x2 = o->co2ix(fp2.fx+dx); y2 = o->co2iy(fp2.fy+dy);
- o->SetLine(&Line); o->SetFill(&Fill);
- if(type == 1) o->oCircle(x1, y1, x2, y2, name);
- else o->oRectangle(x1, y1, x2, y2, name);
- SetMinMaxRect(&rDims, x1, y1, x2, y2);
- }
- o->MrkMode = MRK_NONE;
- if(CurrGO == this) o->ShowMark(this, MRK_GODRAW);
-}
-
-bool
-rectangle::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
-
- switch (cmd) {
- case CMD_FLUSH:
- if(pts) free(pts); pts = 0L;
- if(name) free(name); name = 0L;
- return true;
- case CMD_SAVEPOS:
- bModified = true;
- Undo.SaveLFP(this, &fp1, 0L);
- Undo.SaveLFP(this, &fp2, UNDO_CONTINUE);
- return true;
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- switch (mev->Action) {
- case MOUSE_LBUP:
- if(IsInRect(&rDims, mev->x, mev->y) && !(CurrGO) && (o)){
- return o->ShowMark(this, MRK_GODRAW);
- }
- }
- return false;
- case CMD_SET_DATAOBJ:
- switch (type) {
- case 1: Id = GO_ELLIPSE; break;
- case 2: Id = GO_ROUNDREC; break;
- default: Id = GO_RECTANGLE; break;
- }
- return true;
- case CMD_MOVE:
- bModified = true;
- Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
- case CMD_UNDO_MOVE:
- fp1.fx += ((lfPOINT*)tmpl)[0].fx; fp1.fy += ((lfPOINT*)tmpl)[0].fy;
- fp2.fx += ((lfPOINT*)tmpl)[0].fx; fp2.fy += ((lfPOINT*)tmpl)[0].fy;
- CurrGO = this;
- case CMD_REDRAW:
- if(parent && cmd != CMD_UNDO_MOVE){
- parent->Command(CMD_REDRAW, tmpl, o);
- }
- return true;
- case CMD_SETSCROLL:
- if(parent) return parent->Command(cmd, tmpl, o);
- }
- return false;
-}
-
-void
-rectangle::Track(POINT *p, anyOutput *o)
-{
- POINT tpts[5];
- RECT old_rc;
- double dx, dy;
-
- if(o && parent){
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- memcpy(&old_rc, &rDims, sizeof(rDims));
- o->UpdateRect(&rDims, false);
- tpts[0].x = tpts[1].x = tpts[4].x = o->co2ix(fp1.fx+dx)+p->x;
- tpts[0].y = tpts[3].y = tpts[4].y = o->co2iy(fp1.fy+dy)+p->y;
- tpts[1].y = tpts[2].y = o->co2iy(fp2.fy+dy)+p->y;
- tpts[2].x = tpts[3].x = o->co2ix(fp2.fx+dx)+p->x;
- UpdateMinMaxRect(&rDims, tpts[0].x, tpts[0].y);
- UpdateMinMaxRect(&rDims, tpts[2].x, tpts[2].y);
- if(old_rc.left != rDims.left || old_rc.right != rDims.right || old_rc.top !=
- rDims.top || old_rc.bottom != rDims.bottom)IncrementMinMaxRect(&rDims, 3);
- o->ShowLine(tpts, 5, Line.color);
- if(type == 1) o->ShowEllipse(tpts[0], tpts[2], Line.color);
- }
-}
-
-void *
-rectangle::ObjThere(int x, int y)
-{
- if(drc) return drc->ObjThere(x, y);
- return 0L;
-}
-
-//use circular Bresenham's algorithm to draw rounded rectangles
-//Ref: C. Montani, R. Scopigno (1990) "Speres-To-Voxel Conversion", in:
-// Graphic Gems (A.S. Glassner ed.) Academic Press, Inc.;
-// ISBN 0-12-288165-5
-void
-rectangle::PlotRoundRect(anyOutput *o)
-{
- int i, m, x, y, di, de, lim, ir, x1, x2, y1, y2;
- double dx, dy;
- POINT np;
-
- dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- ir = o->un2ix(rad);
- x1 = o->co2ix(fp1.fx+dx); y1 = o->co2iy(fp1.fy+dy);
- x2 = o->co2ix(fp2.fx+dx); y2 = o->co2iy(fp2.fy+dy);
- if (x1 > x2) Swap(x1, x2); if(y1 > y2) Swap(y1, y2);
- if(pts) free(pts); nPts = 0;
- m = ir*4+10;
- if(!(pts = (POINT*)malloc(m*sizeof(POINT))))return;
- for(i = 0; i < 4; i++) {
- x = lim = 0; y = ir; di = 2*(1-ir);
- while (y >= lim){
- if(di < 0) {
- de = 2*di + 2*y -1;
- if(de > 0) {
- x++; y--; di += (2*x -2*y +2);
- }
- else {
- x++; di += (2*x +1);
- }
- }
- else {
- de = 2*di -2*x -1;
- if(de > 0) {
- y--; di += (-2*y +1);
- }
- else {
- x++; y--; di += (2*x -2*y +2);
- }
- }
- switch(i) {
- case 0:
- np.x = x2-ir+x; np.y = y2-ir+y;
- break;
- case 1:
- np.x = x2-ir+y; np.y = y1+ir-x;
- break;
- case 2:
- np.x = x1+ir-x; np.y = y1+ir-y;
- break;
- case 3:
- np.x = x1+ir-y; np.y = y2-ir+x;
- break;
- }
- AddToPolygon(&nPts, pts, &np);
- }
- }
- AddToPolygon(&nPts, pts, pts); //close polygon
- o->SetLine(&Line); o->SetFill(&Fill);
- o->oPolygon(pts, nPts, name);
- SetMinMaxRect(&rDims, x1, y1, x2, y2);
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// ellipse with absolute coordinates
-ellipse::ellipse(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2)
- :rectangle(par, d, p1, p2)
-{
- type = 1;
- Id = GO_ELLIPSE;
-}
-
-ellipse::ellipse(int src)
- :rectangle(src)
-{
- type = 1;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// rounded rectangle
-roundrec::roundrec(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2)
- :rectangle(par, d, p1, p2)
-{
- type = 2;
- Id = GO_ROUNDREC;
-}
-
-roundrec::roundrec(int src)
- :rectangle(src)
-{
- type = 2;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Add a legend to the graph
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, LineDEF *lf, FillDEF *fd)
- :GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- if(!ld && !fd && lf) ld = lf;
- if(ld) {
- memcpy(&DataLine, ld, sizeof(LineDEF));
- flags |= 0x01;
- }
- if(lf) memcpy(&OutLine, lf, sizeof(LineDEF));
- if(fd) {
- if(fd->hatch) memcpy(&HatchLine, fd->hatch, sizeof(LineDEF));
- memcpy(&Fill, fd, sizeof(FillDEF));
- Fill.hatch = &HatchLine;
- flags |= 0x02;
- }
- DefDesc(0L); Id = GO_LEGITEM; moveable = true;
-}
-
-LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, Symbol *sy)
- :GraphObj(par, d)
-{
- FileIO(INIT_VARS);
- if(ld) {
- memcpy(&DataLine, ld, sizeof(LineDEF)); flags |= 0x01;
- }
- if(sy) {
- Sym = sy; Sym->parent = this; flags |= 0x04;
- }
- DefDesc(0L); Id = GO_LEGITEM; moveable = true;
-}
-
LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, int err, char *desc)
:GraphObj(par, d)
{
@@ -7066,56 +8013,55 @@ LegItem::LegItem(GraphObj *par, DataObj *d, LineDEF *ld, int err, char *desc)
if(ld) {
memcpy(&OutLine, ld, sizeof(LineDEF));
}
- DefDesc(desc); Id = GO_LEGITEM; moveable = true;
-}
-
-LegItem::LegItem(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- moveable = true;
-}
-
-LegItem::~LegItem()
-{
- if(Sym) DeleteGO(Sym); Sym = 0L;
- if(Desc) DeleteGO(Desc); Desc = 0L;
-}
-
-double
-LegItem::GetSize(int select)
-{
- switch(select) {
- case SIZE_XCENTER:
+ DefDesc(desc); Id = GO_LEGITEM; moveable = 1;
+}
+
+LegItem::LegItem(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ moveable = 1;
+}
+
+LegItem::~LegItem()
+{
+ if(Sym) DeleteGO(Sym); Sym = 0L;
+ if(Desc) DeleteGO(Desc); Desc = 0L;
+}
+
+double
+LegItem::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_XCENTER:
return (parent->GetSize((flags & 0x01) ? SIZE_XPOS+2 : SIZE_XPOS) +
parent->GetSize((flags & 0x01) ? SIZE_XPOS+3 : SIZE_XPOS+1))/2.0;
- case SIZE_YCENTER:
- return (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
- case SIZE_LB_XPOS: case SIZE_LB_YPOS:
- case SIZE_GRECT_TOP: case SIZE_GRECT_LEFT:
- default:
- if(parent) return parent->GetSize(select);
- break;
- }
- return 0.0;
-}
-
-void
-LegItem::DoPlot(anyOutput *o)
-{
+ case SIZE_YCENTER:
+ return (parent->GetSize(SIZE_YPOS) + parent->GetSize(SIZE_YPOS+1))/2.0;
+ case SIZE_LB_XPOS: case SIZE_LB_YPOS:
+ case SIZE_GRECT_TOP: case SIZE_GRECT_LEFT:
+ default:
+ if(parent) return parent->GetSize(select);
+ break;
+ }
+ return 0.0;
+}
+
+void
+LegItem::DoPlot(anyOutput *o)
+{
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);
+ ie = o->un2ix(DefSize(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;
@@ -7172,101 +8118,110 @@ LegItem::DoPlot(anyOutput *o)
if(Sym) Sym->DoPlot(o);
}
}
+ SetMinMaxRect(&rDims, hcr.left, hcr.top, hcr.right, hcr.bottom);
if(Desc) {
- Desc->moveable = false; Desc->DoPlot(o);
+ Desc->moveable = 1; 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
-LegItem::DoMark(anyOutput *o, bool mark)
-{
- RECT cr;
- LineDEF ld = {0.0, 1.0, 0x00000000L, 0x00000000L};
- POINT pts[5];
-
- if(!parent || !o) return;
- cr.left = hcr.left-5; cr.right = hcr.right+3;
- cr.top = hcr.top-3; cr.bottom = hcr.bottom+1;
- ld.color = mark ? 0x00000000L : 0x00ffffffL; o->SetLine(&ld);
- pts[0].x = pts[3].x = pts[4].x = cr.left; pts[0].y = pts[1].y = pts[4].y = cr.top;
- pts[1].x = pts[2].x = cr.right; pts[2].y = pts[3].y = cr.bottom;
- o->oPolyline(pts, 5, name); IncrementMinMaxRect(&cr, 3);
- o->UpdateRect(&cr, false);
-}
-
-bool
-LegItem::Command(int cmd, void *tmpl, anyOutput *o)
-{
- GraphObj **tmpPlots;
-
- switch(cmd){
- case CMD_MOUSE_EVENT:
- if(tmpl && IsInRect(&rDims, ((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y) && o) {
- if(Desc && Desc->Command(cmd, tmpl, o)) return true;
- if(!CurrGO) o->ShowMark(CurrGO=this, MRK_GODRAW);
- }
- break;
- case CMD_HIDE_MARK:
- if(!tmpl || !o) return false;
- if(Desc && Desc == (void*)tmpl) {
- Desc->DoMark(o, false);
- return true;
- }
- return false;
- case CMD_REDRAW: case CMD_MOVE:
- if(parent) return parent->Command(cmd, tmpl, o);
- break;
- case CMD_MUTATE:
- if(!parent || !(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
- if(Desc == tmpPlots[0]) {
- Undo.MutateGO((GraphObj**)&Desc, tmpPlots[1], 0L, o);
- return true;
- }
- break;
- case CMD_SET_DATAOBJ:
+}
+
+void
+LegItem::DoMark(anyOutput *o, bool mark)
+{
+ RECT cr;
+ LineDEF ld = {0.0, 1.0, 0x00000000L, 0x00000000L};
+ POINT pts[5];
+
+ if(!parent || !o) return;
+ cr.left = hcr.left-5; cr.right = hcr.right+3;
+ cr.top = hcr.top-3; cr.bottom = hcr.bottom+1;
+ ld.color = mark ? 0x00000000L : 0x00ffffffL; o->SetLine(&ld);
+ pts[0].x = pts[3].x = pts[4].x = cr.left; pts[0].y = pts[1].y = pts[4].y = cr.top;
+ pts[1].x = pts[2].x = cr.right; pts[2].y = pts[3].y = cr.bottom;
+ o->oPolyline(pts, 5, name); IncrementMinMaxRect(&cr, 3);
+ o->UpdateRect(&cr, false);
+}
+
+bool
+LegItem::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ GraphObj **tmpPlots;
+
+ switch(cmd){
+ case CMD_MOUSE_EVENT:
+ if(tmpl && IsInRect(&rDims, ((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y) && o) {
+ if(Desc && Desc->Command(cmd, tmpl, o)) return true;
+ if(!CurrGO) o->ShowMark(CurrGO=this, MRK_GODRAW);
+ }
+ break;
+ case CMD_HIDE_MARK:
+ if(!tmpl || !o) return false;
+ if(Desc && Desc == (void*)tmpl) {
+ Desc->DoMark(o, false);
+ return true;
+ }
+ return false;
+ case CMD_SCALE:
+ DataLine.patlength *= ((scaleINFO*)tmpl)->sy.fy; DataLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ OutLine.patlength *= ((scaleINFO*)tmpl)->sy.fy; OutLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ HatchLine.patlength *= ((scaleINFO*)tmpl)->sy.fy; HatchLine.width *= ((scaleINFO*)tmpl)->sy.fy;
+ Fill.scale *= ((scaleINFO*)tmpl)->sy.fy;
+ if(Sym) Sym->Command(cmd, tmpl, o);
+ if(Desc) Desc->Command(cmd, tmpl, o);
+ break;
+ case CMD_REDRAW: case CMD_MOVE:
+ if(parent) return parent->Command(cmd, tmpl, o);
+ break;
+ case CMD_MUTATE:
+ if(!parent || !(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
+ if(Desc == tmpPlots[0]) {
+ Undo.MutateGO((GraphObj**)&Desc, tmpPlots[1], 0L, o);
+ return true;
+ }
+ break;
+ case CMD_SET_DATAOBJ:
if(Desc) Desc->Command(cmd, tmpl, o);
- Id = GO_LEGITEM;
- data = (DataObj *)tmpl;
- return true;
- }
- return false;
-}
-
-void
-LegItem::Track(POINT *p, anyOutput *o)
-{
- if(parent) parent->Track(p, o);
-}
-
-bool
-LegItem::HasFill(LineDEF *ld, FillDEF *fd)
-{
- if(ld && cmpLineDEF(ld, &OutLine)) return false;
- if(fd && cmpFillDEF(fd, &Fill)) return false;
- if(fd && fd->hatch && cmpLineDEF(fd->hatch, &HatchLine)) return false;
- return true;
-}
-
-bool
-LegItem::HasSym(LineDEF *ld, GraphObj *sy)
-{
+ Id = GO_LEGITEM;
+ data = (DataObj *)tmpl;
+ return true;
+ }
+ return false;
+}
+
+void
+LegItem::Track(POINT *p, anyOutput *o)
+{
+ if(parent) parent->Track(p, o);
+}
+
+bool
+LegItem::HasFill(LineDEF *ld, FillDEF *fd, char *desc)
+{
+ if(ld && cmpLineDEF(ld, &OutLine)) return false;
+ if(fd && cmpFillDEF(fd, &Fill)) return false;
+ if(fd && fd->hatch && cmpLineDEF(fd->hatch, &HatchLine)) return false;
+ return true;
+}
+
+bool
+LegItem::HasSym(LineDEF *ld, GraphObj *sy)
+{
if(sy && !Sym) return false;
if(sy->Id == GO_SYMBOL && (sy->type & 0xfff) != (Sym->type & 0xfff)) return false;
- if(sy && Sym) {
- if(Sym->GetSize(SIZE_SYMBOL) != sy->GetSize(SIZE_SYMBOL)) return false;
- if(Sym->GetSize(SIZE_SYM_LINE) != sy->GetSize(SIZE_SYM_LINE)) return false;
- if(Sym->GetColor(COL_SYM_LINE) != sy->GetColor(COL_SYM_LINE)) return false;
- if(Sym->GetColor(COL_SYM_FILL) != sy->GetColor(COL_SYM_FILL)) return false;
- }
- if(ld && cmpLineDEF(ld, &DataLine)) return false;
- return true;
-}
-
+ if(sy && Sym) {
+ if(Sym->GetSize(SIZE_SYMBOL) != sy->GetSize(SIZE_SYMBOL)) return false;
+ if(Sym->GetSize(SIZE_SYM_LINE) != sy->GetSize(SIZE_SYM_LINE)) return false;
+ if(Sym->GetColor(COL_SYM_LINE) != sy->GetColor(COL_SYM_LINE)) return false;
+ if(Sym->GetColor(COL_SYM_FILL) != sy->GetColor(COL_SYM_FILL)) return false;
+ }
+ if(ld && cmpLineDEF(ld, &DataLine)) return false;
+ return true;
+}
+
bool
LegItem::HasErr(LineDEF *ld, int err)
{
@@ -7274,255 +8229,278 @@ LegItem::HasErr(LineDEF *ld, int err)
if(ld && cmpLineDEF(ld, &OutLine)) return false;
return true;
}
-
-void
-LegItem::DefDesc(char *txt)
-{
- TextDEF td;
-
- td.ColTxt = 0x00000000L; td.ColBg = 0x00ffffffL;
- td.fSize = defs.GetSize(SIZE_TICK_LABELS);
- td.RotBL = td.RotCHAR = 0.0;
- td.iSize = 0; td.Align = TXA_VTOP | TXA_HLEFT;
- td.Mode = TXM_TRANSPARENT; td.Style = TXS_NORMAL;
- td.Font = FONT_HELVETICA; td.text = txt ? strdup(txt) : strdup("text");
- Desc = new Label(this, data, 0, 0, &td, LB_X_PARENT | LB_Y_PARENT);
-}
-
-Legend::Legend(GraphObj *par, DataObj *d):GraphObj(par, d)
-{
- FileIO(INIT_VARS); Id = GO_LEGEND; moveable = true;
-}
-
-Legend::Legend(int src):GraphObj(0L, 0L)
-{
- FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- }
- moveable = true;
-}
-
-Legend::~Legend()
-{
- int i;
-
- if(Items) {
- for(i = 0; i< nItems; i++) if(Items[i]) DeleteGO(Items[i]);
- free(Items); Items = 0L;
- }
- if(to) DelBitmapClass(to); to = 0L;
-}
-double
-Legend::GetSize(int select)
-{
- switch(select) {
- case SIZE_XPOS: return C_Rect.Xmin;
- case SIZE_XPOS+1: return C_Rect.Xmax;
+
+void
+LegItem::DefDesc(char *txt)
+{
+ TextDEF td;
+ int cb;
+
+ cb = txt && *txt ? (int)strlen(txt) : 20;
+ if(cb < 20) cb = 20;
+ td.ColTxt = 0x00000000L; td.ColBg = 0x00ffffffL;
+ td.fSize = DefSize(SIZE_TICK_LABELS);
+ td.RotBL = td.RotCHAR = 0.0;
+ td.iSize = 0; td.Align = TXA_VTOP | TXA_HLEFT;
+ td.Mode = TXM_TRANSPARENT; td.Style = TXS_NORMAL;
+ td.Font = FONT_HELVETICA; td.text = (char*)malloc(cb+2);
+ rlp_strcpy(td.text, cb+2, txt ? txt : (char*)"text");
+ Desc = new Label(this, data, 0, 0, &td, LB_X_PARENT | LB_Y_PARENT);
+}
+
+Legend::Legend(GraphObj *par, DataObj *d):GraphObj(par, d)
+{
+ FileIO(INIT_VARS); Id = GO_LEGEND; moveable = true;
+}
+
+Legend::Legend(int src):GraphObj(0L, 0L)
+{
+ FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ }
+ moveable = true;
+}
+
+Legend::~Legend()
+{
+ int i;
+
+ if(Items) {
+ for(i = 0; i< nItems; i++) if(Items[i]) DeleteGO(Items[i]);
+ free(Items); Items = 0L;
+ }
+ if(to) DelBitmapClass(to); to = 0L;
+}
+double
+Legend::GetSize(int select)
+{
+ switch(select) {
+ case SIZE_XPOS: return C_Rect.Xmin;
+ case SIZE_XPOS+1: return C_Rect.Xmax;
case SIZE_XPOS+2: return E_Rect.Xmin;
case SIZE_XPOS+3: return E_Rect.Xmax;
- case SIZE_YPOS: return C_Rect.Ymin;
+ case SIZE_YPOS: return C_Rect.Ymin;
case SIZE_YPOS+1: return C_Rect.Ymax;
- case SIZE_LB_XPOS: return lb_pos.fx;
- case SIZE_LB_YPOS: return lb_pos.fy;
- case SIZE_GRECT_TOP: case SIZE_GRECT_LEFT:
- if(parent) return parent->GetSize(select);
- break;
- }
- return 0.0;
-}
-
-bool
-Legend::SetSize(int select, double value)
-{
- double tmp;
-
- switch (select & 0xfff){
- case SIZE_XPOS: pos.fx = value; return true;
- case SIZE_YPOS: pos.fy = value; return true;
- case SIZE_YPOS+1:
- tmp = value - C_Rect.Ymax;
- C_Rect.Ymin += tmp; C_Rect.Ymax += tmp; lb_pos.fy +=tmp;
- }
- return false;
-}
-
-void
-Legend::DoPlot(anyOutput *o)
-{
- int i;
- double y_inc, dx, dy;
-
- if(!o || !Items) return;
- if(to) DelBitmapClass(to); to = 0L;
+ case SIZE_LB_XPOS: return lb_pos.fx;
+ case SIZE_LB_YPOS: return lb_pos.fy;
+ case SIZE_GRECT_TOP: case SIZE_GRECT_LEFT:
+ if(parent) return parent->GetSize(select);
+ break;
+ }
+ return 0.0;
+}
+
+bool
+Legend::SetSize(int select, double value)
+{
+ double tmp;
+
+ switch (select & 0xfff){
+ case SIZE_XPOS: pos.fx = value; return true;
+ case SIZE_YPOS: pos.fy = value; return true;
+ case SIZE_YPOS+1:
+ tmp = value - C_Rect.Ymax;
+ C_Rect.Ymin += tmp; C_Rect.Ymax += tmp; lb_pos.fy +=tmp;
+ }
+ return false;
+}
+
+void
+Legend::DoPlot(anyOutput *o)
+{
+ int i;
+ double y_inc, dx, dy;
+
+ if(!o || !Items) return;
+ if(to) DelBitmapClass(to); to = 0L;
dx = parent->GetSize(SIZE_GRECT_LEFT); dy = parent->GetSize(SIZE_GRECT_TOP);
- C_Rect.Xmin = o->co2fix(pos.fx + B_Rect.Xmin + D_Rect.Xmin + dx);
- C_Rect.Ymin = o->co2fiy(pos.fy + B_Rect.Ymin + D_Rect.Ymin + dy);
- C_Rect.Xmax = C_Rect.Xmin + o->un2fix(D_Rect.Xmax - D_Rect.Xmin);
+ C_Rect.Xmin = o->co2fix(pos.fx + B_Rect.Xmin + D_Rect.Xmin + dx);
+ C_Rect.Ymin = o->co2fiy(pos.fy + B_Rect.Ymin + D_Rect.Ymin + dy);
+ C_Rect.Xmax = C_Rect.Xmin + o->un2fix(D_Rect.Xmax - D_Rect.Xmin);
C_Rect.Ymax = C_Rect.Ymin + o->un2fix(D_Rect.Ymax - D_Rect.Ymin);
- E_Rect.Ymin = C_Rect.Ymin; E_Rect.Ymax = C_Rect.Ymax;
+ E_Rect.Ymin = C_Rect.Ymin; E_Rect.Ymax = C_Rect.Ymax;
E_Rect.Xmin = o->co2fix(pos.fx + B_Rect.Xmin + F_Rect.Xmin + dx);
E_Rect.Xmax = E_Rect.Xmin + o->un2fix(F_Rect.Xmax - F_Rect.Xmin);
- y_inc = floor(0.5+o->un2fiy(B_Rect.Ymax - B_Rect.Ymin));
- rDims.left = rDims.right = rDims.top = rDims.bottom = 0;
- lb_pos.fx = o->co2fix(pos.fx + B_Rect.Xmax + dx); lb_pos.fy = C_Rect.Ymin;
- //draw all items
- for(i = 0; i < nItems; i++) {
- if(Items[i]){
+ y_inc = floor(0.5+o->un2fiy(B_Rect.Ymax - B_Rect.Ymin));
+ rDims.top = iround(C_Rect.Ymin); rDims.bottom = iround(C_Rect.Ymax);
+ rDims.left = rDims.right = iround(C_Rect.Xmin);
+ lb_pos.fx = o->co2fix(pos.fx + B_Rect.Xmax + dx); lb_pos.fy = C_Rect.Ymin;
+ //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;
- rDims.top = Items[i]->rDims.top; rDims.bottom = Items[i]->rDims.bottom;
- }
- else {
- UpdateMinMaxRect(&rDims, Items[i]->rDims.left, Items[i]->rDims.top);
- UpdateMinMaxRect(&rDims, Items[i]->rDims.right, Items[i]->rDims.bottom);
- }
- C_Rect.Ymin += y_inc; C_Rect.Ymax += y_inc;
- lb_pos.fy += y_inc;
- }
- }
- IncrementMinMaxRect(&rDims, 6);
-}
-
-void
-Legend::DoMark(anyOutput *o, bool mark)
-{
- RECT cr;
- LineDEF ld = {0.0, 1.0, 0x00c0c0c0L, 0x00000000L};
- POINT pts[5];
-
- if(!parent || !o) return;
- cr.left = rDims.left; cr.right = rDims.right;
- cr.top = rDims.top; cr.bottom = rDims.bottom;
- ld.color = mark ? 0x00c0c0c0L : 0x00ffffffL; o->SetLine(&ld);
- pts[0].x = pts[3].x = pts[4].x = cr.left; pts[0].y = pts[1].y = pts[4].y = cr.top;
- pts[1].x = pts[2].x = cr.right; pts[2].y = pts[3].y = cr.bottom;
- o->oPolyline(pts, 5, name); IncrementMinMaxRect(&cr, 3);
- o->UpdateRect(&cr, false);
-}
-
-bool
-Legend::Command(int cmd, void *tmpl, anyOutput *o)
-{
- int i;
-
- switch(cmd){
- case CMD_MOUSE_EVENT:
- if(o && tmpl && IsInRect(&rDims, ((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y)) {
- if(Items) for(i = 0; i< nItems; i++)
- if(Items[i] && Items[i]->Command(cmd, tmpl, o)) return true;
- if(!CurrGO) o->ShowMark(CurrGO = this, MRK_GODRAW);
- }
- break;
- case CMD_SET_DATAOBJ:
- if(Items) for(i = 0; i < nItems; i++) if(Items[i]) Items[i]->Command(cmd, tmpl, o);
- Id = GO_LEGEND;
- data = (DataObj *)tmpl;
- return true;
- case CMD_HIDE_MARK:
- if(!tmpl || !o) return false;
- if(Items && nItems) for(i = 0; i < nItems; i++) {
- if(Items[i]) {
- if(tmpl == (void*)Items[i]) {
- Items[i]->DoMark(o, false);
- return true;
- }
- else if(Items[i]->Command(cmd, tmpl, o)) return true;
- }
- }
- return false;
- case CMD_DELOBJ:
- o->HideMark();
- if(Items && parent) for(i = 0; i < nItems; i++) {
- if(Items[i] && tmpl == (void *)Items[i]) {
- Undo.DeleteGO((GraphObj**)(&Items[i]), 0L, o);
- parent->Command(CMD_REDRAW, NULL, o);
- return true;
- }
- }
- break;
- case CMD_MOVE:
- Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
- case CMD_UNDO_MOVE:
- pos.fx += ((lfPOINT*)tmpl)[0].fx; pos.fy += ((lfPOINT*)tmpl)[0].fy;
- CurrGO = this;
- case CMD_REDRAW:
- if(parent && cmd != CMD_UNDO_MOVE){
- parent->Command(CMD_REDRAW, tmpl, o);
- }
- return true;
- case CMD_DROP_OBJECT:
- if(!tmpl) return false;
- if(!(Items = (LegItem**)realloc(Items, (2+nItems)*sizeof(LegItem*))))return false;
- Items[nItems++] = (LegItem*)tmpl;
- Items[nItems-1]->parent = this;
- return true;
- }
- return false;
-}
-
-void
-Legend::Track(POINT *p, anyOutput *o)
-{
- POINT pts[5];
- LineDEF tld = {0.0, 1.0, 0x00c0c0c0, 0x0L};
-
- if(!p || !o) return;
- if(to) {
- o->CopyBitmap(trc.left, trc.top, to, 0, 0, trc.right - trc.left,
- trc.bottom - trc.top, false);
- DelBitmapClass(to); to = 0L;
- o->UpdateRect(&trc, false);
- }
- trc.left = pts[0].x = pts[1].x = pts[4].x = rDims.left + p->x;
- trc.top = pts[0].y = pts[3].y = pts[4].y = rDims.top + p->y;
- trc.bottom = pts[1].y = pts[2].y = rDims.bottom + p->y;
- trc.right = pts[2].x = pts[3].x = rDims.right + p->x;
- IncrementMinMaxRect(&trc, 3); to = GetRectBitmap(&trc, o);
- o->SetLine(&tld); o->oPolyline(pts, 5, 0L);
- o->UpdateRect(&trc, false);
-}
-
-bool
-Legend::HasFill(LineDEF *ld, FillDEF *fd)
-{
- int i;
- LegItem *li;
-
- if(Items) for(i = 0; i < nItems; i++) {
- if(Items[i] && Items[i]->HasFill(ld, fd)) return true;
- }
- if(li = new LegItem(this, data, 0L, ld, fd)){
- if(!(Command(CMD_DROP_OBJECT, li, 0L))) DeleteGO(li);
- }
- return false;
-}
-
-bool
-Legend::HasSym(LineDEF *ld, GraphObj *sy)
-{
- int i, sym;
- Symbol *ns;
- LegItem *li;
-
- if(!parent || !sy) return true;
+ Items[i]->DoPlot(o);
+ UpdateMinMaxRect(&rDims, Items[i]->rDims.left, Items[i]->rDims.top);
+ UpdateMinMaxRect(&rDims, Items[i]->rDims.right, Items[i]->rDims.bottom);
+ C_Rect.Ymin += y_inc; C_Rect.Ymax += y_inc;
+ lb_pos.fy += y_inc;
+ }
+ }
+ IncrementMinMaxRect(&rDims, 6);
+}
+
+void
+Legend::DoMark(anyOutput *o, bool mark)
+{
+ RECT cr;
+ LineDEF ld = {0.0, 1.0, 0x00c0c0c0L, 0x00000000L};
+ POINT pts[5];
+
+ if(!parent || !o) return;
+ cr.left = rDims.left; cr.right = rDims.right;
+ cr.top = rDims.top; cr.bottom = rDims.bottom;
+ ld.color = mark ? 0x00c0c0c0L : 0x00ffffffL; o->SetLine(&ld);
+ pts[0].x = pts[3].x = pts[4].x = cr.left; pts[0].y = pts[1].y = pts[4].y = cr.top;
+ pts[1].x = pts[2].x = cr.right; pts[2].y = pts[3].y = cr.bottom;
+ o->oPolyline(pts, 5, name); IncrementMinMaxRect(&cr, 3);
+ o->UpdateRect(&cr, false);
+}
+
+bool
+Legend::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ int i;
+
+ switch(cmd){
+ case CMD_MOUSE_EVENT:
+ if(o && tmpl && IsInRect(&rDims, ((MouseEvent*)tmpl)->x, ((MouseEvent*)tmpl)->y)) {
+ if(Items) for(i = 0; i< nItems; i++)
+ if(Items[i] && Items[i]->Command(cmd, tmpl, o)) return true;
+ if(!CurrGO) o->ShowMark(CurrGO = this, MRK_GODRAW);
+ }
+ break;
+ case CMD_SET_DATAOBJ:
+ if(Items) for(i = 0; i < nItems; i++) if(Items[i]) Items[i]->Command(cmd, tmpl, o);
+ Id = GO_LEGEND;
+ data = (DataObj *)tmpl;
+ return true;
+ case CMD_SCALE:
+ pos.fx *= ((scaleINFO*)tmpl)->sx.fy; pos.fy *= ((scaleINFO*)tmpl)->sy.fy;
+ lb_pos.fx *= ((scaleINFO*)tmpl)->sx.fy; lb_pos.fy *= ((scaleINFO*)tmpl)->sy.fy;
+ B_Rect.Xmax *= ((scaleINFO*)tmpl)->sx.fy; B_Rect.Xmin *= ((scaleINFO*)tmpl)->sx.fy;
+ B_Rect.Ymax *= ((scaleINFO*)tmpl)->sy.fy; B_Rect.Ymin *= ((scaleINFO*)tmpl)->sy.fy;
+ C_Rect.Xmax *= ((scaleINFO*)tmpl)->sx.fy; C_Rect.Xmin *= ((scaleINFO*)tmpl)->sx.fy;
+ C_Rect.Ymax *= ((scaleINFO*)tmpl)->sy.fy; C_Rect.Ymin *= ((scaleINFO*)tmpl)->sy.fy;
+ D_Rect.Xmax *= ((scaleINFO*)tmpl)->sx.fy; D_Rect.Xmin *= ((scaleINFO*)tmpl)->sx.fy;
+ D_Rect.Ymax *= ((scaleINFO*)tmpl)->sy.fy; D_Rect.Ymin *= ((scaleINFO*)tmpl)->sy.fy;
+ E_Rect.Xmax *= ((scaleINFO*)tmpl)->sx.fy; E_Rect.Xmin *= ((scaleINFO*)tmpl)->sx.fy;
+ E_Rect.Ymax *= ((scaleINFO*)tmpl)->sy.fy; E_Rect.Ymin *= ((scaleINFO*)tmpl)->sy.fy;
+ F_Rect.Xmax *= ((scaleINFO*)tmpl)->sx.fy; F_Rect.Xmin *= ((scaleINFO*)tmpl)->sx.fy;
+ F_Rect.Ymax *= ((scaleINFO*)tmpl)->sy.fy; F_Rect.Ymin *= ((scaleINFO*)tmpl)->sy.fy;
+ if(Items) for(i = 0; i < nItems; i++) if(Items[i]) Items[i]->Command(cmd, tmpl, o);
+ return true;
+ case CMD_HIDE_MARK:
+ if(!tmpl || !o) return false;
+ if(Items && nItems) for(i = 0; i < nItems; i++) {
+ if(Items[i]) {
+ if(tmpl == (void*)Items[i]) {
+ Items[i]->DoMark(o, false);
+ return true;
+ }
+ else if(Items[i]->Command(cmd, tmpl, o)) return true;
+ }
+ }
+ return false;
+ case CMD_DELOBJ:
+ o->HideMark();
+ if(Items && parent) for(i = 0; i < nItems; i++) {
+ if(Items[i] && tmpl == (void *)Items[i]) {
+ Undo.DeleteGO((GraphObj**)(&Items[i]), 0L, o);
+ parent->Command(CMD_REDRAW, NULL, o);
+ return true;
+ }
+ }
+ break;
+ case CMD_MOVE:
+ Undo.MoveObj(this, (lfPOINT*)tmpl, 0L);
+ case CMD_UNDO_MOVE:
+ pos.fx += ((lfPOINT*)tmpl)[0].fx; pos.fy += ((lfPOINT*)tmpl)[0].fy;
+ CurrGO = this;
+ case CMD_REDRAW:
+ if(parent && cmd != CMD_UNDO_MOVE){
+ parent->Command(CMD_REDRAW, tmpl, o);
+ }
+ return true;
+ case CMD_DROP_OBJECT:
+ if(!tmpl) return false;
+ if(!(Items = (LegItem**)realloc(Items, (2+nItems)*sizeof(LegItem*))))return false;
+ Items[nItems++] = (LegItem*)tmpl;
+ Items[nItems-1]->parent = this;
+ return true;
+ }
+ return false;
+}
+
+void
+Legend::Track(POINT *p, anyOutput *o)
+{
+ POINT pts[5];
+ LineDEF tld = {0.0, 1.0, 0x00c0c0c0, 0x0L};
+
+ if(!p || !o) return;
+ if(to) {
+ o->CopyBitmap(trc.left, trc.top, to, 0, 0, trc.right - trc.left,
+ trc.bottom - trc.top, false);
+ DelBitmapClass(to); to = 0L;
+ o->UpdateRect(&trc, false);
+ }
+ trc.left = pts[0].x = pts[1].x = pts[4].x = rDims.left + p->x;
+ trc.top = pts[0].y = pts[3].y = pts[4].y = rDims.top + p->y;
+ trc.bottom = pts[1].y = pts[2].y = rDims.bottom + p->y;
+ trc.right = pts[2].x = pts[3].x = rDims.right + p->x;
+ IncrementMinMaxRect(&trc, 3); to = GetRectBitmap(&trc, o);
+ o->SetLine(&tld); o->oPolyline(pts, 5, 0L);
+ o->UpdateRect(&trc, false);
+}
+
+bool
+Legend::HasFill(LineDEF *ld, FillDEF *fd, char *desc)
+{
+ int i;
+ LegItem *li;
+
+ if(Items) for(i = 0; i < nItems; i++) {
+ if(Items[i] && Items[i]->HasFill(ld, fd, desc)) return true;
+ }
+ if(li = new LegItem(this, data, 0L, ld, fd, desc)){
+ if(!(Command(CMD_DROP_OBJECT, li, 0L))) DeleteGO(li);
+ }
+ return false;
+}
+
+bool
+Legend::HasSym(LineDEF *ld, GraphObj *sy, char *desc)
+{
+ int i, sym;
+ Symbol *ns;
+ 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;
- }
- sym = sy->Id == GO_SYMBOL ? (sy->type & 0xff) : 0;
- if(!(ns = new Symbol(this, data, 0.0, 0.0, sym | SYM_POS_PARENT))) return true;
- ns->SetSize(SIZE_SYMBOL, sy->GetSize(SIZE_SYMBOL));
- ns->SetSize(SIZE_SYM_LINE, sy->GetSize(SIZE_SYM_LINE));
- ns->SetColor(COL_SYM_LINE, sy->GetColor(COL_SYM_LINE));
- ns->SetColor(COL_SYM_FILL, sy->GetColor(COL_SYM_FILL));
- if(li = new LegItem(this, data, ld, ns)){
- if(!(Command(CMD_DROP_OBJECT, li, 0L))) DeleteGO(li);
- }
- return false;
-}
+ if(Items) for(i = 0; i < nItems; i++) {
+ if(Items[i] && Items[i]->HasSym(ld, sy)) return true;
+ }
+ sym = sy->Id == GO_SYMBOL ? (sy->type & 0xff) : 0;
+ if(!(ns = new Symbol(this, data, 0.0, 0.0, sym | SYM_POS_PARENT))) return true;
+ ns->SetSize(SIZE_SYMBOL, sy->GetSize(SIZE_SYMBOL));
+ ns->SetSize(SIZE_SYM_LINE, sy->GetSize(SIZE_SYM_LINE));
+ ns->SetColor(COL_SYM_LINE, sy->GetColor(COL_SYM_LINE));
+ ns->SetColor(COL_SYM_FILL, sy->GetColor(COL_SYM_FILL));
+ if(desc && desc[0]) {
+ ns->name = (char*)memdup(desc,(int)strlen(desc)+1, 0);
+ }
+ else if(sy->name && sy->name[0]) {
+ ns->name = (char*)memdup(sy->name,(int)strlen(sy->name)+1, 0);
+ }
+ else if(sy->parent && sy->parent->name && sy->parent->name[0]) {
+ ns->name = (char*)memdup(sy->parent->name,(int)strlen(sy->parent->name)+1, 0);
+ }
+ if(li = new LegItem(this, data, ld, ns)){
+ if(!(Command(CMD_DROP_OBJECT, li, 0L))) DeleteGO(li);
+ }
+ return false;
+}
bool
Legend::HasErr(LineDEF *ld, int err, char *desc)
@@ -7538,188 +8516,167 @@ Legend::HasErr(LineDEF *ld, int err, char *desc)
}
return false;
}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Graphs are graphic objects containing plots, axes, and drawn objects
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Graph::Graph(GraphObj *par, DataObj *d, anyOutput *o):GraphObj(par, d)
-{
- Graph::FileIO(INIT_VARS);
- Disp = o; Id = GO_GRAPH; cGraphs++; bModified = true;
- if (!d && parent) parent->Command(CMD_DELOBJ, this, NULL);
-}
-
-Graph::Graph(int src):GraphObj(0L, 0L)
-{
- int i;
-
- Graph::FileIO(INIT_VARS);
- if(src == FILE_READ) {
- FileIO(FILE_READ);
- x_axis.owner = y_axis.owner = (void *)this;
- //do all axes
- for(i = 0; Axes && i< NumAxes; i++) if(Axes[i]) Axes[i]->parent = this;
- //do all plots
- for(i = 0; Plots && i< NumPlots; i++) if(Plots[i]) Plots[i]->parent = this;
- if(x_axis.max > x_axis.min && y_axis.max > y_axis.min &&
- Bounds.Xmax > Bounds.Xmin && Bounds.Ymax > Bounds.Ymin) dirty = false;
- }
- cGraphs++; bModified = false;
-}
-
-Graph::~Graph()
-{
- int i;
-
- if(!parent) return; parent = 0L;
- 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); Plots = 0L; NumPlots = 0;
- }
- if(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);
- if(x_axis.breaks && x_axis.owner == this) free(x_axis.breaks);
- if(y_axis.breaks && y_axis.owner == this) free(y_axis.breaks);
- if(tl_pts) free(tl_pts);
- if(nscp > 0 && nscp <= NumPlots && Sc_Plots) free(Sc_Plots);
- nscp = 0; Sc_Plots = 0L;
- if(name) free(name); name = 0L;
- if(filename) free(filename); filename= 0L;
-}
-
-double
-Graph::GetSize(int select)
-{
- switch(select) {
- case SIZE_LB_XDIST:
- case SIZE_LB_YDIST: return 0.0f;
- case SIZE_GRECT_TOP: return GRect.Ymin;
- case SIZE_GRECT_BOTTOM: return GRect.Ymax;
- case SIZE_GRECT_LEFT: return GRect.Xmin;
- case SIZE_GRECT_RIGHT: return GRect.Xmax;
- case SIZE_DRECT_TOP: return DRect.Ymin;
- case SIZE_DRECT_BOTTOM: return DRect.Ymax;
- case SIZE_DRECT_LEFT: return DRect.Xmin;
- case SIZE_DRECT_RIGHT: return DRect.Xmax;
- case SIZE_BOUNDS_XMIN: return Bounds.Xmin;
- case SIZE_BOUNDS_XMAX: return Bounds.Xmax;
- case SIZE_BOUNDS_YMIN: return Bounds.Ymin;
- case SIZE_BOUNDS_YMAX: return Bounds.Ymax;
- case SIZE_BOUNDS_LEFT: return x_axis.flags & AXIS_INVERT ? x_axis.max : x_axis.min;
- case SIZE_BOUNDS_RIGHT: return x_axis.flags & AXIS_INVERT ? x_axis.min : x_axis.max;
- case SIZE_BOUNDS_TOP: return y_axis.flags & AXIS_INVERT ? y_axis.min : y_axis.max;
- case SIZE_BOUNDS_BOTTOM: return y_axis.flags & AXIS_INVERT ? y_axis.max : y_axis.min;
- case SIZE_YAXISX:
- if(y_axis.flags & AXIS_X_DATA) return CurrDisp->fx2fix(y_axis.loc[0].fx);
- else return CurrDisp->co2fix(y_axis.loc[0].fx);
- case SIZE_XAXISY:
- if(x_axis.flags & AXIS_Y_DATA) return CurrDisp->fy2fiy(x_axis.loc[0].fy);
- else return CurrDisp->co2fiy(x_axis.loc[0].fy);
- default: return defs.GetSize(select);
- }
-}
-
-bool
-Graph::SetSize(int select, double val)
-{
- switch(select & 0xfff) {
- case SIZE_GRECT_TOP: GRect.Ymin = val; return true;
- case SIZE_GRECT_BOTTOM: GRect.Ymax = val; return true;
- case SIZE_GRECT_LEFT: GRect.Xmin = val; return true;
- case SIZE_GRECT_RIGHT: GRect.Xmax = val; return true;
- case SIZE_DRECT_TOP: DRect.Ymin = val; return true;
- case SIZE_DRECT_BOTTOM: DRect.Ymax = val; return true;
- case SIZE_DRECT_LEFT: DRect.Xmin = val; return true;
- case SIZE_DRECT_RIGHT: DRect.Xmax = val; return true;
- default: return false;
- }
-}
-
-DWORD
-Graph::GetColor(int select)
-{
- switch(select & 0xfff) {
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Graphs are graphic objects containing plots, axes, and drawn objects
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Graph::Graph(GraphObj *par, DataObj *d, anyOutput *o):GraphObj(par, d)
+{
+ Graph::FileIO(INIT_VARS);
+ Disp = o; Id = GO_GRAPH; cGraphs++; bModified = true;
+ if (!d && parent) parent->Command(CMD_DELOBJ, this, NULL);
+}
+
+Graph::Graph(int src):GraphObj(0L, 0L)
+{
+ int i;
+
+ Graph::FileIO(INIT_VARS);
+ if(src == FILE_READ) {
+ FileIO(FILE_READ);
+ x_axis.owner = y_axis.owner = (void *)this;
+ //do all axes
+ for(i = 0; Axes && i< NumAxes; i++) if(Axes[i]) Axes[i]->parent = this;
+ //do all plots
+ for(i = 0; Plots && i< NumPlots; i++) if(Plots[i]) Plots[i]->parent = this;
+ if(x_axis.max > x_axis.min && y_axis.max > y_axis.min &&
+ Bounds.Xmax > Bounds.Xmin && Bounds.Ymax > Bounds.Ymin) dirty = false;
+ }
+ cGraphs++; bModified = false;
+}
+
+Graph::~Graph()
+{
+ int i;
+
+ if(!parent) return; parent = 0L;
+ 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); Plots = 0L; NumPlots = 0;
+ }
+ if(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);
+ if(x_axis.breaks && x_axis.owner == this) free(x_axis.breaks);
+ if(y_axis.breaks && y_axis.owner == this) free(y_axis.breaks);
+ if(tl_pts) free(tl_pts);
+ if(nscp > 0 && nscp <= NumPlots && Sc_Plots) free(Sc_Plots);
+ nscp = 0; Sc_Plots = 0L;
+ if(name) free(name); name = 0L;
+ if(filename) free(filename); filename= 0L;
+}
+
+double
+Graph::GetSize(int select)
+{
+ return Graph::DefSize(select);
+}
+
+bool
+Graph::SetSize(int select, double val)
+{
+ switch(select & 0xfff) {
+ case SIZE_GRECT_TOP: GRect.Ymin = val; return true;
+ case SIZE_GRECT_BOTTOM: GRect.Ymax = val; return true;
+ case SIZE_GRECT_LEFT: GRect.Xmin = val; return true;
+ case SIZE_GRECT_RIGHT: GRect.Xmax = val; return true;
+ case SIZE_DRECT_TOP: DRect.Ymin = val; return true;
+ case SIZE_DRECT_BOTTOM: DRect.Ymax = val; return true;
+ case SIZE_DRECT_LEFT: DRect.Xmin = val; return true;
+ case SIZE_DRECT_RIGHT: DRect.Xmax = val; return true;
+ default: return false;
+ }
+}
+
+DWORD
+Graph::GetColor(int select)
+{
+ switch(select & 0xfff) {
case COL_AXIS: return ColAX;
- case COL_BG: return ColDR;
- }
- if(parent) return parent->GetColor(select);
- else return defs.Color(select);
-}
-
-
-void
-Graph::DoPlot(anyOutput *target)
-{
- int i;
- AxisDEF *ax;
-
- if(nscp > 0 && nscp <= NumPlots && Sc_Plots) free(Sc_Plots);
- nscp = 0; Sc_Plots = 0L;
- rc_mrk.left = rc_mrk.right = rc_mrk.top = rc_mrk.bottom = -1;
- CurrAxes = Axes;
- if(data) do_formula(data, 0L); //init mfcalc
- //verify ownership of axes
- if(Axes) for (i = 0; i < NumAxes; i++){
- if(Axes[i] && (ax = Axes[i]->GetAxis()))
- if(ax == &x_axis || ax == &y_axis) ax->owner = this;
- }
- if(!name){
- sprintf(TmpTxt, "Graph %d", cGraphs);
- name = strdup(TmpTxt);
- }
- if(!target && !Disp) {
- Disp = NewDispClass(this);
- Disp->SetMenu(MENU_GRAPH);
- if(name) Disp->Caption(name);
- Disp->VPorg.fy = (double)Disp->MenuHeight;
- Disp->CheckMenu(ToolMode, true);
- OwnDisp = true; defs.SetDisp(Disp);
- if(GRect.Xmin > 0.0001 || GRect.Xmin < -0.0001) {
- GRect.Xmax -= GRect.Xmin; GRect.Xmin = 0.0;
- }
- if(GRect.Ymin > 0.0001 || GRect.Ymin < -0.0001) {
- GRect.Ymax -= GRect.Ymin; GRect.Ymin = 0.0;
- }
- bModified = false; //first graph is not modified!
- }
- //the first output class is the display class
- if(!Disp && (!(Disp = target))) return;
- Disp->ActualSize(&defs.clipRC);
- if(OwnDisp) Disp->Erase(Disp->dFillCol = defs.Color(COL_BG));
- CurrDisp = target ? target : Disp;
- CurrDisp->MrkMode = MRK_NONE;
- CurrRect.Xmin=GRect.Xmin + DRect.Xmin; CurrRect.Xmax=GRect.Xmin + DRect.Xmax;
- CurrRect.Ymin=GRect.Ymin + DRect.Ymax; CurrRect.Ymax=GRect.Ymin + DRect.Ymin;
- if(dirty) DoAutoscale();
+ case COL_BG: return ColDR;
+ }
+ if(parent) return parent->GetColor(select);
+ else return defs.Color(select);
+}
+
+
+void
+Graph::DoPlot(anyOutput *target)
+{
+ int i, cb;
+ AxisDEF *ax;
+
+ if(nscp > 0 && nscp <= NumPlots && Sc_Plots) free(Sc_Plots);
+ nscp = 0; Sc_Plots = 0L;
+ rc_mrk.left = rc_mrk.right = rc_mrk.top = rc_mrk.bottom = -1;
+ CurrAxes = Axes;
+ if(data) do_formula(data, 0L); //init mfcalc
+ //verify ownership of axes
+ if(Axes) for (i = 0; i < NumAxes; i++){
+ if(Axes[i] && (ax = Axes[i]->GetAxis()))
+ if(ax == &x_axis || ax == &y_axis) ax->owner = this;
+ }
+ if(!name){
+#ifdef USE_WIN_SECURE
+ cb = sprintf_s(TmpTxt, TMP_TXT_SIZE, "Graph %d", cGraphs) + 2;
+#else
+ cb = sprintf(TmpTxt, "Graph %d", cGraphs) + 2;
+#endif
+ name = (char*)realloc(name, cb); rlp_strcpy(name, cb, TmpTxt);
+ }
+ if(!target && !Disp) {
+ Disp = NewDispClass(this);
+ Disp->SetMenu(MENU_GRAPH);
+ if(name) Disp->Caption(name);
+ Disp->VPorg.fy = (double)Disp->MenuHeight;
+ Disp->CheckMenu(ToolMode, true);
+ OwnDisp = true; defs.SetDisp(Disp);
+ if(GRect.Xmin > 0.0001 || GRect.Xmin < -0.0001) {
+ GRect.Xmax -= GRect.Xmin; GRect.Xmin = 0.0;
+ }
+ if(GRect.Ymin > 0.0001 || GRect.Ymin < -0.0001) {
+ GRect.Ymax -= GRect.Ymin; GRect.Ymin = 0.0;
+ }
+ bModified = false; //first graph is not modified!
+ Undo.SetDisp(Disp);
+ }
+ //the first output class is the display class
+ if(!Disp && (!(Disp = target))) return;
+ Disp->ActualSize(&defs.clipRC);
+ if(OwnDisp) Disp->Erase(Disp->dFillCol = defs.Color(COL_BG));
+ CurrDisp = target ? target : Disp;
+ CurrDisp->MrkMode = MRK_NONE;
+ CurrRect.Xmin=GRect.Xmin + DRect.Xmin; CurrRect.Xmax=GRect.Xmin + DRect.Xmax;
+ CurrRect.Ymin=GRect.Ymin + DRect.Ymax; CurrRect.Ymax=GRect.Ymin + DRect.Ymin;
+ if(dirty) DoAutoscale();
CurrDisp->SetRect(CurrRect, units, &x_axis, &y_axis);
CurrDisp->disp_x = CurrDisp->un2fix(GRect.Xmin);
CurrDisp->disp_y = CurrDisp->un2fiy(GRect.Ymin);
- if(!frm_g && !(frm_g = new FrmRect(this, 0L, &GRect, 0L))) return;
- frm_g->SetColor(COL_GRECT, ColGR); frm_g->SetColor(COL_GRECTLINE, ColGRL);
- frm_g->DoPlot(CurrDisp);
- if(type == GT_STANDARD) {
- if(!frm_d && !(frm_d = new FrmRect(this, &GRect, &DRect, 0L))) return;
- SetMinMaxRect(&rDims, CurrDisp->co2ix(CurrRect.Xmin), CurrDisp->co2iy(CurrRect.Ymax),
- CurrDisp->co2ix(CurrRect.Xmax), CurrDisp->co2iy(CurrRect.Ymin));
- frm_g->Command(CMD_MINRC, &rDims, CurrDisp);
- SetMinMaxRect(&rDims, CurrDisp->co2ix(GRect.Xmin), CurrDisp->co2iy(GRect.Ymax),
- CurrDisp->co2ix(GRect.Xmax), CurrDisp->co2iy(GRect.Ymin));
- frm_d->Command(CMD_MAXRC, &rDims, CurrDisp);
- frm_d->SetColor(COL_DRECT, ColDR); frm_d->DoPlot(CurrDisp);
- frm_g->Command(CMD_SETCHILD, &DRect, CurrDisp);
- }
- //do all axes
+ if(!frm_g && !(frm_g = new FrmRect(this, 0L, &GRect, 0L))) return;
+ frm_g->SetColor(COL_GRECT, ColGR); frm_g->SetColor(COL_GRECTLINE, ColGRL);
+ frm_g->DoPlot(CurrDisp);
+ if(type == GT_STANDARD) {
+ if(!frm_d && !(frm_d = new FrmRect(this, &GRect, &DRect, 0L))) return;
+ SetMinMaxRect(&rDims, CurrDisp->co2ix(CurrRect.Xmin), CurrDisp->co2iy(CurrRect.Ymax),
+ CurrDisp->co2ix(CurrRect.Xmax), CurrDisp->co2iy(CurrRect.Ymin));
+ frm_g->Command(CMD_MINRC, &rDims, CurrDisp);
+ SetMinMaxRect(&rDims, CurrDisp->co2ix(GRect.Xmin), CurrDisp->co2iy(GRect.Ymax),
+ CurrDisp->co2ix(GRect.Xmax), CurrDisp->co2iy(GRect.Ymin));
+ frm_d->Command(CMD_MAXRC, &rDims, CurrDisp);
+ frm_d->SetColor(COL_DRECT, ColDR); frm_d->DoPlot(CurrDisp);
+ frm_g->Command(CMD_SETCHILD, &DRect, CurrDisp);
+ }
+ //do all axes
if(Axes) for(i = 0; i< NumAxes; i++) if(Axes[i]){
Axes[i]->SetColor(COL_BG, ColGR);
Axes[i]->DoPlot(CurrDisp);
- }
- //do all plots
+ }
+ //do all plots
if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i]) {
if(Plots[i]->Id >= GO_PLOT && Plots[i]->Id < GO_GRAPH) {
if(((Plot*)Plots[i])->hidden == 0) Plots[i]->DoPlot(CurrDisp);
@@ -7728,199 +8685,212 @@ Graph::DoPlot(anyOutput *target)
Plots[i]->DoPlot(CurrDisp);
}
}
- if(bModified) data->Command(CMD_MRK_DIRTY, 0L, 0L);
- if(target && ToolMode == TM_STANDARD) target->MouseCursor(MC_ARROW, false);
-}
-
-bool
-Graph::Command(int cmd, void *tmpl, anyOutput *o)
-{
- MouseEvent *mev;
- GraphObj **tmpPlots;
- char *f_name;
- RECT rc;
- int i, j;
- DWORD delflg = 0L;
-
- if(!o) o = Disp ? Disp : CurrDisp;
- switch (cmd){
+ if(bModified) data->Command(CMD_MRK_DIRTY, 0L, 0L);
+ if(parent && parent->Id == GO_GRAPH) {
+ parent->Command(CMD_AXIS, 0L, 0L);
+ }
+ if(target && ToolMode == TM_STANDARD) target->MouseCursor(MC_ARROW, false);
+}
+
+bool
+Graph::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ MouseEvent *mev;
+ GraphObj **tmpPlots;
+ char *f_name;
+ RECT rc;
+ int i, j;
+ DWORD delflg = 0L;
+
+ if(!o) o = Disp ? Disp : CurrDisp;
+ switch (cmd){
case CMD_CAN_CLOSE:
HideTextCursor();
if(bModified) {
+ if (Undo.isEmpty(CurrDisp)) return true;
bModified = false;
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%s has not been saved.\nDo you want to save it now?", name);
+#else
sprintf(TmpTxt, "%s has not been saved.\nDo you want to save it now?", name);
+#endif
i = YesNoCancelBox(TmpTxt);
if(i == 2) return false;
else if(i == 1) if(! SaveGraphAs(this)) return false;
}
return true;
+ case CMD_SCALE:
+ return DoScale((scaleINFO*)tmpl, o);
case CMD_LAYERS:
Undo.SetDisp(o ? o : CurrDisp);
return ShowLayers(this);
case CMD_HASSTACK:
return(NumPlots > 1);
- case CMD_SAVEPOS:
- Undo.ValRect(this, &GRect, 0L);
- Undo.ValRect(this, &DRect, UNDO_CONTINUE);
- return true;
- case CMD_LEGEND:
+ case CMD_SAVEPOS:
+ Undo.ValRect(this, &GRect, 0L);
+ Undo.ValRect(this, &DRect, UNDO_CONTINUE);
+ return true;
+ case CMD_LEGEND:
Undo.SetDisp(o ? o : CurrDisp);
- if(Id == GO_PAGE) {
+ 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){
CurrGraph = (Graph*)Plots[0];
return CurrGraph->Command(cmd, tmpl, o);
- }
- InfoBox("No graph selected!\nCreate a new graph first or select\n"
- "a graph before you can add a legend.");
- return false;
- }
- if(Id == GO_GRAPH && !tmpl && Plots) {
- for(i = 0; i< NumPlots; i++){
- if(Plots[i] && Plots[i]->Id == GO_LEGEND) {
- tmpl = (void*)Plots[i];
- Undo.ObjConf(Plots[i], 0L);
- break;
- }
- }
- if(!tmpl) {
+ }
+ InfoBox("No graph selected!\nCreate a new graph first or select\n"
+ "a graph before you can add a legend.");
+ return false;
+ }
+ if(Id == GO_GRAPH && !tmpl && Plots) {
+ for(i = 0; i< NumPlots; i++){
+ if(Plots[i] && Plots[i]->Id == GO_LEGEND) {
+ tmpl = (void*)Plots[i];
+ Undo.ObjConf(Plots[i], 0L);
+ break;
+ }
+ }
+ if(!tmpl) {
if(!(tmpl = (void*) new Legend(this, data)))return false;
if(Disp) {
- Undo.SetDisp(Disp);
- tmpPlots = (GraphObj**)memdup(Plots, sizeof(GraphObj*) * (NumPlots+2), 0);
- if(!tmpPlots) return false;
- Undo.ListGOmoved(Plots, tmpPlots, NumPlots);
- Undo.SetGO(this, &tmpPlots[NumPlots++], (Plot *)tmpl, 0L);
+ Undo.SetDisp(Disp);
+ tmpPlots = (GraphObj**)memdup(Plots, sizeof(GraphObj*) * (NumPlots+2), 0);
+ if(!tmpPlots) return false;
+ Undo.ListGOmoved(Plots, tmpPlots, NumPlots);
+ Undo.SetGO(this, &tmpPlots[NumPlots++], (Plot *)tmpl, 0L);
free(Plots); Plots = tmpPlots; bModified = true;
}
else if(Plots = (GraphObj**)realloc(Plots, sizeof(GraphObj*) * (NumPlots+2))){
Plots[NumPlots++] = (GraphObj*)tmpl; Plots[NumPlots] = 0L;
}
- else return false;
- }
- if(type == GT_CIRCCHART)((Legend*)tmpl)->SetSize(SIZE_XPOS, DRect.Xmin*3.0);
- for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->Command(cmd, tmpl,o);
- if(Disp) Command(CMD_REDRAW, 0L, CurrDisp);
- }
- return true;
- case CMD_REPL_GO:
- if(!(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
- if(Axes) for(i = 0; i < NumAxes; i++) if(Axes[i] && Axes[i] == tmpPlots[0]){
- tmpPlots[1]->parent = this;
- tmpPlots[1]->Command(CMD_SET_DATAOBJ, data, o);
- Axes[i] = (Axis *)tmpPlots[1];
- tmpPlots[0]->parent = 0L; //disable messaging
- //check for default axes
- if(((Axis*)tmpPlots[0])->GetAxis() == &x_axis) {
- if(x_axis.breaks) free(x_axis.breaks);
- memcpy(&x_axis, Axes[i]->axis, sizeof(AxisDEF));
- if(x_axis.owner == Axes[i]) free(Axes[i]->axis);
- Axes[i]->axis = &x_axis; x_axis.owner = this;
- }
- else if(((Axis*)tmpPlots[0])->GetAxis() == &y_axis) {
- if(y_axis.breaks) free(y_axis.breaks);
- memcpy(&y_axis, Axes[i]->axis, sizeof(AxisDEF));
- if(y_axis.owner == Axes[i]) free(Axes[i]->axis);
- Axes[i]->axis = &y_axis; y_axis.owner = this;
- }
- DeleteGO(tmpPlots[0]);
- return bModified = dirty = true;
- }
- if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i] && Plots[i] == tmpPlots[0]) {
- return bModified = dirty = ReplaceGO((GraphObj**)&Plots[i], tmpPlots);
- }
- return false;
- case CMD_MUTATE:
- if(!parent || !(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
- if(Plots) for (i = 0; i < NumPlots; i++) if(Plots[i] && Plots[i] == tmpPlots[0]) {
- Undo.MutateGO((GraphObj**)&Plots[i], tmpPlots[1], 0L, o);
- if(ToolMode) Command(CMD_TOOLMODE, 0L, o);
- return bModified = true;
- }
- break;
- case CMD_HIDE_MARK:
- if(!tmpl || !o) return false;
- //do frame rectangles
- if(frm_g && tmpl == (void*)frm_g) {
- frm_g->DoMark(o, false); return true;
- }
- if(frm_d && tmpl == (void*)frm_d) {
- frm_d->DoMark(o, false); return true;
- }
- //do all axes
- if(Axes)for(i = NumAxes-1; i>=0; i--) {
- if(tmpl == (void*)Axes[i]){
- Axes[i]->DoMark(CurrDisp, false); return true;
- }
- else if(Axes[i] && Axes[i]->Id == GO_AXIS) {
- if(Axes[i]->Command(cmd, tmpl, o)) return true;
- }
- }
- //do all plots
- if(Plots)for(i = NumPlots-1; i>=0; i--) {
- if(tmpl == (void*)Plots[i]){
- Plots[i]->DoMark(CurrDisp, false); return true;
- }
- else if(Plots[i] && (Plots[i]->Id == GO_MLABEL || Plots[i]->Id == GO_LEGEND ||
- (Plots[i]->Id >= GO_PLOT && Plots[i]->Id < GO_GRAPH))) {
- if(Plots[i]->Command(cmd, tmpl, o)) return true;
- }
- }
- return false;
- case CMD_REDRAW:
- if(!CurrDisp) {
- DoPlot(CurrDisp);
- return true;
- }
- if(parent && parent->Id == GO_PAGE) return parent->Command(cmd, tmpl, o);
- if(CurrDisp && CurrDisp->Erase(ColBG)) CurrDisp->StartPage();
- CurrDisp->MrkMode = MRK_NONE;
- DoPlot(CurrDisp);
- if(CurrDisp) CurrDisp->EndPage();
- if(CurrGO && CurrGO == CurrLabel && CurrLabel->Id == GO_LABEL)
- CurrDisp->ShowMark(CurrLabel, MRK_GODRAW);
- return true;
- case CMD_ZOOM:
- return DoZoom((char*)tmpl);
- case CMD_MOUSECURSOR:
- 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);
- return true;
- case CMD_REG_AXISPLOT: //notification: plot can hnadle its own axes
- if(nscp > 0 && nscp <= NumPlots && Sc_Plots) {
- for(i = 0; i < nscp; i++)
- if(Sc_Plots[i] == (GraphObj*)tmpl) return true;
- if(tmpPlots = (GraphObj**)realloc(Sc_Plots, (nscp+1)*sizeof(GraphObj*))){
- tmpPlots[nscp++] = (GraphObj *)tmpl;
- Sc_Plots = tmpPlots;
- }
- else { //memory allocation error
- nscp = 0;
- Sc_Plots = 0L;
- }
- }
- else {
- if(Sc_Plots = (GraphObj **)calloc(1, sizeof(GraphObj*))){
- Sc_Plots[0] = (GraphObj *)tmpl;
- nscp = 1;
- }
- else nscp = 0;
- }
- return true;
- case CMD_BUSY:
- if(Disp) Disp->MouseCursor(MC_WAIT, true);
- break;
- case CMD_UNDO:
- Command(CMD_TOOLMODE, 0L, o);
- if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, true);
- Undo.Restore(true, CurrDisp);
- if(CurrDisp) CurrDisp->MouseCursor(MC_ARROW, true);
- return true;
- case CMD_ADDAXIS:
- Undo.SetDisp(o ? o : CurrDisp); Command(CMD_TOOLMODE, 0L, o);
- if(Id == GO_PAGE) {
+ else return false;
+ }
+ if(type == GT_CIRCCHART)((Legend*)tmpl)->SetSize(SIZE_XPOS, DRect.Xmin*3.0);
+ for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->Command(cmd, tmpl,o);
+ if(Disp) Command(CMD_REDRAW, 0L, CurrDisp);
+ }
+ else if(Id == GO_GRAPH) {
+ for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->Command(cmd, tmpl,o);
+ }
+ return true;
+ case CMD_REPL_GO:
+ if(!(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
+ if(Axes) for(i = 0; i < NumAxes; i++) if(Axes[i] && Axes[i] == tmpPlots[0]){
+ tmpPlots[1]->parent = this;
+ tmpPlots[1]->Command(CMD_SET_DATAOBJ, data, o);
+ Axes[i] = (Axis *)tmpPlots[1];
+ tmpPlots[0]->parent = 0L; //disable messaging
+ //check for default axes
+ if(((Axis*)tmpPlots[0])->GetAxis() == &x_axis) {
+ if(x_axis.breaks) free(x_axis.breaks);
+ memcpy(&x_axis, Axes[i]->axis, sizeof(AxisDEF));
+ if(x_axis.owner == Axes[i]) free(Axes[i]->axis);
+ Axes[i]->axis = &x_axis; x_axis.owner = this;
+ }
+ else if(((Axis*)tmpPlots[0])->GetAxis() == &y_axis) {
+ if(y_axis.breaks) free(y_axis.breaks);
+ memcpy(&y_axis, Axes[i]->axis, sizeof(AxisDEF));
+ if(y_axis.owner == Axes[i]) free(Axes[i]->axis);
+ Axes[i]->axis = &y_axis; y_axis.owner = this;
+ }
+ DeleteGO(tmpPlots[0]);
+ return bModified = dirty = true;
+ }
+ if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i] && Plots[i] == tmpPlots[0]) {
+ return bModified = dirty = ReplaceGO((GraphObj**)&Plots[i], tmpPlots);
+ }
+ return false;
+ case CMD_MUTATE:
+ if(!parent || !(tmpPlots = (GraphObj **)tmpl) || !tmpPlots[0] || !tmpPlots[1]) return false;
+ if(Plots) for (i = 0; i < NumPlots; i++) if(Plots[i] && Plots[i] == tmpPlots[0]) {
+ Undo.MutateGO((GraphObj**)&Plots[i], tmpPlots[1], 0L, o);
+ if(ToolMode) Command(CMD_TOOLMODE, 0L, o);
+ return bModified = true;
+ }
+ break;
+ case CMD_HIDE_MARK:
+ if(!tmpl || !o) return false;
+ //do frame rectangles
+ if(frm_g && tmpl == (void*)frm_g) {
+ frm_g->DoMark(o, false); return true;
+ }
+ if(frm_d && tmpl == (void*)frm_d) {
+ frm_d->DoMark(o, false); return true;
+ }
+ //do all axes
+ if(Axes)for(i = NumAxes-1; i>=0; i--) {
+ if(tmpl == (void*)Axes[i]){
+ Axes[i]->DoMark(CurrDisp, false); return true;
+ }
+ else if(Axes[i] && Axes[i]->Id == GO_AXIS) {
+ if(Axes[i]->Command(cmd, tmpl, o)) return true;
+ }
+ }
+ //do all plots
+ if(Plots)for(i = NumPlots-1; i>=0; i--) {
+ if(tmpl == (void*)Plots[i]){
+ Plots[i]->DoMark(CurrDisp, false); return true;
+ }
+ else if(Plots[i] && (Plots[i]->Id == GO_MLABEL || Plots[i]->Id == GO_LEGEND ||
+ (Plots[i]->Id >= GO_PLOT && Plots[i]->Id < GO_GRAPH))) {
+ if(Plots[i]->Command(cmd, tmpl, o)) return true;
+ }
+ }
+ return false;
+ case CMD_REDRAW:
+ if(!CurrDisp) {
+ DoPlot(CurrDisp);
+ return true;
+ }
+ if(parent && (parent->Id == GO_PAGE || parent->Id == GO_GRAPH)) return parent->Command(cmd, tmpl, o);
+ if(CurrDisp && CurrDisp->Erase(ColBG)) CurrDisp->StartPage();
+ CurrDisp->MrkMode = MRK_NONE; DoPlot(CurrDisp);
+ if(CurrDisp) CurrDisp->EndPage();
+ if(CurrGO == this) CurrGO = 0L;
+ if(CurrGO && CurrGO == CurrLabel && CurrLabel->Id == GO_LABEL)
+ CurrDisp->ShowMark(CurrLabel, MRK_GODRAW);
+ return true;
+ case CMD_ZOOM:
+ return DoZoom((char*)tmpl);
+ case CMD_MOUSECURSOR:
+ 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);
+ return true;
+ case CMD_REG_AXISPLOT: //notification: plot can hnadle its own axes
+ if(nscp > 0 && nscp <= NumPlots && Sc_Plots) {
+ for(i = 0; i < nscp; i++)
+ if(Sc_Plots[i] == (GraphObj*)tmpl) return true;
+ if(tmpPlots = (GraphObj**)realloc(Sc_Plots, (nscp+1)*sizeof(GraphObj*))){
+ tmpPlots[nscp++] = (GraphObj *)tmpl;
+ Sc_Plots = tmpPlots;
+ }
+ else { //memory allocation error
+ nscp = 0;
+ Sc_Plots = 0L;
+ }
+ }
+ else {
+ if(Sc_Plots = (GraphObj **)calloc(1, sizeof(GraphObj*))){
+ Sc_Plots[0] = (GraphObj *)tmpl;
+ nscp = 1;
+ }
+ else nscp = 0;
+ }
+ return true;
+ case CMD_BUSY:
+ if(Disp) Disp->MouseCursor(MC_WAIT, true);
+ break;
+ case CMD_UNDO:
+ Command(CMD_TOOLMODE, 0L, o);
+ if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, true);
+ Undo.Restore(true, CurrDisp);
+ if(CurrDisp) CurrDisp->MouseCursor(MC_ARROW, true);
+ return true;
+ case CMD_ADDAXIS:
+ 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){
CurrGraph = (Graph*)Plots[0];
@@ -7929,200 +8899,235 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
InfoBox("No graph selected!\nCreate a new graph first or select\n"
"a graph before you can add an axis.");
return false;
- }
- else {
- if(type == GT_3D && Plots){
- for(i = 0; i < NumPlots; i++)
+ }
+ 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
|| Plots[i]->Id == GO_FITFUNC3D))
- return Plots[i]->Command(cmd, tmpl, o);
- }
- else if(AddAxis()) {
- Command(CMD_REDRAW, tmpl, o);
- return true;
- }
- }
- return false;
- case CMD_CONFIG:
- Command(CMD_TOOLMODE, 0L, o);
- return Configure();
- case CMD_FILENAME:
- if(tmpl) {
- if(filename) free(filename);
- filename=strdup((char*)tmpl);
- }
- break;
- case CMD_SETNAME:
- if(OwnDisp && CurrDisp && tmpl){
- CurrDisp->Caption((char*)tmpl);
- if(name) free(name); name = strdup((char*)tmpl);
- }
- else return false;
- return true;
- case CMD_SET_DATAOBJ:
- Id = GO_GRAPH;
- data = (DataObj *)tmpl;
- //do axes
- if(Axes) for(i = 0; i< NumAxes; i++) if(Axes[i]) Axes[i]->Command(cmd, tmpl, o);
- //do all plots
- if(Plots) for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->Command(cmd, tmpl,o);
- return true;
- case CMD_OPEN:
- Command(CMD_TOOLMODE, 0L, o);
- if(!parent) return false;
- 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, false);
- }
- return true;
- case CMD_UPDHISTORY:
- if(data) data->Command(CMD_UPDHISTORY, 0L, 0L);
- return true;
- case CMD_UPDATE:
+ return Plots[i]->Command(cmd, tmpl, o);
+ }
+ else if(AddAxis()) {
+ Command(CMD_REDRAW, tmpl, o);
+ return true;
+ }
+ }
+ return false;
+ case CMD_CONFIG:
+ Command(CMD_TOOLMODE, 0L, o); if(CurrGO == this) CurrGO = 0L;
+ return Configure();
+ case CMD_FILENAME:
+ if(tmpl) {
+ i = (int)strlen((char*)tmpl)+2;
+ filename = (char*)realloc(filename, i );
+ rlp_strcpy(filename, i, (char*)tmpl);
+ }
+ break;
+ case CMD_SETNAME:
+ if(OwnDisp && CurrDisp && tmpl && *((char*)tmpl)){
+ CurrDisp->Caption((char*)tmpl);
+ i = (int)strlen((char*)tmpl);
+ j = name && name[0] ? (int)strlen(name) : i;
+ name = (char*)realloc(name, i > j ? i+2 : j+2);
+ rlp_strcpy(name, i+2, (char*)tmpl);
+ }
+ else return false;
+ return true;
+ case CMD_SET_DATAOBJ:
+ Id = GO_GRAPH;
+ data = (DataObj *)tmpl;
+ //do axes
+ if(Axes) for(i = 0; i< NumAxes; i++) if(Axes[i]) Axes[i]->Command(cmd, tmpl, o);
+ //do all plots
+ if(Plots) for(i = 0; i< NumPlots; i++) if(Plots[i]) Plots[i]->Command(cmd, tmpl,o);
+ return true;
+ case CMD_OPEN:
+ Command(CMD_TOOLMODE, 0L, o);
+ if(!parent) return false;
+ 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, false);
+ }
+ return true;
+ case CMD_UPDHISTORY:
+ if(data) data->Command(CMD_UPDHISTORY, 0L, 0L);
+ return true;
+ case CMD_UPDATE:
+ Command(CMD_TOOLMODE, 0L, o);
+ Undo.SetDisp(CurrDisp);
+ if(parent && parent->Id != GO_PAGE && parent->Id != GO_GRAPH){
+ Undo.ValInt(this, &ToolMode, 0L); //stub, all plots have UNDO_CONTINUE
+ }
+ if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, true);
+ for(i = 0; i < NumAxes; i++) if(Axes[i]) Axes[i]->Command(cmd, tmpl, o);
+ if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, false);
+ for(i = 0; Plots && i < NumPlots; i++)
+ if(Plots[i]) Plots[i]->Command(cmd, tmpl, o);
+ dirty = bModified = true; CurrDisp->StartPage();
+ if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, false);
+ DoPlot(CurrDisp); CurrDisp->EndPage(); CurrGO = 0L;
+ return true;
+ case CMD_DELOBJ_CONT:
+ delflg = UNDO_CONTINUE;
+ case CMD_DELOBJ:
Command(CMD_TOOLMODE, 0L, o);
- Undo.SetDisp(CurrDisp);
- if(parent && parent->Id != GO_PAGE){
- Undo.ValInt(this, &ToolMode, 0L); //stub, all plots have UNDO_CONTINUE
- }
- if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, true);
- for(i = 0; i < NumAxes; i++) if(Axes[i]) Axes[i]->Command(cmd, tmpl, o);
- if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, false);
- for(i = 0; Plots && i < NumPlots; i++)
- if(Plots[i]) Plots[i]->Command(cmd, tmpl, o);
- dirty = bModified = true; CurrDisp->StartPage();
- if(CurrDisp) CurrDisp->MouseCursor(MC_WAIT, false);
- DoPlot(CurrDisp); CurrDisp->EndPage(); CurrGO = 0L;
- return true;
- case CMD_DELOBJ_CONT:
- delflg = UNDO_CONTINUE;
- case CMD_DELOBJ:
- Command(CMD_TOOLMODE, 0L, o);
- bModified = true;
- if(!tmpl) return false;
- for(i = 0; i < NumAxes; i++) if(Axes[i] && (void*)Axes[i] == tmpl){
- if(Axes[i]->Command(CMD_CAN_CLOSE, 0L, o)) {
- Undo.DeleteGO((GraphObj**)(&Axes[i]), delflg, o);
- return Command(CMD_REDRAW, 0L, o);
- }
- else {
- InfoBox("Axes used for scaling\ncan not be deleted.");
- return false;
- }
- }
- for(i = 0; Plots && i < NumPlots; i++) if(Plots[i] && (void*)Plots[i] == tmpl) {
- Undo.DeleteGO(&Plots[i], delflg, o);
- Undo.StoreListGO(this, &Plots, &NumPlots, UNDO_CONTINUE);
- for(i = j = 0; i < NumPlots; i++) if(Plots[i]) Plots[j++] = Plots[i];
- NumPlots = j; //compress list of objects
- return Command(CMD_REDRAW, NULL, o);
- }
- if(tmpl == (void*)frm_g && parent && parent->Id == GO_PAGE)
- return parent->Command(CMD_DELOBJ_CONT, (void*)this, o);
- return false;
- case CMD_TOOLMODE:
- if(o && tmpl) {
- o->CheckMenu(ToolMode & 0x0f, false);
- o->CheckMenu(ToolMode = tmpl ? (*((int*)tmpl)) & 0x0f : TM_STANDARD, true);
- }
- if(tl_pts && tl_nPts) free(tl_pts);
- tl_pts = 0L; tl_nPts = 0;
- if(CurrDisp) CurrDisp->MrkMode = MRK_NONE;
- if(o) switch(ToolMode & 0x0f) {
+ bModified = true;
+ if(!tmpl) return false;
+ for(i = 0; i < NumAxes; i++) if(Axes[i] && (void*)Axes[i] == tmpl){
+ if(Axes[i]->Command(CMD_CAN_CLOSE, 0L, o)) {
+ Undo.DeleteGO((GraphObj**)(&Axes[i]), delflg, o);
+ return Command(CMD_REDRAW, 0L, o);
+ }
+ else {
+ InfoBox("Axes used for scaling\ncan not be deleted.");
+ return false;
+ }
+ }
+ for(i = 0; Plots && i < NumPlots; i++) if(Plots[i] && (void*)Plots[i] == tmpl) {
+ Undo.DeleteGO(&Plots[i], delflg, o); HideTextCursor();
+ Undo.StoreListGO(this, &Plots, &NumPlots, UNDO_CONTINUE);
+ for(i = j = 0; i < NumPlots; i++) if(Plots[i]) Plots[j++] = Plots[i];
+ NumPlots = j; //compress list of objects
+ return Command(CMD_REDRAW, NULL, o);
+ }
+ if(tmpl == (void*)frm_g && parent && (parent->Id == GO_PAGE || parent->Id == GO_GRAPH))
+ return parent->Command(CMD_DELOBJ_CONT, (void*)this, o);
+ return false;
+ case CMD_TOOLMODE:
+ if(o && tmpl) {
+ Undo.SetDisp(o);
+ o->CheckMenu(ToolMode & 0x0f, false);
+ o->CheckMenu(ToolMode = tmpl ? (*((int*)tmpl)) & 0x0f : TM_STANDARD, true);
+ }
+ if(tl_pts && tl_nPts) free(tl_pts);
+ tl_pts = 0L; tl_nPts = 0;
+ if(CurrDisp) CurrDisp->MrkMode = MRK_NONE;
+ if(o) switch(ToolMode & 0x0f) {
case TM_TEXT:
- o->MouseCursor(MC_TEXT, false); break;
- case TM_DRAW: case TM_POLYLINE: case TM_POLYGON:
+ o->MouseCursor(MC_TEXT, false); break;
+ case TM_DRAW: case TM_POLYLINE: case TM_POLYGON:
o->MouseCursor(MC_DRAWPEN, false); break;
case TM_RECTANGLE:
o->MouseCursor(MC_DRAWREC, false); break;
case TM_ELLIPSE:
o->MouseCursor(MC_DRAWELLY, false); break;
- case TM_ROUNDREC:
+ case TM_ROUNDREC:
o->MouseCursor(MC_DRAWRREC, false); break;
case TM_ARROW:
- o->MouseCursor(MC_CROSS, false); break;
+ o->MouseCursor(MC_CROSS, false); break;
default:
- o->MouseCursor(MC_ARROW, true); break;
+ o->MouseCursor(MC_ARROW, true); break;
}
- return Command(CMD_REDRAW, 0L, CurrDisp);
- case CMD_ADDPLOT:
+ 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(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){
CurrGraph = (Graph*)Plots[0];
return CurrGraph->Command(cmd, tmpl, o);
}
- InfoBox("No graph selected!\nCreate a new graph first or select\n"
- "a graph before you can add a plot.");
- return false;
- }
- else if(Id == GO_GRAPH) {
- if(type == GT_3D && Plots){
- for(i = 0; i < NumPlots; i++) {
+ InfoBox("No graph selected!\nCreate a new graph first or select\n"
+ "a graph before you can add a plot.");
+ return false;
+ }
+ 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
- || Plots[i]->Id == GO_FITFUNC3D)) {
+ || Plots[i]->Id == GO_FITFUNC3D)) {
if(Plots[i]->Command(cmd, tmpl, CurrDisp)) return Command(CMD_REDRAW, 0L, o);
else return false;
- }
+ }
}
- return false;
- }
- else return AddPlot(0x0);
- }
- return false;
- case CMD_MRK_DIRTY:
- return (dirty = true);
- case CMD_CURRLEFT: case CMD_CURRIGHT: case CMD_ADDCHAR:
- case CMD_BACKSP: case CMD_POS_FIRST: case CMD_POS_LAST:
+ return false;
+ }
+ else return AddPlot(0x0);
+ }
+ return false;
+ case CMD_MRK_DIRTY:
+ 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);
if(tmpl && *((int*)tmpl) == 27) { //Escape
- o->HideMark(); CurrLabel = 0L;
- }
+ if(CurrGO && CurrGO->Id == GO_TEXTFRAME) {
+ CurrGO->DoMark(o, false); o->MrkMode = MRK_NONE;
+ CurrGO = 0L;
+ }
+ else o->HideMark();
+ CurrLabel = 0L; HideTextCursor();
+ }
if(CurrLabel) return CurrLabel->Command(cmd, tmpl, o);
- if(CurrGO && tmpl && *((int*)tmpl) == 13) {
+ if(CurrGO && CurrGO->Id == GO_TEXTFRAME) return CurrGO->Command(cmd, tmpl, o);
+ else if(CurrGO && tmpl && *((int*)tmpl) == 13) {
CurrGO->PropertyDlg();
- }
- case CMD_CURRUP: case CMD_CURRDOWN:
- if(CurrLabel && CurrLabel == CurrGO){
- if(CurrLabel->parent && CurrLabel->parent->Id == GO_MLABEL)
- return CurrLabel->parent->Command(cmd, tmpl, o);
- return true;
- }
- case CMD_SHIFTLEFT: case CMD_SHIFTRIGHT: case CMD_SHIFTUP: case CMD_SHIFTDOWN:
- if(Id == GO_PAGE) {
- if(CurrGraph && CurrGraph->parent == this)
- return CurrGraph->Command(cmd, tmpl, o);
- }
- else {
- if(type == GT_3D && Plots) {
- for(i = 0; i < NumPlots; i++) {
+ }
+ case CMD_CURRUP: case CMD_CURRDOWN:
+ if(CurrLabel && CurrLabel == CurrGO){
+ if(CurrLabel->parent && CurrLabel->parent->Id == GO_MLABEL)
+ return CurrLabel->parent->Command(cmd, tmpl, o);
+ return true;
+ }
+ else if(CurrGO && CurrGO->Id == GO_TEXTFRAME) return CurrGO->Command(cmd, tmpl, o);
+ case CMD_SHIFTLEFT: case CMD_SHIFTRIGHT: case CMD_SHIFTUP: case CMD_SHIFTDOWN:
+ if(Id == GO_PAGE || (CurrGraph && CurrGraph->parent == this)) {
+ if(CurrGraph && CurrGraph->parent == this) return CurrGraph->Command(cmd, tmpl, o);
+ else if(CurrGO && CurrGO->Id == GO_TEXTFRAME) return CurrGO->Command(cmd, tmpl, 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
- || Plots[i]->Id == GO_FITFUNC3D))
- return Plots[i]->Command(cmd, tmpl, CurrDisp);
- }
- }
- }
- return false;
- case CMD_MOVE_TOP: case CMD_MOVE_UP:
- case CMD_MOVE_DOWN: case CMD_MOVE_BOTTOM:
- Undo.StoreListGO(this, &Plots, &NumPlots, 0L);
- if(MoveObj(cmd, (GraphObj *)tmpl)){
- bModified = true;
- CurrDisp->StartPage(); DoPlot(CurrDisp);
- CurrDisp->EndPage(); return true;
- }
- return false;
- case CMD_DELETE:
- if(!CurrGO) return false;
- bModified = true;
+ || Plots[i]->Id == GO_FITFUNC3D))
+ return Plots[i]->Command(cmd, tmpl, CurrDisp);
+ }
+ }
+ else if(CurrGO && CurrGO->Id == GO_TEXTFRAME) return CurrGO->Command(cmd, tmpl, o);
+ }
+ return false;
+ case CMD_MOVE_TOP: case CMD_MOVE_UP:
+ case CMD_MOVE_DOWN: case CMD_MOVE_BOTTOM:
+ Undo.StoreListGO(this, &Plots, &NumPlots, 0L);
+ if(MoveObj(cmd, (GraphObj *)tmpl)){
+ bModified = true;
+ CurrDisp->StartPage(); DoPlot(CurrDisp);
+ CurrDisp->EndPage(); return true;
+ }
+ return false;
+ case CMD_DELETE:
+ if(!CurrGO) return false; bModified = true;
+ if(CurrGO->Id == GO_TEXTFRAME) return CurrGO->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);
+ if(CurrGO->Id == GO_FRAMERECT) if(!(CurrGO = CurrGO->parent))return false;
+ if(CurrGO->parent == this) return Command(CMD_DELOBJ, (void*)CurrGO, 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(Disp) {
+ if(!(tmpPlots = (GraphObj**)memdup(Plots, (NumPlots+2)*sizeof(GraphObj*), 0)))
+ return false;
+ Undo.ListGOmoved(Plots, tmpPlots, NumPlots);
+ free(Plots); Plots = tmpPlots; Plots[NumPlots] = Plots[NumPlots+1] = 0L;
+ Undo.SetGO(this, &Plots[NumPlots], (GraphObj*)tmpl, 0L);
+ }
+ else if(Plots = (GraphObj**)realloc(Plots, sizeof(GraphObj*) * (NumPlots+2))){
+ Plots[NumPlots] = (GraphObj*)tmpl; Plots[NumPlots+1] = 0L;
+ }
+ else return false;
+ if(Plots[NumPlots]){
+ Plots[NumPlots]->parent = this;
+ Plots[NumPlots]->Command(CMD_SET_DATAOBJ, data, 0L);
+ if(Plots[NumPlots]->Id == GO_GRAPH) CurrGraph = (Graph*)Plots[NumPlots];
+ Plots[NumPlots]->moveable = 1; //all page items should be freely
+ } // moveable by user
+ NumPlots++;
+ if(CurrDisp) {
+ CurrDisp->StartPage(); DoPlot(CurrDisp); CurrDisp->EndPage();
+ }
+ return true;
+ case CMD_DROP_PLOT:
if(!tmpl) return false;
((GraphObj*)tmpl)->parent = this;
if(((GraphObj*)tmpl)->Id < GO_PLOT) {
@@ -8136,186 +9141,195 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
CurrDisp->EndPage();
}
return true;
- }
- if(Id == GO_GRAPH) CurrGraph = this; bModified =true;
- if(!NumPlots) {
- Plots = (GraphObj**)calloc(2, sizeof(GraphObj*));
- if(Plots) {
- Plots[0] = (Plot *)tmpl; Plots[0]->parent = this;
- switch(Plots[0]->Id) {
- case GO_PIECHART: case GO_RINGCHART: case GO_STARCHART:
- type = GT_CIRCCHART;
- break;
- case GO_POLARPLOT:
- type = GT_POLARPLOT;
- break;
+ }
+ if(Id == GO_GRAPH) CurrGraph = this; bModified =true;
+ if(!NumPlots) {
+ Plots = (GraphObj**)calloc(2, sizeof(GraphObj*));
+ if(Plots) {
+ Plots[0] = (Plot *)tmpl; Plots[0]->parent = this;
+ switch(Plots[0]->Id) {
+ case GO_PIECHART: case GO_RINGCHART: case GO_STARCHART:
+ type = GT_CIRCCHART;
+ break;
+ case GO_POLARPLOT:
+ type = GT_POLARPLOT;
+ break;
case GO_SCATT3D: case GO_PLOT3D: case GO_FUNC3D:
- case GO_FITFUNC3D:
- type = GT_3D;
- break;
- default:
- type = GT_STANDARD;
- break;
- }
- Bounds.Xmin = x_axis.min = ((Plot*)Plots[0])->Bounds.Xmin;
- Bounds.Xmax = x_axis.max = ((Plot*)Plots[0])->Bounds.Xmax;
- Bounds.Ymin = y_axis.min = ((Plot*)Plots[0])->Bounds.Ymin;
- Bounds.Ymax = y_axis.max = ((Plot*)Plots[0])->Bounds.Ymax;
- if(Bounds.Ymax == Bounds.Ymin) {
- if(Bounds.Ymax != 0.0f) {
- Bounds.Ymax = y_axis.max = Bounds.Ymax + (Bounds.Ymax)/10.0f;
- Bounds.Ymin = y_axis.min = Bounds.Ymin - (Bounds.Ymax)/10.0f;
- }
- else {
- Bounds.Ymax = y_axis.max = 1.0f;
- Bounds.Ymin = y_axis.min = -1.0f;
- }
- }
- if(Bounds.Xmax == Bounds.Xmin) {
- if(Bounds.Xmax != 0.0f) {
- Bounds.Xmax = x_axis.max = Bounds.Xmax + (Bounds.Xmax)/10.0f;
- Bounds.Xmin = x_axis.min = Bounds.Xmin - (Bounds.Xmax)/10.0f;
- }
- else {
- Bounds.Xmax = 1.0f;
- Bounds.Xmin = -1.0f;
- }
- }
- NiceAxis(&x_axis, 4); NiceAxis(&y_axis, 4);
- NumPlots = 1;
- if(type == GT_STANDARD && !NumAxes) CreateAxes(AxisTempl);
- dirty = false;
- return true;
- }
- return false;
- }
+ case GO_FITFUNC3D:
+ type = GT_3D;
+ break;
+ default:
+ type = GT_STANDARD;
+ break;
+ }
+ Bounds.Xmin = x_axis.min = ((Plot*)Plots[0])->Bounds.Xmin;
+ Bounds.Xmax = x_axis.max = ((Plot*)Plots[0])->Bounds.Xmax;
+ Bounds.Ymin = y_axis.min = ((Plot*)Plots[0])->Bounds.Ymin;
+ Bounds.Ymax = y_axis.max = ((Plot*)Plots[0])->Bounds.Ymax;
+ if(Bounds.Ymax == Bounds.Ymin) {
+ if(Bounds.Ymax != 0.0f) {
+ Bounds.Ymax = y_axis.max = Bounds.Ymax + (Bounds.Ymax)/10.0f;
+ Bounds.Ymin = y_axis.min = Bounds.Ymin - (Bounds.Ymax)/10.0f;
+ }
+ else {
+ Bounds.Ymax = y_axis.max = 1.0f;
+ Bounds.Ymin = y_axis.min = -1.0f;
+ }
+ }
+ if(Bounds.Xmax == Bounds.Xmin) {
+ if(Bounds.Xmax != 0.0f) {
+ Bounds.Xmax = x_axis.max = Bounds.Xmax + (Bounds.Xmax)/10.0f;
+ Bounds.Xmin = x_axis.min = Bounds.Xmin - (Bounds.Xmax)/10.0f;
+ }
+ else {
+ Bounds.Xmax = 1.0f;
+ Bounds.Xmin = -1.0f;
+ }
+ }
+ NiceAxis(&x_axis, 4); NiceAxis(&y_axis, 4);
+ NumPlots = 1;
+ if(type == GT_STANDARD && !NumAxes) CreateAxes(AxisTempl);
+ dirty = false;
+ return true;
+ }
+ return false;
+ }
else {
if(Disp) {
- Undo.SetDisp(Disp);
+ Undo.SetDisp(Disp);
tmpPlots = (GraphObj**)memdup(Plots, sizeof(GraphObj*) * (NumPlots+2), 0);
- Undo.ListGOmoved(Plots, tmpPlots, NumPlots);
- Undo.SetGO(this, &tmpPlots[NumPlots++], (Plot *)tmpl, 0L);
+ Undo.ListGOmoved(Plots, tmpPlots, NumPlots);
+ Undo.SetGO(this, &tmpPlots[NumPlots++], (Plot *)tmpl, 0L);
free(Plots); Plots = tmpPlots;
}
else if(Plots = (GraphObj**)realloc(Plots, sizeof(GraphObj*) * (NumPlots+2))){
Plots[NumPlots++] = (Plot*)tmpl; Plots[NumPlots] = 0L;
}
else return false;
- if(type == GT_STANDARD && ((x_axis.flags & AXIS_AUTOSCALE) ||
- (y_axis.flags & AXIS_AUTOSCALE))) {
- if(x_axis.flags & AXIS_AUTOSCALE) {
- Bounds.Xmin = x_axis.min = ((Plot *)tmpl)->Bounds.Xmin < Bounds.Xmin ?
- ((Plot *)tmpl)->Bounds.Xmin : Bounds.Xmin;
- Bounds.Xmax = x_axis.max = ((Plot *)tmpl)->Bounds.Xmax > Bounds.Xmax ?
- ((Plot *)tmpl)->Bounds.Xmax : Bounds.Xmax;
- NiceAxis(&x_axis, 4);
- if(Axes)for(i = 0; i < NumAxes; i++)
- if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &x_axis, o);
- }
- if(y_axis.flags & AXIS_AUTOSCALE) {
- Bounds.Ymin = y_axis.min = ((Plot *)tmpl)->Bounds.Ymin < Bounds.Ymin ?
- ((Plot *)tmpl)->Bounds.Ymin : Bounds.Ymin;
- Bounds.Ymax = y_axis.max = ((Plot *)tmpl)->Bounds.Ymax > Bounds.Ymax ?
- ((Plot *)tmpl)->Bounds.Ymax : Bounds.Ymax;
- NiceAxis(&y_axis, 4);
- if(Axes)for(i = 0; i < NumAxes; i++)
- if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &y_axis, o);
- }
- }
- dirty = false;
+ if(type == GT_STANDARD && ((x_axis.flags & AXIS_AUTOSCALE) ||
+ (y_axis.flags & AXIS_AUTOSCALE))) {
+ if(x_axis.flags & AXIS_AUTOSCALE) {
+ Bounds.Xmin = x_axis.min = ((Plot *)tmpl)->Bounds.Xmin < Bounds.Xmin ?
+ ((Plot *)tmpl)->Bounds.Xmin : Bounds.Xmin;
+ Bounds.Xmax = x_axis.max = ((Plot *)tmpl)->Bounds.Xmax > Bounds.Xmax ?
+ ((Plot *)tmpl)->Bounds.Xmax : Bounds.Xmax;
+ NiceAxis(&x_axis, 4);
+ if(Axes)for(i = 0; i < NumAxes; i++)
+ if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &x_axis, o);
+ }
+ if(y_axis.flags & AXIS_AUTOSCALE) {
+ Bounds.Ymin = y_axis.min = ((Plot *)tmpl)->Bounds.Ymin < Bounds.Ymin ?
+ ((Plot *)tmpl)->Bounds.Ymin : Bounds.Ymin;
+ Bounds.Ymax = y_axis.max = ((Plot *)tmpl)->Bounds.Ymax > Bounds.Ymax ?
+ ((Plot *)tmpl)->Bounds.Ymax : Bounds.Ymax;
+ NiceAxis(&y_axis, 4);
+ if(Axes)for(i = 0; i < NumAxes; i++)
+ if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &y_axis, o);
+ }
+ }
+ dirty = false;
//Redraw graph to show all plots
- if(CurrDisp) {
- CurrDisp->StartPage();
- DoPlot(CurrDisp);
+ if(CurrDisp) {
+ CurrDisp->StartPage();
+ DoPlot(CurrDisp);
CurrDisp->EndPage();
- }
- return true;
- }
+ }
+ return true;
+ }
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 &&
- (TrackGO = (GraphObj*)CurrGO->ObjThere(mev->x, mev->y))){
- ToolMode |= TM_MOVE;
- }
- else if(mev->Action == MOUSE_LBDOWN){
- CurrGO = 0L;
- if((ToolMode & 0xff) == TM_STANDARD || (ToolMode & 0xff) == TM_ZOOMIN){
- rc_mrk.left = mev->x; rc_mrk.top = mev->y;
- }
- }
- if(ToolMode != TM_STANDARD && ExecTool(mev)) return true;
- switch(mev->Action) {
- case MOUSE_RBUP:
+ if(!tmpl) return false;
+ Undo.SetDisp(o ? o : CurrDisp);
+ PasteObj = (GraphObj*)tmpl;
+ if(PasteObj->Id == GO_GRAPH) {
+ ToolMode = TM_PASTE; o->MouseCursor(MC_PASTE, false);
+ return true;
+ }
+ PasteObj = 0L;
+ return false;
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *)tmpl; defs.SetDisp(o);
+ if(CurrGO && CurrGO->moveable && mev->Action == MOUSE_LBDOWN &&
+ (TrackGO = (GraphObj*)CurrGO->ObjThere(mev->x, mev->y))){
+ ToolMode |= TM_MOVE;
+ }
+ else if(mev->Action == MOUSE_LBDOWN){
+ if(CurrGO && CurrGO->Id == GO_TEXTFRAME && CurrGO->Command(cmd, tmpl, o)) return true;
+ CurrGO = 0L;
+ if((ToolMode & 0xff) == TM_STANDARD || (ToolMode & 0xff) == TM_ZOOMIN){
+ rc_mrk.left = mev->x; rc_mrk.top = mev->y;
+ }
+ }
+ if(ToolMode != TM_STANDARD && ExecTool(mev)) return true;
+ switch(mev->Action) {
+ case MOUSE_RBUP:
Undo.SetDisp(o);
- i = ToolMode;
- ToolMode = TM_STANDARD;
- mev->Action = MOUSE_LBUP; //fake select
- Command(cmd, tmpl, o);
- ToolMode = i;
- //the default behaviour for right button click is the same as for
- // double click: execute properties dialog, just continue.
+ i = ToolMode;
+ ToolMode = TM_STANDARD;
+ mev->Action = MOUSE_LBUP; //fake select
+ Command(cmd, tmpl, o); ToolMode = i;
+ if(!CurrGO) CurrGO = this;
+ //the default behaviour for right button click is the same as for
+ // double click: execute properties dialog, just continue.
case MOUSE_LBDOUBLECLICK:
- if(!CurrGO){
- mev->Action = MOUSE_LBUP;
- Command(CMD_MOUSE_EVENT, mev, CurrDisp);
- mev->Action = MOUSE_LBDOUBLECLICK;
- }
+ if(!CurrGO){
+ mev->Action = MOUSE_LBUP;
+ Command(CMD_MOUSE_EVENT, mev, CurrDisp);
+ mev->Action = MOUSE_LBDOUBLECLICK;
+ if(!CurrGO) CurrGO = this;
+ if(CurrGO->Command(CMD_CONFIG, 0L, o)) return Command(CMD_REDRAW, 0L, o);
+ }
else if(CurrGO->Id < GO_PLOT) {
- if(CurrGO->PropertyDlg()) {
- bModified = true;
+ if(CurrGO->PropertyDlg()) {
+ bModified = true;
return Command(CMD_REDRAW, 0L, o);
}
}
else if(CurrGO->Command(CMD_CONFIG, 0L, o)) return Command(CMD_REDRAW, 0L, o);
- else if (Id == GO_PAGE) return Command(CMD_CONFIG, 0L, o);
- else o->HideMark();
- TrackGO = 0L; CurrLabel = 0L;
- return false;
- case MOUSE_LBUP:
+ else o->HideMark();
+ TrackGO = 0L; CurrLabel = 0L;
+ if(CurrGO == this) CurrGO = 0L;
+ return false;
+ case MOUSE_LBUP:
Undo.SetDisp(o);
- if(Id == GO_GRAPH){
- CurrGO = TrackGO = 0L;
- CurrGraph = this;
- }
- case MOUSE_MOVE:
- if(mev->Action == MOUSE_MOVE && !(mev->StateFlags & 0x01)) return false;
- //do all axes
- for(i = 0; Axes && i< NumAxes; i++)
- if(Axes[i] && Axes[i]->Command(cmd, tmpl,o)) return true;
- //do all plots
- if(Plots)for(i = NumPlots-1; i>=0; i--)
- if(Plots[i] && Plots[i]->Command(cmd, tmpl,o)) return true;
- if(frm_d && frm_d->Command(cmd, tmpl, o)) return true;
- if(frm_g && frm_g->Command(cmd, tmpl, o)) return true;
- if(mev->Action == MOUSE_MOVE && ToolMode == TM_STANDARD &&
- rc_mrk.left >=0 && rc_mrk.top >=0) ToolMode = TM_MARK;
- if(!CurrGO) CurrGraph = 0L;
- return false;
- }
- break;
- case CMD_SETSCROLL:
- if(o) {
- o->ActualSize(&rc);
- i = o->un2iy(GRect.Ymax);
- o->SetScroll(true, -(i>>3), i+(i>>3), (rc.bottom -rc.top)>>1, - iround(o->VPorg.fy));
- i = o->un2ix(GRect.Xmax);
- o->SetScroll(false, -(i>>3), i+(i>>3), (rc.right -rc.left)>>1, - iround(o->VPorg.fx));
- if(CurrDisp && o->Erase(ColBG)) Command(CMD_REDRAW, 0L, o);
- return true;
- }
- return false;
- case CMD_SETHPOS:
- if(o && tmpl) o->VPorg.fx = - (double)(*((int*)tmpl));
- return Command(CMD_SETSCROLL, tmpl, o);
- case CMD_SETVPOS:
- if(o && tmpl) o->VPorg.fy = - (double)(*((int*)tmpl));
+ if(Id == GO_GRAPH){
+ CurrGO = TrackGO = 0L;
+ CurrGraph = this;
+ }
+ case MOUSE_MOVE:
+ if(mev->Action == MOUSE_MOVE && !(mev->StateFlags & 0x01)) return false;
+ //do all axes
+ for(i = 0; Axes && i< NumAxes; i++)
+ if(Axes[i] && Axes[i]->Command(cmd, tmpl,o)) return true;
+ //do all plots
+ if(Plots)for(i = NumPlots-1; i>=0; i--)
+ if(Plots[i] && Plots[i]->Command(cmd, tmpl,o)) return true;
+ if(frm_d && frm_d->Command(cmd, tmpl, o)) return true;
+ if(frm_g && frm_g->Command(cmd, tmpl, o)) return true;
+ if(mev->Action == MOUSE_MOVE && ToolMode == TM_STANDARD &&
+ rc_mrk.left >=0 && rc_mrk.top >=0) ToolMode = TM_MARK;
+ if(!CurrGO) CurrGraph = 0L;
+ return false;
+ }
+ break;
+ case CMD_SETSCROLL:
+ if(o) {
+ o->ActualSize(&rc);
+ i = o->un2iy(GRect.Ymax);
+ o->SetScroll(true, -(i>>3), i+(i>>3), (rc.bottom -rc.top)>>1, - iround(o->VPorg.fy));
+ i = o->un2ix(GRect.Xmax);
+ o->SetScroll(false, -(i>>3), i+(i>>3), (rc.right -rc.left)>>1, - iround(o->VPorg.fx));
+ if(CurrDisp && o->Erase(ColBG)) Command(CMD_REDRAW, 0L, o);
+ return true;
+ }
+ return false;
+ case CMD_SETHPOS:
+ if(o && tmpl) o->VPorg.fx = - (double)(*((int*)tmpl));
+ return Command(CMD_SETSCROLL, tmpl, o);
+ case CMD_SETVPOS:
+ if(o && tmpl) o->VPorg.fy = - (double)(*((int*)tmpl));
return Command(CMD_SETSCROLL, tmpl, o);
- case CMD_OBJTREE:
+ case CMD_OBJTREE:
for(i = 0; Plots && i < NumPlots; i++) if(Plots[i]) {
((ObjTree*)tmpl)->Command(CMD_UPDATE, Plots[i], 0L);
if(Plots[i]->Id == GO_STACKBAR || Plots[i]->Id == GO_GRAPH ||
@@ -8324,480 +9338,522 @@ Graph::Command(int cmd, void *tmpl, anyOutput *o)
Plots[i]->Command(cmd, tmpl, o);
}
return true;
- }
- return false;
-}
-
-void
-Graph::DoAutoscale()
-{
- int i;
- fRECT oB;
-
- memcpy(&oB, &Bounds, sizeof(fRECT));
- if(type == GT_STANDARD && ((x_axis.flags & AXIS_AUTOSCALE) ||
- (y_axis.flags & AXIS_AUTOSCALE))) {
- for(i = 0; i < NumPlots; i++) {
- if(Plots[i] && (Plots[i]->Id == GO_PLOTSCATT || Plots[i]->Id == GO_BUBBLEPLOT ||
- Plots[i]->Id == GO_BOXPLOT || Plots[i]->Id == GO_STACKBAR ||
- Plots[i]->Id == GO_STACKPG || Plots[i]->Id == GO_DENSDISP ||
- Plots[i]->Id == GO_LIMITS || Plots[i]->Id == GO_FUNCTION ||
- Plots[i]->Id == GO_FITFUNC || Plots[i]->Id== GO_FREQDIST)) {
- bModified = true;
- if(dirty) {
- if(x_axis.flags & AXIS_AUTOSCALE) {
- Bounds.Xmin = HUGE_VAL; Bounds.Xmax = -HUGE_VAL;
- }
- if(y_axis.flags & AXIS_AUTOSCALE) {
- Bounds.Ymin = HUGE_VAL; Bounds.Ymax = -HUGE_VAL;
- }
- dirty = false;
- }
+ }
+ return false;
+}
+
+double
+Graph::DefSize(int select)
+{
+ switch(select) {
+ case SIZE_LB_XDIST:
+ case SIZE_LB_YDIST: return 0.0f;
+ case SIZE_GRECT_TOP: return GRect.Ymin;
+ case SIZE_GRECT_BOTTOM: return GRect.Ymax;
+ case SIZE_GRECT_LEFT: return GRect.Xmin;
+ case SIZE_GRECT_RIGHT: return GRect.Xmax;
+ case SIZE_DRECT_TOP: return DRect.Ymin;
+ case SIZE_DRECT_BOTTOM: return DRect.Ymax;
+ case SIZE_DRECT_LEFT: return DRect.Xmin;
+ case SIZE_DRECT_RIGHT: return DRect.Xmax;
+ case SIZE_BOUNDS_XMIN: return Bounds.Xmin;
+ case SIZE_BOUNDS_XMAX: return Bounds.Xmax;
+ case SIZE_BOUNDS_YMIN: return Bounds.Ymin;
+ case SIZE_BOUNDS_YMAX: return Bounds.Ymax;
+ case SIZE_BOUNDS_LEFT: return x_axis.flags & AXIS_INVERT ? x_axis.max : x_axis.min;
+ case SIZE_BOUNDS_RIGHT: return x_axis.flags & AXIS_INVERT ? x_axis.min : x_axis.max;
+ case SIZE_BOUNDS_TOP: return y_axis.flags & AXIS_INVERT ? y_axis.min : y_axis.max;
+ case SIZE_BOUNDS_BOTTOM: return y_axis.flags & AXIS_INVERT ? y_axis.max : y_axis.min;
+ case SIZE_YAXISX:
+ if(y_axis.flags & AXIS_X_DATA) return CurrDisp->fx2fix(y_axis.loc[0].fx);
+ else return CurrDisp->co2fix(y_axis.loc[0].fx);
+ case SIZE_XAXISY:
+ if(x_axis.flags & AXIS_Y_DATA) return CurrDisp->fy2fiy(x_axis.loc[0].fy);
+ else return CurrDisp->co2fiy(x_axis.loc[0].fy);
+ }
+ if(scale > 0.0) return scale * defs.GetSize(select);
+ else return defs.GetSize(select);
+}
+
+void
+Graph::DoAutoscale()
+{
+ int i;
+ fRECT oB;
+
+ memcpy(&oB, &Bounds, sizeof(fRECT));
+ if(type == GT_STANDARD && ((x_axis.flags & AXIS_AUTOSCALE) ||
+ (y_axis.flags & AXIS_AUTOSCALE))) {
+ for(i = 0; i < NumPlots; i++) {
+ if(Plots[i] && (Plots[i]->Id == GO_PLOTSCATT || Plots[i]->Id == GO_BUBBLEPLOT ||
+ Plots[i]->Id == GO_BOXPLOT || Plots[i]->Id == GO_STACKBAR ||
+ Plots[i]->Id == GO_STACKPG || Plots[i]->Id == GO_DENSDISP ||
+ Plots[i]->Id == GO_LIMITS || Plots[i]->Id == GO_FUNCTION ||
+ Plots[i]->Id == GO_FITFUNC || Plots[i]->Id== GO_FREQDIST)) {
+ bModified = true;
+ if(dirty) {
+ if(x_axis.flags & AXIS_AUTOSCALE) {
+ Bounds.Xmin = HUGE_VAL; Bounds.Xmax = -HUGE_VAL;
+ }
+ if(y_axis.flags & AXIS_AUTOSCALE) {
+ Bounds.Ymin = HUGE_VAL; Bounds.Ymax = -HUGE_VAL;
+ }
+ dirty = false;
+ }
Plots[i]->Command(CMD_AUTOSCALE, 0L, CurrDisp);
- if(!((Plot*)Plots[i])->hidden) {
- if(x_axis.flags & AXIS_AUTOSCALE) {
- Bounds.Xmin = ((Plot*)Plots[i])->Bounds.Xmin < Bounds.Xmin ?
- ((Plot*)Plots[i])->Bounds.Xmin : Bounds.Xmin;
- Bounds.Xmax = ((Plot*)Plots[i])->Bounds.Xmax > Bounds.Xmax ?
- ((Plot*)Plots[i])->Bounds.Xmax : Bounds.Xmax;
- }
- if(y_axis.flags & AXIS_AUTOSCALE) {
- Bounds.Ymin = ((Plot*)Plots[i])->Bounds.Ymin < Bounds.Ymin ?
- ((Plot*)Plots[i])->Bounds.Ymin : Bounds.Ymin;
- Bounds.Ymax = ((Plot*)Plots[i])->Bounds.Ymax > Bounds.Ymax ?
- ((Plot*)Plots[i])->Bounds.Ymax : Bounds.Ymax;
- }
- }
- }
- }
- if(Bounds.Xmax <= Bounds.Xmin) {
- Bounds.Xmax = oB.Xmax > oB.Xmin ? oB.Xmax : oB.Xmax + 1.0;
- Bounds.Xmin = oB.Xmin < oB.Xmax ? oB.Xmin : oB.Xmin - 1.0;
- }
- if(Bounds.Ymax <= Bounds.Ymin) {
- Bounds.Ymax = oB.Ymax > oB.Ymin ? oB.Ymax : oB.Ymax + 1.0;
- Bounds.Ymin = oB.Ymin < oB.Ymax ? oB.Ymin : oB.Ymin - 1.0;
- }
- if(x_axis.flags & AXIS_AUTOSCALE){
- x_axis.min = Bounds.Xmin; x_axis.max = Bounds.Xmax;
- NiceAxis(&x_axis, 4);
- if(x_axis.min <= 0.0 && ((x_axis.flags & 0xf000) == AXIS_LOG ||
- (x_axis.flags & 0xf000) == AXIS_RECI)) {
- x_axis.min = base4log(&x_axis, 0);
- }
- if(Axes)for(i = 0; i < NumAxes; i++)
- if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &x_axis, 0L);
- }
- if(y_axis.flags & AXIS_AUTOSCALE){
- y_axis.min = Bounds.Ymin; y_axis.max = Bounds.Ymax;
- NiceAxis(&y_axis, 4);
- if(y_axis.min <= 0.0 && ((y_axis.flags & 0xf000) == AXIS_LOG ||
- (y_axis.flags & 0xf000) == AXIS_RECI)) {
- y_axis.min = base4log(&y_axis, 1);
- }
- if(Axes)for(i = 0; i < NumAxes; i++)
- if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &y_axis, 0L);
- }
- }
- dirty = false;
-}
-
-void
-Graph::CreateAxes(int templ)
-{
- AxisDEF tmp_axis;
- TextDEF label_def, tlbdef;
- char label_text[500];
- Label *label;
- double ts, lb_ydist, lb_xdist, tlb_dist;
- DWORD ptick, ntick, utick;
-
- if(Axes && NumAxes) return;
- label_def.ColTxt = defs.Color(COL_AXIS);
- label_def.ColBg = 0x00ffffffL;
- label_def.fSize = defs.GetSize(SIZE_TICK_LABELS)*1.2;
- label_def.RotBL = label_def.RotCHAR = 0.0;
- label_def.iSize = 0;
- label_def.Align = TXA_VTOP | TXA_HCENTER;
- label_def.Mode = TXM_TRANSPARENT;
- label_def.Style = TXS_NORMAL;
- label_def.Font = FONT_HELVETICA;
- label_def.text = label_text;
- tlbdef.ColTxt = defs.Color(COL_AXIS);
- tlbdef.ColBg = 0x00ffffffL;
- tlbdef.RotBL = tlbdef.RotCHAR = 0.0;
- tlbdef.iSize = 0;
- tlbdef.fSize = defs.GetSize(SIZE_TICK_LABELS);
- tlbdef.Align = TXA_VCENTER | TXA_HCENTER;
- tlbdef.Style = TXS_NORMAL;
- tlbdef.Mode = TXM_TRANSPARENT;
- tlbdef.Font = FONT_HELVETICA;
- tlbdef.text = 0L;
- ts = defs.GetSize(SIZE_AXIS_TICKS);
- switch (tickstyle & 0x07){
- case 1: //ticks inside
- ntick = AXIS_POSTICKS; ptick = AXIS_POSTICKS; utick = AXIS_NEGTICKS;
- ts *= 0.5;
- break;
- case 2: //centered, symetrical
- ptick = ntick = utick = AXIS_SYMTICKS;
- ts *= 0.75;
- break;
- default: //ticks outside
- ptick = AXIS_NEGTICKS; ntick = AXIS_NEGTICKS; utick = AXIS_POSTICKS;
- break;
- }
- tlb_dist = NiceValue(ts * 2.0);
- lb_ydist = NiceValue((ts+defs.GetSize(SIZE_AXIS_TICKS))*2.0);
- lb_xdist = NiceValue((ts+defs.GetSize(SIZE_AXIS_TICKS))*3.0);
- switch(templ) {
- case 0:
- Axes = (Axis**)calloc(5, sizeof(Axis *));
- x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
- x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
- x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
- y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fx = y_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;;
- if((Axes[0] = new Axis(this, data, &x_axis, AXIS_BOTTOM | ptick |
- AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
- Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
- Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
- strcpy(label_text, "x-axis");
- label = new Label(Axes[0], data, GRect.Xmin + (DRect.Xmin+DRect.Xmax)/2.0f,
- GRect.Ymin+DRect.Ymax+defs.GetSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
- if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VTOP | TXA_HCENTER;
- Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- if((Axes[1] = new Axis(this, data, &y_axis, AXIS_LEFT | ntick | AXIS_AUTOTICK |
- AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
- Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
- Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
- strcpy(label_text, "y-axis");
- label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
- label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - defs.GetSize(SIZE_AXIS_TICKS)*6.0,
- GRect.Ymin+(DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
- if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
- Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- label = 0L;
- memcpy(&tmp_axis, &x_axis, sizeof(AxisDEF));
- tmp_axis.owner = NULL;
- tmp_axis.loc[0].fy = tmp_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- if((Axes[2] = new Axis(this, data, &tmp_axis, AXIS_TOP | AXIS_NOTICKS | AXIS_AUTOTICK))){
- Axes[2]->SetSize(SIZE_LB_YDIST, -lb_ydist);
- Axes[2]->SetSize(SIZE_TLB_YDIST, -tlb_dist);
- tlbdef.Align = TXA_VBOTTOM | TXA_HCENTER;
- Axes[2]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- memcpy(&tmp_axis, &y_axis, sizeof(AxisDEF));
- tmp_axis.owner = NULL;
- tmp_axis.loc[0].fx = tmp_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
- if((Axes[3] = new Axis(this, data, &tmp_axis, AXIS_RIGHT | AXIS_NOTICKS | AXIS_AUTOTICK))){
- Axes[3]->SetSize(SIZE_LB_XDIST, lb_xdist);
- Axes[3]->SetSize(SIZE_TLB_XDIST, tlb_dist);
- tlbdef.Align = TXA_VCENTER | TXA_HLEFT;
- Axes[3]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- NumAxes = 4;
- break;
- case 1:
- Axes = (Axis**)calloc(7, sizeof(Axis *));
- if(x_axis.Start >= 0.0f) x_axis.min = x_axis.Start = -x_axis.Step;
- if(y_axis.Start >= 0.0f) y_axis.min = y_axis.Start = -y_axis.Step;
- x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
- x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
- x_axis.loc[0].fy = x_axis.loc[1].fy = 0.0f;
- y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
- y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fx = y_axis.loc[1].fx = 0.0f;
- if((Axes[0] = new Axis(this, data, &x_axis, ptick | AXIS_Y_DATA |
- AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
- Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
- Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
- strcpy(label_text, "x-axis");
- label_def.Align = TXA_VTOP | TXA_HRIGHT;
- label = new Label(Axes[0], data, GRect.Xmin + DRect.Xmax - defs.GetSize(SIZE_AXIS_TICKS)*2.0,
- GRect.Ymin+DRect.Ymax+defs.GetSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
- if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VTOP | TXA_HCENTER;
- Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- if((Axes[1] = new Axis(this, data, &y_axis, ntick | AXIS_AUTOTICK | AXIS_X_DATA |
- AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
- Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
- Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
- strcpy(label_text, "y-axis");
- label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HRIGHT;
- label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - defs.GetSize(SIZE_AXIS_TICKS)*6.0,
- GRect.Ymin + DRect.Ymin + defs.GetSize(SIZE_AXIS_TICKS)*2.0,
- &label_def, LB_X_PARENT);
- if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
- Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- memcpy(&tmp_axis, &x_axis, sizeof(AxisDEF));
- tmp_axis.owner = NULL;
- tmp_axis.loc[0].fy = tmp_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- if(Axes[2] = new Axis(this, data, &tmp_axis, AXIS_TOP | AXIS_NOTICKS | AXIS_AUTOTICK)){
- Axes[2]->SetSize(SIZE_LB_YDIST, -lb_ydist);
- Axes[2]->SetSize(SIZE_TLB_YDIST, -tlb_dist);
- tlbdef.Align = TXA_VBOTTOM | TXA_HCENTER;
- Axes[2]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- tmp_axis.loc[0].fy = tmp_axis.loc[1].fy = GRect.Ymin + DRect.Ymin;
- if(Axes[3] = new Axis(this, data, &tmp_axis, AXIS_BOTTOM | AXIS_NOTICKS | AXIS_AUTOTICK)){
- Axes[3]->SetSize(SIZE_LB_YDIST, lb_xdist);
- Axes[3]->SetSize(SIZE_TLB_YDIST, tlb_dist);
- tlbdef.Align = TXA_VTOP | TXA_HCENTER;
- Axes[3]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- memcpy(&tmp_axis, &y_axis, sizeof(AxisDEF));
- tmp_axis.owner = NULL;
- tmp_axis.loc[0].fx = tmp_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;
- if(Axes[4] = new Axis(this, data, &tmp_axis, AXIS_LEFT | AXIS_NOTICKS | AXIS_AUTOTICK)){
- Axes[4]->SetSize(SIZE_LB_XDIST, -lb_xdist);
- Axes[4]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
- tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
- Axes[4]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- tmp_axis.loc[0].fx = tmp_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
- if(Axes[5] = new Axis(this, data, &tmp_axis, AXIS_RIGHT | AXIS_NOTICKS | AXIS_AUTOTICK)){
- Axes[5]->SetSize(SIZE_LB_XDIST, lb_xdist);
- Axes[5]->SetSize(SIZE_TLB_XDIST, tlb_dist);
- tlbdef.Align = TXA_VCENTER | TXA_HLEFT;
- Axes[5]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- NumAxes = 6;
- break;
- case 2:
- Axes = (Axis**)calloc(3, sizeof(Axis *));
- x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
- x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
- x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
- y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fx = y_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;
- if((Axes[0] = new Axis(this, data, &x_axis, AXIS_BOTTOM | ptick |
- AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
- Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
- Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
- strcpy(label_text, "x-axis");
- label = new Label(Axes[0], data, GRect.Xmin + (DRect.Xmin+DRect.Xmax)/2.0f,
- GRect.Ymin+DRect.Ymax+defs.GetSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
- if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VTOP | TXA_HCENTER;
- Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- if((Axes[1] = new Axis(this, data, &y_axis, AXIS_LEFT | ntick | AXIS_AUTOTICK |
- AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
- Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
- Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
- strcpy(label_text, "y-axis");
- label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
- label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - defs.GetSize(SIZE_AXIS_TICKS)*6.0,
- GRect.Ymin+(DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
- if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
- Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- label = 0L;
- NumAxes = 2;
- break;
- case 3:
- label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
- Axes = (Axis**)calloc(3, sizeof(Axis *));
- x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
- x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
- x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymin;
- y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
- y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fx = y_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;
- if((Axes[0] = new Axis(this, data, &x_axis, AXIS_TOP | utick |
- AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
- Axes[0]->SetSize(SIZE_LB_YDIST, -lb_ydist);
- Axes[0]->SetSize(SIZE_TLB_YDIST, -tlb_dist);
- strcpy(label_text, "x-axis");
- label = new Label(Axes[0], data, GRect.Xmin + (DRect.Xmin+DRect.Xmax)/2.0f,
- GRect.Ymin+DRect.Ymax+defs.GetSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
- if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VBOTTOM | TXA_HCENTER;
- Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- if((Axes[1] = new Axis(this, data, &y_axis, AXIS_LEFT | ntick | AXIS_AUTOTICK |
- AXIS_AUTOSCALE | AXIS_INVERT | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
- Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
- Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
- strcpy(label_text, "y-axis");
- label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
- label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - defs.GetSize(SIZE_AXIS_TICKS)*6.0,
- GRect.Ymin+(DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
- if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
- Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- label = 0L;
- NumAxes = 2;
- break;
- case 4:
- Axes = (Axis**)calloc(3, sizeof(Axis *));
- if(x_axis.Start >= 0.0f) x_axis.min = -x_axis.Step;
- x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
- x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
- x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
- y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
- y_axis.loc[0].fx = y_axis.loc[1].fx = 0.0f;
- if((Axes[0] = new Axis(this, data, &x_axis, AXIS_BOTTOM | ptick |
- AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
- Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
- Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
- strcpy(label_text, "x-axis");
- label = new Label(Axes[0], data, GRect.Xmin + (DRect.Xmin+DRect.Xmax)/2.0f,
- GRect.Ymin+DRect.Ymax+defs.GetSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
- if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VTOP | TXA_HCENTER;
- Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- if((Axes[1] = new Axis(this, data, &y_axis, ntick | AXIS_AUTOTICK | AXIS_X_DATA |
- AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
- Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
- Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
- strcpy(label_text, "y-axis");
- label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
- label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - defs.GetSize(SIZE_AXIS_TICKS)*6.0,
- GRect.Ymin+(DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
- if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
- else if(label) DeleteGO(label);
- tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
- Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
- }
- label = 0L;
- NumAxes = 2;
- break;
- }
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Pages are graphic objects containing graphs and drawn objects
-Page::Page(GraphObj *par, DataObj *d):Graph(par, d, 0L)
-{
- FileIO(INIT_VARS);
- cGraphs--; cPages++; Id = GO_PAGE; bModified = true;
-}
-
-Page::Page(int src):Graph(src)
-{
- int i;
-
- //most of the object is read by Graph::FileIO()
- ColBG = 0x00e8e8e8L;
- LineDef.width = 0.0; LineDef.patlength = 1.0;
- LineDef.color = LineDef.pattern = 0x0L;
- FillDef.type = FILL_NONE;
- FillDef.color = 0x00ffffffL; //use white paper
- FillDef.scale = 1.0;
- FillDef.hatch = 0L;
- cGraphs--; cPages++; bModified = false;
- if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i]) Plots[i]->moveable = 1;
-}
-
-void
-Page::DoPlot(anyOutput *o)
-{
- int i;
- POINT pts[3];
-
- if(!o && !Disp) {
- Disp = NewDispClass(this);
- Disp->SetMenu(MENU_PAGE);
- sprintf(TmpTxt, "Page %d", cPages);
- if(!name) name = strdup(TmpTxt); Disp->Caption(TmpTxt);
- Disp->VPorg.fy = iround(Disp->MenuHeight);
- Disp->VPscale = 0.5;
- Disp->CheckMenu(ToolMode, true);
- OwnDisp = true;
- }
- //the first output class is the display class
- if(!Disp && (!(Disp = o))) return;
- CurrDisp = o ? o : Disp;
- CurrDisp->Erase(CurrDisp->dFillCol = ColBG);
- if(OwnDisp && CurrDisp == Disp)LineDef.color = 0x0L;
- else LineDef.color = FillDef.color;
- CurrDisp->SetLine(&LineDef);
- CurrDisp->SetFill(&FillDef);
- CurrDisp->oRectangle(rDims.left = CurrDisp->co2ix(GRect.Xmin),
- rDims.top = CurrDisp->co2iy(GRect.Ymin), rDims.right = CurrDisp->co2ix(GRect.Xmax),
- rDims.bottom = CurrDisp->co2iy(GRect.Ymax));
- pts[0].x = rDims.left+7; pts[0].y = pts[1].y = rDims.bottom;
- pts[1].x = pts[2].x = rDims.right; pts[2].y = rDims.top +3;
- CurrDisp->oPolyline(pts, 3);
- //do all plots
+ if(!((Plot*)Plots[i])->hidden) {
+ if(x_axis.flags & AXIS_AUTOSCALE) {
+ Bounds.Xmin = ((Plot*)Plots[i])->Bounds.Xmin < Bounds.Xmin ?
+ ((Plot*)Plots[i])->Bounds.Xmin : Bounds.Xmin;
+ Bounds.Xmax = ((Plot*)Plots[i])->Bounds.Xmax > Bounds.Xmax ?
+ ((Plot*)Plots[i])->Bounds.Xmax : Bounds.Xmax;
+ }
+ if(y_axis.flags & AXIS_AUTOSCALE) {
+ Bounds.Ymin = ((Plot*)Plots[i])->Bounds.Ymin < Bounds.Ymin ?
+ ((Plot*)Plots[i])->Bounds.Ymin : Bounds.Ymin;
+ Bounds.Ymax = ((Plot*)Plots[i])->Bounds.Ymax > Bounds.Ymax ?
+ ((Plot*)Plots[i])->Bounds.Ymax : Bounds.Ymax;
+ }
+ }
+ }
+ }
+ if(Bounds.Xmax <= Bounds.Xmin) {
+ Bounds.Xmax = oB.Xmax > oB.Xmin ? oB.Xmax : oB.Xmax + 1.0;
+ Bounds.Xmin = oB.Xmin < oB.Xmax ? oB.Xmin : oB.Xmin - 1.0;
+ }
+ if(Bounds.Ymax <= Bounds.Ymin) {
+ Bounds.Ymax = oB.Ymax > oB.Ymin ? oB.Ymax : oB.Ymax + 1.0;
+ Bounds.Ymin = oB.Ymin < oB.Ymax ? oB.Ymin : oB.Ymin - 1.0;
+ }
+ if(x_axis.flags & AXIS_AUTOSCALE){
+ x_axis.min = Bounds.Xmin; x_axis.max = Bounds.Xmax;
+ NiceAxis(&x_axis, 4);
+ if(x_axis.min <= 0.0 && ((x_axis.flags & 0xf000) == AXIS_LOG ||
+ (x_axis.flags & 0xf000) == AXIS_RECI)) {
+ x_axis.min = base4log(&x_axis, 0);
+ }
+ if(Axes)for(i = 0; i < NumAxes; i++)
+ if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &x_axis, 0L);
+ }
+ if(y_axis.flags & AXIS_AUTOSCALE){
+ y_axis.min = Bounds.Ymin; y_axis.max = Bounds.Ymax;
+ NiceAxis(&y_axis, 4);
+ if(y_axis.min <= 0.0 && ((y_axis.flags & 0xf000) == AXIS_LOG ||
+ (y_axis.flags & 0xf000) == AXIS_RECI)) {
+ y_axis.min = base4log(&y_axis, 1);
+ }
+ if(Axes)for(i = 0; i < NumAxes; i++)
+ if(Axes[i]) Axes[i]->Command(CMD_AUTOSCALE, &y_axis, 0L);
+ }
+ }
+ dirty = false;
+}
+
+void
+Graph::CreateAxes(int templ)
+{
+ AxisDEF tmp_axis;
+ TextDEF label_def, tlbdef;
+ char label_text[500];
+ Label *label;
+ double ts, lb_ydist, lb_xdist, tlb_dist;
+ DWORD ptick, ntick, utick;
+ char xa_desc[50], ya_desc[50];
+
+ if(Axes && NumAxes) return;
+ label_def.ColTxt = defs.Color(COL_AXIS); label_def.ColBg = 0x00ffffffL;
+ label_def.fSize = DefSize(SIZE_TICK_LABELS)*1.2; label_def.RotBL = label_def.RotCHAR = 0.0;
+ label_def.iSize = 0; label_def.Align = TXA_VTOP | TXA_HCENTER;
+ label_def.Mode = TXM_TRANSPARENT; label_def.Style = TXS_NORMAL;
+ label_def.Font = FONT_HELVETICA; label_def.text = label_text;
+ tlbdef.ColTxt = defs.Color(COL_AXIS); tlbdef.ColBg = 0x00ffffffL;
+ tlbdef.RotBL = tlbdef.RotCHAR = 0.0; tlbdef.iSize = 0;
+ tlbdef.fSize = DefSize(SIZE_TICK_LABELS); tlbdef.Align = TXA_VCENTER | TXA_HCENTER;
+ tlbdef.Style = TXS_NORMAL; tlbdef.Mode = TXM_TRANSPARENT;
+ tlbdef.Font = FONT_HELVETICA; tlbdef.text = 0L;
+ ts = DefSize(SIZE_AXIS_TICKS);
+ rlp_strcpy(xa_desc, 50, (char*)"x-axis"); rlp_strcpy(ya_desc, 50, (char*)"y-axis");
+ if(Plots && NumPlots && Plots[0] && Plots[0]->Id >= GO_PLOT && Plots[0]->Id < GO_GRAPH) {
+ if(((Plot*)Plots[0])->x_info) rlp_strcpy(xa_desc, 50,((Plot*)Plots[0])->x_info);
+ if(((Plot*)Plots[0])->y_info) rlp_strcpy(ya_desc, 50,((Plot*)Plots[0])->y_info);
+ }
+ switch (tickstyle & 0x07){
+ case 1: //ticks inside
+ ntick = AXIS_POSTICKS; ptick = AXIS_POSTICKS; utick = AXIS_NEGTICKS;
+ ts *= 0.5;
+ break;
+ case 2: //centered, symetrical
+ ptick = ntick = utick = AXIS_SYMTICKS;
+ ts *= 0.75;
+ break;
+ default: //ticks outside
+ ptick = AXIS_NEGTICKS; ntick = AXIS_NEGTICKS; utick = AXIS_POSTICKS;
+ break;
+ }
+ tlb_dist = NiceValue(ts * 2.0);
+ lb_ydist = NiceValue((ts+DefSize(SIZE_AXIS_TICKS))*2.0);
+ lb_xdist = NiceValue((ts+DefSize(SIZE_AXIS_TICKS))*3.0);
+ switch(templ) {
+ case 0:
+ Axes = (Axis**)calloc(5, sizeof(Axis *));
+ x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
+ x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
+ x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
+ y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fx = y_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;;
+ if((Axes[0] = new Axis(this, data, &x_axis, AXIS_BOTTOM | ptick |
+ AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
+ Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
+ Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
+ rlp_strcpy(label_text, 500, xa_desc);
+ label = new Label(Axes[0], data, (DRect.Xmin+DRect.Xmax)/2.0,
+ GRect.Ymin+DRect.Ymax+DefSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
+ if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VTOP | TXA_HCENTER;
+ Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ if((Axes[1] = new Axis(this, data, &y_axis, AXIS_LEFT | ntick | AXIS_AUTOTICK |
+ AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
+ Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
+ Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
+ rlp_strcpy(label_text, 500, ya_desc);
+ label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
+ label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - DefSize(SIZE_AXIS_TICKS)*6.0,
+ (DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
+ if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
+ Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ label = 0L;
+ memcpy(&tmp_axis, &x_axis, sizeof(AxisDEF));
+ tmp_axis.owner = NULL;
+ tmp_axis.loc[0].fy = tmp_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ if((Axes[2] = new Axis(this, data, &tmp_axis, AXIS_TOP | AXIS_NOTICKS | AXIS_AUTOTICK))){
+ Axes[2]->SetSize(SIZE_LB_YDIST, -lb_ydist);
+ Axes[2]->SetSize(SIZE_TLB_YDIST, -tlb_dist);
+ tlbdef.Align = TXA_VBOTTOM | TXA_HCENTER;
+ Axes[2]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ memcpy(&tmp_axis, &y_axis, sizeof(AxisDEF));
+ tmp_axis.owner = NULL;
+ tmp_axis.loc[0].fx = tmp_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
+ if((Axes[3] = new Axis(this, data, &tmp_axis, AXIS_RIGHT | AXIS_NOTICKS | AXIS_AUTOTICK))){
+ Axes[3]->SetSize(SIZE_LB_XDIST, lb_xdist);
+ Axes[3]->SetSize(SIZE_TLB_XDIST, tlb_dist);
+ tlbdef.Align = TXA_VCENTER | TXA_HLEFT;
+ Axes[3]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ NumAxes = 4;
+ break;
+ case 1:
+ Axes = (Axis**)calloc(7, sizeof(Axis *));
+ if(x_axis.Start >= 0.0f) x_axis.min = x_axis.Start = -x_axis.Step;
+ if(y_axis.Start >= 0.0f) y_axis.min = y_axis.Start = -y_axis.Step;
+ x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
+ x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
+ x_axis.loc[0].fy = x_axis.loc[1].fy = 0.0f;
+ y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
+ y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fx = y_axis.loc[1].fx = 0.0f;
+ if((Axes[0] = new Axis(this, data, &x_axis, ptick | AXIS_Y_DATA |
+ AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
+ Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
+ Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
+ rlp_strcpy(label_text, 500, xa_desc);
+ label_def.Align = TXA_VTOP | TXA_HRIGHT;
+ label = new Label(Axes[0], data, GRect.Xmin + DRect.Xmax - DefSize(SIZE_AXIS_TICKS)*2.0,
+ GRect.Ymin+DRect.Ymax+DefSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
+ if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VTOP | TXA_HCENTER;
+ Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ if((Axes[1] = new Axis(this, data, &y_axis, ntick | AXIS_AUTOTICK | AXIS_X_DATA |
+ AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
+ Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
+ Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
+ rlp_strcpy(label_text, 500, ya_desc);
+ label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HRIGHT;
+ label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - DefSize(SIZE_AXIS_TICKS)*6.0,
+ GRect.Ymin + DRect.Ymin + DefSize(SIZE_AXIS_TICKS)*2.0,
+ &label_def, LB_X_PARENT);
+ if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
+ Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ memcpy(&tmp_axis, &x_axis, sizeof(AxisDEF));
+ tmp_axis.owner = NULL;
+ tmp_axis.loc[0].fy = tmp_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ if(Axes[2] = new Axis(this, data, &tmp_axis, AXIS_TOP | AXIS_NOTICKS | AXIS_AUTOTICK)){
+ Axes[2]->SetSize(SIZE_LB_YDIST, -lb_ydist);
+ Axes[2]->SetSize(SIZE_TLB_YDIST, -tlb_dist);
+ tlbdef.Align = TXA_VBOTTOM | TXA_HCENTER;
+ Axes[2]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ tmp_axis.loc[0].fy = tmp_axis.loc[1].fy = GRect.Ymin + DRect.Ymin;
+ if(Axes[3] = new Axis(this, data, &tmp_axis, AXIS_BOTTOM | AXIS_NOTICKS | AXIS_AUTOTICK)){
+ Axes[3]->SetSize(SIZE_LB_YDIST, lb_xdist);
+ Axes[3]->SetSize(SIZE_TLB_YDIST, tlb_dist);
+ tlbdef.Align = TXA_VTOP | TXA_HCENTER;
+ Axes[3]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ memcpy(&tmp_axis, &y_axis, sizeof(AxisDEF));
+ tmp_axis.owner = NULL;
+ tmp_axis.loc[0].fx = tmp_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;
+ if(Axes[4] = new Axis(this, data, &tmp_axis, AXIS_LEFT | AXIS_NOTICKS | AXIS_AUTOTICK)){
+ Axes[4]->SetSize(SIZE_LB_XDIST, -lb_xdist);
+ Axes[4]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
+ tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
+ Axes[4]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ tmp_axis.loc[0].fx = tmp_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
+ if(Axes[5] = new Axis(this, data, &tmp_axis, AXIS_RIGHT | AXIS_NOTICKS | AXIS_AUTOTICK)){
+ Axes[5]->SetSize(SIZE_LB_XDIST, lb_xdist);
+ Axes[5]->SetSize(SIZE_TLB_XDIST, tlb_dist);
+ tlbdef.Align = TXA_VCENTER | TXA_HLEFT;
+ Axes[5]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ NumAxes = 6;
+ break;
+ case 2:
+ Axes = (Axis**)calloc(3, sizeof(Axis *));
+ x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
+ x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
+ x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
+ y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fx = y_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;
+ if((Axes[0] = new Axis(this, data, &x_axis, AXIS_BOTTOM | ptick |
+ AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
+ Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
+ Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
+ rlp_strcpy(label_text, 500, xa_desc);
+ label = new Label(Axes[0], data, GRect.Xmin + (DRect.Xmin+DRect.Xmax)/2.0f,
+ GRect.Ymin+DRect.Ymax+DefSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
+ if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VTOP | TXA_HCENTER;
+ Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ if((Axes[1] = new Axis(this, data, &y_axis, AXIS_LEFT | ntick | AXIS_AUTOTICK |
+ AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
+ Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
+ Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
+ rlp_strcpy(label_text, 500, ya_desc);
+ label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
+ label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - DefSize(SIZE_AXIS_TICKS)*6.0,
+ GRect.Ymin+(DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
+ if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
+ Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ label = 0L;
+ NumAxes = 2;
+ break;
+ case 3:
+ label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
+ Axes = (Axis**)calloc(3, sizeof(Axis *));
+ x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
+ x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
+ x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymin;
+ y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
+ y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fx = y_axis.loc[1].fx = GRect.Xmin + DRect.Xmin;
+ if((Axes[0] = new Axis(this, data, &x_axis, AXIS_TOP | utick |
+ AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
+ Axes[0]->SetSize(SIZE_LB_YDIST, -lb_ydist);
+ Axes[0]->SetSize(SIZE_TLB_YDIST, -tlb_dist);
+ rlp_strcpy(label_text, 500, xa_desc);
+ label = new Label(Axes[0], data, GRect.Xmin + (DRect.Xmin+DRect.Xmax)/2.0f,
+ GRect.Ymin+DRect.Ymax+DefSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
+ if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VBOTTOM | TXA_HCENTER;
+ Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ if((Axes[1] = new Axis(this, data, &y_axis, AXIS_LEFT | ntick | AXIS_AUTOTICK |
+ AXIS_AUTOSCALE | AXIS_INVERT | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
+ Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
+ Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
+ rlp_strcpy(label_text, 500, ya_desc);
+ label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
+ label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - DefSize(SIZE_AXIS_TICKS)*6.0,
+ GRect.Ymin+(DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
+ if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
+ Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ label = 0L;
+ NumAxes = 2;
+ break;
+ case 4:
+ Axes = (Axis**)calloc(3, sizeof(Axis *));
+ if(x_axis.Start >= 0.0f) x_axis.min = -x_axis.Step;
+ x_axis.loc[0].fx = GRect.Xmin + DRect.Xmin;
+ x_axis.loc[1].fx = GRect.Xmin + DRect.Xmax;
+ x_axis.loc[0].fy = x_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fy = GRect.Ymin + DRect.Ymin;
+ y_axis.loc[1].fy = GRect.Ymin + DRect.Ymax;
+ y_axis.loc[0].fx = y_axis.loc[1].fx = 0.0f;
+ if((Axes[0] = new Axis(this, data, &x_axis, AXIS_BOTTOM | ptick |
+ AXIS_AUTOTICK | AXIS_AUTOSCALE | ((tickstyle & 0x100) ? AXIS_GRIDLINE : 0)))){
+ Axes[0]->SetSize(SIZE_LB_YDIST, lb_ydist);
+ Axes[0]->SetSize(SIZE_TLB_YDIST, tlb_dist);
+ rlp_strcpy(label_text, 500, xa_desc);
+ label = new Label(Axes[0], data, GRect.Xmin + (DRect.Xmin+DRect.Xmax)/2.0f,
+ GRect.Ymin+DRect.Ymax+DefSize(SIZE_AXIS_TICKS)*4.0f, &label_def, LB_Y_PARENT);
+ if(label && Axes[0]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VTOP | TXA_HCENTER;
+ Axes[0]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ if((Axes[1] = new Axis(this, data, &y_axis, ntick | AXIS_AUTOTICK | AXIS_X_DATA |
+ AXIS_AUTOSCALE | ((tickstyle & 0x200) ? AXIS_GRIDLINE : 0)))){
+ Axes[1]->SetSize(SIZE_LB_XDIST, -lb_xdist);
+ Axes[1]->SetSize(SIZE_TLB_XDIST, -tlb_dist);
+ rlp_strcpy(label_text, 500, ya_desc);
+ label_def.RotBL = 90.0; label_def.Align = TXA_VBOTTOM | TXA_HCENTER;
+ label = new Label(Axes[1], data, GRect.Xmin + DRect.Xmin - DefSize(SIZE_AXIS_TICKS)*6.0,
+ GRect.Ymin+(DRect.Ymax+DRect.Ymin)/2.0, &label_def, LB_X_PARENT);
+ if(label && Axes[1]->Command(CMD_DROP_LABEL, (void*)label, 0L)) label = 0L;
+ else if(label) DeleteGO(label);
+ tlbdef.Align = TXA_VCENTER | TXA_HRIGHT;
+ Axes[1]->Command(CMD_TLB_TXTDEF, (void*)&tlbdef, 0L);
+ }
+ label = 0L;
+ NumAxes = 2;
+ break;
+ }
+}
+
+bool
+Graph::DoScale(scaleINFO* sc, anyOutput *o)
+{
+ int i;
+ double x0, y0, z0;
+
+ if(sc->sy.fy > 0.0) {
+ scale = scale > 0.0 ? scale * sc->sy.fy : sc->sy.fy;
+ }
+ else return false;
+ GRect.Xmax = sc->sx.fx + GRect.Xmax* sc->sx.fy;
+ GRect.Xmin = sc->sx.fx + GRect.Xmin * sc->sx.fy;
+ GRect.Ymax = sc->sy.fx + GRect.Ymax * sc->sy.fy;
+ GRect.Ymin = sc->sy.fx + GRect.Ymin * sc->sy.fy;
+ DRect.Xmax *= sc->sx.fy; DRect.Xmin *= sc->sx.fy;
+ DRect.Ymax *= sc->sy.fy; DRect.Ymin *= sc->sy.fy;
+ x0 = sc->sx.fx; y0 = sc->sy.fx; z0= sc->sz.fx;
+ sc->sx.fx = sc->sy.fx = sc->sz.fx = 0.0; sc->sx.fy = sc->sz.fy = sc->sy.fy;
+ if(Axes) for(i = 0; i< NumAxes; i++) if(Axes[i]) Axes[i]->Command(CMD_SCALE, sc, o);
+ if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i]) Plots[i]->Command(CMD_SCALE, sc, o);
+ sc->sx.fx = x0; sc->sy.fx = y0; sc->sz.fx = z0;
+ return true;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Pages are graphic objects containing graphs and drawn objects
+Page::Page(GraphObj *par, DataObj *d):Graph(par, d, 0L)
+{
+ FileIO(INIT_VARS);
+ cGraphs--; cPages++; Id = GO_PAGE; bModified = true;
+}
+
+Page::Page(int src):Graph(src)
+{
+ int i;
+
+ //most of the object is read by Graph::FileIO()
+ ColBG = 0x00e8e8e8L;
+ LineDef.width = 0.0; LineDef.patlength = 1.0;
+ LineDef.color = LineDef.pattern = 0x0L;
+ FillDef.type = FILL_NONE;
+ FillDef.color = 0x00ffffffL; //use white paper
+ FillDef.scale = 1.0;
+ FillDef.hatch = 0L;
+ cGraphs--; cPages++; bModified = false;
+ if(Plots) for(i = 0; i < NumPlots; i++) if(Plots[i]) Plots[i]->moveable = 1;
+}
+
+void
+Page::DoPlot(anyOutput *o)
+{
+ int i;
+ POINT pts[3];
+
+ if(!o && !Disp) {
+ Disp = NewDispClass(this);
+ Disp->SetMenu(MENU_PAGE);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "Page %d", cPages);
+#else
+ i = sprintf(TmpTxt, "Page %d", cPages);
+#endif
+ if(!name && (name = (char*)malloc(i += 2)))rlp_strcpy(name, i, TmpTxt);
+ Disp->Caption(TmpTxt);
+ Disp->VPorg.fy = iround(Disp->MenuHeight);
+ Disp->VPscale = 0.5;
+ Disp->CheckMenu(ToolMode, true);
+ OwnDisp = true;
+ }
+ //the first output class is the display class
+ if(!Disp && (!(Disp = o))) return;
+ CurrDisp = o ? o : Disp;
+ CurrDisp->Erase(CurrDisp->dFillCol = ColBG);
+ if(OwnDisp && CurrDisp == Disp)LineDef.color = 0x0L;
+ else LineDef.color = FillDef.color;
+ CurrDisp->SetLine(&LineDef);
+ CurrDisp->SetFill(&FillDef);
+ CurrDisp->oRectangle(rDims.left = CurrDisp->co2ix(GRect.Xmin),
+ rDims.top = CurrDisp->co2iy(GRect.Ymin), rDims.right = CurrDisp->co2ix(GRect.Xmax),
+ rDims.bottom = CurrDisp->co2iy(GRect.Ymax));
+ pts[0].x = rDims.left+7; pts[0].y = pts[1].y = rDims.bottom;
+ 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(PasteObj) {
ToolMode = TM_PASTE; CurrDisp->MouseCursor(MC_PASTE, false);
- }
-}
-
-bool
-Page::Command(int cmd, void *tmpl, anyOutput *o)
-{
- GraphObj **tmpPlots;
- Graph *g;
-
- switch(cmd) {
- case CMD_MOUSE_EVENT:
- return Graph::Command(cmd, tmpl, o);
- case CMD_REDRAW:
- Disp->StartPage(); DoPlot(Disp); Disp->EndPage();
- return true;
- case CMD_CONFIG:
- return Configure();
- case CMD_DROP_GRAPH:
- if(Disp) {
- if(!(tmpPlots = (GraphObj**)memdup(Plots, (NumPlots+2)*sizeof(GraphObj*), 0)))
- return false;
- Undo.ListGOmoved(Plots, tmpPlots, NumPlots);
- free(Plots); Plots = tmpPlots; Plots[NumPlots] = Plots[NumPlots+1] = 0L;
- Undo.SetGO(this, &Plots[NumPlots], (GraphObj*)tmpl, 0L);
- }
- else if(Plots = (GraphObj**)realloc(Plots, sizeof(GraphObj*) * (NumPlots+2))){
- Plots[NumPlots] = (GraphObj*)tmpl; Plots[NumPlots+1] = 0L;
- }
- else return false;
- if(Plots[NumPlots]){
- Plots[NumPlots]->parent = this;
- Plots[NumPlots]->Command(CMD_SET_DATAOBJ, data, 0L);
- if(Plots[NumPlots]->Id == GO_GRAPH) CurrGraph = (Graph*)Plots[NumPlots];
- Plots[NumPlots]->moveable = 1; //all page items should be freely
- } // moveable by user
- NumPlots++;
- if(CurrDisp) {
- CurrDisp->StartPage(); DoPlot(CurrDisp); CurrDisp->EndPage();
- }
- return true;
- case CMD_NEWGRAPH:
- if((g = new Graph(this, data, Disp)) && g->PropertyDlg() &&
- Command(CMD_DROP_GRAPH, g, o))return true;
- else if(g) DeleteGO(g);
- return false;
- case CMD_SET_DATAOBJ:
- Graph::Command(cmd, tmpl, o);
- Id = GO_PAGE;
- return true;
- default:
- return Graph::Command(cmd, tmpl, o);
- }
-}
+ }
+}
+
+bool
+Page::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ Graph *g;
+
+ switch(cmd) {
+ case CMD_MOUSE_EVENT:
+ return Graph::Command(cmd, tmpl, o);
+ case CMD_REDRAW:
+ Disp->StartPage(); DoPlot(Disp); Disp->EndPage();
+ return true;
+ case CMD_CONFIG:
+ return Configure();
+ case CMD_NEWGRAPH:
+ if((g = new Graph(this, data, Disp)) && g->PropertyDlg() &&
+ Command(CMD_DROP_GRAPH, g, o))return true;
+ else if(g) DeleteGO(g);
+ return false;
+ case CMD_SET_DATAOBJ:
+ Graph::Command(cmd, tmpl, o);
+ Id = GO_PAGE;
+ return true;
+ case CMD_SCALE:
+ return true;
+ default:
+ return Graph::Command(cmd, tmpl, o);
+ }
+}
+
+double
+Page::DefSize(int select)
+{
+ return defs.GetSize(select);
+}
diff --git a/rlplot.h b/rlplot.h
index e38a201..25ac873 100755
--- a/rlplot.h
+++ b/rlplot.h
@@ -1,113 +1,122 @@
-//RLPlot.h, Copyright (c) 2000-2006 R.Lackner
-//
-// This file is part of RLPlot.
-//
-// RLPlot is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// RLPlot is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with RLPlot; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-#define NUM_UNITS 3
-#define TMP_TXT_SIZE 4096
-
-#include <stdio.h>
-#include "Version.h"
-
-#define Swap(a,b) {a^=b;b^=a;a^=b;}
-inline int iround(double a) {return a < 0.0 ?(int)(a-0.499) : (int)(a+0.499);}
-inline int WriteFloatToBuff(char *buff, double val) {return sprintf(buff, " %g", val);}
+//RLPlot.h, Copyright (c) 2000-2006 R.Lackner
+//
+// This file is part of RLPlot.
+//
+// RLPlot is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// RLPlot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RLPlot; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#define NUM_UNITS 3
+#define TMP_TXT_SIZE 4096
+
+#include <stdio.h>
+#include "Version.h"
+
+#define Swap(a,b) {a^=b;b^=a;a^=b;}
+inline int iround(double a) {return a < 0.0 ?(int)(a-0.499) : (int)(a+0.499);}
#define _PI 3.1415926535897932384626433832795028841971693993751
#define _SQRT2 1.4142135623730950488016887242096980785696718753769
-
-#ifdef _WINDOWS
+
+#ifdef _WINDOWS //platform is windows
+#pragma warning( disable : 4996 )
#include <windows.h>
-#define w_char unsigned short
+#if _MSC_VER >= 1400
+#define USE_WIN_SECURE
+#endif
+#define w_char unsigned short
#define _SBINC 1 //scrollbox extra space/line
#define _TXH 4.0 //graph text default size in mm
-
-#else
-#define DWORD unsigned long
-#define w_char unsigned short
+
+#else //platform is *nix
+#include <sys/types.h>
+#define DWORD u_int32_t
+#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;
- long y;
-} POINT;
-
-typedef struct _RECT { // rc
- long left;
- long top;
- long right;
- long bottom;
-} RECT;
-
-#endif //_WINDOWS
-
-enum {SIZE_MINE, SIZE_SYMBOL, SIZE_SYM_LINE, SIZE_DATA_LINE, SIZE_TEXT,
- SIZE_GRECT_TOP, SIZE_GRECT_BOTTOM, SIZE_GRECT_LEFT, SIZE_GRECT_RIGHT,
- SIZE_DRECT_LEFT, SIZE_DRECT_RIGHT, SIZE_DRECT_TOP, SIZE_DRECT_BOTTOM,
- SIZE_DATA_LINE_PAT, SIZE_XPOS, SIZE_XPOS_LAST = SIZE_XPOS+200,
- SIZE_YPOS, SIZE_YPOS_LAST = SIZE_YPOS+200, SIZE_ZPOS,
- SIZE_ZPOS_LAST = SIZE_ZPOS+200, SIZE_BOUNDS_XMIN,
- SIZE_BOUNDS_XMAX, SIZE_BOUNDS_YMIN, SIZE_BOUNDS_YMAX, SIZE_BOUNDS_ZMIN,
- SIZE_BOUNDS_ZMAX, SIZE_BOUNDS_LEFT, SIZE_BAR_BASE,
- SIZE_BOUNDS_RIGHT, SIZE_BOUNDS_TOP, SIZE_BOUNDS_BOTTOM, SIZE_XAXISY,
- SIZE_YAXISX, SIZE_AXIS_LINE, SIZE_PATLENGTH, SIZE_BAR_DEPTH,
- SIZE_AXIS_TICKS, SIZE_TICK_LABELS, SIZE_ERRBAR, SIZE_ERRBAR_LINE,
- SIZE_BAR_LINE, SIZE_BAR, SIZE_XBASE, SIZE_YBASE, SIZE_ZBASE, SIZE_BUBBLE_LINE,
- SIZE_BUBBLE_HATCH_LINE, SIZE_BARMINX, SIZE_BARMINY, SIZE_ARROW_LINE,
- SIZE_ARROW_CAPWIDTH, SIZE_ARROW_CAPLENGTH, SIZE_HAIRLINE, SIZE_WHISKER,
- SIZE_WHISKER_LINE, SIZE_BOX_LINE, SIZE_BOXMINX, SIZE_BOXMINY, SIZE_BOX,
- SIZE_RADIUS1, SIZE_RADIUS2, SIZE_SEGLINE, SIZE_LB_XPOS, SIZE_LB_YPOS,
- SIZE_LB_XDIST, SIZE_LB_YDIST, SIZE_TLB_XDIST, SIZE_TLB_YDIST, SIZE_ANGLE1,
- SIZE_ANGLE2, SIZE_XCENTER, SIZE_YCENTER, SIZE_ZCENTER, SIZE_CELLWIDTH, SIZE_CELLTEXT,
- SIZE_A, SIZE_B, SIZE_MX, SIZE_MY, SIZE_MIN_Z, SIZE_MAX_Z, SIZE_MIN_X, SIZE_MAX_X,
- SIZE_MIN_Y, SIZE_MAX_Y, SIZE_TICK_ANGLE, SIZE_RRECT_RAD, SIZE_XCENT, SIZE_YCENT,
- SIZE_ZCENT, SIZE_DRADIUS, SIZE_CURSORPOS, SIZE_CURSOR_XMIN, SIZE_CURSOR_YMIN,
- SIZE_CURSOR_XMAX, SIZE_CURSOR_YMAX, SIZE_XSTEP, SIZE_LSPC};
-enum {COL_SYM_LINE, COL_SYM_FILL, COL_DATA_LINE, COL_TEXT, COL_BG,
- COL_AXIS, COL_BAR_LINE, COL_BAR_FILL, COL_ERROR_LINE, COL_BUBBLE_LINE,
- COL_BUBBLE_FILLLINE, COL_BUBBLE_FILL, COL_ARROW, COL_WHISKER, COL_BOX_LINE,
- COL_DRECT, COL_GRECT, COL_GRECTLINE, COL_POLYLINE, COL_POLYGON};
-enum {MRK_NONE, MRK_INVERT, MRK_GODRAW, MRK_SSB_DRAW};
-enum {CMD_NONE, CMD_ADDCHAR, CMD_SETFOCUS, CMD_KILLFOCUS, CMD_DELETE,
- CMD_BACKSP, CMD_CURRLEFT, CMD_CURRIGHT, CMD_CURRUP, CMD_CURRDOWN,
- CMD_SHIFTLEFT, CMD_SHIFTRIGHT, CMD_SHIFTUP, CMD_SHIFTDOWN,
- CMD_NEWGRAPH, CMD_DELGRAPH, CMD_DELOBJ, CMD_DROP_PLOT, CMD_DROP_GRAPH, CMD_OPEN,
- CMD_SAVEDATAAS, CMD_ADDROWCOL, CMD_MOUSE_EVENT, CMD_REDRAW, CMD_DOPLOT,
- CMD_LBUP, CMD_ENDDIALOG, CMD_RADIOBUTT, CMD_ADDCHILD, CMD_BAR_TYPE,
- CMD_BAR_FILL, CMD_SET_AXDEF, CMD_SET_DATAOBJ, CMD_SETTEXT, CMD_GETTEXT,
- CMD_SETTEXTDEF, CMD_GETTEXTDEF, CMD_ADDPLOT, CMD_SYM_TYPE, CMD_SYMTEXT,
- CMD_SYMTEXTDEF, CMD_RANGETEXT, CMD_SYM_RANGETEXT, CMD_FOCTXT, CMD_CONTINUE,
- CMD_ERR_TYPE, CMD_ARROW_ORG, CMD_ARROW_TYPE, CMD_FLUSH, CMD_BOX_FILL,
- CMD_TABDLG, CMD_NOTABDLG, CMD_TAB, CMD_SHTAB, CMD_BOX_TYPE, CMD_BUBBLE_TYPE,
- CMD_BUBBLE_ATTRIB, CMD_BUBBLE_FILL, CMD_BUBBLE_LINE, CMD_DL_LINE,
- CMD_DL_TYPE, CMD_SEG_FILL, CMD_SEG_LINE, CMD_SELECT, CMD_MOVE, CMD_CUT,
- CMD_SETSCROLL, CMD_SETHPOS, CMD_SETVPOS, CMD_PG_FILL, CMD_BOUNDS,
- CMD_SHIFT_OUT, CMD_CAN_CLOSE, CMD_RESET_LINE, CMD_SET_TICKSTYLE,
- CMD_GET_GRIDLINE, CMD_SET_GRIDLINE, CMD_SET_GRIDTYPE, CMD_TLB_TXTDEF,
- CMD_DROP_LABEL, CMD_DROP_OBJECT, CMD_PAGEUP, CMD_PAGEDOWN, CMD_AUTOSCALE,
- CMD_MRK_DIRTY, CMD_SETNAME, CMD_TOOLMODE, CMD_DROPFILE, CMD_AXIS, CMD_INIT,
- CMD_GET_CELLDIMS, CMD_SET_CELLDIMS, CMD_TEXTSIZE, CMD_PASTE_TSV, CMD_PASTE_XML,
- CMD_PASTE_SSV, CMD_PASTE_CSV, CMD_COPY_TSV, CMD_COPY_XML, CMD_COPY_SYLK, CMD_QUERY_COPY,
- CMD_MOUSECURSOR, CMD_NEWPAGE, CMD_MINRC, CMD_MAXRC,CMD_SETCHILD, CMD_SYM_FILL,
- CMD_LINEUP, CMD_LINEDOWN, CMD_CONFIG, CMD_FINDTEXT, CMD_MOVE_TOP, CMD_MOVE_UP,
- CMD_MOVE_DOWN, CMD_MOVE_BOTTOM, CMD_UPDATE, CMD_CURRPOS, CMD_POS_FIRST, CMD_POS_LAST,
- CMD_ADDAXIS, CMD_REG_AXISPLOT, CMD_USEAXIS, CMD_SET_GO3D, CMD_UNDO, CMD_DELOBJ_CONT,
- CMD_RMU, CMD_REPL_GO, CMD_UNDO_MOVE, CMD_SAVEPOS, CMD_WHISKER_STYLE, CMD_TICK_TYPE,
+#define _strdup strdup
+#define _open open
+#define _write write
+#define _close close
+#define _lseek lseek
+
+typedef struct tagPOINT { // pt
+ long x;
+ long y;
+} POINT;
+
+typedef struct _RECT { // rc
+ long left;
+ long top;
+ long right;
+ long bottom;
+} RECT;
+
+#endif //_WINDOWS
+
+enum {SIZE_MINE, SIZE_SYMBOL, SIZE_SYM_LINE, SIZE_DATA_LINE, SIZE_TEXT,
+ SIZE_GRECT_TOP, SIZE_GRECT_BOTTOM, SIZE_GRECT_LEFT, SIZE_GRECT_RIGHT,
+ SIZE_DRECT_LEFT, SIZE_DRECT_RIGHT, SIZE_DRECT_TOP, SIZE_DRECT_BOTTOM,
+ SIZE_DATA_LINE_PAT, SIZE_XPOS, SIZE_XPOS_LAST = SIZE_XPOS+200,
+ SIZE_YPOS, SIZE_YPOS_LAST = SIZE_YPOS+200, SIZE_ZPOS,
+ SIZE_ZPOS_LAST = SIZE_ZPOS+200, SIZE_BOUNDS_XMIN,
+ SIZE_BOUNDS_XMAX, SIZE_BOUNDS_YMIN, SIZE_BOUNDS_YMAX, SIZE_BOUNDS_ZMIN,
+ SIZE_BOUNDS_ZMAX, SIZE_BOUNDS_LEFT, SIZE_BAR_BASE,
+ SIZE_BOUNDS_RIGHT, SIZE_BOUNDS_TOP, SIZE_BOUNDS_BOTTOM, SIZE_XAXISY,
+ SIZE_YAXISX, SIZE_AXIS_LINE, SIZE_PATLENGTH, SIZE_BAR_DEPTH,
+ SIZE_AXIS_TICKS, SIZE_TICK_LABELS, SIZE_ERRBAR, SIZE_ERRBAR_LINE,
+ SIZE_BAR_LINE, SIZE_BAR, SIZE_XBASE, SIZE_YBASE, SIZE_ZBASE, SIZE_BUBBLE_LINE,
+ SIZE_BUBBLE_HATCH_LINE, SIZE_BARMINX, SIZE_BARMINY, SIZE_ARROW_LINE,
+ SIZE_ARROW_CAPWIDTH, SIZE_ARROW_CAPLENGTH, SIZE_HAIRLINE, SIZE_WHISKER,
+ SIZE_WHISKER_LINE, SIZE_BOX_LINE, SIZE_BOXMINX, SIZE_BOXMINY, SIZE_BOX,
+ SIZE_RADIUS1, SIZE_RADIUS2, SIZE_SEGLINE, SIZE_LB_XPOS, SIZE_LB_YPOS,
+ SIZE_LB_XDIST, SIZE_LB_YDIST, SIZE_TLB_XDIST, SIZE_TLB_YDIST, SIZE_ANGLE1,
+ SIZE_ANGLE2, SIZE_XCENTER, SIZE_YCENTER, SIZE_ZCENTER, SIZE_CELLWIDTH, SIZE_CELLTEXT,
+ SIZE_A, SIZE_B, SIZE_MX, SIZE_MY, SIZE_MIN_Z, SIZE_MAX_Z, SIZE_MIN_X, SIZE_MAX_X,
+ SIZE_MIN_Y, SIZE_MAX_Y, SIZE_TICK_ANGLE, SIZE_RRECT_RAD, SIZE_XCENT, SIZE_YCENT,
+ SIZE_ZCENT, SIZE_DRADIUS, SIZE_CURSORPOS, SIZE_CURSOR_XMIN, SIZE_CURSOR_YMIN,
+ SIZE_CURSOR_XMAX, SIZE_CURSOR_YMAX, SIZE_XSTEP, SIZE_LSPC};
+enum {COL_SYM_LINE, COL_SYM_FILL, COL_DATA_LINE, COL_TEXT, COL_BG,
+ COL_AXIS, COL_BAR_LINE, COL_BAR_FILL, COL_ERROR_LINE, COL_BUBBLE_LINE,
+ COL_BUBBLE_FILLLINE, COL_BUBBLE_FILL, COL_ARROW, COL_WHISKER, COL_BOX_LINE,
+ COL_DRECT, COL_GRECT, COL_GRECTLINE, COL_POLYLINE, COL_POLYGON};
+enum {MRK_NONE, MRK_INVERT, MRK_GODRAW, MRK_SSB_DRAW};
+enum {CMD_NONE, CMD_ADDCHAR, CMD_SETFOCUS, CMD_KILLFOCUS, CMD_DELETE,
+ CMD_BACKSP, CMD_CURRLEFT, CMD_CURRIGHT, CMD_CURRUP, CMD_CURRDOWN,
+ CMD_SHIFTLEFT, CMD_SHIFTRIGHT, CMD_SHIFTUP, CMD_SHIFTDOWN,
+ CMD_NEWGRAPH, CMD_DELGRAPH, CMD_DELOBJ, CMD_DROP_PLOT, CMD_DROP_GRAPH, CMD_OPEN,
+ CMD_SAVEDATAAS, CMD_ADDROWCOL, CMD_MOUSE_EVENT, CMD_REDRAW, CMD_DOPLOT,
+ CMD_LBUP, CMD_ENDDIALOG, CMD_RADIOBUTT, CMD_ADDCHILD, CMD_BAR_TYPE,
+ CMD_BAR_FILL, CMD_SET_AXDEF, CMD_SET_DATAOBJ, CMD_SETTEXT, CMD_GETTEXT,
+ CMD_SETTEXTDEF, CMD_GETTEXTDEF, CMD_ADDPLOT, CMD_SYM_TYPE, CMD_SYMTEXT,
+ CMD_SYMTEXTDEF, CMD_RANGETEXT, CMD_SYM_RANGETEXT, CMD_FOCTXT, CMD_CONTINUE,
+ CMD_ERR_TYPE, CMD_ARROW_ORG, CMD_ARROW_TYPE, CMD_FLUSH, CMD_BOX_FILL,
+ CMD_TABDLG, CMD_NOTABDLG, CMD_TAB, CMD_SHTAB, CMD_BOX_TYPE, CMD_BUBBLE_TYPE,
+ CMD_BUBBLE_ATTRIB, CMD_BUBBLE_FILL, CMD_BUBBLE_LINE, CMD_DL_LINE,
+ CMD_DL_TYPE, CMD_SEG_FILL, CMD_SEG_LINE, CMD_SELECT, CMD_MOVE, CMD_CUT,
+ CMD_SETSCROLL, CMD_SETHPOS, CMD_SETVPOS, CMD_PG_FILL, CMD_BOUNDS,
+ CMD_SHIFT_OUT, CMD_CAN_CLOSE, CMD_RESET_LINE, CMD_SET_TICKSTYLE,
+ CMD_GET_GRIDLINE, CMD_SET_GRIDLINE, CMD_SET_GRIDTYPE, CMD_TLB_TXTDEF,
+ CMD_DROP_LABEL, CMD_DROP_OBJECT, CMD_PAGEUP, CMD_PAGEDOWN, CMD_AUTOSCALE,
+ CMD_MRK_DIRTY, CMD_SETNAME, CMD_TOOLMODE, CMD_DROPFILE, CMD_AXIS, CMD_INIT,
+ CMD_GET_CELLDIMS, CMD_SET_CELLDIMS, CMD_TEXTSIZE, CMD_PASTE_TSV, CMD_PASTE_XML,
+ CMD_PASTE_SSV, CMD_PASTE_CSV, CMD_COPY_TSV, CMD_COPY_XML, CMD_COPY_SYLK, CMD_QUERY_COPY,
+ CMD_MOUSECURSOR, CMD_NEWPAGE, CMD_MINRC, CMD_MAXRC,CMD_SETCHILD, CMD_SYM_FILL,
+ CMD_LINEUP, CMD_LINEDOWN, CMD_CONFIG, CMD_FINDTEXT, CMD_MOVE_TOP, CMD_MOVE_UP,
+ CMD_MOVE_DOWN, CMD_MOVE_BOTTOM, CMD_UPDATE, CMD_CURRPOS, CMD_POS_FIRST, CMD_POS_LAST,
+ CMD_ADDAXIS, CMD_REG_AXISPLOT, CMD_USEAXIS, CMD_SET_GO3D, CMD_UNDO, CMD_DELOBJ_CONT,
+ CMD_RMU, CMD_REPL_GO, CMD_UNDO_MOVE, CMD_SAVEPOS, CMD_WHISKER_STYLE, CMD_TICK_TYPE,
CMD_ZOOM, CMD_CLIP, CMD_STARTLINE, CMD_ADDTOLINE, CMD_REQ_POINT, CMD_DRAW_LATER,
CMD_SEG_MOVEABLE, CMD_ARROW_ORG3D, CMD_MUTATE, CMD_PRINT, CMD_UPDHISTORY, CMD_ALLTEXT,
CMD_SET_LINE, CMD_SAVE_SYMBOLS, CMD_SAVE_TICKS, CMD_SAVE_BARS, CMD_SAVE_BARS_CONT,
@@ -116,202 +125,207 @@ enum {CMD_NONE, CMD_ADDCHAR, CMD_SETFOCUS, CMD_KILLFOCUS, CMD_DELETE,
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_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};
-//types of graphic objects: stored in Id and used for proper destruction of objects
-// and retrieving information.
-enum {GO_UNKNOWN, GO_AXIS, GO_TICK, GO_GRIDLINE, GO_SYMBOL, GO_BUBBLE, GO_BAR,
- GO_ERRBAR, GO_ARROW, GO_BOX, GO_LABEL, GO_MLABEL, GO_WHISKER, GO_DROPLINE,
- GO_DATALINE, GO_DATAPOLYGON, GO_REGLINE, GO_SDELLIPSE, GO_SEGMENT,
- GO_POLYLINE, GO_POLYGON, GO_RECTANGLE, GO_ELLIPSE, GO_ROUNDREC,
- GO_DRAGHANDLE, GO_DRAGRECT, GO_DRAG3D, GO_FRAMERECT, GO_SPHERE, GO_SVGOPTIONS,
- GO_PLANE, GO_BRICK, GO_LINESEG, GO_LINE3D, GO_GRIDLINE3D, GO_GRIDRADIAL,
+ CMD_SHPGDOWN, CMD_ERRDESC, CMD_SAVEDATA, CMD_GETMARK, CMD_PASTE_OBJ, CMD_COL_MOUSE,
+ CMD_MARKOBJ, CMD_SCALE};
+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};
+//types of graphic objects: stored in Id and used for proper destruction of objects
+// and retrieving information.
+enum {GO_UNKNOWN, GO_AXIS, GO_TICK, GO_GRIDLINE, GO_SYMBOL, GO_BUBBLE, GO_BAR,
+ GO_ERRBAR, GO_ARROW, GO_BOX, GO_LABEL, GO_MLABEL, GO_WHISKER, GO_DROPLINE,
+ GO_DATALINE, GO_DATAPOLYGON, GO_REGLINE, GO_SDELLIPSE, GO_SEGMENT,
+ GO_POLYLINE, GO_POLYGON, GO_RECTANGLE, GO_ELLIPSE, GO_ROUNDREC,
+ 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_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_OBJTREE, GO_BEZIER, GO_TEXTFRAME,
+ 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_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,
+ 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,
- 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,
+ 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_PASTE=0x200};
-enum {MC_LAST, MC_ARROW, MC_CROSS, MC_TEXT, MC_WAIT, MC_MOVE, MC_NORTH,
+ 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_PASTE, MC_DRAWPEN, MC_DRAWREC,
- MC_DRAWRREC, MC_DRAWELLY};
-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};
-enum {GT_UNKNOWN, GT_STANDARD, GT_CIRCCHART, GT_POLARPLOT, GT_3D};
-enum {ICO_NONE, ICO_INFO, ICO_ERROR, ICO_RLPLOT, ICO_QT};
-enum {FF_UNKNOWN, FF_CSV, FF_TSV, FF_XML, FF_SYLK, FF_RLP, FF_SVG, FF_EPS,
- FF_WMF, FF_RLW, FF_SSV};
-enum {LB_X_DATA = 0x01, LB_X_PARENT = 0x02, LB_Y_DATA = 0x10, LB_Y_PARENT = 0x20};
-enum {BUBBLE_CIRCLE = 0x000, BUBBLE_SQUARE = 0x001, BUBBLE_UPTRIA = 0x002,
- BUBBLE_DOWNTRIA = 0x003, BUBBLE_UNITS = 0x000, BUBBLE_XAXIS = 0x010,
- BUBBLE_YAXIS = 0x020, BUBBLE_DIAMET = 0x000, BUBBLE_CIRCUM = 0x100,
- BUBBLE_AREA = 0x200};
-enum {DH_UNKNOWN, DH_12, DH_22, DH_19, DH_29, DH_39, DH_49, DH_59, DH_69, DH_79,
- DH_89, DH_99, DH_18, DH_28, DH_38, DH_48, DH_58, DH_68, DH_78, DH_88, DH_DATA};
+ MC_DRAWRREC, MC_DRAWELLY};
+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};
+enum {GT_UNKNOWN, GT_STANDARD, GT_CIRCCHART, GT_POLARPLOT, GT_3D};
+enum {ICO_NONE, ICO_INFO, ICO_ERROR, ICO_RLPLOT, ICO_QT};
+enum {FF_UNKNOWN, FF_CSV, FF_TSV, FF_XML, FF_SYLK, FF_RLP, FF_SVG, FF_EPS,
+ FF_WMF, FF_RLW, FF_SSV};
+enum {LB_X_DATA = 0x01, LB_X_PARENT = 0x02, LB_Y_DATA = 0x10, LB_Y_PARENT = 0x20};
+enum {BUBBLE_CIRCLE = 0x000, BUBBLE_SQUARE = 0x001, BUBBLE_UPTRIA = 0x002,
+ BUBBLE_DOWNTRIA = 0x003, BUBBLE_UNITS = 0x000, BUBBLE_XAXIS = 0x010,
+ BUBBLE_YAXIS = 0x020, BUBBLE_DIAMET = 0x000, BUBBLE_CIRCUM = 0x100,
+ BUBBLE_AREA = 0x200};
+enum {DH_UNKNOWN, DH_12, DH_22, DH_19, DH_29, DH_39, DH_49, DH_59, DH_69, DH_79,
+ DH_89, DH_99, DH_18, DH_28, DH_38, DH_48, DH_58, DH_68, DH_78, DH_88, DH_DATA};
enum {FE_NONE = 0x1000, FE_PARENT, FE_PLOT, FE_FLUSH, FE_DELOBJ, FE_REPLGO, FE_MUTATE};
-
-//drop line styles
-#define DL_LEFT 0x001
-#define DL_RIGHT 0x002
-#define DL_YAXIS 0x004
-#define DL_TOP 0x010
-#define DL_BOTTOM 0x020
-#define DL_XAXIS 0x040
-#define DL_CIRCULAR 0x100
-
-typedef struct {
- int num;
- char* display;
- float convert; //multiply to get mm
- }tag_Units;
-
-typedef struct {
- int x, y, z;
- }POINT3D;
-
-typedef struct {
- double Xmin;
- double Ymax;
- double Xmax;
- double Ymin;
- }fRECT;
-
-typedef struct {
- double fx;
- double fy;
- double fz;
- }fPOINT3D;
-
-typedef struct {
- double fx;
- double fy;
- }lfPOINT;
-
-typedef struct {
- double finc, fp;
- }RunLinePat; //used for line patterns
-
-typedef struct {
- double width, patlength;
- DWORD color, pattern;
- }LineDEF;
-
-typedef struct {
- int type; //pattern
- DWORD color;
- double scale;
- LineDEF *hatch;
- DWORD color2;
- }FillDEF;
-
-typedef struct {
- lfPOINT org; //zoom origin
- double scale; //zoom factor
- }ZoomDEF;
-
-// Axis definitions are stored in the following structure
-// not to be confused with the Axis class grapic object
-// bits stored in flags havethe following meaning
-#define AXIS_NOTICKS 0x0 // no ticks at all
-#define AXIS_POSTICKS 0x1 // positive direction of ticks
-#define AXIS_NEGTICKS 0x2 // negative direction
-#define AXIS_SYMTICKS 0x3 // ticks are symmetrical
-#define AXIS_GRIDLINE 0x4 // ticks control a gridline
-#define AXIS_MINORTICK 0x8 // its a small tick only
-#define AXIS_USER 0x00 // axis placement by user
-#define AXIS_LEFT 0x10 // left of plot
-#define AXIS_RIGHT 0x20 // right -"-
-#define AXIS_TOP 0x30 // top -"-
-#define AXIS_BOTTOM 0x40 // bottom -"-
-#define AXIS_AUTOSCALE 0x80 // rescale upon editing
-#define AXIS_INVERT 0x100 // axis top->bottom, right to left
-#define AXIS_AUTOTICK 0x200 // select tick s automatically
-#define AXIS_DEFRECT 0x400 // use axis to define drawing rectangle
-#define AXIS_LINEAR 0x0000 // transforms ...
-#define AXIS_LOG 0x1000
-#define AXIS_RECI 0x2000
-#define AXIS_SQR 0x3000
-#define AXIS_X_DATA 0x10000 // loc.x is data coordinates
-#define AXIS_Y_DATA 0x20000 // loc.y is data coordinates
-#define AXIS_Z_DATA 0x40000 // loc.z is data coordinates
-#define AXIS_ANGULAR 0x100000 // angular (circular) axis
-#define AXIS_RADIAL 0x200000 // radial axis
-#define AXIS_3D 0x400000 // three dimensional axis
-
-typedef struct {
- void *owner; //owners are usually graph, output or axis classes
- DWORD flags;
- double min, max;
- fPOINT3D loc[2]; //placement of axis coordinates
- double Start, Step; //used for linear axis
- lfPOINT Center; //of polar plot
- double Radius; // -"-
- int nBreaks; //axis break ...
- lfPOINT *breaks;
- }AxisDEF;
-
-//Attributes for text properties
-//Text fonts
-enum {FONT_HELVETICA, FONT_TIMES, FONT_COURIER, FONT_GREEK};
-//Text styles
-#define TXA_VTOP 0
-#define TXA_VCENTER 4
-#define TXA_VBOTTOM 8
-#define TXA_HLEFT 0
-#define TXA_HCENTER 1
-#define TXA_HRIGHT 2
-#define TXM_OPAQUE 0
-#define TXM_TRANSPARENT 1
-#define TXS_NORMAL 0
-#define TXS_ITALIC 1
-#define TXS_BOLD 2
+
+//drop line styles
+#define DL_LEFT 0x001
+#define DL_RIGHT 0x002
+#define DL_YAXIS 0x004
+#define DL_TOP 0x010
+#define DL_BOTTOM 0x020
+#define DL_XAXIS 0x040
+#define DL_CIRCULAR 0x100
+
+typedef struct {
+ int num;
+ char* display;
+ float convert; //multiply to get mm
+ }tag_Units;
+
+typedef struct {
+ int x, y, z;
+ }POINT3D;
+
+typedef struct {
+ double Xmin;
+ double Ymax;
+ double Xmax;
+ double Ymin;
+ }fRECT;
+
+typedef struct {
+ double fx;
+ double fy;
+ double fz;
+ }fPOINT3D;
+
+typedef struct {
+ double fx;
+ double fy;
+ }lfPOINT;
+
+typedef struct {
+ lfPOINT sx, sy, sz;
+ }scaleINFO;
+
+typedef struct {
+ double finc, fp;
+ }RunLinePat; //used for line patterns
+
+typedef struct {
+ double width, patlength;
+ DWORD color, pattern;
+ }LineDEF;
+
+typedef struct {
+ int type; //pattern
+ DWORD color;
+ double scale;
+ LineDEF *hatch;
+ DWORD color2;
+ }FillDEF;
+
+typedef struct {
+ lfPOINT org; //zoom origin
+ double scale; //zoom factor
+ }ZoomDEF;
+
+// Axis definitions are stored in the following structure
+// not to be confused with the Axis class grapic object
+// bits stored in flags havethe following meaning
+#define AXIS_NOTICKS 0x0 // no ticks at all
+#define AXIS_POSTICKS 0x1 // positive direction of ticks
+#define AXIS_NEGTICKS 0x2 // negative direction
+#define AXIS_SYMTICKS 0x3 // ticks are symmetrical
+#define AXIS_GRIDLINE 0x4 // ticks control a gridline
+#define AXIS_MINORTICK 0x8 // its a small tick only
+#define AXIS_USER 0x00 // axis placement by user
+#define AXIS_LEFT 0x10 // left of plot
+#define AXIS_RIGHT 0x20 // right -"-
+#define AXIS_TOP 0x30 // top -"-
+#define AXIS_BOTTOM 0x40 // bottom -"-
+#define AXIS_AUTOSCALE 0x80 // rescale upon editing
+#define AXIS_INVERT 0x100 // axis top->bottom, right to left
+#define AXIS_AUTOTICK 0x200 // select tick s automatically
+#define AXIS_DEFRECT 0x400 // use axis to define drawing rectangle
+#define AXIS_LINEAR 0x0000 // transforms ...
+#define AXIS_LOG 0x1000
+#define AXIS_RECI 0x2000
+#define AXIS_SQR 0x3000
+#define AXIS_X_DATA 0x10000 // loc.x is data coordinates
+#define AXIS_Y_DATA 0x20000 // loc.y is data coordinates
+#define AXIS_Z_DATA 0x40000 // loc.z is data coordinates
+#define AXIS_ANGULAR 0x100000 // angular (circular) axis
+#define AXIS_RADIAL 0x200000 // radial axis
+#define AXIS_3D 0x400000 // three dimensional axis
+
+typedef struct {
+ void *owner; //owners are usually graph, output or axis classes
+ DWORD flags;
+ double min, max;
+ fPOINT3D loc[2]; //placement of axis coordinates
+ double Start, Step; //used for linear axis
+ lfPOINT Center; //of polar plot
+ double Radius; // -"-
+ int nBreaks; //axis break ...
+ lfPOINT *breaks;
+ }AxisDEF;
+
+//Attributes for text properties
+//Text fonts
+enum {FONT_HELVETICA, FONT_TIMES, FONT_COURIER, FONT_GREEK};
+//Text styles
+#define TXA_VTOP 0
+#define TXA_VCENTER 4
+#define TXA_VBOTTOM 8
+#define TXA_HLEFT 0
+#define TXA_HCENTER 1
+#define TXA_HRIGHT 2
+#define TXM_OPAQUE 0
+#define TXM_TRANSPARENT 1
+#define TXS_NORMAL 0
+#define TXS_ITALIC 1
+#define TXS_BOLD 2
#define TXS_UNDERLINE 4
#define TXS_SUPER 8
-#define TXS_SUB 16
-typedef struct {
- DWORD ColTxt, ColBg; //colors ..
- double fSize; //Text size in units
- double RotBL, RotCHAR; //Rotation in degrees
- int iSize; //Text size is given in iSize as pix
- int Align, Mode, Style; //Text Alignement 0 1 2
- // 4 5 6
- // 8 9 10
- //Mode 0 = opaque, 1 = transparent
- int Font;
- char *text;
- }TextDEF;
-
-// Store mouse events in the following structure
-// Action defines the type of event:
-enum {MOUSE_LBDOWN, MOUSE_LBUP, MOUSE_LBDOUBLECLICK, MOUSE_MBDOWN, MOUSE_MBUP,
- MOUSE_MBDOUBLECLICK, MOUSE_RBDOWN, MOUSE_RBUP, MOUSE_RBDOUBLECLICK,
- MOUSE_MOVE};
-typedef struct {
- unsigned short StateFlags; // 1 Mouse left button down
- // 2 middle button down
- // 4 right button down
- // 8 shift pressed
- // 16 control pressed
- unsigned short Action;
- int x, y;
+#define TXS_SUB 16
+typedef struct {
+ DWORD ColTxt, ColBg; //colors ..
+ double fSize; //Text size in units
+ double RotBL, RotCHAR; //Rotation in degrees
+ int iSize; //Text size is given in iSize as pix
+ int Align, Mode, Style; //Text Alignement 0 1 2
+ // 4 5 6
+ // 8 9 10
+ //Mode 0 = opaque, 1 = transparent
+ int Font;
+ char *text;
+ }TextDEF;
+
+// Store mouse events in the following structure
+// Action defines the type of event:
+enum {MOUSE_LBDOWN, MOUSE_LBUP, MOUSE_LBDOUBLECLICK, MOUSE_MBDOWN, MOUSE_MBUP,
+ MOUSE_MBDOUBLECLICK, MOUSE_RBDOWN, MOUSE_RBUP, MOUSE_RBDOUBLECLICK,
+ MOUSE_MOVE};
+typedef struct {
+ unsigned short StateFlags; // 1 Mouse left button down
+ // 2 middle button down
+ // 4 right button down
+ // 8 shift pressed
+ // 16 control pressed
+ unsigned short Action;
+ int x, y;
} MouseEvent;
//use this structure if type of data is not known
@@ -319,167 +333,202 @@ typedef struct {
int type;
double value;
char *text;
- } anyResult;
-
-//the AccRange class allows to access data objects with a 'a1:b1' style
-class AccRange{
-public:
- AccRange(char *asc);
- ~AccRange();
- int CountItems();
- bool GetFirst(int *x, int *y);
+ } anyResult;
+
+//the AccRange class allows to access data objects with a 'a1:b1' style
+class AccRange{
+public:
+ AccRange(char *asc);
+ ~AccRange();
+ int CountItems();
+ bool GetFirst(int *x, int *y);
bool GetNext(int *x, int *y);
bool NextRow(int *y);
- bool NextCol(int *x);
- bool IsInRange(int x, int y);
- bool BoundRec(RECT *rec);
-
-private:
- char *txt;
- int x1, y1, x2, y2, cx, cy, curridx;
-
- bool Reset();
- bool Parse(int start);
-};
-
-class anyOutput{
-public:
- int units; //use units mm, inch ...
- int MrkMode; //existing mark on screen
- void *MrkRect; //pointer to e.g. the marked rectangle
- fRECT Box1; //User drawing rectangle
- lfPOINT Box1z; // add 3D to Box1
- RECT DeskRect; //this is maximum size Rectangle
- double ddx, ddy, ddz; //convert to device coordinates
- double hres, vres; //resolution in dpi
- double LineWidth; //line width in units
- int iLine; //current width of line in pixels
- DWORD dLineCol; //current color of line;
- DWORD dBgCol; //color of background
- DWORD dFillCol, dFillCol2;
- DWORD dPattern; //current line bit-pattern
- TextDEF TxtSet; //store current text settings here
- RunLinePat RLP; //continuous setings of pattern line
- AxisDEF xAxis, yAxis, zAxis; //axis and transform definitions
- lfPOINT VPorg; //zoom origin
- double VPscale; //zoom factor
- int MenuHeight; //ofset due to pull down menus
- int cCursor; //mouse coursor identifier
- double rotM[3][3]; //rotation matrix for 3D
- fPOINT3D rotC; //rotation center
- bool hasHistMenu; //File History List
- int HistMenuSize; // -"-
- lfPOINT light_source; //angles for shading
+ bool NextCol(int *x);
+ bool IsInRange(int x, int y);
+ bool BoundRec(RECT *rec);
+ char *RangeDesc(void *d, int style); //d points to a DataObj class
+
+private:
+ char *txt;
+ int x1, y1, x2, y2, cx, cy, curridx;
+
+ bool Reset();
+ bool Parse(int start);
+};
+
+class Triangle {
+public:
+ Triangle *next;
+ fPOINT3D pt[4];
+
+ void SetRect();
+ bool TestVertex(double x, double y);
+
+private:
+ double cx, cy, r2; //circumcircle
+ fRECT rc; //bounding rectangle
+ lfPOINT ld[3]; //line eqations
+};
+
+class Triangulate {
+public:
+ Triangle *trl;
+
+ Triangulate(Triangle *t_list);
+ bool AddEdge(fPOINT3D *p1, fPOINT3D *p2);
+ bool AddVertex(fPOINT3D *v);
+
+private:
+ typedef struct edge {
+ edge *next;
+ fPOINT3D p1, p2;
+ };
+ edge *edges;
+};
+
+class anyOutput{
+public:
+ int units; //use units mm, inch ...
+ int MrkMode; //existing mark on screen
+ void *MrkRect; //pointer to e.g. the marked rectangle
+ fRECT Box1; //User drawing rectangle
+ lfPOINT Box1z; // add 3D to Box1
+ RECT DeskRect; //this is maximum size Rectangle
+ double ddx, ddy, ddz; //convert to device coordinates
+ double hres, vres; //resolution in dpi
+ double LineWidth; //line width in units
+ int iLine; //current width of line in pixels
+ DWORD dLineCol; //current color of line;
+ DWORD dBgCol; //color of background
+ DWORD dFillCol, dFillCol2;
+ DWORD dPattern; //current line bit-pattern
+ TextDEF TxtSet; //store current text settings here
+ RunLinePat RLP; //continuous setings of pattern line
+ AxisDEF xAxis, yAxis, zAxis; //axis and transform definitions
+ lfPOINT VPorg; //zoom origin
+ double VPscale; //zoom factor
+ int MenuHeight; //ofset due to pull down menus
+ int cCursor; //mouse coursor identifier
+ double rotM[3][3]; //rotation matrix for 3D
+ fPOINT3D rotC; //rotation center
+ bool hasHistMenu; //File History List
+ int HistMenuSize; // -"-
+ lfPOINT light_source; //angles for shading
double light_vec[3][3]; // -"-
- double disp_x, disp_y; //displacement on page
-
- anyOutput();
- void SetRect(fRECT rec, int units, AxisDEF *x_ax, AxisDEF *y_ax);
- void SetSpace(fPOINT3D*,fPOINT3D*,int,double*,fPOINT3D*,AxisDEF*,AxisDEF*,AxisDEF*);
- void LightSource(double x, double y);
- DWORD VecColor(double *plane_vec, DWORD col1, DWORD col2);
- bool GetSize(RECT *rc);
- virtual bool ActualSize(RECT *rc) {return GetSize(rc);};
- double fx2fix(double x);
- int fx2ix(double x){return (int)(0.5 + fx2fix(x));};
- double fy2fiy(double y);
- int fy2iy(double y){return (int)(0.5 + fy2fiy(y));};
- bool fp2fip(lfPOINT *fdp, lfPOINT *fip);
- bool fvec2ivec(fPOINT3D *v, fPOINT3D *iv);
- bool cvec2ivec(fPOINT3D *v, fPOINT3D *iv);
- bool uvec2ivec(fPOINT3D *v, fPOINT3D *iv);
- double un2fix(double x);
- int un2ix(double x) {return (int)(0.5 + un2fix(x));};
- int co2ix(double x) {return un2ix(x) + iround(VPorg.fx);};
- double co2fix(double x) {return un2fix(x) + VPorg.fx;};
- double un2fiy(double y);
- int un2iy(double y) {return (int)(0.5 + un2fiy(y));};
- int co2iy(double y) {return un2iy(y) + iround(VPorg.fy);};
- double co2fiy(double y) {return un2fiy(y) + VPorg.fy;};
- double un2fiz(double z);
- double fz2fiz(double z);
- double fix2un(double fix);
- double fiy2un(double fiy);
- virtual bool SetLine(LineDEF *lDef){return false;};
+ double disp_x, disp_y; //displacement on page
+
+ anyOutput();
+ void SetRect(fRECT rec, int units, AxisDEF *x_ax, AxisDEF *y_ax);
+ void SetSpace(fPOINT3D*,fPOINT3D*,int,double*,fPOINT3D*,AxisDEF*,AxisDEF*,AxisDEF*);
+ void LightSource(double x, double y);
+ DWORD VecColor(double *plane_vec, DWORD col1, DWORD col2);
+ bool GetSize(RECT *rc);
+ virtual bool ActualSize(RECT *rc) {return GetSize(rc);};
+ double fx2fix(double x);
+ int fx2ix(double x){return (int)(0.5 + fx2fix(x));};
+ double fy2fiy(double y);
+ int fy2iy(double y){return (int)(0.5 + fy2fiy(y));};
+ bool fp2fip(lfPOINT *fdp, lfPOINT *fip);
+ bool fvec2ivec(fPOINT3D *v, fPOINT3D *iv);
+ bool cvec2ivec(fPOINT3D *v, fPOINT3D *iv);
+ bool uvec2ivec(fPOINT3D *v, fPOINT3D *iv);
+ double un2fix(double x);
+ int un2ix(double x) {return (int)(0.5 + un2fix(x));};
+ int co2ix(double x) {return un2ix(x) + iround(VPorg.fx);};
+ double co2fix(double x) {return un2fix(x) + VPorg.fx;};
+ double un2fiy(double y);
+ int un2iy(double y) {return (int)(0.5 + un2fiy(y));};
+ int co2iy(double y) {return un2iy(y) + iround(VPorg.fy);};
+ double co2fiy(double y) {return un2fiy(y) + VPorg.fy;};
+ double un2fiz(double z);
+ double fz2fiz(double z);
+ double fix2un(double fix);
+ double fiy2un(double fiy);
+ virtual bool SetLine(LineDEF *lDef){return false;};
bool GetLine(LineDEF *lDef);
- virtual void Focus() {return;};
- virtual void Caption(char *txt){return;};
- virtual void MouseCursor(int cid, bool force){return;};
- virtual bool SetScroll(bool, int, int, int, int){return false;};
- virtual bool SetFill(FillDEF *fill){return false;};
- virtual bool SetTextSpec(TextDEF *set);
- virtual bool Erase(DWORD Color){return false;};
- virtual bool StartPage(){return false;};
- virtual bool EndPage(){return false;};
- virtual bool Eject() {return false;}; //printers only
- virtual bool UpdateRect(RECT *rc, bool invert){return false;};
- virtual bool CopyBitmap(int x, int y, anyOutput* src, int sx, int sy,
- int sw, int sh, bool invert){return false;};
- virtual void ShowBitmap(int x, int y, anyOutput* src){return;};
- bool ShowMark(void *rc, int Mode);
- bool HideMark();
- int CalcCursorPos(char *txt, POINT p, POINT *fit);
- bool TextCursor(char *txt, POINT p, POINT *fit, int *pos, int disp);
- bool PatLine(POINT p1, POINT p2);
- virtual void ShowLine(POINT * pts, int cp, DWORD color) {return;};
- virtual void ShowEllipse(POINT p1, POINT p2, DWORD color){return;};
- virtual bool SetMenu(int type){return false;};
- virtual void CheckMenu(int mid, bool check){return;};
- virtual void FileHistory(){return;};
- virtual bool oGetPix(int x, int y, DWORD *col){return false;};
- virtual bool oDrawIcon(int type, int x, int y) {return false;};
- virtual bool oGetTextExtent(char *text, int cb, int *width, int *height);
- virtual bool oCircle(int x1, int y1, int x2, int y2, char *nam = 0L){return false;};
- virtual bool oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam = 0L);
- virtual bool oPolyline(POINT * pts, int cp, char *nam = 0L){return false;};
- virtual bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L){return false;};
- virtual bool oSolidLine(POINT *p){return false;};
- virtual bool oTextOut(int x, int y, char *txt, int cb){return false;};
- virtual bool oPolygon(POINT *pts, int cp, char *nam = 0L){return false;};
- virtual bool oArc(int x1, int y1, int x2, int y2, int quads){return false;};
-};
-
+ virtual void Focus() {return;};
+ virtual void Caption(char *txt){return;};
+ virtual void MouseCursor(int cid, bool force){return;};
+ virtual bool SetScroll(bool, int, int, int, int){return false;};
+ virtual bool SetFill(FillDEF *fill){return false;};
+ virtual bool SetTextSpec(TextDEF *set);
+ virtual bool Erase(DWORD Color){return false;};
+ virtual bool StartPage(){return false;};
+ virtual bool EndPage(){return false;};
+ virtual bool Eject() {return false;}; //printers only
+ virtual bool UpdateRect(RECT *rc, bool invert){return false;};
+ virtual bool CopyBitmap(int x, int y, anyOutput* src, int sx, int sy,
+ int sw, int sh, bool invert){return false;};
+ virtual void ShowBitmap(int x, int y, anyOutput* src){return;};
+ bool ShowMark(void *rc, int Mode);
+ bool HideMark();
+ int CalcCursorPos(char *txt, POINT p, POINT *fit);
+ bool TextCursor(char *txt, POINT p, POINT *fit, int *pos, int disp);
+ bool PatLine(POINT p1, POINT p2);
+ virtual void ShowLine(POINT * pts, int cp, DWORD color) {return;};
+ virtual void ShowEllipse(POINT p1, POINT p2, DWORD color){return;};
+ virtual bool SetMenu(int type){return false;};
+ virtual void CheckMenu(int mid, bool check){return;};
+ virtual void FileHistory(){return;};
+ virtual bool oGetPix(int x, int y, DWORD *col){return false;};
+ virtual bool oDrawIcon(int type, int x, int y) {return false;};
+ virtual bool oGetTextExtent(char *text, int cb, int *width, int *height);
+ virtual bool oCircle(int x1, int y1, int x2, int y2, char *nam = 0L){return false;};
+ virtual bool oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam = 0L);
+ virtual bool oPolyline(POINT * pts, int cp, char *nam = 0L){return false;};
+ virtual bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L){return false;};
+ virtual bool oSolidLine(POINT *p){return false;};
+ virtual bool oTextOut(int x, int y, char *txt, int cb){return false;};
+ virtual bool oPolygon(POINT *pts, int cp, char *nam = 0L){return false;};
+ 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_BOOL,
- ET_DATE, ET_TIME, ET_DATETIME, ET_BUSY=0x100, ET_CIRCULAR=0x200};
+ ET_DATE, ET_TIME, ET_DATETIME, ET_BUSY=0x100, ET_CIRCULAR=0x200, ET_EMPTY=0x400,
+ ET_NODRAW=0x800, ET_NODRAW_EMPTY=0xc00};
-class EditText {
-public:
- char *text, *ftext;
- int Align, type, row, col;
+class EditText {
+public:
+ char *text, *ftext;
+ int Align, type, row, col;
void *parent; //points to a data object: defined below
- anyOutput *disp;
+ anyOutput *disp;
double Value;
-
- EditText(void *par, char *msg, int r, int c);
- ~EditText();
- bool AddChar(int c, anyOutput *Out, void *data_obj);
- void Update(int select, anyOutput *Out, POINT *MousePos);
- bool Redraw(anyOutput *Out, bool display);
- void Mark(anyOutput *Out, int mark);
- bool Command(int cmd, anyOutput *Out, void *data_obj);
- bool GetValue(double *v);
+
+ EditText(void *par, char *msg, int r, int c);
+ ~EditText();
+ bool AddChar(int c, anyOutput *Out, void *data_obj);
+ void Update(int select, anyOutput *Out, POINT *MousePos);
+ bool Redraw(anyOutput *Out, bool display);
+ 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 bTranslate);
- bool GetResult(anyResult *r, bool use_last = false);
- bool SetValue(double v);
- bool SetText(char *t);
- void SetRec(RECT *rc);
- int GetX() {return loc.x;};
+ bool GetResult(anyResult *r, bool use_last = false);
+ bool SetValue(double v);
+ bool SetText(char *t);
+ void SetRec(RECT *rc);
+ int GetX() {return loc.x;};
int GetY() {return loc.y;};
- int Cursor() {return CursorPos;};
- bool isValue();
- bool isFormula();
- bool isInRect(POINT *p) {return (p->x>loc.x && p->x<crb.x && p->y>loc.y && p->y<rb.y);};
+ int GetRX() {return crb.x;};
+ int GetRY() {return crb.y;};
+ int Cursor() {return CursorPos;};
+ bool isValue();
+ bool isFormula();
+ bool isInRect(POINT *p) {return (p->x>loc.x && p->x<crb.x && p->y>loc.y && p->y<rb.y);};
bool hasMark() {return (m1 != m2 && m1 >= 0 && m2 >= 0);};
-
-private:
- LineDEF *bgLine;
- FillDEF *bgFill;
- int length, CursorPos, m1, m2, mx1, mx2;
- POINT loc, rb, crb;
- DWORD TextCol;
-
- void FindType();
-};
+
+private:
+ LineDEF *bgLine;
+ FillDEF *bgFill;
+ int length, CursorPos, m1, m2, mx1, mx2;
+ POINT loc, rb, crb;
+ DWORD TextCol;
+
+ void FindType();
+ void set_etracc();
+};
class fmtText {
@@ -489,6 +538,7 @@ typedef struct _fmt_txt_info {
}fmt_txt_info;
public:
+ fmtText();
fmtText(anyOutput *o, int x, int y, char *txt);
~fmtText();
bool StyleAt(int idx, TextDEF *txt_def, int *style, int *font);
@@ -499,6 +549,7 @@ public:
bool oGetTextExtent(anyOutput *o, int *width, int *height, int cb);
void SetText(anyOutput *o, char *txt, int *px, int *py);
void DrawText(anyOutput *o);
+ void EditMode(bool bEdit);
private:
bool SetTextDef(TextDEF *td, int idx);
@@ -509,41 +560,66 @@ private:
char *src;
POINT pos;
int n_split;
+ DWORD flags;
fmt_txt_info *split_text;
};
-
-class DataObj{
-public:
- int cRows, cCols;
- EditText ***etRows;
-
- DataObj();
- ~DataObj();
- virtual bool Init(int nRows, int nCols);
- virtual bool SetValue(int row, int col, double val);
+
+class RangeInfo {
+public:
+ int col_width, row_height, first_width;
+ RangeInfo(int sel, int cw, int rh, int fw, RangeInfo *next);
+ RangeInfo(int sel, char *range, RangeInfo *next);
+ ~RangeInfo();
+ int SetWidth(int w);
+ int SetDefWidth(int w);
+ int SetHeight(int h);
+ int SetFirstWidth(int w);
+ int GetWidth(int col);
+ int GetHeight(int row);
+ int GetFirstWidth();
+
+private:
+ int r_type; // 0 default
+ // 1 column info
+ // 2 row info
+ RangeInfo *ri_next;
+ AccRange *ar;
+};
+
+class DataObj{
+public:
+ int cRows, cCols;
+ RangeInfo *ri;
+ EditText ***etRows;
+
+ DataObj();
+ ~DataObj();
+ virtual bool Init(int nRows, int nCols);
+ 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 GetValue(int row, int col, double *v);
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);
- virtual bool Select(POINT *p){return false;};
- virtual bool WriteData(char *FileName) {return false;};
- virtual bool AddCols(int nCols){return false;};
- virtual bool AddRows(int nRows){return false;};
- virtual bool ChangeSize(int nCols, int nRows, bool bUndo){return false;};
- virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
- virtual bool ReadData(char *, unsigned char *, int){return false;};
+ virtual bool GetResult(anyResult *r, int row, int col, bool use_last = false);
+ virtual bool GetSize(int *width, int *height);
+ virtual bool isEmpty(int row, int col);
+ virtual bool Select(POINT *p){return false;};
+ virtual bool WriteData(char *FileName) {return false;};
+ virtual bool AddCols(int nCols){return false;};
+ virtual bool AddRows(int nRows){return false;};
+ virtual bool ChangeSize(int nCols, int nRows, bool bUndo){return false;};
+ 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 {
public:
StrData(DataObj *par, RECT *rc = 0L);
~StrData();
bool GetSize(int *w, int *h);
- void StrData::RestoreData(DataObj *dest);
+ void RestoreData(DataObj *dest);
private:
int pw, ph;
@@ -551,1328 +627,1376 @@ private:
DataObj *src;
char ***str_data;
};
-
-class HatchOut:public anyOutput {
-public:
- HatchOut(anyOutput *Parent);
- ~HatchOut();
- bool SetFill(FillDEF *fill);
- bool StartPage();
- bool oCircle(int x1, int y1, int x2, int y2, char *nam = 0L);
- bool oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam = 0L);
- bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L);
- bool oPolygon(POINT *pts, int cp, char *nam = 0L);
-
-private:
- anyOutput *out;
- double xbase, ybase;
- LineDEF ParLineDef, MyLineDef;
- bool ParInit;
- int ho, ht;
- DWORD ParLinPat;
- RECT UseRect;
- struct {
- int cx, cy, r;
- }circ_grad;
-
- bool PrepareParent(bool Restore);
- bool DoHatch();
- bool MkPolyLine(POINT *p, anyOutput *o);
- bool HatchLine(POINT p1, POINT p2);
- bool HatchArc(int x, int y, int r, int qad, bool start);
- bool IsInside(POINT p);
- void Lines000();
- void Lines090();
- void Lines045();
- void Lines315();
- void Stipple(int type);
- void Zigzag();
- void Combs();
- void BricksH();
- void BricksV();
- void Bricks045();
- void Bricks315();
- void Texture1();
- void Texture2();
- void Arcs(int type);
- void Waves2(int type);
- void Herringbone();
- void Circles();
- void Grass();
- void Foam();
+
+class HatchOut:public anyOutput {
+public:
+ HatchOut(anyOutput *Parent);
+ ~HatchOut();
+ bool SetFill(FillDEF *fill);
+ bool StartPage();
+ bool oCircle(int x1, int y1, int x2, int y2, char *nam = 0L);
+ bool oSphere(int cx, int cy, int r, POINT *pts, int cp, char *nam = 0L);
+ bool oRectangle(int x1, int y1, int x2, int y2, char *nam = 0L);
+ bool oPolygon(POINT *pts, int cp, char *nam = 0L);
+
+private:
+ anyOutput *out;
+ double xbase, ybase;
+ LineDEF ParLineDef, MyLineDef;
+ bool ParInit;
+ int ho, ht;
+ DWORD ParLinPat;
+ RECT UseRect;
+ struct {
+ int cx, cy, r;
+ }circ_grad;
+
+ bool PrepareParent(bool Restore);
+ bool DoHatch();
+ bool MkPolyLine(POINT *p, anyOutput *o);
+ bool HatchLine(POINT p1, POINT p2);
+ bool HatchArc(int x, int y, int r, int qad, bool start);
+ bool IsInside(POINT p);
+ void Lines000();
+ void Lines090();
+ void Lines045();
+ void Lines315();
+ void Stipple(int type);
+ void Zigzag();
+ void Combs();
+ void BricksH();
+ void BricksV();
+ void Bricks045();
+ void Bricks315();
+ void Texture1();
+ void Texture2();
+ void Arcs(int type);
+ void Waves2(int type);
+ void Herringbone();
+ void Circles();
+ void Grass();
+ void Foam();
void Recs();
- void Hash();
- void CircGrad();
-};
-
-class GraphObj {
-public:
- unsigned long Id; //accepts an identifier during read from file
- // it is set to an object identifier after
- // construction
- GraphObj *parent;
- DataObj *data;
- int type, moveable;
- RECT rDims;
- char *name;
-
- GraphObj(GraphObj *par, DataObj *d);
- virtual ~GraphObj();
- virtual double GetSize(int select);
- virtual bool SetSize(int select, double value){return false;};
- virtual DWORD GetColor(int select);
- virtual bool SetColor(int select, DWORD col) {return false;};
- virtual void DoPlot(anyOutput *target){return;};
- virtual void DoMark(anyOutput *target, bool mark){return;};
- virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
- virtual bool PropertyDlg(){return false;};
+ void Hash();
+ void CircGrad();
+};
+
+class GraphObj {
+public:
+ unsigned long Id; //accepts an identifier during read from file
+ // it is set to an object identifier after
+ // construction
+ GraphObj *parent;
+ DataObj *data;
+ int type, moveable;
+ RECT rDims;
+ char *name;
+
+ GraphObj(GraphObj *par, DataObj *d);
+ virtual ~GraphObj();
+ virtual double GetSize(int select);
+ virtual bool SetSize(int select, double value){return false;};
+ virtual DWORD GetColor(int select);
+ virtual bool SetColor(int select, DWORD col) {return false;};
+ virtual void DoPlot(anyOutput *target){return;};
+ virtual void DoMark(anyOutput *target, bool mark){return;};
+ virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
+ virtual bool PropertyDlg(){return false;};
virtual void RegGO(void *n);
- virtual bool FileIO(int rw) {return false;};
- virtual void * ObjThere(int x, int y);
+ virtual bool FileIO(int rw) {return false;};
+ virtual void * ObjThere(int x, int y);
virtual void Track(POINT *p, anyOutput *o);
-};
-
-class ssButton:public GraphObj {
-public:
-
- ssButton(GraphObj *par, int x, int y, int w, int h);
- ~ssButton();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *target, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
-
-private:
- bool bLBdown, bSelected, bMarked;
- TextDEF TextDef;
- LineDEF Line;
- FillDEF Fill;
-};
-
-class dragHandle:public GraphObj {
-public:
-
- dragHandle(GraphObj *par, int type);
- ~dragHandle();
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
-
-private:
- RECT upd, drec, *minRC, *maxRC;
- LineDEF LineDef;
- FillDEF FillDef;
-};
-
-class dragRect:public GraphObj {
-public:
-
- dragRect(GraphObj *par, int type);
- ~dragRect();
- double GetSize(int select){return parent->GetSize(select);};
- DWORD GetColor(int select){return parent->GetColor(select);};
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void*tmpl, anyOutput *o);
- void * ObjThere(int x, int y);
-
-private:
- dragHandle **handles;
-};
-
-class Drag3D:public GraphObj {
-public:
- Drag3D(GraphObj *par);
- ~Drag3D();
- double GetSize(int select){return parent->GetSize(select);};
- void DoPlot(anyOutput *o);
- void * ObjThere(int x, int y);
-
-private:
- dragHandle **handles;
-};
-
-class FrmRect:public GraphObj {
-public:
-
- FrmRect(GraphObj *par, fRECT *limRC, fRECT *cRC, fRECT *chld);
- ~FrmRect();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoMark(anyOutput *o, bool mark);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg(){return parent ? parent->Command(CMD_CONFIG, 0L, 0L) : false;};
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
-
-private:
- RECT *minRC, *maxRC;
- anyOutput *mo;
- RECT mrc;
- dragRect *drag;
- bool swapX, swapY;
- fRECT *limRC, *cRC, *chldRC, CurrRect;
- LineDEF Line, FillLine;
- FillDEF Fill;
-};
-
-class svgOptions:public GraphObj{
-public:
- svgOptions(int src);
- ~svgOptions();
- bool FileIO(int rw);
-
-private:
- char *script, *svgattr;
-};
-
-class Symbol:public GraphObj{
-public:
- int idx;
-
- Symbol(GraphObj *par, DataObj *d, double x, double y, int which,
- int xc = -1, int xr = -1, int yc = -1, int yr = -1);
- Symbol(int src);
- ~Symbol();
- double GetSize(int select);
- bool SetSize(int select, double value);
- DWORD GetColor(int select);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *target);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- lfPOINT fPos;
- POINT *ssRef;
- long cssRef;
- double size;
- LineDEF SymLine;
- FillDEF SymFill;
- TextDEF *SymTxt;
-};
-
-class Bubble:public GraphObj{
-public:
- Bubble(GraphObj *par, DataObj *d, double x, double y, double s,
- int which, FillDEF *fill, LineDEF *outline, int xc = -1,
- int xr = -1, int yc = -1, int yr = -1, int sc = -1, int sr = -1);
- Bubble(int src);
- ~Bubble();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
+ virtual double DefSize(int select);
+};
+
+class ssButton:public GraphObj {
+public:
+
+ ssButton(GraphObj *par, int x, int y, int w, int h);
+ ~ssButton();
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *target, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+
private:
- bool DoAutoscale(anyOutput *o);
-
- lfPOINT fPos;
- double fs;
- LineDEF BubbleLine, BubbleFillLine;
- FillDEF BubbleFill;
- POINT pts[5];
- POINT *ssRef;
- long cssRef;
-};
-
-class Bar:public GraphObj {
-public:
- Bar(GraphObj *par, DataObj *d, double x, double y, int which,
- int xc = -1, int xr = -1, int yc = -1, int yr = -1);
- Bar(int src);
- ~Bar();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *target);
+ bool bLBdown, bSelected, bMarked;
+ TextDEF TextDef;
+ LineDEF Line;
+ FillDEF Fill;
+};
+
+class dragHandle:public GraphObj {
+public:
+
+ dragHandle(GraphObj *par, int type);
+ ~dragHandle();
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ RECT upd, drec, *minRC, *maxRC;
+ LineDEF LineDef;
+ FillDEF FillDef;
+};
+
+class dragRect:public GraphObj {
+public:
+
+ dragRect(GraphObj *par, int type);
+ ~dragRect();
+ double GetSize(int select){return parent->GetSize(select);};
+ DWORD GetColor(int select){return parent->GetColor(select);};
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void*tmpl, anyOutput *o);
+ void * ObjThere(int x, int y);
+
+private:
+ dragHandle **handles;
+};
+
+class Drag3D:public GraphObj {
+public:
+ Drag3D(GraphObj *par);
+ ~Drag3D();
+ double GetSize(int select){return parent->GetSize(select);};
+ void DoPlot(anyOutput *o);
+ void * ObjThere(int x, int y);
+
+private:
+ dragHandle **handles;
+};
+
+class FrmRect:public GraphObj {
+public:
+
+ FrmRect(GraphObj *par, fRECT *limRC, fRECT *cRC, fRECT *chld);
+ ~FrmRect();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- anyOutput *mo;
- RECT mrc;
- double size;
- LineDEF BarLine, HatchLine;
- FillDEF BarFill;
- lfPOINT fPos, BarBase;
- POINT *ssRef;
- long cssRef;
-};
-
-class DataLine:public GraphObj{
-public:
- bool isPolygon, dirty;
- lfPOINT *Values;
- lfPOINT min, max;
- LineDEF LineDef;
- long nPnt, nPntSet, cp;
- DWORD BgColor;
- POINT *pts;
- char *ssXref, *ssYref;
- anyOutput *mo;
- RECT mrc;
-
- DataLine(GraphObj *par, DataObj *d, char *xrange=0L, char *yrange=0L);
- DataLine(GraphObj *par, DataObj *d, lfPOINT *val, long nval);
- DataLine(int src);
- ~DataLine();
- bool SetColor(int select, DWORD col);
- virtual void DoPlot(anyOutput *target);
- virtual void DoMark(anyOutput *o, bool mark);
- virtual bool Command(int cmd, void *tmpl, anyOutput *o);
- virtual bool PropertyDlg();
- virtual bool FileIO(int rw);
-
- void FileValues(char *name, int type, double start, double step);
- void SetValues();
- void LineData(lfPOINT *val, long nval);
- void DrawCurve(anyOutput *target);
- void DrawSpline(anyOutput *target);
-};
-
-class DataPolygon:public DataLine{
-public:
- DataPolygon(GraphObj *par, DataObj *d, char *xrange=0L, char *yrange=0L);
- DataPolygon(int src);
- ~DataPolygon();
- void DoPlot(anyOutput *target);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- FillDEF pgFill;
- LineDEF pgFillLine;
-};
-
-class RegLine:public GraphObj{
-public:
- RegLine(GraphObj *par, DataObj *d, lfPOINT *values, long n, int type);
- RegLine(int src);
- ~RegLine();
- double GetSize(int select);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
- void Recalc(lfPOINT *values, long n);
- LineDEF *GetLine(){return &LineDef;};
-
-private:
- long nPoints, cp;
- double mx, my;
- LineDEF LineDef;
- fRECT lim, uclip;
- lfPOINT l1, l2, l3, l4, l5;
- DWORD BgColor;
- POINT *pts;
-};
-
-class SDellipse:public GraphObj{
-public:
- SDellipse(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel);
- SDellipse(int src);
- ~SDellipse();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- void RegGO(void *n);
- bool FileIO(int rw);
-
- void Recalc(lfPOINT *values, long n);
-
-private:
- long nPoints, cp;
- double sd1, sd2, mx, my;
- POINT *pts;
- LineDEF LineDef;
- fRECT lim;
- lfPOINT *val;
- RegLine *rl;
-};
-
-class ErrorBar:public GraphObj{
-public:
- ErrorBar(GraphObj *par, DataObj *d, double x, double y, double err, int type,
- int xc=-1, int xr=-1, int yc=-1, int yr=-1, int ec=-1, int er=-1);
- ErrorBar(int src);
- ~ErrorBar();
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *target);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- anyOutput *mo;
- RECT mrc;
- lfPOINT fPos;
- double ferr, SizeBar;
- POINT ebpts[6];
- LineDEF ErrLine;
- POINT *ssRef;
- long cssRef;
-};
-
-class Arrow:public GraphObj {
-public:
- Arrow(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which = 0,
- int xc1=-1, int xr1=-1, int yc1=-1, int yr1=-1, int xc2=-1, int xr2=-1,
- int yc2=-1, int yr2=-1);
- Arrow(int src);
- ~Arrow();
- double GetSize(int select);
- bool SetSize(int select, double value);
- DWORD GetColor(int select){return LineDef.color;};
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
-
-private:
- dragHandle *dh1, *dh2;
- POINT pts[5];
- lfPOINT pos1, pos2;
- double cw, cl;
- LineDEF LineDef;
- POINT *ssRef;
- long cssRef;
- bool bModified;
-
- void Redraw(anyOutput *o);
-};
-
-class Box:public GraphObj {
-public:
- Box(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);
- Box(int src);
- ~Box();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- double size;
- lfPOINT pos1, pos2;
- POINT pts[5];
- LineDEF Outline, Hatchline;
- FillDEF Fill;
- POINT *ssRef;
- long cssRef;
-};
-
-class Whisker:public GraphObj {
-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();
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- anyOutput *mo;
- RECT mrc;
- double size;
- POINT pts[6];
- lfPOINT pos1, pos2;
- LineDEF LineDef;
- POINT *ssRef;
- long cssRef;
-};
-
-class DropLine:public GraphObj{
-public:
- DropLine(GraphObj *par, DataObj *d, double x, double y, int which, int xc = -1,
- int xr = -1, int yc = -1, int yr = -1);
- DropLine(int src);
- ~DropLine();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- lfPOINT fPos;
- POINT pts[4];
- LineDEF LineDef;
- POINT *ssRef;
- long cssRef;
- bool bModified;
-};
-
-class line_segment:public GraphObj{
-public:
- line_segment(GraphObj *par, DataObj *d, LineDEF *ld, POINT3D *p1, POINT3D *p2);
- ~line_segment();
- double GetSize(int select);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- void * ObjThere(int x, int y);
-
-private:
- LineDEF Line;
- POINT3D **ldata;
- fPOINT3D fmin, fmax;
- int *nldata, nli, ndf_go;
- double prop;
- bool bDrawDone;
- GraphObj *co, **df_go;
-
- void DoClip(GraphObj *co);
-};
-
-class sph_scanline:public GraphObj{
-public:
- int rad;
- bool vert;
-
- sph_scanline(POINT3D *center, int radius, bool bVert);
- bool Command(int cmd, void *tmpl, anyOutput *o);
-
- void DoClip(GraphObj *co);
- bool GetPoint(POINT *p, int sel);
-
-private:
- POINT3D p1, p2, cent;
- bool bValid1, bValid2;
-};
-
-class Sphere:public GraphObj{
-public:
- Sphere(GraphObj *par, DataObj *d, int sel, double x, double y, double z, double r,
- int xc = -1, int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1,
- int rc = -1, int rr = -1);
- Sphere(int src);
- ~Sphere();
- double GetSize(int select);
- bool SetSize(int select, double value);
- DWORD GetColor(int select);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- int ix, iy, rx, ry, nscl;
- LineDEF Line;
- FillDEF Fill;
- fPOINT3D fPos, fip;
- double size;
- POINT *ssRef;
- long cssRef;
- GraphObj *co;
- bool bModified, bDrawDone;
- sph_scanline **scl;
-
- void DoClip(GraphObj *co);
- void DrawPG(anyOutput *o, int start);
-};
-
-class plane:public GraphObj{
-public:
- plane(GraphObj *par, DataObj *d, fPOINT3D *pts, int nPts, LineDEF *line,
- FillDEF *fill);
- ~plane();
- double GetSize(int select);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- void * ObjThere(int x, int y);
-
- bool GetPolygon(POINT3D **pla, int *npt, int sel);
- double *GetVec() {return PlaneVec;};
-
-private:
- LineDEF Line;
- FillDEF Fill;
- double *PlaneVec;
- POINT3D **ldata, ReqPoint;
- int *nldata, nli, n_ipts, n_lines;
- POINT *ipts;
- lfPOINT xBounds, yBounds, zBounds;
- bool bDrawDone, bReqPoint;
- GraphObj *co;
- line_segment **lines;
- long totalArea;
-
- void DoClip(GraphObj *co);
- bool IsValidPG(POINT3D *pg, int npg);
-};
-
-class Plane3D:public GraphObj {
-public:
- Plane3D(GraphObj *par, DataObj *da, fPOINT3D *pt, long npt);
- Plane3D(int src);
- ~Plane3D();
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- plane *ipl;
- fPOINT3D *dt, *pts;
- long ndt;
- LineDEF Line;
- FillDEF Fill;
-};
-
-class Brick:public GraphObj{
-public:
- Brick(GraphObj *par, DataObj *da, double x, double y, double z,
- double d, double w, double h, DWORD flags, int xc = -1,
- int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1,
- int dc = -1, int dr = -1, int wc = -1, int wr = -1, int hc = -1,
- int hr = -1);
- Brick(int src);
- ~Brick();
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- LineDEF Line;
- FillDEF Fill;
- fPOINT3D fPos;
- double depth, width, height;
- DWORD flags;
- POINT *ssRef;
- long cssRef;
- plane **faces;
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg(){return parent ? parent->Command(CMD_CONFIG, 0L, 0L) : false;};
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ RECT *minRC, *maxRC;
anyOutput *mo;
RECT mrc;
- bool bModified;
-};
-
-class DropLine3D:public GraphObj{
-public:
- DropLine3D(GraphObj *par, DataObj *d, fPOINT3D *p1, int xc = -1,
- int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1);
- DropLine3D(int src);
- ~DropLine3D();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- line_segment *ls[6];
- POINT mpts[6][2];
- LineDEF Line;
- fPOINT3D fPos;
- POINT *ssRef;
- long cssRef;
- bool bModified;
- anyOutput *mo;
- RECT mrc;
-};
-
-class Arrow3D:public GraphObj{
-public:
- Arrow3D(GraphObj *par, DataObj *d, fPOINT3D *p1, fPOINT3D *p2, int xc1 = -1,
- int xr1 = -1, int yc1 = -1, int yr1 = -1, int zc1 = -1, int zr1 = -1,
- int xc2 = -1, int xr2 = -1, int yc2 = -1, int yr2 = -1, int zc2 = -1,
- int zr2 = -1);
- Arrow3D(int src);
- ~Arrow3D();
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- line_segment *ls[3];
- plane *cap;
- double cw, cl;
- POINT mpts[3][2];
- LineDEF Line;
- fPOINT3D fPos1, fPos2;
- POINT *ssRef;
- long cssRef;
- bool bModified;
-};
-
-class Line3D:public GraphObj{
+ dragRect *drag;
+ bool swapX, swapY;
+ fRECT *limRC, *cRC, *chldRC, CurrRect;
+ LineDEF Line, FillLine;
+ FillDEF Fill;
+};
+
+class svgOptions:public GraphObj{
public:
- LineDEF Line;
-
- Line3D(GraphObj *par, DataObj *d, char *rx, char *ry, char *rz);
- Line3D(GraphObj *par, DataObj *d, fPOINT3D *pt, int n_pt, int xc1 = -1,
- int xr1 = -1, int yc1 = -1, int yr1 = -1, int zc1 = -1, int zr1 = -1,
- int xc2 = -1, int xr2 = -1, int yc2 = -1, int yr2 = -1, int zc2 = -1,
- int zr2 = -1);
- Line3D(int src);
- ~Line3D();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-
-private:
- line_segment **ls;
- fPOINT3D *values, min, max;
- POINT *pts;
- long nPts, npts;
- char *x_range, *y_range, *z_range;
+ svgOptions(int src);
+ ~svgOptions();
+ bool FileIO(int rw);
+
+private:
+ char *script, *svgattr;
+};
+
+class Symbol:public GraphObj{
+public:
+ int idx;
+
+ Symbol(GraphObj *par, DataObj *d, double x, double y, int which,
+ int xc = -1, int xr = -1, int yc = -1, int yr = -1);
+ Symbol(int src);
+ ~Symbol();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ DWORD GetColor(int select);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *target);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ lfPOINT fPos;
POINT *ssRef;
long cssRef;
- bool bModified;
- anyOutput *mo;
- RECT mrc;
-
- void DoUpdate();
-};
-
-class Label:public GraphObj{
-public:
- Label(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, DWORD flg,
- int xc = -1, int xr = -1, int yc = -1, int yr = -1, int tc = -1, int tr = -1);
- Label(int src);
- ~Label();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
-
- bool CalcRect(anyOutput *o);
- void RedrawEdit(anyOutput *o);
- void ShowCursor(anyOutput *o);
- bool AddChar(int ci, anyOutput *o);
- void CalcCursorPos(int x, int y, anyOutput *o);
- void SetModified();
- void DoPlotText(anyOutput *o);
- TextDEF *GetTextDef(){return &TextDef;};
-
-private:
- lfPOINT fPos, fDist;
- double si, csi, curr_z;
- DWORD flags, bgcolor;
- TextDEF TextDef;
- LineDEF bgLine;
- int ix, iy, CursorPos;
- bool is3D;
- RECT Cursor;
- POINT pts[5];
- POINT *ssRef;
- long cssRef;
- anyOutput *defDisp;
- bool bModified, bBGvalid;
- fmtText *fmt_txt;
-};
-
-class mLabel:public GraphObj{
-public:
- mLabel(GraphObj *, DataObj *, double, double, TextDEF *, char *, int, DWORD);
- mLabel(GraphObj *, DataObj *, double, double, TextDEF *, char *);
- mLabel(int src);
- ~mLabel();
- double GetSize(int select);
- bool SetSize(int select, double value);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- void RegGO(void *n);
- bool FileIO(int rw);
- void Track(POINT *p, anyOutput *o);
-
-private:
- lfPOINT fPos, fDist, cPos, cPos1, dist;
- double si, csi, curr_z, lspc;
- DWORD flags, undo_flags;
- TextDEF TextDef;
- long nLines;
- int cli;
- bool is3D;
- Label **Lines;
-};
-
-class segment:public GraphObj{
-public:
- segment(GraphObj *par, DataObj *d, lfPOINT *c, double r1, double r2, double a1, double a2);
- segment(int src);
- ~segment();
- bool SetSize(int select, double value);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
-
-private:
- lfPOINT fCent;
- long nPts;
- double radius1, radius2, angle1, angle2, shift;
- LineDEF segLine, segFillLine;
- FillDEF segFill;
- POINT *pts;
- bool bModified;
-};
-
-class polyline:public GraphObj {
-public:
- dragHandle **pHandles;
- lfPOINT *Values;
- long nPoints, nPts;
- POINT *pts;
- LineDEF pgLine, pgFillLine;
- FillDEF pgFill;
- bool bModified;
-
- polyline(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts);
- polyline(int src);
- ~polyline();
- double GetSize(int select);
- bool SetSize(int select, double value);
- DWORD GetColor(int select);
- virtual void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- virtual bool PropertyDlg();
- virtual bool FileIO(int rw);
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
-
-private:
- void ShowPoints(anyOutput *o);
+ double size;
+ LineDEF SymLine;
+ FillDEF SymFill;
+ TextDEF *SymTxt;
};
-class Bezier:public polyline {
+class Bubble:public GraphObj{
public:
- Bezier(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts, int mode, double res);
- Bezier(int src);
+ Bubble(GraphObj *par, DataObj *d, double x, double y, double s,
+ int which, FillDEF *fill, LineDEF *outline, int xc = -1,
+ int xr = -1, int yc = -1, int yr = -1, int sc = -1, int sr = -1);
+ Bubble(int src);
+ ~Bubble();
void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
bool FileIO(int rw);
private:
- void AddPoints(int n, lfPOINT *p);
+ bool DoAutoscale(anyOutput *o);
- 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);
+ lfPOINT fPos;
+ double fs;
+ LineDEF BubbleLine, BubbleFillLine;
+ FillDEF BubbleFill;
+ POINT pts[5];
+ POINT *ssRef;
+ long cssRef;
};
-
-class polygon:public polyline {
-public:
- polygon(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts);
- polygon(int src):polyline(src){};
- bool PropertyDlg();
-};
-
-class rectangle:public GraphObj {
-public:
- lfPOINT fp1, fp2;
- LineDEF Line, FillLine;
- FillDEF Fill;
- double rad;
- bool bModified;
-
- rectangle(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
- rectangle(int src);
- ~rectangle();
- double GetSize(int select);
- bool SetSize(int select, double value);
- DWORD GetColor(int select){return Line.color;};
- void DoMark(anyOutput *o, bool mark);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
-
-private:
- POINT *pts;
- long nPts;
- dragRect *drc;
- void PlotRoundRect(anyOutput *o);
-};
-
-class ellipse:public rectangle {
-public:
- ellipse(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
- ellipse(int src);
-};
-
-class roundrec:public rectangle {
-public:
- roundrec(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
- roundrec(int src);
-};
-
-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);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- void RegGO(void *n);
- bool FileIO(int rw);
- void Track(POINT *p, anyOutput *o);
-
- 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;
- RECT hcr;
-
- void DefDesc(char *txt);
-};
-
-class Legend:public GraphObj{
-public:
- Legend(GraphObj *par, DataObj *d);
- Legend(int src);
- ~Legend();
- double GetSize(int select);
- bool SetSize(int select, double value);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- void RegGO(void *n);
- bool FileIO(int rw);
- void Track(POINT *p, anyOutput *o);
-
- 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;
- RECT trc;
- anyOutput *to;
- fRECT B_Rect, C_Rect, D_Rect, E_Rect, F_Rect;
- long nItems;
- bool hasLine;
- LegItem **Items;
-};
-
-class Plot:public GraphObj{
-public:
- fRECT Bounds; //contains minima and maxima for x and y
- bool dirty; //rescale before redraw;
- int use_xaxis, use_yaxis; //this plot uses its own axes
- lfPOINT xBounds, yBounds, zBounds; //like Bounds but in 3D space
- int hidden; //plot (layer) is not visible
-
- Plot(GraphObj *par, DataObj *d);
- virtual double GetSize(int select);
- virtual bool SetSize(int select, double value){return false;};
- virtual DWORD GetColor(int select);
- virtual bool SetColor(int select, DWORD col){return false;};
- virtual void DoPlot(anyOutput *o){return;};
- virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
- virtual bool PropertyDlg(){return false;};
-
- void CheckBounds(double x, double y);
- bool UseAxis(int idx);
- void ApplyAxes(anyOutput *o);
- void CheckBounds3D(double x, double y, double z);
- bool SavVarObs(GraphObj **gol, long ngo, DWORD flags);
- DataObj *CreaCumData(char *xr, char *yr, int mode, double base);
-};
-
-class PlotScatt:public Plot{
-public:
- char *xRange, *yRange;
- long nPoints;
- int DefSym;
- lfPOINT BarDist;
- Bar **Bars;
- Symbol **Symbols;
- DataLine *TheLine;
- ErrorBar **Errors;
- Label **Labels;
+class Bar:public GraphObj {
+public:
+ Bar(GraphObj *par, DataObj *d, double x, double y, int which,
+ int xc = -1, int xr = -1, int yc = -1, int yr = -1, char *desc = 0L);
+ Bar(int src);
+ ~Bar();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *target);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
- PlotScatt(GraphObj *par, DataObj *d, DWORD presel);
- PlotScatt(GraphObj *par, DataObj *d, int cBars, Bar **bars);
- PlotScatt(GraphObj *par, DataObj *d, int nPts, Symbol **sym, DataLine *lin);
- PlotScatt(int src);
- ~PlotScatt();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *target);
- virtual bool Command(int cmd, void *tmpl, anyOutput *o);
- virtual bool PropertyDlg();
- void RegGO(void *n);
- virtual bool FileIO(int rw);
+private:
+ anyOutput *mo;
+ RECT mrc;
+ double size;
+ LineDEF BarLine, HatchLine;
+ FillDEF BarFill;
+ lfPOINT fPos, BarBase;
+ POINT *ssRef;
+ long cssRef;
+};
- bool ForEach(int cmd, void *tmp, anyOutput *o);
-
-private:
- DWORD DefSel;
- char *ErrRange, *LbRange;
- Arrow **Arrows;
- DropLine **DropLines;
-
- bool CreateBarChart();
+class DataLine:public GraphObj{
+public:
+ bool isPolygon, dirty;
+ lfPOINT *Values;
+ lfPOINT min, max;
+ LineDEF LineDef;
+ long nPnt, nPntSet, cp;
+ DWORD BgColor;
+ POINT *pts;
+ char *ssXref, *ssYref;
+ anyOutput *mo;
+ RECT mrc;
+
+ DataLine(GraphObj *par, DataObj *d, char *xrange=0L, char *yrange=0L, char *name=0L);
+ DataLine(GraphObj *par, DataObj *d, lfPOINT *val, long nval, char *name);
+ DataLine(int src);
+ ~DataLine();
+ bool SetColor(int select, DWORD col);
+ virtual void DoPlot(anyOutput *target);
+ virtual void DoMark(anyOutput *o, bool mark);
+ virtual bool Command(int cmd, void *tmpl, anyOutput *o);
+ virtual bool PropertyDlg();
+ virtual bool FileIO(int rw);
+
+ void FileValues(char *name, int type, double start, double step);
+ void SetValues();
+ void LineData(lfPOINT *val, long nval);
+ void DrawCurve(anyOutput *target);
+ void DrawSpline(anyOutput *target);
+};
+
+class DataPolygon:public DataLine{
+public:
+ DataPolygon(GraphObj *par, DataObj *d, char *xrange=0L, char *yrange=0L, char *name=0L);
+ DataPolygon(int src);
+ ~DataPolygon();
+ void DoPlot(anyOutput *target);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ FillDEF pgFill;
+ LineDEF pgFillLine;
+};
+
+class RegLine:public GraphObj{
+public:
+ RegLine(GraphObj *par, DataObj *d, lfPOINT *values, long n, int type);
+ RegLine(int src);
+ ~RegLine();
+ double GetSize(int select);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+ void Recalc(lfPOINT *values, long n);
+ LineDEF *GetLine(){return &LineDef;};
+
+private:
+ long nPoints, cp;
+ double mx, my;
+ LineDEF LineDef;
+ fRECT lim, uclip;
+ lfPOINT l1, l2, l3, l4, l5;
+ DWORD BgColor;
+ POINT *pts;
+};
+
+class SDellipse:public GraphObj{
+public:
+ SDellipse(GraphObj *par, DataObj *d, lfPOINT *values, long n, int sel);
+ SDellipse(int src);
+ ~SDellipse();
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ void RegGO(void *n);
+ bool FileIO(int rw);
+
+ void Recalc(lfPOINT *values, long n);
+
+private:
+ long nPoints, cp;
+ double sd1, sd2, mx, my;
+ POINT *pts;
+ LineDEF LineDef;
+ fRECT lim;
+ lfPOINT *val;
+ RegLine *rl;
+};
+
+class ErrorBar:public GraphObj{
+public:
+ ErrorBar(GraphObj *par, DataObj *d, double x, double y, double err, int type,
+ int xc=-1, int xr=-1, int yc=-1, int yr=-1, int ec=-1, int er=-1);
+ ErrorBar(int src);
+ ~ErrorBar();
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *target);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ anyOutput *mo;
+ RECT mrc;
+ lfPOINT fPos;
+ double ferr, SizeBar;
+ POINT ebpts[6];
+ LineDEF ErrLine;
+ POINT *ssRef;
+ long cssRef;
+};
+
+class Arrow:public GraphObj {
+public:
+ Arrow(GraphObj *par, DataObj *d, lfPOINT fp1, lfPOINT fp2, int which = 0,
+ int xc1=-1, int xr1=-1, int yc1=-1, int yr1=-1, int xc2=-1, int xr2=-1,
+ int yc2=-1, int yr2=-1);
+ Arrow(int src);
+ ~Arrow();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ DWORD GetColor(int select){return LineDef.color;};
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ dragHandle *dh1, *dh2;
+ POINT pts[5];
+ lfPOINT pos1, pos2;
+ double cw, cl;
+ LineDEF LineDef;
+ POINT *ssRef;
+ long cssRef;
+ bool bModified;
+
+ void Redraw(anyOutput *o);
+};
+
+class Box:public GraphObj {
+public:
+ Box(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);
+ Box(int src);
+ ~Box();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ double size;
+ lfPOINT pos1, pos2;
+ POINT pts[5];
+ LineDEF Outline, Hatchline;
+ FillDEF Fill;
+ POINT *ssRef;
+ long cssRef;
+};
+
+class Whisker:public GraphObj {
+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();
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ anyOutput *mo;
+ RECT mrc;
+ double size;
+ POINT pts[6];
+ lfPOINT pos1, pos2;
+ LineDEF LineDef;
+ POINT *ssRef;
+ long cssRef;
+};
+
+class DropLine:public GraphObj{
+public:
+ DropLine(GraphObj *par, DataObj *d, double x, double y, int which, int xc = -1,
+ int xr = -1, int yc = -1, int yr = -1);
+ DropLine(int src);
+ ~DropLine();
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ lfPOINT fPos;
+ POINT pts[4];
+ LineDEF LineDef;
+ POINT *ssRef;
+ long cssRef;
+ bool bModified;
+};
+
+class line_segment:public GraphObj{
+public:
+ line_segment(GraphObj *par, DataObj *d, LineDEF *ld, POINT3D *p1, POINT3D *p2);
+ ~line_segment();
+ double GetSize(int select);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ void * ObjThere(int x, int y);
+
+private:
+ LineDEF Line;
+ POINT3D **ldata;
+ fPOINT3D fmin, fmax;
+ int *nldata, nli, ndf_go;
+ double prop;
+ bool bDrawDone;
+ GraphObj *co, **df_go;
+
+ void DoClip(GraphObj *co);
+};
+
+class sph_scanline:public GraphObj{
+public:
+ int rad;
+ bool vert;
+
+ sph_scanline(POINT3D *center, int radius, bool bVert);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+
+ void DoClip(GraphObj *co);
+ bool GetPoint(POINT *p, int sel);
+
+private:
+ POINT3D p1, p2, cent;
+ bool bValid1, bValid2;
+};
+
+class Sphere:public GraphObj{
+public:
+ Sphere(GraphObj *par, DataObj *d, int sel, double x, double y, double z, double r,
+ int xc = -1, int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1,
+ int rc = -1, int rr = -1);
+ Sphere(int src);
+ ~Sphere();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ DWORD GetColor(int select);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ int ix, iy, rx, ry, nscl;
+ LineDEF Line;
+ FillDEF Fill;
+ fPOINT3D fPos, fip;
+ double size;
+ POINT *ssRef;
+ long cssRef;
+ GraphObj *co;
+ bool bModified, bDrawDone;
+ sph_scanline **scl;
+
+ void DoClip(GraphObj *co);
+ void DrawPG(anyOutput *o, int start);
+};
+
+class plane:public GraphObj{
+public:
+ plane(GraphObj *par, DataObj *d, fPOINT3D *pts, int nPts, LineDEF *line,
+ FillDEF *fill);
+ ~plane();
+ double GetSize(int select);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ void * ObjThere(int x, int y);
+
+ bool GetPolygon(POINT3D **pla, int *npt, int sel);
+ double *GetVec() {return PlaneVec;};
+
+private:
+ LineDEF Line;
+ FillDEF Fill;
+ double *PlaneVec;
+ POINT3D **ldata, ReqPoint;
+ int *nldata, nli, n_ipts, n_lines;
+ POINT *ipts;
+ lfPOINT xBounds, yBounds, zBounds;
+ bool bDrawDone, bReqPoint;
+ GraphObj *co;
+ line_segment **lines;
+ long totalArea;
+
+ void DoClip(GraphObj *co);
+ bool IsValidPG(POINT3D *pg, int npg);
+};
+
+class Plane3D:public GraphObj {
+public:
+ Plane3D(GraphObj *par, DataObj *da, fPOINT3D *pt, long npt);
+ Plane3D(int src);
+ ~Plane3D();
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ plane *ipl;
+ fPOINT3D *dt, *pts;
+ long ndt;
+ LineDEF Line;
+ FillDEF Fill;
+};
+
+class Brick:public GraphObj{
+public:
+ Brick(GraphObj *par, DataObj *da, double x, double y, double z,
+ double d, double w, double h, DWORD flags, int xc = -1,
+ int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1,
+ int dc = -1, int dr = -1, int wc = -1, int wr = -1, int hc = -1,
+ int hr = -1);
+ Brick(int src);
+ ~Brick();
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ LineDEF Line;
+ FillDEF Fill;
+ fPOINT3D fPos;
+ double depth, width, height;
+ DWORD flags;
+ POINT *ssRef;
+ long cssRef;
+ plane **faces;
+ anyOutput *mo;
+ RECT mrc;
+ bool bModified;
+};
+
+class DropLine3D:public GraphObj{
+public:
+ DropLine3D(GraphObj *par, DataObj *d, fPOINT3D *p1, int xc = -1,
+ int xr = -1, int yc = -1, int yr = -1, int zc = -1, int zr = -1);
+ DropLine3D(int src);
+ ~DropLine3D();
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ line_segment *ls[6];
+ POINT mpts[6][2];
+ LineDEF Line;
+ fPOINT3D fPos;
+ POINT *ssRef;
+ long cssRef;
+ bool bModified;
+ anyOutput *mo;
+ RECT mrc;
+};
+
+class Arrow3D:public GraphObj{
+public:
+ Arrow3D(GraphObj *par, DataObj *d, fPOINT3D *p1, fPOINT3D *p2, int xc1 = -1,
+ int xr1 = -1, int yc1 = -1, int yr1 = -1, int zc1 = -1, int zr1 = -1,
+ int xc2 = -1, int xr2 = -1, int yc2 = -1, int yr2 = -1, int zc2 = -1,
+ int zr2 = -1);
+ Arrow3D(int src);
+ ~Arrow3D();
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ line_segment *ls[3];
+ plane *cap;
+ double cw, cl;
+ POINT mpts[3][2];
+ LineDEF Line;
+ fPOINT3D fPos1, fPos2;
+ POINT *ssRef;
+ long cssRef;
+ bool bModified;
+};
+
+class Line3D:public GraphObj{
+public:
+ LineDEF Line;
+
+ Line3D(GraphObj *par, DataObj *d, char *rx, char *ry, char *rz);
+ Line3D(GraphObj *par, DataObj *d, fPOINT3D *pt, int n_pt, int xc1 = -1,
+ int xr1 = -1, int yc1 = -1, int yr1 = -1, int zc1 = -1, int zr1 = -1,
+ int xc2 = -1, int xr2 = -1, int yc2 = -1, int yr2 = -1, int zc2 = -1,
+ int zr2 = -1);
+ Line3D(int src);
+ ~Line3D();
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+
+private:
+ line_segment **ls;
+ fPOINT3D *values, min, max;
+ POINT *pts;
+ long nPts, npts;
+ char *x_range, *y_range, *z_range;
+ POINT *ssRef;
+ long cssRef;
+ bool bModified;
+ anyOutput *mo;
+ RECT mrc;
+
+ void DoUpdate();
+};
+
+class Label:public GraphObj{
+public:
+ Label(GraphObj *par, DataObj *d, double x, double y, TextDEF *td, DWORD flg,
+ int xc = -1, int xr = -1, int yc = -1, int yr = -1, int tc = -1, int tr = -1);
+ Label(int src);
+ ~Label();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+ bool CalcRect(anyOutput *o);
+ void RedrawEdit(anyOutput *o);
+ void ShowCursor(anyOutput *o);
+ bool AddChar(int ci, anyOutput *o);
+ void CalcCursorPos(int x, int y, anyOutput *o);
+ void SetModified();
+ void DoPlotText(anyOutput *o);
+ TextDEF *GetTextDef(){return &TextDef;};
+
+private:
+ lfPOINT fPos, fDist;
+ double si, csi, curr_z;
+ DWORD flags, bgcolor;
+ TextDEF TextDef;
+ LineDEF bgLine;
+ int ix, iy, CursorPos;
+ bool is3D;
+ RECT Cursor;
+ POINT pts[5];
+ POINT *ssRef;
+ long cssRef;
+ anyOutput *defDisp;
+ bool bModified, bBGvalid;
+ fmtText *fmt_txt;
+};
+
+class mLabel:public GraphObj{
+public:
+ mLabel(GraphObj *, DataObj *, double, double, TextDEF *, char *, int, DWORD);
+ mLabel(GraphObj *, DataObj *, double, double, TextDEF *, char *);
+ mLabel(int src);
+ ~mLabel();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ void RegGO(void *n);
+ bool FileIO(int rw);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ lfPOINT fPos, fDist, cPos, cPos1, dist;
+ double si, csi, curr_z, lspc;
+ DWORD flags, undo_flags;
+ TextDEF TextDef;
+ long nLines;
+ int cli;
+ bool is3D;
+ Label **Lines;
+};
+
+class TextFrame:public GraphObj{
+ enum {TF_MAXLINE=120};
+public:
+ TextFrame(GraphObj *parent, DataObj *data, lfPOINT *p1, lfPOINT *p2, char *txt);
+ TextFrame(int src);
+ ~TextFrame();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ void DoMark(anyOutput *o, bool mark);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ fRECT pad;
+ RECT ipad, Cursor, *tm_rec;
+ fmtText fmt_txt;
+ int nlines, linc, tm_c, csize, cpos;
+ bool bModified, bResize, has_m1, has_m2;
+ unsigned char c_char, m1_char, m2_char;
+ double lspc;
+ lfPOINT pos1, pos2;
+ POINT cur_pos, m1_pos, m2_pos, m1_cpos, m2_cpos;
+ TextDEF TextDef;
+ dragRect *drc;
+ unsigned char *text, **lines;
+ LineDEF Line, FillLine;
+ FillDEF Fill;
+
+ void text2lines(anyOutput *o);
+ void lines2text();
+ void ShowCursor(anyOutput *o);
+ void AddChar(anyOutput *o, unsigned char c);
+ void DelChar(anyOutput *o);
+ void CalcCursorPos(int x, int y, anyOutput *o);
+ void ReplMark(anyOutput *o, char *ntext);
+ void procTokens();
+ bool DoPaste(anyOutput *o);
+ void TextMark(anyOutput *o, int mode);
+ bool CopyText(anyOutput *o, bool b_cut);
+};
+
+class segment:public GraphObj{
+public:
+ segment(GraphObj *par, DataObj *d, lfPOINT *c, double r1, double r2, double a1, double a2);
+ segment(int src);
+ ~segment();
+ bool SetSize(int select, double value);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ lfPOINT fCent;
+ long nPts;
+ double radius1, radius2, angle1, angle2, shift;
+ LineDEF segLine, segFillLine;
+ FillDEF segFill;
+ POINT *pts;
+ bool bModified;
+};
+
+class polyline:public GraphObj {
+public:
+ dragHandle **pHandles;
+ lfPOINT *Values;
+ long nPoints, nPts;
+ POINT *pts;
+ LineDEF pgLine, pgFillLine;
+ FillDEF pgFill;
+ bool bModified;
+
+ polyline(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts);
+ polyline(int src);
+ ~polyline();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ DWORD GetColor(int select);
+ virtual void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ virtual bool PropertyDlg();
+ virtual bool FileIO(int rw);
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ 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 IpolBez(lfPOINT *d, lfPOINT tHat1, lfPOINT tHat2);
+ 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:
+ polygon(GraphObj *par, DataObj *d, lfPOINT *fpts, int cpts);
+ polygon(int src):polyline(src){};
+ bool PropertyDlg();
+};
+
+class rectangle:public GraphObj {
+public:
+ lfPOINT fp1, fp2;
+ LineDEF Line, FillLine;
+ FillDEF Fill;
+ double rad;
+ bool bModified;
+
+ rectangle(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
+ rectangle(int src);
+ ~rectangle();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ DWORD GetColor(int select){return Line.color;};
+ void DoMark(anyOutput *o, bool mark);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+
+private:
+ POINT *pts;
+ long nPts;
+ dragRect *drc;
+ void PlotRoundRect(anyOutput *o);
+};
+
+class ellipse:public rectangle {
+public:
+ ellipse(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
+ ellipse(int src);
+};
+
+class roundrec:public rectangle {
+public:
+ roundrec(GraphObj *par, DataObj *d, lfPOINT *p1, lfPOINT *p2);
+ roundrec(int src);
+};
+
+class LegItem:public GraphObj{
+public:
+ DWORD flags;
+
+ LegItem(GraphObj *par, DataObj *d, LineDEF *ld, LineDEF *lf, FillDEF *fill, char *desc);
+ 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);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ void RegGO(void *n);
+ bool FileIO(int rw);
+ void Track(POINT *p, anyOutput *o);
+
+ bool HasFill(LineDEF *ld, FillDEF *fd, char *desc);
+ bool HasSym(LineDEF *ld, GraphObj *sy);
+ bool HasErr(LineDEF *ld, int err);
+
+private:
+ LineDEF DataLine, OutLine, HatchLine;
+ FillDEF Fill;
+ Symbol *Sym;
+ Label *Desc;
+ RECT hcr;
+
+ void DefDesc(char *txt);
+};
+
+class Legend:public GraphObj{
+public:
+ Legend(GraphObj *par, DataObj *d);
+ Legend(int src);
+ ~Legend();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ void RegGO(void *n);
+ bool FileIO(int rw);
+ void Track(POINT *p, anyOutput *o);
+
+ bool HasFill(LineDEF *ld, FillDEF *fd, char *desc);
+ bool HasSym(LineDEF *ld, GraphObj *sy, char *desc);
+ bool HasErr(LineDEF *ld, int err, char *desc);
+
+private:
+ lfPOINT pos, lb_pos;
+ RECT trc;
+ anyOutput *to;
+ fRECT B_Rect, C_Rect, D_Rect, E_Rect, F_Rect;
+ long nItems;
+ bool hasLine;
+ LegItem **Items;
+};
+
+class Plot:public GraphObj{
+public:
+ fRECT Bounds; //contains minima and maxima for x and y
+ bool dirty; //rescale before redraw;
+ int use_xaxis, use_yaxis; //this plot uses its own axes
+ lfPOINT xBounds, yBounds, zBounds; //like Bounds but in 3D space
+ int hidden; //plot (layer) is not visible
+ char *x_info, *y_info, *z_info; //descriptor used e.g. for axis label or legend
+
+ Plot(GraphObj *par, DataObj *d);
+ virtual double GetSize(int select);
+ virtual bool SetSize(int select, double value){return false;};
+ virtual DWORD GetColor(int select);
+ virtual bool SetColor(int select, DWORD col){return false;};
+ virtual void DoPlot(anyOutput *o){return;};
+ virtual bool Command(int cmd, void *tmpl, anyOutput *o){return false;};
+ virtual bool PropertyDlg(){return false;};
+
+ void CheckBounds(double x, double y);
+ bool UseAxis(int idx);
+ void ApplyAxes(anyOutput *o);
+ void CheckBounds3D(double x, double y, double z);
+ bool SavVarObs(GraphObj **gol, long ngo, DWORD flags);
+ DataObj *CreaCumData(char *xr, char *yr, int mode, double base);
+};
+
+class PlotScatt:public Plot{
+public:
+ char *xRange, *yRange;
+ long nPoints;
+ int DefSym;
+ lfPOINT BarDist;
+ Bar **Bars;
+ Symbol **Symbols;
+ DataLine *TheLine;
+ ErrorBar **Errors;
+ Label **Labels;
+
+ PlotScatt(GraphObj *par, DataObj *d, DWORD presel);
+ PlotScatt(GraphObj *par, DataObj *d, int cBars, Bar **bars);
+ PlotScatt(GraphObj *par, DataObj *d, int nPts, Symbol **sym, DataLine *lin);
+ PlotScatt(int src);
+ ~PlotScatt();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *target);
+ virtual bool Command(int cmd, void *tmpl, anyOutput *o);
+ virtual bool PropertyDlg();
+ void RegGO(void *n);
+ virtual bool FileIO(int rw);
+
+ bool ForEach(int cmd, void *tmp, anyOutput *o);
+
+private:
+ DWORD DefSel;
+ char *ErrRange, *LbRange;
+ Arrow **Arrows;
+ DropLine **DropLines;
+
+ bool CreateBarChart();
+};
+
+class xyStat:public PlotScatt{
+public:
+ xyStat(GraphObj *par, DataObj *d);
+ xyStat(int src);
+ ~xyStat();
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ virtual bool FileIO(int rw);
+
+ void CreateData();
+
+private:
+ double ci;
+ DataObj *curr_data;
+ char *case_prefix;
+
+};
+
+class BarChart:public PlotScatt{
+public:
+ BarChart(GraphObj *par, DataObj *d);
+};
+
+class FreqDist:public Plot {
+public:
+ FreqDist(GraphObj *par, DataObj *d);
+ FreqDist(int src);
+ ~FreqDist();
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ void RegGO(void *n);
+ bool FileIO(int rw);
+
+private:
+ double start, step;
+ long nPlots;
+ char *ssRef;
+ LineDEF BarLine, HatchLine;
+ FillDEF BarFill;
+ DataObj *curr_data;
+ GraphObj **plots;
+
+ void ProcData(int sel);
+};
+
+class Regression:public Plot{
+public:
+ Regression(GraphObj *par, DataObj *d);
+ Regression(int src);
+ ~Regression();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *target);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ void RegGO(void *n);
+ bool FileIO(int rw);
+
+private:
+ long nPoints;
+ char *xRange, *yRange;
+ Symbol **Symbols;
+ RegLine *rLine;
+ SDellipse *sde;
+
+ void Recalc();
+};
+
+class BubblePlot:public Plot{
+public:
+ BubblePlot(GraphObj *par, DataObj *d);
+ BubblePlot(int src);
+ ~BubblePlot();
+ void DoPlot(anyOutput *target);
+ DWORD GetColor(int select);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ void RegGO(void *n);
+ bool FileIO(int rw);
+
+private:
+ long nPoints;
+ LineDEF BubbleLine, BubbleFillLine;
+ FillDEF BubbleFill;
+ Bubble **Bubbles;
+};
+
+class PolarPlot:public Plot{
+public:
+ PolarPlot(GraphObj *par, DataObj *d);
+ PolarPlot(int src);
+ ~PolarPlot();
+ double GetSize(int select);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ void RegGO(void *n);
+ bool FileIO(int rw);
+
+ bool AddPlot();
+ bool Config();
+
+private:
+ int nPlots, nAxes;
+ double offs;
+ anyOutput *CurrDisp;
+ fRECT CurrRect;
+ LineDEF FillLine;
+ FillDEF Fill;
+ Plot **Plots;
+ GraphObj **Axes; //Axis not yet defined
+};
+
+class BoxPlot:public Plot {
+public:
+ BoxPlot(GraphObj *par, DataObj *d);
+ BoxPlot(int src);
+ BoxPlot(GraphObj *par, DataObj *dt, int mode, int c1, int c2, int c3, char *box_name);
+ ~BoxPlot();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ 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);
+
+ bool ForEach(int cmd, void *tmp, anyOutput *o);
+ void CreateData();
+
+private:
+ char *xRange, *yRange, *case_prefix;
+ long nPoints;
+ double ci_box, ci_err;
+ DataObj *curr_data;
+ lfPOINT BoxDist;
+ Box **Boxes;
+ Whisker **Whiskers;
+ Symbol **Symbols;
+ Label **Labels;
+ DataLine *TheLine;
+};
+
+class DensDisp:public Plot {
+public:
+ DensDisp(GraphObj *par, DataObj *d);
+ DensDisp(int src);
+ ~DensDisp();
+ bool SetSize(int select, double value);
+ 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);
+
+private:
+ LineDEF DefLine, DefFillLine;
+ FillDEF DefFill;
+ long nPoints;
+ char *xRange, *yRange;
+ Box **Boxes;
+
+ void DoUpdate();
+
+};
+
+class StackBar:public Plot{
+public:
+ int numPlots, numXY, numPG, numPL;
+ BoxPlot **Boxes;
+ PlotScatt **xyPlots;
+ DataPolygon **Polygons;
+ DataLine **Lines;
+ lfPOINT dspm;
+
+ StackBar(GraphObj *par, DataObj *d);
+ StackBar(int src);
+ ~StackBar();
+ bool SetSize(int select, double value);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ void RegGO(void *n);
+ bool FileIO(int rw);
+
+private:
+ char *ssXrange, *ssYrange;
+ double StartVal;
+ int cum_data_mode;
+ DataObj *CumData;
+};
+
+class StackPG:public StackBar{
+public:
+ StackPG(GraphObj *par, DataObj *d);
+};
+
+class GroupBars:public StackBar{
+public:
+ GroupBars(GraphObj *par, DataObj *d):StackBar(par, d){};
+ bool PropertyDlg();
+};
+
+class Waterfall:public StackBar{
+public:
+ Waterfall(GraphObj *par, DataObj *d);
+ bool PropertyDlg();
};
-class xyStat:public PlotScatt{
+class MultiLines:public StackBar{
public:
- xyStat(GraphObj *par, DataObj *d);
- xyStat(int src);
- ~xyStat();
- bool Command(int cmd, void *tmpl, anyOutput *o);
+ MultiLines(GraphObj *par, DataObj *d);
bool PropertyDlg();
- virtual bool FileIO(int rw);
-
- void CreateData();
-
-private:
- double ci;
- DataObj *curr_data;
- char *case_prefix;
-
};
-
-class BarChart:public PlotScatt{
-public:
- BarChart(GraphObj *par, DataObj *d);
-};
-class FreqDist:public Plot {
+class PieChart:public Plot {
public:
- FreqDist(GraphObj *par, DataObj *d);
- FreqDist(int src);
- ~FreqDist();
+ PieChart(GraphObj *par, DataObj *d);
+ PieChart(int src);
+ ~PieChart();
+ bool SetSize(int select, double value);
void DoPlot(anyOutput *o);
bool Command(int cmd, void *tmpl, anyOutput *o);
bool PropertyDlg();
void RegGO(void *n);
bool FileIO(int rw);
+ void DoUpdate();
private:
- double start, step;
- long nPlots;
- char *ssRef;
- LineDEF BarLine, HatchLine;
- FillDEF BarFill;
- DataObj *curr_data;
- GraphObj **plots;
+ long nPts;
+ char *ssRefA, *ssRefR;
+ lfPOINT CtDef;
+ double FacRad;
+ segment **Segments;
+};
- void ProcData(int sel);
+class RingChart:public PieChart {
+public:
+ RingChart(GraphObj *par, DataObj *d);
};
-
-class Regression:public Plot{
-public:
- Regression(GraphObj *par, DataObj *d);
- Regression(int src);
- ~Regression();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *target);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- void RegGO(void *n);
- bool FileIO(int rw);
-
-private:
- long nPoints;
- char *xRange, *yRange;
- Symbol **Symbols;
- RegLine *rLine;
- SDellipse *sde;
-
- void Recalc();
-};
-
-class BubblePlot:public Plot{
-public:
- BubblePlot(GraphObj *par, DataObj *d);
- BubblePlot(int src);
- ~BubblePlot();
- void DoPlot(anyOutput *target);
- DWORD GetColor(int select);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- void RegGO(void *n);
- bool FileIO(int rw);
-
-private:
- long nPoints;
- LineDEF BubbleLine, BubbleFillLine;
- FillDEF BubbleFill;
- Bubble **Bubbles;
-};
-
-class PolarPlot:public Plot{
-public:
- PolarPlot(GraphObj *par, DataObj *d);
- PolarPlot(int src);
- ~PolarPlot();
- double GetSize(int select);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- void RegGO(void *n);
- bool FileIO(int rw);
-
- bool AddPlot();
- bool Config();
-
-private:
- int nPlots, nAxes;
- double offs;
- anyOutput *CurrDisp;
- fRECT CurrRect;
- LineDEF FillLine;
- FillDEF Fill;
- Plot **Plots;
- GraphObj **Axes; //Axis not yet defined
-};
-
-class BoxPlot:public Plot {
-public:
- BoxPlot(GraphObj *par, DataObj *d);
- BoxPlot(int src);
- BoxPlot(GraphObj *par, DataObj *dt, int mode, int c1, int c2, int c3);
- ~BoxPlot();
- double GetSize(int select);
- bool SetSize(int select, double value);
- 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);
- bool ForEach(int cmd, void *tmp, anyOutput *o);
- void CreateData();
-
-private:
- char *xRange, *yRange, *case_prefix;
- long nPoints;
- double ci_box, ci_err;
- DataObj *curr_data;
- lfPOINT BoxDist;
- Box **Boxes;
- Whisker **Whiskers;
- Symbol **Symbols;
- Label **Labels;
- DataLine *TheLine;
-};
-
-class DensDisp:public Plot {
-public:
- DensDisp(GraphObj *par, DataObj *d);
- DensDisp(int src);
- ~DensDisp();
- bool SetSize(int select, double value);
- 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);
-
-private:
- LineDEF DefLine, DefFillLine;
- FillDEF DefFill;
- long nPoints;
- char *xRange, *yRange;
- Box **Boxes;
-
- void DoUpdate();
-
-};
-
-class StackBar:public Plot{
-public:
- int numPlots, numXY, numPG, numPL;
- BoxPlot **Boxes;
- PlotScatt **xyPlots;
- DataPolygon **Polygons;
- DataLine **Lines;
- lfPOINT dspm;
-
- StackBar(GraphObj *par, DataObj *d);
- StackBar(int src);
- ~StackBar();
- bool SetSize(int select, double value);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
+class GoGroup:public Plot {
+public:
+ GraphObj **Objects;
+ int nObs;
+ lfPOINT fPos;
+
+ GoGroup(GraphObj *par, DataObj *d);
+ GoGroup(int src);
+ ~GoGroup();
+ double GetSize(int select);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
void RegGO(void *n);
- bool FileIO(int rw);
-
-private:
- char *ssXrange, *ssYrange;
- double StartVal;
- int cum_data_mode;
- DataObj *CumData;
-};
-
-class StackPG:public StackBar{
-public:
- StackPG(GraphObj *par, DataObj *d);
-};
-
-class GroupBars:public StackBar{
-public:
- GroupBars(GraphObj *par, DataObj *d):StackBar(par, d){};
- bool PropertyDlg();
-};
-
-class Waterfall:public StackBar{
-public:
- Waterfall(GraphObj *par, DataObj *d);
- bool PropertyDlg();
-};
+ bool FileIO(int rw);
+};
-class MultiLines:public StackBar{
+class StarChart:public GoGroup {
public:
- MultiLines(GraphObj *par, DataObj *d);
+ StarChart(GraphObj *par, DataObj *d);
bool PropertyDlg();
+
+private:
};
-
-class PieChart:public Plot {
-public:
- PieChart(GraphObj *par, DataObj *d);
- PieChart(int src);
- ~PieChart();
- bool SetSize(int select, double value);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- void RegGO(void *n);
- bool FileIO(int rw);
- void DoUpdate();
-
-private:
- long nPts;
- char *ssRefA, *ssRefR;
- lfPOINT CtDef;
- double FacRad;
- segment **Segments;
-};
-
-class RingChart:public PieChart {
-public:
- RingChart(GraphObj *par, DataObj *d);
-};
-
-class GoGroup:public Plot {
-public:
- GraphObj **Objects;
- int nObs;
- lfPOINT fPos;
-
- GoGroup(GraphObj *par, DataObj *d);
- GoGroup(int src);
- ~GoGroup();
- double GetSize(int select);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- void RegGO(void *n);
- bool FileIO(int rw);
-};
-
-class StarChart:public GoGroup {
-public:
- StarChart(GraphObj *par, DataObj *d);
- bool PropertyDlg();
-
-private:
-};
-
-class Ribbon:public Plot {
-public:
- Ribbon(GraphObj *par, DataObj *d, double z, double width, char *xr, char *yr);
- Ribbon(GraphObj *par, DataObj *d, char *xr, char *yr, char *zr);
+
+class Ribbon:public Plot {
+public:
+ Ribbon(GraphObj *par, DataObj *d, double z, double width, char *xr, char *yr);
+ Ribbon(GraphObj *par, DataObj *d, int which, char *xr, char *yr, char *zr);
Ribbon(GraphObj *par, DataObj *d, GraphObj **go, int ngo);
- Ribbon(int src);
- ~Ribbon();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
+ Ribbon(int src);
+ ~Ribbon();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
void RegGO(void *n);
- bool FileIO(int rw);
-
-private:
- long nPlanes, nVal;
- double z_value, z_width, relwidth;
- char *ssRefX, *ssRefY, *ssRefZ;
- FillDEF Fill;
+ bool FileIO(int rw);
+
+private:
+ long nPlanes, nVal;
+ double z_value, z_width, relwidth;
+ char *ssRefX, *ssRefY, *ssRefZ;
+ FillDEF Fill;
LineDEF Line;
- fPOINT3D *values;
- Plane3D **planes;
-
- void CreateObs();
- void UpdateObs(bool bNewData);
-};
+ fPOINT3D *values;
+ Plane3D **planes;
+
+ void CreateObs();
+ void UpdateObs(bool bNewData);
+};
class Grid3D:public Plot {
public:
@@ -1927,258 +2051,258 @@ private:
Arrow3D **Arrows;
Ribbon *rib;
};
-
-class Limits:public Plot {
-public:
- Limits(int src);
- ~Limits();
- double GetSize(int select);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool FileIO(int rw);
-};
-
-class Function:public Plot{
-public:
- Function(GraphObj *par, DataObj *d);
- Function(int src);
- ~Function();
- bool SetSize(int select, double value);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
+
+class Limits:public Plot {
+public:
+ Limits(int src);
+ ~Limits();
+ double GetSize(int select);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool FileIO(int rw);
+};
+
+class Function:public Plot{
+public:
+ Function(GraphObj *par, DataObj *d, char *desc);
+ Function(int src);
+ ~Function();
+ bool SetSize(int select, double value);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
void RegGO(void *n);
- bool FileIO(int rw);
-
+ bool FileIO(int rw);
+
bool Update(anyOutput *o, DWORD flags);
- LineDEF *GetLine() {return &Line;};
-
-private:
- double x1,x2, xstep;
- LineDEF Line;
- char *param;
- char *cmdxy;
- DataLine *dl;
-};
-
-class FitFunc:public Plot{
-public:
- FitFunc(GraphObj *par, DataObj *d);
- FitFunc(int src);
- ~FitFunc();
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
+ LineDEF *GetLine() {return &Line;};
+
+private:
+ double x1,x2, xstep;
+ LineDEF Line;
+ char *param;
+ char *cmdxy;
+ DataLine *dl;
+};
+
+class FitFunc:public Plot{
+public:
+ FitFunc(GraphObj *par, DataObj *d);
+ FitFunc(int src);
+ ~FitFunc();
+ bool SetSize(int select, double value);
+ 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);
-
-private:
- double x1, x2, xstep, conv, chi2;
- char *ssXref, *ssYref;
- long nPoints;
- int maxiter;
- LineDEF Line;
- Symbol **Symbols;
- char *cmdxy, *parxy;
- Function *dl;
-};
-
-class GridLine:public GraphObj{
-public:
- DWORD flags;
- long ncpts;
- POINT pts[6], *cpts;
- LineDEF LineDef;
- POINT3D *gl1, *gl2, *gl3;
- line_segment **ls;
+ bool FileIO(int rw);
+
+private:
+ double x1, x2, xstep, conv, chi2;
+ char *ssXref, *ssYref;
+ long nPoints;
+ int maxiter;
+ LineDEF Line;
+ Symbol **Symbols;
+ char *cmdxy, *parxy;
+ Function *dl;
+};
+
+class GridLine:public GraphObj{
+public:
+ DWORD flags;
+ long ncpts;
+ POINT pts[6], *cpts;
+ LineDEF LineDef;
+ POINT3D *gl1, *gl2, *gl3;
+ line_segment **ls;
bool bModified;
anyOutput *mo;
- RECT mrc;
-
- GridLine(GraphObj *par, DataObj *d, int type, DWORD df);
- GridLine(int src);
- ~GridLine();
- virtual void DoPlot(anyOutput *o);
- virtual void DoMark(anyOutput *o, bool mark);
- virtual bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
- bool FileIO(int rw);
-};
-
-class GridLine3D:public GridLine {
-public:
- GridLine3D(GraphObj *par, DataObj *d, int type, DWORD df);
- GridLine3D(int src);
- ~GridLine3D();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
-};
-
-class GridRadial:public GridLine {
-public:
- GridRadial(GraphObj *par, DataObj *d, int type, DWORD df);
- GridRadial(int src);
- ~GridRadial();
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
-};
-
-class Tick:public GraphObj{
-public:
- Tick(GraphObj *par, DataObj *d, double val, DWORD Flags);
- Tick(int src);
- ~Tick();
- double GetSize(int select);
- bool SetSize(int select, double value);
- bool SetColor(int select, DWORD col);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
+ RECT mrc;
+
+ GridLine(GraphObj *par, DataObj *d, int type, DWORD df);
+ GridLine(int src);
+ ~GridLine();
+ virtual void DoPlot(anyOutput *o);
+ virtual void DoMark(anyOutput *o, bool mark);
+ virtual bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
+ bool FileIO(int rw);
+};
+
+class GridLine3D:public GridLine {
+public:
+ GridLine3D(GraphObj *par, DataObj *d, int type, DWORD df);
+ GridLine3D(int src);
+ ~GridLine3D();
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+};
+
+class GridRadial:public GridLine {
+public:
+ GridRadial(GraphObj *par, DataObj *d, int type, DWORD df);
+ GridRadial(int src);
+ ~GridRadial();
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+};
+
+class Tick:public GraphObj{
+public:
+ Tick(GraphObj *par, DataObj *d, double val, DWORD Flags);
+ Tick(int src);
+ ~Tick();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ bool SetColor(int select, DWORD col);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
void RegGO(void *n);
- bool FileIO(int rw);
-
- void DoPlot(double six, double csx, anyOutput *o);
-
-private:
- double value, size, fix, fiy, fiz, lsi, lcsi, angle, lbx, lby;
- bool bModified;
+ bool FileIO(int rw);
+
+ void DoPlot(double six, double csx, anyOutput *o);
+
+private:
+ double value, size, fix, fiy, fiz, lsi, lcsi, angle, lbx, lby;
+ bool bModified;
anyOutput *mo;
RECT mrc;
- int gl_type;
- GridLine *Grid;
- Label *label;
- DWORD flags;
- POINT pts[2];
- line_segment *ls;
-};
-
-class Axis:public GraphObj{
-public:
- AxisDEF *axis;
- LineDEF axline;
-
- Axis(GraphObj *par, DataObj *d, AxisDEF *ax, DWORD flags);
- Axis(int src);
- ~Axis();
- double GetSize(int select);
- bool SetSize(int select, double value);
- DWORD GetColor(int select);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
+ int gl_type;
+ GridLine *Grid;
+ Label *label;
+ DWORD flags;
+ POINT pts[2];
+ line_segment *ls;
+};
+
+class Axis:public GraphObj{
+public:
+ AxisDEF *axis;
+ LineDEF axline;
+
+ Axis(GraphObj *par, DataObj *d, AxisDEF *ax, DWORD flags);
+ Axis(int src);
+ ~Axis();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ DWORD GetColor(int select);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
void RegGO(void *n);
- bool FileIO(int rw);
-
- AxisDEF *GetAxis() {return axis;};
- bool GetValuePos(double val, double *fix, double *fiy, double *fiz, anyOutput *o);
- void TickFile(char *name);
- void BreakSymbol(POINT3D *p1, double dsi, double dcsi, bool connect, anyOutput *o);
- void DrawBreaks(anyOutput *o);
-
-private:
- double sizAxLine, sizAxTick, sizAxTickLabel;
- double si, csi;
- double brksymsize, brkgap, tick_angle;
- int brksym, nl_segs, gl_type, tick_type;
- bool bModified;
- DWORD colAxis;
- LineDEF GridLine;
- Tick **Ticks;
- GraphObj *axisLabel;
- long NumTicks;
- POINT pts[2];
- POINT3D pts3D[2];
- fPOINT3D flim[2];
- lfPOINT lbdist, tlbdist;
- TextDEF tlbdef;
- anyOutput *drawOut, *scaleOut;
- line_segment **l_segs;
- char *ssMATval, *ssMATlbl, *ssMITval;
- anyOutput *mo;
- RECT mrc;
-
- void SetTick(long idx, double val, DWORD flags, char *txt);
- void CreateTicks();
- void ManuTicks(double sa, double st, int n, DWORD flags);
- void UpdateTicks();
- bool ssTicks();
-
-};
-
-class Plot3D:public Plot{
- typedef struct {
- double Zmin, Zmax;
- GraphObj *go;
- }obj_desc;
-public:
- long nPlots, nAxes;
- Axis **Axes;
- GraphObj **plots;
- double *RotDef;
+ bool FileIO(int rw);
+
+ AxisDEF *GetAxis() {return axis;};
+ bool GetValuePos(double val, double *fix, double *fiy, double *fiz, anyOutput *o);
+ void TickFile(char *name);
+ void BreakSymbol(POINT3D *p1, double dsi, double dcsi, bool connect, anyOutput *o);
+ void DrawBreaks(anyOutput *o);
+
+private:
+ double sizAxLine, sizAxTick, sizAxTickLabel;
+ double si, csi;
+ double brksymsize, brkgap, tick_angle;
+ int brksym, nl_segs, gl_type, tick_type;
+ bool bModified;
+ DWORD colAxis;
+ LineDEF GridLine;
+ Tick **Ticks;
+ GraphObj *axisLabel;
+ long NumTicks;
+ POINT pts[2];
+ POINT3D pts3D[2];
+ fPOINT3D flim[2];
+ lfPOINT lbdist, tlbdist;
+ TextDEF tlbdef;
+ anyOutput *drawOut, *scaleOut;
+ line_segment **l_segs;
+ char *ssMATval, *ssMATlbl, *ssMITval;
+ anyOutput *mo;
+ RECT mrc;
+
+ void SetTick(long idx, double val, DWORD flags, char *txt);
+ void CreateTicks();
+ void ManuTicks(double sa, double st, int n, DWORD flags);
+ void UpdateTicks();
+ bool ssTicks();
+
+};
+
+class Plot3D:public Plot{
+ typedef struct {
+ double Zmin, Zmax;
+ GraphObj *go;
+ }obj_desc;
+public:
+ long nPlots, nAxes;
+ Axis **Axes;
+ GraphObj **plots;
+ double *RotDef;
fPOINT3D cub1, cub2, rotC;
-
- Plot3D(GraphObj *par, DataObj *d, DWORD flags);
- Plot3D(int src);
- ~Plot3D();
- double GetSize(int select);
- bool SetColor(int select, DWORD col);
- void DoPlot(anyOutput *o);
- void DoMark(anyOutput *o, bool mark);
- virtual bool Command(int cmd, void *tmpl, anyOutput *o);
- virtual bool PropertyDlg();
+
+ Plot3D(GraphObj *par, DataObj *d, DWORD flags);
+ Plot3D(int src);
+ ~Plot3D();
+ double GetSize(int select);
+ bool SetColor(int select, DWORD col);
+ void DoPlot(anyOutput *o);
+ void DoMark(anyOutput *o, bool mark);
+ virtual bool Command(int cmd, void *tmpl, anyOutput *o);
+ virtual bool PropertyDlg();
virtual void RegGO(void *n);
- virtual bool FileIO(int rw);
-
- void * ObjThere(int x, int y);
- void Track(POINT *p, anyOutput *o);
- void CreateAxes();
- void DoAutoscale();
- void CalcRotation(double dx, double dy, anyOutput *o, bool accept);
- bool AcceptObj(GraphObj *go);
- void SortObj();
- bool Rotate(double dx, double dy, double dz, anyOutput *o, bool accept);
-
-private:
- long nObs, nmaxObs;
- DWORD crea_flags;
- Drag3D *drag;
- fPOINT3D cu1, cu2, rc;
- obj_desc **dispObs;
-
- bool AddPlot(int family);
-};
-
-class Chart25D:public Plot3D {
-public:
- Chart25D(GraphObj *par, DataObj *d, DWORD flags);
- ~Chart25D();
- bool PropertyDlg();
-
-private:
- fPOINT3D dspm;
-};
-
-class Ribbon25D:public Plot3D {
-public:
- Ribbon25D(GraphObj *par, DataObj *d, DWORD flags);
- ~Ribbon25D();
- bool PropertyDlg();
-
-private:
- fPOINT3D dspm;
-};
-
-class BubblePlot3D:public Plot3D {
-public:
- BubblePlot3D(GraphObj *par, DataObj *d);
- ~BubblePlot3D();
- bool PropertyDlg();
-};
+ virtual bool FileIO(int rw);
+
+ void * ObjThere(int x, int y);
+ void Track(POINT *p, anyOutput *o);
+ void CreateAxes();
+ void DoAutoscale();
+ void CalcRotation(double dx, double dy, anyOutput *o, bool accept);
+ bool AcceptObj(GraphObj *go);
+ void SortObj();
+ bool Rotate(double dx, double dy, double dz, anyOutput *o, bool accept);
+
+private:
+ long nObs, nmaxObs;
+ DWORD crea_flags;
+ Drag3D *drag;
+ fPOINT3D cu1, cu2, rc;
+ obj_desc **dispObs;
+
+ bool AddPlot(int family);
+};
+
+class Chart25D:public Plot3D {
+public:
+ Chart25D(GraphObj *par, DataObj *d, DWORD flags);
+ ~Chart25D();
+ bool PropertyDlg();
+
+private:
+ fPOINT3D dspm;
+};
+
+class Ribbon25D:public Plot3D {
+public:
+ Ribbon25D(GraphObj *par, DataObj *d, DWORD flags);
+ ~Ribbon25D();
+ bool PropertyDlg();
+
+private:
+ fPOINT3D dspm;
+};
+
+class BubblePlot3D:public Plot3D {
+public:
+ BubblePlot3D(GraphObj *par, DataObj *d);
+ ~BubblePlot3D();
+ bool PropertyDlg();
+};
class Func3D:public Plot3D {
public:
@@ -2223,72 +2347,76 @@ private:
DataObj *gda;
Grid3D *gob;
};
-
-class Graph:public GraphObj{
-public:
- long NumPlots;
- int ToolMode, units, nscp;
- anyOutput *Disp, *CurrDisp;
- fRECT GRect, DRect, Bounds;
- bool OwnDisp, bModified;
- fRECT CurrRect;
- GraphObj **Plots, *PasteObj;
- DWORD ColBG, ColAX;
- GraphObj **Sc_Plots;
- Axis **Axes;
- char *filename;
-
- Graph(GraphObj *par, DataObj *d, anyOutput *o);
- Graph(int src);
- ~Graph();
- double GetSize(int select);
- bool SetSize(int select, double value);
- DWORD GetColor(int select);
- virtual void DoPlot(anyOutput *o);
- virtual bool Command(int cmd, void *tmpl, anyOutput *o);
- bool PropertyDlg();
+
+class Graph:public GraphObj{
+public:
+ long NumPlots;
+ int ToolMode, units, nscp;
+ anyOutput *Disp, *CurrDisp;
+ fRECT GRect, DRect, Bounds;
+ bool OwnDisp, bModified;
+ fRECT CurrRect;
+ GraphObj **Plots, *PasteObj;
+ DWORD ColBG, ColAX;
+ GraphObj **Sc_Plots;
+ Axis **Axes;
+ char *filename;
+
+ Graph(GraphObj *par, DataObj *d, anyOutput *o);
+ Graph(int src);
+ ~Graph();
+ double GetSize(int select);
+ bool SetSize(int select, double value);
+ DWORD GetColor(int select);
+ virtual void DoPlot(anyOutput *o);
+ virtual bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool PropertyDlg();
void RegGO(void *n);
- virtual bool FileIO(int rw);
-
-private:
- int NumAxes, AxisTempl, tickstyle, zoom_level;
- RECT rcDim, rcUpd, rc_mrk;
- DWORD ColDR, ColGR, ColGRL;
- AxisDEF x_axis, y_axis;
- FrmRect *frm_g, *frm_d;
- bool dirty;
- POINT *tl_pts;
- long tl_nPts;
- ZoomDEF *zoom_def;
-
- bool AddPlot(int family);
- void DoAutoscale();
- void CreateAxes(int templ);
- bool ExecTool(MouseEvent *mev);
- bool Configure();
- bool AddAxis();
- bool MoveObj(int cmd, GraphObj *g);
- bool DoZoom(char *z);
-};
-
-class Page:public Graph{
-public:
- Page(GraphObj *par, DataObj *d);
- Page(int src);
- void DoPlot(anyOutput *o);
- bool Command(int cmd, void *tmpl, anyOutput *o);
+ virtual bool FileIO(int rw);
+ virtual double DefSize(int select);
+
+private:
+ int NumAxes, AxisTempl, tickstyle, zoom_level;
+ double scale;
+ RECT rcDim, rcUpd, rc_mrk;
+ DWORD ColDR, ColGR, ColGRL;
+ AxisDEF x_axis, y_axis;
+ FrmRect *frm_g, *frm_d;
+ bool dirty;
+ POINT *tl_pts;
+ long tl_nPts;
+ ZoomDEF *zoom_def;
+
+ bool AddPlot(int family);
+ void DoAutoscale();
+ void CreateAxes(int templ);
+ bool ExecTool(MouseEvent *mev);
+ bool Configure();
+ bool AddAxis();
+ bool MoveObj(int cmd, GraphObj *g);
+ bool DoZoom(char *z);
+ bool DoScale(scaleINFO *sc, anyOutput *o);
+};
+
+class Page:public Graph{
+public:
+ Page(GraphObj *par, DataObj *d);
+ Page(int src);
+ void DoPlot(anyOutput *o);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
void RegGO(void *n);
- bool FileIO(int rw);
-
-private:
- LineDEF LineDef;
- FillDEF FillDef;
-
- bool Configure();
-};
+ bool FileIO(int rw);
+ double DefSize(int select);
+
+private:
+ LineDEF LineDef;
+ FillDEF FillDef;
+
+ bool Configure();
+};
class ObjTree:public GraphObj {
-public:
+public:
ObjTree(GraphObj *par, DataObj *d, GraphObj *root);
~ObjTree();
void DoPlot(anyOutput *o);
@@ -2307,342 +2435,360 @@ private:
TextDEF TextDef;
};
-class notary{
-public:
- notary();
- ~notary();
- unsigned long RegisterGO(GraphObj *go);
- void AddRegGO(GraphObj *go);
- bool PushGO(unsigned long id, GraphObj *go);
- GraphObj *PopGO(unsigned long id);
- void FreeStack();
-
-private:
- unsigned long NextPopGO, NextPushGO, NextRegGO;
- GraphObj ***gObs;
- GraphObj ***goStack;
-};
-
-class Default{
-public:
- int dUnits, cUnits;
- char DecPoint[2], ColSep[2];
- char *svgAttr, *svgScript, *currPath, *IniFile;
+class notary{
+public:
+ notary();
+ ~notary();
+ int RegisterGO(GraphObj *go);
+ void AddRegGO(GraphObj *go);
+ bool PushGO(unsigned int id, GraphObj *go);
+ GraphObj *PopGO(unsigned int id);
+ void FreeStack();
+
+private:
+ unsigned int NextPopGO, NextPushGO, NextRegGO;
+ GraphObj ***gObs;
+ GraphObj ***goStack;
+};
+
+class Default{
+public:
+ int dUnits, cUnits;
+ char DecPoint[2], ColSep[2];
+ char *svgAttr, *svgScript, *currPath, *IniFile;
char *File1, *File2, *File3, *File4, *File5, *File6;
- char *fmt_date, *fmt_time, *fmt_datetime;
- double min4log, ss_txt;
- RECT clipRC;
-
- Default();
- ~Default();
- void SetDisp(anyOutput *o);
- double GetSize(int select);
- DWORD Color(int select);
- LineDEF *GetLine();
- void SetLine(int u, LineDEF *l, int which);
- FillDEF *GetFill();
- void SetFill(int u, FillDEF *fd);
- LineDEF *GetOutLine();
- bool PropertyDlg();
- LineDEF *plLineDEF(LineDEF *ld);
- LineDEF *pgLineDEF(LineDEF *ol);
- FillDEF *pgFillDEF(FillDEF *fd);
- double rrectRad(double rad);
- void FileHistory(char *path);
-
-private:
- LineDEF Line_0, Line_1, Line_2, *pl, *pgl;
- FillDEF Fill_0, Fill_1, Fill_2, *pg;
- LineDEF FillLine_0, FillLine_1, FillLine_2, *pg_fl;
- LineDEF OutLine_0, OutLine_1, OutLine_2;
- double *rrect_rad;
- anyOutput *cdisp;
- DWORD axis_color;
-};
-
-class DefsRW:public GraphObj{
-public:
- DefsRW():GraphObj(0, 0){Id = 0; return;};
- DefsRW(int rw):GraphObj(0,0){FileIO(rw);Id=GO_DEFRW;return;};
- ~DefsRW() {return;};
- bool FileIO(int rw);
-};
-
-class ReadCache{
-public:
- unsigned char last, *Cache, Line[4096];
- int iFile, idx, max;
- bool eof;
-
- ReadCache();
- ~ReadCache();
- virtual bool Open(char *name);
- virtual void Close();
- virtual unsigned char Getc();
- virtual unsigned char *GetField();
- void ReadLine(char *dest, int size);
- bool GetInt(long *in);
- bool GetFloat(double *fn);
- unsigned char Lastc();
- bool IsEOF();
-};
-
-class MemCache:public ReadCache{
-public:
- MemCache(unsigned char *ptr);
- ~MemCache();
- bool Open(char *name){return false;};
- void Close(){return;};
- unsigned char Getc();
- unsigned char *GetField();
-};
-
-#define UNDO_CONTINUE 0x01
-#define UNDO_STORESET 0x1000
-class UndoObj {
- enum {UNDO_UNDEFINED, UNDO_DEL_GO, UNDO_GOLIST, UNDO_DROPMEM,
- UNDO_VALDWORD, UNDO_VALINT, UNDO_VALLONG, UNDO_OBJCONF, UNDO_OBJCONF_1,
+ char *fmt_date, *fmt_time, *fmt_datetime;
+ double min4log, ss_txt;
+ RECT clipRC;
+
+ Default();
+ ~Default();
+ void SetDisp(anyOutput *o);
+ double GetSize(int select);
+ DWORD Color(int select);
+ LineDEF *GetLine();
+ void SetLine(int u, LineDEF *l, int which);
+ FillDEF *GetFill();
+ void SetFill(int u, FillDEF *fd);
+ LineDEF *GetOutLine();
+ bool PropertyDlg();
+ LineDEF *plLineDEF(LineDEF *ld);
+ LineDEF *pgLineDEF(LineDEF *ol);
+ FillDEF *pgFillDEF(FillDEF *fd);
+ double rrectRad(double rad);
+ void FileHistory(char *path);
+
+private:
+ LineDEF Line_0, Line_1, Line_2, *pl, *pgl;
+ FillDEF Fill_0, Fill_1, Fill_2, *pg;
+ LineDEF FillLine_0, FillLine_1, FillLine_2, *pg_fl;
+ LineDEF OutLine_0, OutLine_1, OutLine_2;
+ double *rrect_rad;
+ anyOutput *cdisp;
+ DWORD axis_color;
+};
+
+class DefsRW:public GraphObj{
+public:
+ DefsRW():GraphObj(0, 0){Id = 0; return;};
+ DefsRW(int rw):GraphObj(0,0){FileIO(rw);Id=GO_DEFRW;return;};
+ ~DefsRW() {return;};
+ bool FileIO(int rw);
+};
+
+class ReadCache{
+public:
+ unsigned char last, *Cache, Line[4096];
+ int iFile, idx, max;
+ bool eof;
+
+ ReadCache();
+ ~ReadCache();
+ virtual bool Open(char *name);
+ virtual void Close();
+ virtual unsigned char Getc();
+ virtual unsigned char *GetField();
+ void ReadLine(char *dest, int size);
+ bool GetInt(long *in);
+ bool GetFloat(double *fn);
+ unsigned char Lastc();
+ bool IsEOF();
+};
+
+class MemCache:public ReadCache{
+public:
+ MemCache(unsigned char *ptr);
+ ~MemCache();
+ bool Open(char *name){return false;};
+ void Close(){return;};
+ unsigned char Getc();
+ unsigned char *GetField();
+};
+
+#define UNDO_CONTINUE 0x01
+#define UNDO_STORESET 0x1000
+class UndoObj {
+ enum {UNDO_UNDEFINED, UNDO_DEL_GO, UNDO_GOLIST, UNDO_DROPMEM,
+ UNDO_VALDWORD, UNDO_VALINT, UNDO_VALLONG, UNDO_OBJCONF, UNDO_OBJCONF_1,
UNDO_LFP, UNDO_POINT, UNDO_VOIDPTR, UNDO_MOVE, UNDO_RECT,
UNDO_STRING, UNDO_ROTDEF, UNDO_SETGO, UNDO_LINEDEF, UNDO_FILLDEF,
UNDO_AXISDEF, UNDO_LFP3D, UNDO_FLOAT, UNDO_MEM, UNDO_MUTATE,
- UNDO_DROPGOLIST, UNDO_TEXTDEF, UNDO_SAVVAR, UNDO_DATA, UNDO_ET};
- typedef struct _UndoInfo {
- int cmd;
- DWORD flags;
- GraphObj *owner;
- void *data;
- void **loc;
- ZoomDEF zd;
- }UndoInfo;
-
- typedef struct _UndoList {
- void *array;
- void **loc_arr;
- long count, size;
- long *loc_count;
- }UndoList;
-
- typedef struct _UndoBuff {
- int count;
- UndoInfo **buff;
- anyOutput *disp;
- }UndoBuff;
+ UNDO_DROPGOLIST, UNDO_TEXTDEF, UNDO_SAVVAR, UNDO_DATA, UNDO_ET, UNDO_TEXTBUF};
+ typedef struct _UndoInfo {
+ int cmd;
+ DWORD flags;
+ GraphObj *owner;
+ void *data;
+ void **loc;
+ ZoomDEF zd;
+ }UndoInfo;
+
+ typedef struct _UndoList {
+ void *array;
+ void **loc_arr;
+ long count, size;
+ long *loc_count;
+ }UndoList;
+
+ typedef struct _UndoBuff {
+ int count;
+ UndoInfo **buff;
+ anyOutput *disp;
+ }UndoBuff;
typedef struct _EtBuff {
char *txt;
DataObj *DaO;
int *cur, *m1, *m2, vcur, vm1, vm2, row, col;
- }EtBuff;
-
-public:
- int *pcb;
+ }EtBuff;
+
+ typedef struct _TextBuff {
+ int *psize, size, *ppos, pos;
+ unsigned char **pbuff, *buff;
+ }TextBuff;
+
+public:
+ int *pcb;
anyOutput *cdisp, *ldisp;
bool busy;
-
+
UndoObj();
- ~UndoObj();
- void Flush();
+ ~UndoObj();
+ void Flush();
+ bool isEmpty(anyOutput *o);
void SetDisp(anyOutput *o);
- void KillDisp(anyOutput *o);
- void InvalidGO(GraphObj *go);
- void Pop(anyOutput *o);
- void Restore(bool redraw, anyOutput *o);
- void ListGOmoved(GraphObj **oldlist, GraphObj **newlist, long size);
- void DeleteGO(GraphObj **go, DWORD flags, anyOutput *o);
- void MutateGO(GraphObj **old, GraphObj *repl, DWORD flags, anyOutput *o);
- void StoreListGO(GraphObj *parent, GraphObj ***go, long *count, DWORD flags);
- void DropListGO(GraphObj *parent, GraphObj ***go, long *count, DWORD flags);
- void DropMemory(GraphObj *parent, void **mem, DWORD flags);
- void SavVarBlock(GraphObj *parent, void **mem, DWORD flags);
+ void KillDisp(anyOutput *o);
+ void InvalidGO(GraphObj *go);
+ void Pop(anyOutput *o);
+ void Restore(bool redraw, anyOutput *o);
+ void ListGOmoved(GraphObj **oldlist, GraphObj **newlist, long size);
+ void DeleteGO(GraphObj **go, DWORD flags, anyOutput *o);
+ void MutateGO(GraphObj **old, GraphObj *repl, DWORD flags, anyOutput *o);
+ void StoreListGO(GraphObj *parent, GraphObj ***go, long *count, DWORD flags);
+ void DropListGO(GraphObj *parent, GraphObj ***go, long *count, DWORD flags);
+ void DropMemory(GraphObj *parent, void **mem, DWORD flags);
+ void SavVarBlock(GraphObj *parent, void **mem, DWORD flags);
void ValDword(GraphObj *parent, DWORD *val, DWORD flags);
- void Point(GraphObj *parent, POINT *pt, anyOutput * o, DWORD flags);
+ void Point(GraphObj *parent, POINT *pt, anyOutput * o, DWORD flags);
void VoidPtr(GraphObj *parent, void **pptr, void *ptr, anyOutput * o, DWORD flags);
- void ValInt(GraphObj *parent, int *val, DWORD flags);
+ void ValInt(GraphObj *parent, int *val, DWORD flags);
void ValLong(GraphObj *parent, long *val, DWORD flags);
- void ObjConf(GraphObj *go, DWORD flags);
- int SaveLFP(GraphObj *go, lfPOINT *lfp, DWORD flags);
- void MoveObj(GraphObj *go, lfPOINT *lfp, DWORD flags);
- void ValRect(GraphObj *go, fRECT *rec, DWORD flags);
- void String(GraphObj *go, char **s, DWORD flags);
- void RotDef(GraphObj *go, double **d, DWORD flags);
- void SetGO(GraphObj *parent, GraphObj **where, GraphObj *go, DWORD flags);
- void Line(GraphObj *go, LineDEF *ld, DWORD flags);
- void Fill(GraphObj *go, FillDEF *fd, DWORD flags);
- void AxisDef(GraphObj *go, AxisDEF *ad, DWORD flags);
- void TextDef(GraphObj *go, TextDEF *td, DWORD flags);
- void ValLFP3D(GraphObj *go, fPOINT3D *lfp, DWORD flags);
- void ValFloat(GraphObj *parent, double *val, DWORD flags);
+ void ObjConf(GraphObj *go, DWORD flags);
+ int SaveLFP(GraphObj *go, lfPOINT *lfp, DWORD flags);
+ void MoveObj(GraphObj *go, lfPOINT *lfp, DWORD flags);
+ void ValRect(GraphObj *go, fRECT *rec, DWORD flags);
+ int String(GraphObj *go, char **s, DWORD flags);
+ void RotDef(GraphObj *go, double **d, DWORD flags);
+ void SetGO(GraphObj *parent, GraphObj **where, GraphObj *go, DWORD flags);
+ void Line(GraphObj *go, LineDEF *ld, DWORD flags);
+ void Fill(GraphObj *go, FillDEF *fd, DWORD flags);
+ void AxisDef(GraphObj *go, AxisDEF *ad, DWORD flags);
+ void TextDef(GraphObj *go, TextDEF *td, DWORD flags);
+ void ValLFP3D(GraphObj *go, fPOINT3D *lfp, DWORD flags);
+ void ValFloat(GraphObj *parent, double *val, DWORD flags);
void DataMem(GraphObj *go, void **mem, int size, long *count, DWORD flags);
void DataObject(GraphObj *go, anyOutput *o, DataObj *d, RECT *rc, DWORD flags);
void TextCell(EditText *et, anyOutput *o, char *text, int *cur, int *m1, int *m2, void* DaO, DWORD flags);
-
-private:
- UndoInfo **buff, **buff0;
- int stub1, ndisp;
- UndoBuff **buffers;
-
- int NewItem(int cmd, DWORD flags, GraphObj *owner, void *data, void **loc);
- void FreeInfo(UndoInfo** inf);
+ void TextBuffer(GraphObj *parent, int *psize, int *ppos, unsigned char **pbuff, DWORD flags, anyOutput *o);
+
+private:
+ UndoInfo **buff, **buff0;
+ int stub1, ndisp;
+ UndoBuff **buffers;
+
+ int NewItem(int cmd, DWORD flags, GraphObj *owner, void *data, void **loc);
+ void FreeInfo(UndoInfo** inf);
void RestoreConf(UndoInfo *inf);
- void RestoreData(UndoInfo *inf);
-};
-
-//prototypes: spreadwi.cpp
-int ProcMemData(GraphObj *g, unsigned char *ptr, bool dispatch);
-void SpreadMain(bool show);
-
-//prototypes: WinSpec.cpp or QT_Spec.cpp
-char *SaveDataAsName(char *oldname);
-char *SaveGraphAsName(char *oldname);
-char *OpenGraphName(char *oldname);
-char *OpenDataName(char *oldname);
-void InfoBox(char *Msg);
-void ErrorBox(char *Msg);
-bool YesNoBox(char *Msg);
+ void RestoreData(UndoInfo *inf);
+};
+
+//prototypes: spreadwi.cpp
+int ProcMemData(GraphObj *g, unsigned char *ptr, bool dispatch);
+void SpreadMain(bool show);
+
+//prototypes: WinSpec.cpp or QT_Spec.cpp
+char *SaveDataAsName(char *oldname);
+char *SaveGraphAsName(char *oldname);
+char *OpenGraphName(char *oldname);
+char *OpenDataName(char *oldname);
+void InfoBox(char *Msg);
+void ErrorBox(char *Msg);
+bool YesNoBox(char *Msg);
int YesNoCancelBox(char *Msg);
-void Qt_Box();
-void HideTextCursor();
-void HideTextCursorObj(anyOutput *out);
-void ShowTextCursor(anyOutput *out, RECT *disp, DWORD color);
-void HideCopyMark();
-void ShowCopyMark(anyOutput *out, RECT *mrk, int nRec);
-void InitTextCursor(bool init);
-void EmptyClip();
+void Qt_Box();
+void HideTextCursor();
+void HideTextCursorObj(anyOutput *out);
+void ShowTextCursor(anyOutput *out, RECT *disp, DWORD color);
+void HideCopyMark();
+void ShowCopyMark(anyOutput *out, RECT *mrk, int nRec);
+void InitTextCursor(bool init);
+void EmptyClip();
void CopyText(char *txt, int len);
unsigned char* PasteText();
-void GetDesktopSize(int *width, int *height);
-void FindBrowser();
-void LoopDlgWnd();
-void CloseDlgWnd(void *hDlg);
-void ShowDlgWnd(void *hDlg);
-anyOutput *NewDispClass(GraphObj *g);
-bool DelDispClass(anyOutput *w);
-anyOutput *NewBitmapClass(int w, int h, double hr, double vr);
-bool DelBitmapClass(anyOutput *w);
-
-//prototypes: FileIO.cpp
-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 bPaste);
-void SavVarInit(long len);
-void *SavVarFetch();
-
-//prototypes:TheDialog.cpp
-DWORD GetNewColor(DWORD oldcol);
+void GetDesktopSize(int *width, int *height);
+void FindBrowser();
+void LoopDlgWnd();
+void CloseDlgWnd(void *hDlg);
+void ShowDlgWnd(void *hDlg);
+void ResizeDlgWnd(void *hDlg, int w, int h);
+anyOutput *NewDispClass(GraphObj *g);
+bool DelDispClass(anyOutput *w);
+anyOutput *NewBitmapClass(int w, int h, double hr, double vr);
+bool DelBitmapClass(anyOutput *w);
+
+//prototypes: FileIO.cpp
+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 bPaste);
+void SavVarInit(long len);
+void *SavVarFetch();
+
+//prototypes:TheDialog.cpp
+DWORD GetNewColor(DWORD oldcol);
bool ShowLayers(GraphObj *root);
-void GetNewFill(FillDEF *oldfill);
-void ShowBanner(bool show);
-void RLPlotInfo();
-bool DoSpShSize(DataObj *dt);
-bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go);
-bool GetBitmapRes(double *res, double *width, double *height, char *header);
-void OD_scheme(int, void *, RECT *, anyOutput *, void *, int);
-FillDEF *GetSchemeFill(int *i);
-void OD_linedef(int, void *, RECT *, anyOutput *o, void *, int);
-void OD_filldef(int, void *, RECT *, anyOutput *o, void *, int);
-void OD_paperdef(int, void *, RECT *, anyOutput *o, void *, int);
-void FindPaper(double w, double h, double tol);
-bool GetPaper(double *w, double *h);
-void OD_axisplot(int, void *, RECT *, anyOutput *o, void *, int);
-
-//prototypes: Utils.cpp
-anyOutput *GetRectBitmap(RECT *rc, anyOutput *src);
-void RestoreRectBitmap(anyOutput **pmo, RECT *mrc, anyOutput *o);
-void NiceAxis(AxisDEF *axis, int nTick);
-void NiceStep(AxisDEF *axis, int nTick);
-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);
+void GetNewFill(FillDEF *oldfill);
+void ShowBanner(bool show);
+void RLPlotInfo();
+bool DoSpShSize(DataObj *dt);
+bool FillSsRange(DataObj *d, char **range, GraphObj *msg_go);
+bool GetBitmapRes(double *res, double *width, double *height, char *header);
+void OD_scheme(int, void *, RECT *, anyOutput *, void *, int);
+FillDEF *GetSchemeFill(int *i);
+void OD_linedef(int, void *, RECT *, anyOutput *o, void *, int);
+void OD_filldef(int, void *, RECT *, anyOutput *o, void *, int);
+void OD_paperdef(int, void *, RECT *, anyOutput *o, void *, int);
+void FindPaper(double w, double h, double tol);
+bool GetPaper(double *w, double *h);
+void OD_axisplot(int, void *, RECT *, anyOutput *o, void *, int);
+
+//prototypes: Utils.cpp
+anyOutput *GetRectBitmap(RECT *rc, anyOutput *src);
+void RestoreRectBitmap(anyOutput **pmo, RECT *mrc, anyOutput *o);
+void NiceAxis(AxisDEF *axis, int nTick);
+void NiceStep(AxisDEF *axis, int nTick);
+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 rmquot(char *str);
+int strpos(char *needle, char *haystack);
+char *strreplace(char *needle, char *replace, char *haystack);
+char *substr(char *text, int pos1, int pos2);
+int rlp_strcpy(char*dest, int size, char*src);
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);
-char *Nat2Int(char *Text);
-void WriteNatFloatToBuff(char *buff, double val);
-bool Txt2Flt(char *txt, double *val);
-void RmTrail(char *txt);
-double NiceValue(double fv);
-char *Int2ColLabel(int nr, bool uc);
-char *str2xml(char *str);
-char **split(char *str, char sep, int *nl);
+void ChangeChar(char *text, char c1, char c2);
+char *Int2Nat(char *Text);
+char *Nat2Int(char *Text);
+void WriteNatFloatToBuff(char *buff, double val);
+bool Txt2Flt(char *txt, double *val);
+void RmTrail(char *txt);
+double NiceValue(double fv);
+char *Int2ColLabel(int nr, bool uc);
+char *str2xml(char *str);
+char **split(char *str, char sep, int *nl);
char *fit_num_rect(anyOutput *o, int max_width, char *num_str);
-void SetMinMaxRect(RECT *rc, int x1, int y1, int x2, int y2);
-void UpdateMinMaxRect(RECT *rc, int x, int y);
-void IncrementMinMaxRect(RECT *rc, int i);
-bool IsInRect(RECT *rc, int x, int y);
-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 add_to_buff(char** dest, int *pos, int *csize, char *txt, int len);
+void add_int_to_buff(char** dest, int *pos, int *csize, int value, bool lsp, int ndig);
+void add_dbl_to_buff(char** dest, int *pos, int *csize, double value, bool lsp);
+void add_hex_to_buff(char** dest, int *pos, int *csize, DWORD value, bool lsp);
+void SetMinMaxRect(RECT *rc, int x1, int y1, int x2, int y2);
+void UpdateMinMaxRect(RECT *rc, int x, int y);
+void IncrementMinMaxRect(RECT *rc, int i);
+bool IsInRect(RECT *rc, int x, int y);
+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 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);
-unsigned int ColDiff(DWORD col1, DWORD col2);
-DWORD IpolCol(DWORD color1, DWORD color2, double fact);
-double ran2(long *idum);
-unsigned long isqr(unsigned long n);
-bool MatMul(double a[3][3], double b[3][3], double c[3][3]);
-char *GetNumFormat(double Magn);
-void DeleteGO(GraphObj *go);
+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);
+unsigned int ColDiff(DWORD col1, DWORD col2);
+DWORD IpolCol(DWORD color1, DWORD color2, double fact);
+double ran2(long *idum);
+unsigned long isqr(unsigned long n);
+bool MatMul(double a[3][3], double b[3][3], double c[3][3]);
+char *GetNumFormat(double Magn);
+void DeleteGO(GraphObj *go);
bool DeleteGOL(GraphObj ***gol, long n, GraphObj *go, anyOutput *o);
-bool BackupFile(char *FileName);
-bool IsRlpFile(char *FileName);
+bool BackupFile(char *FileName);
+bool IsRlpFile(char *FileName);
bool IsXmlFile(char *FileName);
-bool FileExist(char *FileName);
+bool FileExist(char *FileName);
bool IsPlot3D(GraphObj *g);
-void *memdup(void *ptr, int cb_old, int cb_new);
-double sininv(double val);
-double trig2deg(double si, double csi);
-bool ReplaceGO(GraphObj **oldobj, GraphObj **newobj);
-unsigned int HashValue(unsigned char *str);
+void *memdup(void *ptr, int cb_old, int cb_new);
+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);
-bool cmpTextDEF(TextDEF *t1, TextDEF *t2);
-DWORD CheckNewFloat(double *loc, double old_v, double new_v, GraphObj *par, DWORD flags);
-DWORD CheckNewInt(int *loc, int old_v, int new_v, GraphObj *par, DWORD flags);
-DWORD CheckNewDword(DWORD *loc, DWORD old_v, DWORD new_v, GraphObj *par, DWORD flags);
-DWORD CheckNewLFPoint(lfPOINT *loc, lfPOINT *old_v, lfPOINT *new_v, GraphObj *par, DWORD flags);
-void clip_line_sphere(GraphObj *par, POINT3D **li, int r, int cx, int cy, int cz);
-void clip_line_plane(GraphObj *par, POINT3D **li, POINT3D *pg, int np, double *vec);
-void clip_sphline_sphere(GraphObj *par, POINT3D *lim1, POINT3D *lim2, POINT3D *cent,
- int r1, int r2, int cx, int cy, int cz);
-void clip_sphline_plane(GraphObj *par, POINT3D *lim1, POINT3D *lim2, POINT3D *cent,
- int r1, POINT3D *pg, int np, double *vec);
-void clip_plane_plane(GraphObj *par, POINT3D *pg1, int n1, double *v1, POINT3D *pg2,
- int n2, double *v2, POINT *m, int nm);
-
-//prototypes Export.cpp
-void DoExportWmf(GraphObj *g, char *FileName, float res, DWORD flags);
-void DoExportSvg(GraphObj *g, char *FileName, DWORD flags);
-void DoExportEps(GraphObj *g, char *FileName, DWORD flags);
-
-//prototypes Output.cpp
-void DoExportTif(GraphObj *g, char *FileName, DWORD flags);
-
-//prototypes mfcalc.cpp
-bool do_xyfunc(DataObj *, double, double, double, char *, lfPOINT **, long *, char *);
+bool cmpLineDEF(LineDEF *l1, LineDEF *l2);
+bool cmpFillDEF(FillDEF *f1, FillDEF *f2);
+bool cmpAxisDEF(AxisDEF *a1, AxisDEF *a2);
+bool cmpTextDEF(TextDEF *t1, TextDEF *t2);
+DWORD CheckNewFloat(double *loc, double old_v, double new_v, GraphObj *par, DWORD flags);
+DWORD CheckNewInt(int *loc, int old_v, int new_v, GraphObj *par, DWORD flags);
+DWORD CheckNewDword(DWORD *loc, DWORD old_v, DWORD new_v, GraphObj *par, DWORD flags);
+DWORD CheckNewLFPoint(lfPOINT *loc, lfPOINT *old_v, lfPOINT *new_v, GraphObj *par, DWORD flags);
+void clip_line_sphere(GraphObj *par, POINT3D **li, int r, int cx, int cy, int cz);
+void clip_line_plane(GraphObj *par, POINT3D **li, POINT3D *pg, int np, double *vec);
+void clip_sphline_sphere(GraphObj *par, POINT3D *lim1, POINT3D *lim2, POINT3D *cent,
+ int r1, int r2, int cx, int cy, int cz);
+void clip_sphline_plane(GraphObj *par, POINT3D *lim1, POINT3D *lim2, POINT3D *cent,
+ int r1, POINT3D *pg, int np, double *vec);
+void clip_plane_plane(GraphObj *par, POINT3D *pg1, int n1, double *v1, POINT3D *pg2,
+ int n2, double *v2, POINT *m, int nm);
+
+//prototypes Export.cpp
+void DoExportWmf(GraphObj *g, char *FileName, float res, DWORD flags);
+void DoExportSvg(GraphObj *g, char *FileName, DWORD flags);
+void DoExportEps(GraphObj *g, char *FileName, DWORD flags);
+
+//prototypes Output.cpp
+void DoExportTif(GraphObj *g, char *FileName, DWORD flags);
+
+//prototypes mfcalc.cpp
+char *yywarn(char *txt, bool bNew);
+bool do_xyfunc(DataObj *, double, double, double, char *, lfPOINT **, long *, char *);
bool do_func3D(DataObj *d, double x1, double x2, double xstep, double z1, double z2, double zstep,
char *expr, char *param);
-anyResult *do_formula(DataObj *, char *);
-bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0);
+anyResult *do_formula(DataObj *, char *);
+bool MoveFormula(DataObj *d, char *of, char *nf, int dx, int dy, int r0, int c0);
int do_fitfunc(DataObj *d, char *rx, char *ry, char *rz, char **par, char *expr,
- double conv, int maxiter, double *chi_2);
-
-//prototypes rlp_math.cp
-double **dmatrix(int nrl, int nrh, int ncl, int nch);
-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 *);
+ double conv, int maxiter, double *chi_2);
+
+//prototypes rlp_math.cp
+double **dmatrix(int nrl, int nrh, int ncl, int nch);
+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);
@@ -2665,9 +2811,12 @@ double exp_freq(double x, double l, double s);
double lognorm_dist(double x, double m, double s);
double lognorm_freq(double x, double m, double s);
double chi_dist(double x, double df, double);
+double chi_freq(double x, double df);
double t_dist(double t, double df, double);
+double t_freq(double t, double df);
double pois_dist(double x, double m, double);
double f_dist(double f, double df1, double df2);
+double f_freq(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);
@@ -2684,16 +2833,20 @@ 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_utest(double *x, double *y, int n1, int n2, char *dest, DataObj *data, double *results);
+double d_ttest(double *x, double *y, int n1, int n2, char *dest, DataObj *data, double *results);
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);
+Triangle* Triangulate1(char *xr, char *yr, char *zr, DataObj *data);
Ribbon *SurfTria(GraphObj *parent, DataObj *data, char *text1, char *text2, char *text3);
//prototypes reports.cpp
void rep_anova(GraphObj *parent, DataObj *data);
void rep_regression(GraphObj *parent, DataObj *data);
+void rep_twowaytable(GraphObj *parent, DataObj *data);
+void rep_compmeans(GraphObj *parent, DataObj *data);
+
diff --git a/rlplot.spec b/rlplot.spec
index e280847..88e95c3 100755
--- a/rlplot.spec
+++ b/rlplot.spec
@@ -1,5 +1,5 @@
Name: rlplot
-Version: 1.1
+Version: 1.2
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
+* Thu Oct 19 2006 Reinhard Lackner
+- release 1.2
+
* Fri Feb 24 2006 Reinhard Lackner
- release 1.1
@@ -59,3 +62,4 @@ rm -rf "$RPM_BUILD_ROOT"
* Mon Nov 25 2002 Guido Gonzato
- initial
+
diff --git a/spreadwi.cpp b/spreadwi.cpp
index d8c0ed5..72a5740 100755
--- a/spreadwi.cpp
+++ b/spreadwi.cpp
@@ -1,200 +1,205 @@
-//spreadwin.cpp, (c)2000-2006 by R. Lackner
-//
-// This file is part of RLPlot.
-//
-// RLPlot is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// RLPlot is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with RLPlot; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-#include "rlplot.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+//spreadwin.cpp, (c)2000-2006 by R. Lackner
+//
+// This file is part of RLPlot.
+//
+// RLPlot is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// RLPlot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with RLPlot; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+#include "rlplot.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <time.h>
-#include <math.h>
-
-#include <fcntl.h> //file open flags
-#include <sys/stat.h> //I/O flags
-
-#ifdef _WINDOWS
- #include <io.h> //for read/write
-#else
- #define O_BINARY 0x0
- #include <unistd.h>
-#endif
-
-extern const LineDEF GrayLine;
-extern EditText *CurrText;
-extern char *LoadFile;
-extern char TmpTxt[];
-extern Default defs;
-extern UndoObj Undo;
-
-static ReadCache *Cache = 0L;
+#include <math.h>
+
+#include <fcntl.h> //file open flags
+#include <sys/stat.h> //I/O flags
+
+#ifdef _WINDOWS
+ #include <io.h> //for read/write
+#else
+ #define O_BINARY 0x0
+ #include <unistd.h>
+#endif
+
+extern const LineDEF GrayLine;
+extern GraphObj *CurrGO, *TrackGO; //Selected Graphic Objects
+extern EditText *CurrText;
+extern char *LoadFile;
+extern char TmpTxt[];
+extern Default defs;
+extern UndoObj Undo;
+
+static ReadCache *Cache = 0L;
static TextDEF ssText;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Get item from *.csv file
-bool GetItemCSV(char *Text, int cbText)
-{
- char c;
- int i;
-
- for (i = 0, *Text = 0; i < cbText; ) {
- c = Cache->Getc();
- switch(c) {
- case ',': //column separator
- Text[i] = 0;
- return true;
- case 0x0a: //end of line: mark by false return but text o.k.
- Text[i] = 0;
- return false;
- default:
- if(c > 0x20) Text[i++] = c; //printable character
- else if(i >0 && c == 0x20) Text[i++] = c;
- else if(!c && Cache->IsEOF()) {
- Text[i] = 0;
- return false;
- }
- else Text[i] = 0; //ignore non printing characters
- }
- }
- return false;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// process a memory block (i.e. clipboard data) as if file input
-int ProcMemData(GraphObj *g, unsigned char *ptr, bool dispatch)
-{
- int i, RetVal = FF_UNKNOWN, nt, nl, nc, ns;
-
- if(ptr) {
- for(i = nt = nl = nc = ns = 0; ptr[i] && nl<100; i++) {
- switch(ptr[i]) {
- case 0x09: //tab
- nt++;
- break;
- case 0x0a: //LF
- nl++;
- break;
- case ',':
- nc++;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Get item from *.csv file
+bool GetItemCSV(char *Text, int cbText)
+{
+ char c;
+ int i;
+
+ for (i = 0, *Text = 0; i < cbText; ) {
+ c = Cache->Getc();
+ switch(c) {
+ case ',': //column separator
+ Text[i] = 0;
+ return true;
+ case 0x0a: //end of line: mark by false return but text o.k.
+ Text[i] = 0;
+ return false;
+ default:
+ if(c > 0x20) Text[i++] = c; //printable character
+ else if(i >0 && c == 0x20) Text[i++] = c;
+ else if(!c && Cache->IsEOF()) {
+ Text[i] = 0;
+ return false;
+ }
+ else Text[i] = 0; //ignore non printing characters
+ }
+ }
+ return false;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// process a memory block (i.e. clipboard data) as if file input
+int ProcMemData(GraphObj *g, unsigned char *ptr, bool dispatch)
+{
+ int i, RetVal = FF_UNKNOWN, nt, nl, nc, ns;
+
+ if(ptr) {
+ for(i = nt = nl = nc = ns = 0; ptr[i] && nl<100; i++) {
+ switch(ptr[i]) {
+ case 0x09: //tab
+ nt++;
+ break;
+ case 0x0a: //LF
+ nl++;
break;
- case ' ':
+ case ',':
+ nc++;
+ break;
+ case ' ':
ns++;
break;
- }
- }
- if(dispatch && i && !nt && !nl) {
+ }
+ }
+ if(dispatch && i && !nt && !nl) {
if(CurrText){
g->Command(CMD_SETFOCUS, 0L, 0L);
- for(i = 0; ptr[i]; i++) CurrText->AddChar(ptr[i], i? 0L : Undo.cdisp, 0L);
+ for(i = 0; ptr[i]; i++) CurrText->AddChar(ptr[i], i? 0L : Undo.cdisp, 0L);
g->Command(CMD_REDRAW, 0L, 0L);
}
- }
- else if(nt) RetVal = FF_TSV;
- else if(nl && ptr[0] == '<') RetVal = FF_XML;
- else if(nc == nl && defs.DecPoint[0] == ',') RetVal = FF_TSV;
- else if(nl && nc && 0 == (nc % nl)) RetVal = FF_CSV;
+ }
+ else if(nt) RetVal = FF_TSV;
+ else if(nl && ptr[0] == '<') RetVal = FF_XML;
+ else if(nc == nl && defs.DecPoint[0] == ',') RetVal = FF_TSV;
+ else if(nl && nc && 0 == (nc % nl)) RetVal = FF_CSV;
else if(nl && ns && 0 == (ns % nl)) RetVal = FF_SSV;
- else if(nl) RetVal = FF_TSV;
- if(dispatch) switch(RetVal) {
- case FF_CSV: g->Command(CMD_PASTE_CSV, ptr, 0L); break;
- case FF_TSV: g->Command(CMD_PASTE_TSV, ptr, 0L); break;
+ else if(nl) RetVal = FF_TSV;
+ if(dispatch) switch(RetVal) {
+ case FF_CSV: g->Command(CMD_PASTE_CSV, ptr, 0L); break;
+ case FF_TSV: g->Command(CMD_PASTE_TSV, ptr, 0L); break;
case FF_SSV: g->Command(CMD_PASTE_SSV, ptr, 0L); break;
- case FF_XML: g->Command(CMD_PASTE_XML, ptr, 0L); break;
- }
- }
- return RetVal;
-}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// This graphic object displays a spreadsheet
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class SpreadWin:public GraphObj{
-public:
- anyOutput *w;
- POINT ssOrg;
- RECT currRC;
-
- SpreadWin(GraphObj *par, DataObj *Data);
- ~SpreadWin();
- void DoPlot(anyOutput *target);
- bool Command(int cmd, void *tmpl, anyOutput *o);
-
- bool ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cpos);
+ case FF_XML: g->Command(CMD_PASTE_XML, ptr, 0L); break;
+ }
+ }
+ return RetVal;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// This graphic object displays a spreadsheet
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class SpreadWin:public GraphObj{
+public:
+ anyOutput *w;
+ POINT ssOrg;
+ RECT currRC;
+
+ SpreadWin(GraphObj *par, DataObj *Data);
+ ~SpreadWin();
+ void DoPlot(anyOutput *target);
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+
+ bool ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cpos);
void MarkButtons(char *rng, POINT *cp = 0L);
bool PrintData(anyOutput *o);
- void WriteGraphXML(unsigned char **ptr, long *cbd);
-
-private:
- int ch, cw, fw; //cell height and width, row button width
- bool is_modified;
- char *filename;
+ void WriteGraphXML(unsigned char **ptr, long *cbd);
+
+private:
+ bool is_modified, bDoColWidth;
+ char *filename;
ssButton **cButtons, **rButtons;
ssButton *aButton;
- POINT cpos;
- DataObj *d;
- int NumGraphs;
- Graph **g;
-};
-
-SpreadWin::SpreadWin(GraphObj *par, DataObj *Data):GraphObj(par, Data)
-{
- d = Data; g = 0L; ssOrg.x = ssOrg.y = 0; NumGraphs = 0;
- ch = 19; cw = 76; fw = 32; filename=0L; aButton = 0L;
- w = 0L; cButtons = rButtons = 0L;
- if(w = NewDispClass(this)){
- w->hasHistMenu = true;
- ssText.RotBL = ssText.RotCHAR = 0.0;
- ssText.fSize = 0.0f;
-#ifdef _WINDOWS
- ssText.iSize = w->un2iy(defs.GetSize(SIZE_CELLTEXT));
-#else
- ssText.iSize = w->un2iy(defs.GetSize(SIZE_CELLTEXT)*.7);
-#endif
- ssText.Align = TXA_VCENTER | TXA_HLEFT; ssText.Mode = TXM_TRANSPARENT;
- ssText.Style = TXS_NORMAL; ssText.ColBg = 0x00e8e8e8L;
- ssText.ColTxt = 0x00000000L; ssText.text = 0L;
- ssText.Font = FONT_HELVETICA; w->SetTextSpec(&ssText);
- w->SetMenu(MENU_SPREAD); w->FileHistory();
- w->Erase(0x00e8e8e8L); w->Caption("RLPlot data");
- cw = w->un2ix(defs.GetSize(SIZE_CELLWIDTH));
- ch = w->un2iy(defs.GetSize(SIZE_CELLTEXT)/defs.ss_txt) + 2;
- fw = 32;
- }
- cButtons = rButtons = 0L;
+ POINT cpos;
+ DataObj *d;
+ int NumGraphs, CurrCol;
+ Graph **g;
+ RECT rc_line;
+ POINT line[2];
+};
+
+SpreadWin::SpreadWin(GraphObj *par, DataObj *Data):GraphObj(par, Data)
+{
+ d = Data; g = 0L; ssOrg.x = ssOrg.y = 0; NumGraphs = 0;
+ filename=0L; aButton = 0L;
+ w = 0L; cButtons = rButtons = 0L;
+ if(w = NewDispClass(this)){
+ w->hasHistMenu = true;
+ ssText.RotBL = ssText.RotCHAR = 0.0;
+ ssText.fSize = 0.0f;
+#ifdef _WINDOWS
+ ssText.iSize = w->un2iy(defs.GetSize(SIZE_CELLTEXT));
+#else
+ ssText.iSize = w->un2iy(defs.GetSize(SIZE_CELLTEXT)*.7);
+#endif
+ ssText.Align = TXA_VCENTER | TXA_HLEFT; ssText.Mode = TXM_TRANSPARENT;
+ ssText.Style = TXS_NORMAL; ssText.ColBg = 0x00e8e8e8L;
+ ssText.ColTxt = 0x00000000L; ssText.text = 0L;
+ ssText.Font = FONT_HELVETICA; w->SetTextSpec(&ssText);
+ w->SetMenu(MENU_SPREAD); w->FileHistory();
+ w->Erase(0x00e8e8e8L); w->Caption("RLPlot data");
+ d->ri->SetDefWidth(w->un2ix(defs.GetSize(SIZE_CELLWIDTH)));
+ d->ri->SetHeight(w->un2iy(defs.GetSize(SIZE_CELLTEXT)/defs.ss_txt) + 2);
+ d->ri->SetFirstWidth(32);
+ }
+ else if(d && d->ri) {
+ d->ri->SetHeight(19); d->ri->SetDefWidth(76); d->ri->SetFirstWidth(32);
+ }
+ cButtons = rButtons = 0L;
Id = GO_SPREADDATA;
- is_modified = false;
-}
-
-SpreadWin::~SpreadWin()
-{
- int i;
-
- if(parent) {
- if(cButtons) {
- for(i = 0; cButtons[i]; i++) if(cButtons[i]) delete(cButtons[i]);
- free(cButtons);
- }
- if(rButtons) {
- for(i = 0; rButtons[i]; i++) if(rButtons[i]) delete(rButtons[i]);
- free(rButtons);
- }
- if (aButton) delete(aButton);
- if (w) delete w;
- if (g && NumGraphs) {
- for(i = 0; i < NumGraphs; i++) if(g[i]) delete(g[i]);
+ is_modified = bDoColWidth = false;
+}
+
+SpreadWin::~SpreadWin()
+{
+ int i;
+
+ if(parent) {
+ if(cButtons) {
+ for(i = 0; cButtons[i]; i++) if(cButtons[i]) delete(cButtons[i]);
+ free(cButtons);
+ }
+ if(rButtons) {
+ for(i = 0; rButtons[i]; i++) if(rButtons[i]) delete(rButtons[i]);
+ free(rButtons);
+ }
+ if (aButton) delete(aButton);
+ if (w) delete w;
+ if (g && NumGraphs) {
+ for(i = 0; i < NumGraphs; i++) if(g[i]) delete(g[i]);
free (g);
}
if(filename) free(filename); filename=0L;
@@ -202,25 +207,25 @@ SpreadWin::~SpreadWin()
}
void
-SpreadWin::DoPlot(anyOutput *o)
-{
- o->ActualSize(&currRC);
- o->StartPage();
- d->Command(CMD_DOPLOT, (void*)this, o);
- o->EndPage();
-}
-
-bool
-SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
-{
- char *Name;
- Graph *g2;
- int i, j, k;
+SpreadWin::DoPlot(anyOutput *o)
+{
+ o->ActualSize(&currRC);
+ o->StartPage();
+ d->Command(CMD_DOPLOT, (void*)this, o);
+ o->EndPage();
+}
+
+bool
+SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ char *Name;
+ Graph *g2;
+ int i, j, k;
MouseEvent *mev;
- POINT p1;
-
+ POINT p1;
+
if(d) {
- if(!o) o = w;
+ if(!o) o = w;
switch(cmd) {
case CMD_CURRPOS:
if(tmpl && cButtons && rButtons) {
@@ -231,7 +236,7 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
cButtons[i]->Command(CMD_SELECT, (cpos.x == (i+ssOrg.x)) ? &ac : &na, w);
}
urc.left = cButtons[0]->rDims.left; urc.bottom = cButtons[0]->rDims.bottom;
- urc.top = cButtons[0]->rDims.top; urc.right = urc.left + cw * (i-1);
+ urc.top = cButtons[0]->rDims.top; urc.right = urc.left + d->ri->GetWidth(i+ssOrg.x) * (i-1);
w->UpdateRect(&urc, false);
}
if(((POINT*)tmpl)->y != cpos.y) {
@@ -239,15 +244,16 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
rButtons[i]->Command(CMD_SELECT, (cpos.y == (i+ssOrg.y)) ? &ac : &na, w);
}
urc.left = rButtons[0]->rDims.left; urc.right = rButtons[0]->rDims.right;
- urc.top = rButtons[0]->rDims.top; urc.bottom = urc.top + ch * (i-1);
+ urc.top = rButtons[0]->rDims.top; urc.bottom = urc.top + d->ri->GetHeight(i+ssOrg.y) * (i-1);
w->UpdateRect(&urc, false);
}
}
- return true;
+ return true;
case CMD_CAN_CLOSE:
HideTextCursor();
if(is_modified == true) {
is_modified=false;
+ if(Undo.isEmpty(0L)) return true;
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);
@@ -258,7 +264,7 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
case CMD_WRITE_GRAPHS:
if (g && NumGraphs) WriteGraphXML((unsigned char**)tmpl, (long*)o);
return true;
- case CMD_DROP_GRAPH:
+ case CMD_DROP_GRAPH:
if(!tmpl) return false; if(o) o->FileHistory();
if(g && NumGraphs) {
if(g = (Graph**)realloc(g, (NumGraphs+2) * sizeof(Graph*)))
@@ -279,25 +285,25 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
}
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);
+ case CMD_NEWGRAPH:
+ if((g2 = new Graph(this, d, 0L)) && g2->PropertyDlg() &&
+ Command(CMD_DROP_GRAPH, g2, o))return Command(CMD_REDRAW, 0L, o);
+ else if(g2) DeleteGO(g2);
+ Undo.SetDisp(w);
+ return false;
+ case CMD_NEWPAGE:
+ if((g2 = new Page(this, d)) &&
+ Command(CMD_DROP_GRAPH, g2, o))return Command(CMD_REDRAW, 0L, o);
else if(g2) DeleteGO(g2);
- Undo.SetDisp(w);
- return false;
- case CMD_NEWPAGE:
- if((g2 = new Page(this, d)) &&
- Command(CMD_DROP_GRAPH, g2, o))return Command(CMD_REDRAW, 0L, o);
- else if(g2) DeleteGO(g2);
Undo.SetDisp(w);
- return false;
- case CMD_DELGRAPH:
- if (g && NumGraphs) {
- for(i = 0; i < NumGraphs; i++) if(g[i]) DeleteGO(g[i]);
- free (g);
- }
- g = 0L; NumGraphs = 0; Undo.Flush();
- return true;
+ return false;
+ case CMD_DELGRAPH:
+ if (g && NumGraphs) {
+ for(i = 0; i < NumGraphs; i++) if(g[i]) DeleteGO(g[i]);
+ free (g);
+ }
+ g = 0L; NumGraphs = 0; Undo.Flush();
+ return true;
case CMD_DELOBJ:
i = j = 0;
if(g && tmpl) for(; i < NumGraphs; i++) {
@@ -314,85 +320,150 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
is_modified=false;
if(o) o->MouseCursor(MC_ARROW, false);
return true;
- }
+ }
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);
+ is_modified=false;
+ if((Name = SaveDataAsName(filename)) && Name[0]){
+ if(o) o->FileHistory();
+ if(Name && d->WriteData(Name)) {
+ if(filename) free(filename); filename = _strdup(Name);
}
- else return false;
+ else return false;
}
- else return false;
- return true;
+ else return false;
+ return true;
case CMD_DROPFILE:
if(!Command(CMD_CAN_CLOSE, 0L, o)) return false;
- if(IsRlpFile((char*)tmpl)) return OpenGraph(this, (char*)tmpl, 0L, false);
- else if(d->ReadData((char*)tmpl, 0L, FF_UNKNOWN)){
- if(filename) free(filename); filename = strdup((char*)tmpl);
- return Command(CMD_SETSCROLL, 0L, w);
- }
- return false;
- case CMD_OPEN:
+ if(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);
+ return Command(CMD_SETSCROLL, 0L, w);
+ }
+ return false;
+ case CMD_OPEN:
if(!Command(CMD_CAN_CLOSE, 0L, o)) return false;
- if((Name = OpenDataName(filename)) && Name[0]){
- if(o) o->FileHistory();
- if(IsRlpFile(Name)) return OpenGraph(this, Name, 0L, false);
- else if(d->ReadData(Name, 0L, FF_UNKNOWN)){
- if(filename) free(filename); filename = strdup(Name);
- return Command(CMD_SETSCROLL, 0L, w);
- }
- }
- return false;
- case CMD_ADDROWCOL:
+ Undo.KillDisp(o);
+ Undo.SetDisp(o);
+ if((Name = OpenDataName(filename)) && Name[0]){
+ if(o) o->FileHistory();
+ if(IsRlpFile(Name)) return OpenGraph(this, Name, 0L, false);
+ else if(d->ReadData(Name, 0L, FF_UNKNOWN)){
+ if(filename) free(filename); filename = _strdup(Name);
+ return Command(CMD_SETSCROLL, 0L, w);
+ }
+ }
+ return false;
+ case CMD_ADDROWCOL:
if(DoSpShSize(d)) DoPlot(o);
- return true;
- case CMD_MOUSE_EVENT:
+ return true;
+ case CMD_COL_MOUSE:
if(o && cButtons && rButtons && (mev = (MouseEvent*)tmpl) && mev->y > o->MenuHeight) {
- if(mev->x < fw && mev->y < (o->MenuHeight + ch) && aButton) {
+ for(i = 0; cButtons[i]; i++){
+ if(bDoColWidth) {
+ o->MouseCursor(MC_EAST, false);
+ }
+ else if(mev->x > cButtons[i]->rDims.left && mev->x < cButtons[i]->rDims.right+2){
+ if(mev->x > cButtons[i]->rDims.right-4) {
+ o->MouseCursor(MC_EAST, false);
+ switch(mev->Action) {
+ case MOUSE_LBDOWN:
+ CurrCol = i; line[0].x = line[1].x = mev->x;
+ line[0].y = o->MenuHeight; line[1].y = currRC.bottom;
+ d->Command(CMD_TOOLMODE, tmpl, o);
+ return bDoColWidth = true;
+ }
+ }
+ else o->MouseCursor(MC_ARROW, false);
+ return false;
+ }
+ else o->MouseCursor(MC_ARROW, false);
+ if(mev->Action == MOUSE_MOVE && bDoColWidth && (mev->StateFlags & 0x01)) {
+ rc_line.left = line[0].x - 2; rc_line.right = line[1].x + 2;
+ rc_line.top = line[0].y - 2; rc_line.bottom = line[1].y +2;
+ o->UpdateRect(&rc_line, false);
+ if(mev->x < (cButtons[CurrCol]->rDims.left +20))mev->x = cButtons[CurrCol]->rDims.left +20;
+ k = mev->x - cButtons[CurrCol]->rDims.right;
+ for(j = CurrCol; cButtons[j] && cButtons[j]->rDims.left < (currRC.right-k); j++) {
+ cButtons[j]->rDims.right += k; cButtons[j]->rDims.left += j > CurrCol ? k : 0;
+ cButtons[j]->DoPlot(o); o->UpdateRect(&cButtons[j]->rDims, false);
+ cButtons[j]->rDims.right -= k; cButtons[j]->rDims.left -= j > CurrCol ? k : 0;
+ }
+ line[0].x = line[1].x = mev->x;
+ line[0].y = o->MenuHeight; line[1].y = currRC.bottom;
+ o->ShowLine(line, 2, 0x00a0a0a0);
+ return true;
+ }
+ if(mev->Action == MOUSE_LBUP && bDoColWidth) {
+ bDoColWidth = false;
+ k = line[0].x - cButtons[CurrCol]->rDims.left;
+ if(abs(k - cButtons[CurrCol]->rDims.right + cButtons[CurrCol]->rDims.left)>3) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%s1:%s1", Int2ColLabel(CurrCol + ssOrg.x, false), Int2ColLabel(CurrCol + ssOrg.x, false));
+#else
+ sprintf(TmpTxt, "%s1:%s1", Int2ColLabel(CurrCol + ssOrg.x, false), Int2ColLabel(CurrCol + ssOrg.x, false));
+#endif
+ d->ri = new RangeInfo(1, TmpTxt, d->ri);
+ d->ri->SetWidth(k >=20 ? k : 20);
+ }
+ d->Command(CMD_REDRAW, 0L, o);
+ return true;
+ }
+ else bDoColWidth = false;
+ }
+ }
+ else o->MouseCursor(MC_ARROW, false);
+ return false;
+ case CMD_MOUSE_EVENT:
+ if(!tmpl) return false;
+ if(bDoColWidth)return Command(CMD_COL_MOUSE, tmpl, o);
+ if((mev = (MouseEvent*)tmpl)->y < o->MenuHeight) o->MouseCursor(MC_ARROW, false);
+ else if(o && cButtons && rButtons) {
+ if(mev->x < d->ri->GetFirstWidth() && mev->y < (o->MenuHeight + d->ri->GetHeight(-1)) && aButton) {
aButton->Command(cmd, tmpl, o);
- }
- else if(mev->x < fw && rButtons) {
- i = (mev->y - o->MenuHeight - ch)/ch;
- if(rButtons[i]) rButtons[i]->Command(cmd, tmpl, o);
- }
- else if(mev->y < (o->MenuHeight + ch) && cButtons) {
- i = (mev->x - fw)/cw;
- if(cButtons[i]) cButtons[i]->Command(cmd, tmpl, o);
- }
- else if(o->MrkMode == MRK_SSB_DRAW) o->HideMark();
+ }
+ else if(mev->x < d->ri->GetFirstWidth() && rButtons) {
+ i = (mev->y - o->MenuHeight - d->ri->GetHeight(-1))/d->ri->GetHeight(-1);
+ if(rButtons[i]) rButtons[i]->Command(cmd, tmpl, o);
+ }
+ else if(mev->y < (o->MenuHeight + d->ri->GetHeight(-1)) && cButtons) {
+ i = (mev->x - d->ri->GetFirstWidth())/d->ri->GetWidth(-1);
+ if(cButtons[i]) cButtons[i]->Command(cmd, tmpl, o);
+ }
+ else if(o->MrkMode == MRK_SSB_DRAW) o->HideMark();
}
return d->Command(cmd, tmpl, o);
case CMD_PASTE_TSV: case CMD_PASTE_CSV: case CMD_PASTE_SSV:
Undo.DataObject(this, w, d, 0L, 0L);
- case CMD_COPY_SYLK: case CMD_ADDCHAR: case CMD_SHIFTUP:
- case CMD_COPY_TSV: case CMD_COPY_XML: case CMD_QUERY_COPY:
- case CMD_TAB: case CMD_SHTAB: case CMD_SHIFTDOWN:
- case CMD_CURRLEFT: case CMD_CURRIGHT: case CMD_CURRUP:
- case CMD_CURRDOWN: case CMD_SHIFTRIGHT: case CMD_POS_FIRST:
- case CMD_POS_LAST: case CMD_SHIFTLEFT: case CMD_DELETE:
+ case CMD_COPY_SYLK: case CMD_ADDCHAR: case CMD_SHIFTUP:
+ case CMD_COPY_TSV: case CMD_COPY_XML: case CMD_QUERY_COPY:
+ case CMD_TAB: case CMD_SHTAB: case CMD_SHIFTDOWN:
+ case CMD_CURRLEFT: case CMD_CURRIGHT: case CMD_CURRUP:
+ case CMD_CURRDOWN: case CMD_SHIFTRIGHT: case CMD_POS_FIRST:
+ case CMD_POS_LAST: case CMD_SHIFTLEFT: case CMD_DELETE:
case CMD_TOOLMODE: case CMD_FILLRANGE: case CMD_CUT:
case CMD_PASTE_XML: case CMD_DELROW: case CMD_INSROW:
- case CMD_INSCOL: case CMD_DELCOL: case CMD_UNDO:
+ case CMD_INSCOL: case CMD_DELCOL: case CMD_UNDO:
case CMD_SHPGUP: case CMD_SHPGDOWN:
+ bDoColWidth = false;
return d->Command(cmd, tmpl, o);
case CMD_REDRAW:
Undo.SetDisp(w); d->Command(cmd, tmpl, o);
- return true;
+ 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);
- 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;
+ case CMD_SETSCROLL:
+ HideTextCursor(); o->ActualSize(&currRC);
+ k = (currRC.bottom-currRC.top)/d->ri->GetHeight(-1);
+ d->GetSize(&i, &j);
+ o->SetScroll(true, 0, j, k, ssOrg.y); k = (currRC.right-currRC.left)/d->ri->GetWidth(-1);
+ o->SetScroll(false, 0, i, k, ssOrg.x); DoPlot(o);
+ return true;
+ case CMD_PAGEUP: case CMD_PAGEDOWN:
+ k = (currRC.bottom-currRC.top)/d->ri->GetHeight(-1);
+ k = k > 3 ? k-2 : 1; p1.x = d->ri->GetFirstWidth() + 2;
+ p1.y = d->ri->GetHeight(-1) + 2;
if(CurrText){
p1.x = CurrText->GetX()+2; p1.y = CurrText->GetY()+12;
}
@@ -401,108 +472,108 @@ SpreadWin::Command(int cmd, void *tmpl, anyOutput *o)
else ssOrg.y = ssOrg.y < j-k*2 ? ssOrg.y+k : j > k ? j-k : 0;
Command(CMD_SETSCROLL, tmpl, o);
CurrText = 0L; d->Select(&p1);
- return true;
- case CMD_SETHPOS:
- ssOrg.x = *((int*)tmpl) >= 0 ? *((long*)tmpl) : 0L;
- return Command(CMD_SETSCROLL, tmpl, o);
- case CMD_SETVPOS:
- ssOrg.y = *((int*)tmpl) >= 0 ? *((long*)tmpl) : 0L;
- return Command(CMD_SETSCROLL, tmpl, o);
+ return true;
+ case CMD_SETHPOS:
+ ssOrg.x = *((int*)tmpl) >= 0 ? *((long*)tmpl) : 0L;
+ return Command(CMD_SETSCROLL, tmpl, o);
+ case CMD_SETVPOS:
+ ssOrg.y = *((int*)tmpl) >= 0 ? *((long*)tmpl) : 0L;
+ return Command(CMD_SETSCROLL, tmpl, o);
case CMD_SETFOCUS:
- Undo.SetDisp(w);
- return true;
- case CMD_KILLFOCUS:
- return true;
- case CMD_TEXTSIZE:
- if(tmpl)ssText.iSize = *((int*)tmpl);
- return true;
- case CMD_CONFIG:
+ Undo.SetDisp(w);
+ return true;
+ case CMD_KILLFOCUS:
+ return true;
+ case CMD_TEXTSIZE:
+ if(tmpl)ssText.iSize = *((int*)tmpl);
+ return true;
+ case CMD_CONFIG:
if(defs.PropertyDlg()) return Command(CMD_REDRAW, 0L, o);
return false;
- case CMD_NONE:
- return true;
- case CMD_PRINT:
- return PrintData(o);
- }
- }
- return false;
-}
-
-bool
-SpreadWin::ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cp)
-{
- int i, c, nr, nc, ac = 1, na = 0;
- RECT rc;
+ case CMD_NONE:
+ return true;
+ case CMD_PRINT:
+ return PrintData(o);
+ }
+ }
+ return false;
+}
+
+bool
+SpreadWin::ShowGrid(int CellWidth, int CellHeight, int FirstWidth, POINT *cp)
+{
+ int i, c, nr, nc, cx, cw, ac = 1, na = 0;
+ RECT rc;
char text[20];
- POINT grid[2];
- TextDEF ButtText;
- bool redim = false;
-
- cpos.x = cp->x; cpos.y = cp->y;
- if(ch != CellHeight || cw != CellWidth || fw != FirstWidth) redim = true;
- ch = CellHeight; cw = CellWidth; fw = FirstWidth;
- if(redim){
- if(cButtons) {
- for(i = 0; cButtons[i]; i++) if(cButtons[i]) delete(cButtons[i]);
- free(cButtons);
- }
- if(rButtons) {
- for(i = 0; rButtons[i]; i++) if(rButtons[i]) delete(rButtons[i]);
- free(rButtons);
- }
- if(aButton) delete(aButton); aButton = 0L;
- cButtons = rButtons = 0L;
+ TextDEF ButtText;
+ bool redim = bDoColWidth;
+
+ w->HideMark();
+ cpos.x = cp->x; cpos.y = cp->y;
+ if(d->ri->GetHeight(-1) != CellHeight || d->ri->GetWidth(-1) != CellWidth || d->ri->GetFirstWidth() != FirstWidth) redim = true;
+ if(redim){
+ d->ri->SetHeight(CellHeight); d->ri->SetDefWidth(CellWidth); d->ri->SetFirstWidth(FirstWidth);
+ if(cButtons) {
+ for(i = 0; cButtons[i]; i++) if(cButtons[i]) delete(cButtons[i]);
+ free(cButtons);
+ }
+ if(rButtons) {
+ for(i = 0; rButtons[i]; i++) if(rButtons[i]) delete(rButtons[i]);
+ free(rButtons);
+ }
+ if(aButton) delete(aButton); aButton = 0L;
+ cButtons = rButtons = 0L;
}
if(!aButton) aButton = new ssButton(this, 0, w->MenuHeight, FirstWidth, CellHeight);
- memcpy(&ButtText, &ssText, sizeof(TextDEF));
- ButtText.Align = TXA_HCENTER | TXA_VCENTER;
- w->GetSize(&rc);
- if(!cButtons) {
- c = (rc.right/CellWidth)+1;
- cButtons = (ssButton **)calloc(c, sizeof(ssButton*));
- for(i = 0; i < (c-1); i++) cButtons[i] =
- new ssButton(this, i*CellWidth+FirstWidth, w->MenuHeight,
- CellWidth+1, CellHeight);
- }
- if(!rButtons) {
- c = (rc.bottom/CellHeight)+1;
- rButtons = (ssButton**)calloc(c, sizeof(ssButton*));
- for(i = 0; i < (c-1); i++) rButtons[i] =
- new ssButton(this, 0, i*CellHeight+CellHeight+w->MenuHeight,
- FirstWidth, CellHeight);
- }
- w->SetLine((LineDEF *)&GrayLine);
- d->GetSize(&nc, &nr);
- grid[0].x = rc.left+FirstWidth;
- i = (nc-ssOrg.x)*CellWidth+FirstWidth;
- grid[1].x = i < rc.right ? i : rc.right;
- if(rButtons) for(i = 0; rButtons[i]; i++) {
- sprintf(text, "%d", i+1+ssOrg.y);
- if(rButtons[i]) {
- rButtons[i]->Command(CMD_SETTEXTDEF, &ButtText, w);
- rButtons[i]->Command(CMD_SETTEXT, text, w);
+ memcpy(&ButtText, &ssText, sizeof(TextDEF));
+ ButtText.Align = TXA_HCENTER | TXA_VCENTER;
+ w->GetSize(&rc);
+ if(!cButtons) {
+ c = ((rc.right/CellWidth)<<2) +1;
+ cButtons = (ssButton **)calloc(c, sizeof(ssButton*));
+ for(i = 0, cx = FirstWidth; i < (c-1); i++) {
+ cw = d->ri->GetWidth(i+ssOrg.x);
+ cButtons[i] = new ssButton(this, cx, w->MenuHeight, cw+1, CellHeight);
+ cx += cw;
+ }
+ }
+ else {
+ for(i = 0, cx = FirstWidth; cButtons[i]; i++) {
+ cw = d->ri->GetWidth(i+ssOrg.x);
+ cButtons[i]->rDims.left = cx; cButtons[i]->rDims.right = cx + cw + 1;
+ cx += cw;
+ }
+ }
+ if(!rButtons) {
+ c = (rc.bottom/CellHeight)+1;
+ rButtons = (ssButton**)calloc(c, sizeof(ssButton*));
+ for(i = 0; i < (c-1); i++) rButtons[i] =
+ new ssButton(this, 0, i*CellHeight+CellHeight+w->MenuHeight,
+ FirstWidth, CellHeight);
+ }
+ d->GetSize(&nc, &nr);
+ if(rButtons) for(i = 0; rButtons[i]; i++) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(text, 20, "%d", i+1+ssOrg.y);
+#else
+ sprintf(text, "%d", i+1+ssOrg.y);
+#endif
+ if(rButtons[i]) {
+ rButtons[i]->Command(CMD_SETTEXTDEF, &ButtText, w);
+ rButtons[i]->Command(CMD_SETTEXT, text, w);
rButtons[i]->Command(CMD_SELECT, (cpos.y == (i+ssOrg.y)) ? &ac : &na, w);
- w->SetLine((LineDEF *)&GrayLine);
- }
- grid[0].y = grid[1].y = w->MenuHeight + i*CellHeight - 1;
- if(i < (2+nr-ssOrg.y)) w->oSolidLine(grid);
- }
- grid[0].y = rc.top+CellHeight+w->MenuHeight;
- i = (1+nr-ssOrg.y)*CellHeight;
- grid[1].y = (i+w->MenuHeight)< rc.bottom ? i+w->MenuHeight : rc.bottom;
- if(cButtons) for(i = 0; cButtons[i]; i++) {
- if(cButtons[i]) {
- cButtons[i]->Command(CMD_SETTEXTDEF, &ButtText, w);
- cButtons[i]->Command(CMD_SETTEXT, Int2ColLabel(i+ssOrg.x, true), w);
- cButtons[i]->Command(CMD_SELECT, (cpos.x == (i+ssOrg.x)) ? &ac : &na, w);
- w->SetLine((LineDEF *)&GrayLine);
- }
- grid[0].x = grid[1].x = i*CellWidth+FirstWidth-1;
- if(i <= (nc-ssOrg.x)) w->oSolidLine(grid);
+ }
+ }
+ if(cButtons) for(i = 0; cButtons[i]; i++) {
+ if(cButtons[i]) {
+ cButtons[i]->Command(CMD_SETTEXTDEF, &ButtText, w);
+ cButtons[i]->Command(CMD_SETTEXT, Int2ColLabel(i+ssOrg.x, true), w);
+ cButtons[i]->Command(CMD_SELECT, (cpos.x == (i+ssOrg.x)) ? &ac : &na, w);
+ }
}
w->SetTextSpec(&ssText);
- if(aButton) aButton->DoPlot(w);
- return true;
+ if(aButton) aButton->DoPlot(w);
+ return true;
}
void
@@ -535,187 +606,213 @@ SpreadWin::MarkButtons(char *rng, POINT *cp)
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;
+}
+
+bool
+SpreadWin::PrintData(anyOutput *o)
+{
+ int i, j, k, l, pgw, 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);
- anyResult res;
-
- Line1.patlength = Line2.patlength = 1.0;
- Line1.color = Line2.color = 0x0; //black gridlines
- Line1.pattern = Line2.pattern = 0x0; //solid lines
- switch(defs.cUnits) {
- case 1: Line1.width = 0.01; break;
- case 2: Line1.width = 0.003937; break;
- default: Line1.width = 0.1; break;
- }
+ double scale;
+ RECT rc, margin, margin_first;
+ POINT pp_pos, ss_pos, grid[3];
+ LineDEF Line1, Line2;
+ TextDEF td, tdp;
+ bool bContinue;
+ time_t ti = time(0L);
+ anyResult res;
+
+ Line1.patlength = Line2.patlength = 1.0;
+ Line1.color = Line2.color = 0x00808080; //gray gridlines
+ Line1.pattern = Line2.pattern = 0x0; //solid lines
+ switch(defs.cUnits) {
+ case 1: Line1.width = 0.01; break;
+ 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 * 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;
-#ifdef _WINDOWS
- tdp.iSize = iround(o->hres/6.0);
-#else
- tdp.iSize = iround(o->hres/7.5);
-#endif
- tdp.Mode = TXM_TRANSPARENT;
- tdp.Style = TXS_NORMAL; tdp.Font = FONT_HELVETICA; tdp.text = 0L;
- memcpy(&td, &ssText, sizeof(TextDEF));
- td.Align = TXA_HCENTER | TXA_VCENTER;
- td.Style = TXS_NORMAL; td.iSize = 0;
-#ifdef _WINDOWS
- td.fSize = defs.GetSize(SIZE_CELLTEXT);
-#else
- td.fSize = defs.GetSize(SIZE_CELLTEXT)*.8;
-#endif
- margin.left = iround(o->hres); margin.right = iround(o->hres/2.0);
- margin.top = margin.bottom = iround(o->hres);
- memcpy(&margin_first, &margin, sizeof(RECT));
- cpp = (rc.right - margin.left - margin.right - pfw)/pcw;
- rpp = (rc.bottom - margin.top - margin.bottom - pch)/pch;
- pp_pos.x = margin.left; pp_pos.y = margin.top;
- ss_pos.x = 0; ss_pos.y = 0; cpages = 1;
- do {
- pp_pos.x = margin.left; pp_pos.y = margin.top;
- k = (ss_pos.x + cpp) > nc ? nc-ss_pos.x : cpp;
- l = (ss_pos.y + rpp) > nr ? nr-ss_pos.y : rpp;
- grid[0].y = margin.top +pch; grid[1].y = grid[0].y + l * pch;
- o->SetLine(&Line2);
- grid[0].x = grid[1].x = pp_pos.x; o->oSolidLine(grid);
- grid[0].x = grid[1].x = pp_pos.x+pfw; o->oSolidLine(grid);
- o->SetLine(&Line1);
- for(i = 1; i <= k; i++) { //vertical grid
- grid[0].x = grid[1].x = pp_pos.x + pfw + i * pcw;
- o->oSolidLine(grid);
- }
- grid[0].x = margin.left+pfw; grid[1].x = grid[0].x + k * pcw;
- o->SetLine(&Line2);
- grid[0].y = grid[1].y = pp_pos.y; o->oSolidLine(grid);
- grid[0].y = grid[1].y = pp_pos.y+pch; o->oSolidLine(grid);
- o->SetLine(&Line1);
- for(i = 1; i <= l; i++) { //horizontal grid
- grid[0].y = grid[1].y = pp_pos.y + pch + i * pch;
- o->oSolidLine(grid);
- }
- o->SetLine(&Line2);
- td.Align = TXA_HCENTER | TXA_VCENTER; o->SetTextSpec(&td);
- grid[0].y = margin.top; grid[1].y = grid[0].y + pch;
- iy = margin.top + (pch >>1);
- for(i = 0; i <= k; i++) { //column headers
- grid[0].x = grid[1].x = pp_pos.x + pfw + i * pcw;
- o->oSolidLine(grid); ix = grid[0].x + (pcw >>1);
- if(i < k) o->oTextOut(ix, iy, Int2ColLabel(i+ss_pos.x, true), 0);
- }
- td.Align = TXA_HRIGHT | TXA_VCENTER;
- o->SetTextSpec(&td); ix = margin.left + pfw - iround(o->hres/20.0);
- grid[0].x = margin.left; grid[1].x = grid[0].x + pfw;
- for(i = 0; i <= l; i++) { //row labels
- grid[0].y = grid[1].y = pp_pos.y + pch + i * pch;
- 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
+ Line2.width = Line1.width * 3.0;
+ d->GetSize(&nc, &nr);
+ if(!(o->StartPage())) return false;
+ pfw = iround(o->hres * ((double)d->ri->GetFirstWidth())/w->hres * scale);
+ pcw = iround(o->hres * ((double)d->ri->GetWidth(-1))/w->hres * scale);
+ pch = iround((o->vres * ((double)d->ri->GetHeight(-1))/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;
+ tdp.Mode = TXM_TRANSPARENT;
+ tdp.Style = TXS_NORMAL; tdp.Font = FONT_HELVETICA; tdp.text = 0L;
+ memcpy(&td, &ssText, sizeof(TextDEF));
+ td.Align = TXA_HCENTER | TXA_VCENTER;
+ td.Style = TXS_NORMAL; td.iSize = 0;
+#ifdef _WINDOWS
+ tdp.iSize = iround(o->hres/6.0);
+ td.fSize = defs.GetSize(SIZE_CELLTEXT);
+#else
+ tdp.iSize = iround(o->hres/7.5);
+ td.fSize = defs.GetSize(SIZE_CELLTEXT)*.8;
+#endif
+ margin.left = iround(o->hres); margin.right = iround(o->hres/2.0);
+ margin.top = margin.bottom = iround(o->hres);
+ memcpy(&margin_first, &margin, sizeof(RECT));
+ pp_pos.x = margin.left; pp_pos.y = margin.top;
+ ss_pos.x = 0; ss_pos.y = 0; cpages = 1;
+ rpp = (rc.bottom - margin.top - margin.bottom - pch)/pch;
+ do {
+ k = (rc.right - margin.left - margin.right - pfw);
+ for(i = pgw = 0; pgw < k && (i+ss_pos.x) < nc; i++ ){
+ pgw += (pcw = iround(o->hres * ((double)d->ri->GetWidth(i+ss_pos.x))/w->hres * scale));
+ if(i >=(nc-1)) break;
+ }
+ if(pgw < k) {
+ cpp = i+1;
+ }
+ else {
+ cpp = i-1; pgw -= pcw;
+ }
+ pp_pos.x = margin.left; pp_pos.y = margin.top;
+ k = (ss_pos.x + cpp) > nc ? nc-ss_pos.x : cpp;
+ l = (ss_pos.y + rpp) > nr ? nr-ss_pos.y : rpp;
+ grid[0].y = margin.top +pch; grid[1].y = grid[0].y + l * pch;
+ o->SetLine(&Line2);
+ grid[0].x = grid[1].x = pp_pos.x; o->oSolidLine(grid);
+ grid[0].x = grid[1].x = pp_pos.x+pfw; o->oSolidLine(grid);
+ grid[0].x = margin.left+pfw; grid[1].x = grid[0].x + pgw;
+ o->SetLine(&Line2);
+ grid[0].y = grid[1].y = pp_pos.y; o->oSolidLine(grid);
+ grid[0].y = grid[1].y = pp_pos.y+pch; o->oSolidLine(grid);
+ o->SetLine(&Line2);
+ td.Align = TXA_HCENTER | TXA_VCENTER; o->SetTextSpec(&td);
+ grid[0].y = margin.top; grid[1].y = grid[0].y + pch;
+ iy = margin.top + (pch >>1); grid[0].x = grid[1].x = pp_pos.x + pfw;
+ for(i = 0, ix = pp_pos.x + pfw; i <= k; i++) { //column headers
+ pcw = iround(o->hres * ((double)d->ri->GetWidth(i+ss_pos.x))/w->hres * scale);
+ o->oSolidLine(grid); grid[0].x = grid[1].x = ix + pcw;
+ if(i < k) o->oTextOut(ix + (pcw >>1), iy, Int2ColLabel(i+ss_pos.x, true), 0);
+ ix += pcw;
+ }
+ td.Align = TXA_HRIGHT | TXA_VCENTER;
+ o->SetTextSpec(&td); ix = margin.left + pfw - iround(o->hres/20.0);
+ grid[0].x = margin.left; grid[1].x = grid[0].x + pfw;
+ for(i = 0; i <= l; i++) { //row labels
+ grid[0].y = grid[1].y = pp_pos.y + pch + i * pch;
+ o->oSolidLine(grid); iy = grid[0].y + (pch >>1);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%d", i+1+ss_pos.y);
+#else
+ sprintf(TmpTxt, "%d", i+1+ss_pos.y);
+#endif
+ if(i < l) o->oTextOut(ix, iy, TmpTxt, 0);
+ }
+ ipad = iround(o->hres/30.0);
+ grid[0].x = margin.left+pfw + ipad;
+ for(i = 0; i < k; i++, grid[0].x += pcw) { //spreadsheet data
+ pcw = iround(o->hres * ((double)d->ri->GetWidth(i+ss_pos.x))/w->hres * scale);
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;
+ ix = grid[0].x;
switch (res.type) {
case ET_VALUE:
- ix = margin.left+pfw+pcw + i*pcw - ipad;
+ ix = ix + pcw - ( ipad<<1 );
td.Align = TXA_HRIGHT | TXA_VCENTER;
- strcpy(TmpTxt, res.text);
+ rlp_strcpy(TmpTxt, TMP_TXT_SIZE, 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;
+ ix = ix + pcw - ( ipad<<1 );
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");
+ if(res.text&& strlen(res.text) < 40)
+ rlp_strcpy(TmpTxt, TMP_TXT_SIZE, res.text[0] != '\'' ? res.text : res.text +1);
+ else if(res.text) rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "#SIZE");
else TmpTxt[0] = 0;
do {
- o->oGetTextExtent(TmpTxt, strlen(TmpTxt), &width, &height);
+ o->oGetTextExtent(TmpTxt, (int)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;
+ rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "#ERROR"); break;
default:
- strcpy(TmpTxt, "#VALUE"); break;
+ rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "#VALUE"); break;
}
iy = pp_pos.y + pch + (pch>>1) + j * pch;
o->SetTextSpec(&td); o->oTextOut(ix, iy, TmpTxt, 0);
- }
- }
- }
- //prepare for next table
- ss_pos.x += k; bContinue = false;
- if(ss_pos.x >= nc) {ss_pos.x = 0; ss_pos.y += l; }
- if(ss_pos.y < nr) {
- ix = pfw + (cpp % nc)*pcw + iround(o->hres/3.5);
- iy = (l+2)*pch;
- if((margin.left + ix + pfw + k*pcw) < (rc.right-margin.right)) {
- margin.left += pfw + k*pcw + iround(o->hres/3.5);
- bContinue = true;
- }
- else if((margin.top + iy + pch + l*pch) < (rc.bottom - margin.bottom)) {
- margin.top += iy; margin.left = margin_first.left;
- bContinue = true;
- }
- else {
- tdp.Align = TXA_HRIGHT | TXA_VCENTER; o->SetTextSpec(&tdp);
- sprintf(TmpTxt, "page %d", cpages++);
- o->oTextOut(rc.right-margin.right, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
- tdp.Align = TXA_HCENTER | TXA_VCENTER; o->SetTextSpec(&tdp);
- sprintf(TmpTxt, "%s", ctime(&ti)); TmpTxt[24] = 0;
- o->oTextOut((rc.right-rc.left)>>1, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
- tdp.Align = TXA_HLEFT | TXA_VCENTER; o->SetTextSpec(&tdp);
- sprintf(TmpTxt, "RLPlot %s", SZ_VERSION);
- o->oTextOut(margin_first.left, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
- memcpy(&margin, &margin_first, sizeof(RECT));
- bContinue = true;
- o->Eject();
- }
- }
- }while(bContinue);
- tdp.Align = TXA_HRIGHT | TXA_VCENTER; o->SetTextSpec(&tdp);
- sprintf(TmpTxt, "page %d", cpages++);
- o->oTextOut(rc.right-margin.right, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
- tdp.Align = TXA_HCENTER | TXA_VCENTER; o->SetTextSpec(&tdp);
- sprintf(TmpTxt, "%s", ctime(&ti)); TmpTxt[24] = 0;
- o->oTextOut((rc.right-rc.left)>>1, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
- tdp.Align = TXA_HLEFT | TXA_VCENTER; o->SetTextSpec(&tdp);
- sprintf(TmpTxt, "RLPlot %s", SZ_VERSION);
- o->oTextOut(margin_first.left, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
- o->EndPage();
- return true;
-}
+ grid[0].y = grid[1].y = iy+(pch>>1); grid[2].y = grid[1].y - pch;
+ grid[0].x -= ipad; grid[1].x = grid[2].x = grid[0].x + pcw;
+ o->SetLine(&Line1); o->oPolyline(grid, 3, 0L);
+ grid[0].x += ipad;
+ }
+ }
+ }
+ //prepare for next table
+ ss_pos.x += k; bContinue = false;
+ if(ss_pos.x >= nc) {ss_pos.x = 0; ss_pos.y += l; }
+ if(ss_pos.y < nr) {
+ ix = pfw + pgw + iround(o->hres/3.5);
+ iy = (l+2)*pch;
+ if((margin.left + ix + pfw + pgw) < (rc.right-margin.right)) {
+ margin.left += pfw + k*pcw + iround(o->hres/3.5);
+ bContinue = true;
+ }
+ else if((margin.top + iy + pch + l*pch) < (rc.bottom - margin.bottom)) {
+ margin.top += iy; margin.left = margin_first.left;
+ bContinue = true;
+ }
+ else {
+ tdp.Align = TXA_HRIGHT | TXA_VCENTER; o->SetTextSpec(&tdp);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "page %d", cpages++);
+#else
+ sprintf(TmpTxt, "page %d", cpages++);
+#endif
+ o->oTextOut(rc.right-margin.right, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
+ tdp.Align = TXA_HCENTER | TXA_VCENTER; o->SetTextSpec(&tdp);
+#ifdef USE_WIN_SECURE
+ ctime_s(TmpTxt, 24, &ti);
+#else
+ sprintf(TmpTxt, "%s", ctime(&ti)); TmpTxt[24] = 0;
+#endif
+ o->oTextOut((rc.right-rc.left)>>1, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
+ tdp.Align = TXA_HLEFT | TXA_VCENTER; o->SetTextSpec(&tdp);
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "RLPlot ");
+ rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, SZ_VERSION);
+ o->oTextOut(margin_first.left, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
+ memcpy(&margin, &margin_first, sizeof(RECT));
+ bContinue = true;
+ o->Eject();
+ }
+ }
+ }while(bContinue);
+ tdp.Align = TXA_HRIGHT | TXA_VCENTER; o->SetTextSpec(&tdp);
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "page %d", cpages++);
+#else
+ sprintf(TmpTxt, "page %d", cpages++);
+#endif
+ o->oTextOut(rc.right-margin.right, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
+ tdp.Align = TXA_HCENTER | TXA_VCENTER; o->SetTextSpec(&tdp);
+#ifdef USE_WIN_SECURE
+ ctime_s(TmpTxt, 24, &ti);
+#else
+ sprintf(TmpTxt, "%s", ctime(&ti)); TmpTxt[24] = 0;
+#endif
+ o->oTextOut((rc.right-rc.left)>>1, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
+ tdp.Align = TXA_HLEFT | TXA_VCENTER; o->SetTextSpec(&tdp);
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "RLPlot ");
+ rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, SZ_VERSION);
+ o->oTextOut(margin_first.left, rc.bottom-(margin.bottom>>1), TmpTxt, 0);
+ o->EndPage();
+ return true;
+}
void
SpreadWin::WriteGraphXML(unsigned char **ptr, long *cbd)
@@ -728,290 +825,297 @@ SpreadWin::WriteGraphXML(unsigned char **ptr, long *cbd)
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");
- *cbd += sprintf(((char*)*ptr)+*cbd, "%s", pg);
- *cbd += sprintf(((char*)*ptr)+*cbd, "]]>\n</Graph>\n");
+ *cbd += rlp_strcpy((char*)(*ptr)+*cbd, 20, "<Graph><![CDATA[\n");
+ memcpy(*ptr+ *cbd, pg, cb); *cbd += cb;
+ *cbd += rlp_strcpy((char*)(*ptr)+*cbd, 20, "]]>\n</Graph>\n");
if(pg) free(pg); pg = 0L; cb = 0;
}
}
}
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// This data object is a spreadsheet
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class SpreadData:public DataObj{
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// This data object is a spreadsheet
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class SpreadData:public DataObj{
typedef struct _pos_info {
POINT ssOrg, currpos;
void *CurrText;};
-public:
- SpreadData(GraphObj *par);
- ~SpreadData();
- bool Init(int nRows, int nCols);
- bool mpos2dpos(POINT *mp, POINT *dp);
- bool Select(POINT *p);
- void MarkRange(char *range, POINT *cp = 0L);
- void HideMark(bool cclp);
- bool WriteData(char *FileName);
- bool AddCols(int nCols);
+public:
+ SpreadData(GraphObj *par);
+ ~SpreadData();
+ bool Init(int nRows, int nCols);
+ bool mpos2dpos(POINT *mp, POINT *dp, bool can_scroll);
+ bool Select(POINT *p);
+ void MarkRange(char *range, POINT *cp = 0L);
+ void HideMark(bool cclp);
+ bool WriteData(char *FileName);
+ bool AddCols(int nCols);
bool AddRows(int nRows);
bool ChangeSize(int nCols, int nRows, bool bUndo);
- bool DeleteCols();
+ bool DeleteCols();
bool InsertCols();
bool DeleteRows();
bool InsertRows();
- void DoPlot(anyOutput *o);
- bool DelRange();
- bool PasteRange(int cmd, char *txt);
+ void DoPlot(anyOutput *o);
+ bool DelRange();
+ bool PasteRange(int cmd, char *txt);
bool InitCopy(int cmd, void *tmpl, anyOutput *o);
- bool SavePos();
- bool Command(int cmd, void *tmpl, anyOutput *o);
- bool ReadData(char *FileName, unsigned char *buffer, int type);
-
- bool ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flags = 0L);
- bool ReadTSV(char *file, unsigned char *buffer, int type);
- bool MemList(unsigned char **ptr, int type);
-
-private:
- int CellHeight, CellWidth, FirstWidth, r_disp, c_disp, mrk_offs;
- RECT cp_src_rec; //bounding rectangle for copy range
- bool bActive, new_mark, bCopyCut, bUpdate, isRowMark, isColMark;
- POINT currpos, currpos2;
- anyOutput *w;
+ bool SavePos();
+ bool Command(int cmd, void *tmpl, anyOutput *o);
+ bool ReadData(char *FileName, unsigned char *buffer, int type);
+
+ bool ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flags = 0L);
+ bool ReadTSV(char *file, unsigned char *buffer, int type);
+ bool MemList(unsigned char **ptr, int type);
+
+private:
+ int CellHeight, CellWidth, FirstWidth, r_disp, c_disp, mrk_offs;
+ RECT cp_src_rec; //bounding rectangle for copy range
+ bool bActive, new_mark, bCopyCut, bUpdate, isRowMark, isColMark;
+ POINT currpos, currpos2;
+ anyOutput *w;
SpreadWin *Disp;
GraphObj *g_parent;
- EditText *et_racc;
- char *m_range, *c_range; //mark and copy ranges
+ 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=rlw_file = 0L;
+ _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=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;
- 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, false);
- }
+ et_racc = 0L;
+ currpos.x = currpos.y = r_disp = c_disp = mrk_offs = 0;
+ bActive = bCopyCut = bUpdate = isRowMark = isColMark = false;
+ 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, false);
+ }
pos_info.currpos.x = currpos.x; pos_info.currpos.y = currpos.y;
pos_info.CurrText = CurrText;
-}
-
-SpreadData::~SpreadData()
-{
- FlushData();
- if(Disp) delete Disp; Disp = 0L;
- if(m_range) free(m_range); m_range = 0L;
+}
+
+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(rlw_file) free(rlw_file); rlw_file = 0L;
-}
-
-bool
-SpreadData::Init(int nRows, int nCols)
-{
- int i, j;
- RECT rc;
-
+ if(rlw_file) free(rlw_file); rlw_file = 0L;
+}
+
+bool
+SpreadData::Init(int nRows, int nCols)
+{
+ int i, j;
+ RECT rc;
+
cRows = nRows; cCols = nCols; currpos.x = currpos.y = 0;
- new_mark = bCopyCut = false; if(w && m_range) HideMark(true);
- if(!Disp) {
- Disp = new SpreadWin(g_parent, this);
- w = Disp->w;
- if(w) {
- CellWidth = w->un2ix(defs.GetSize(SIZE_CELLWIDTH));
- CellHeight = w->un2iy(defs.GetSize(SIZE_CELLTEXT)/defs.ss_txt) + 2;
+ new_mark = bCopyCut = false; if(w && m_range) HideMark(true);
+ if(!Disp) {
+ Disp = new SpreadWin(g_parent, this);
+ w = Disp->w;
+ if(w) {
+ CellWidth = w->un2ix(defs.GetSize(SIZE_CELLWIDTH));
+ CellHeight = w->un2iy(defs.GetSize(SIZE_CELLTEXT)/defs.ss_txt) + 2;
FirstWidth = 32;
- w->GetSize(&rc);
- r_disp = (rc.bottom-rc.top)/CellHeight;
- c_disp = (rc.right-rc.left)/CellWidth+1;
- }
- else return false;
+ w->GetSize(&rc);
+ r_disp = (rc.bottom-rc.top)/CellHeight;
+ c_disp = (rc.right-rc.left)/CellWidth+1;
+ }
+ else return false;
pos_info.ssOrg.x = Disp->ssOrg.x; pos_info.ssOrg.y = Disp->ssOrg.y;
pos_info.CurrText = CurrText;
- }
- if(etRows)FlushData();
- etRows = (EditText ***)calloc (cRows, sizeof(EditText **));
- if(etRows) for(i = 0; i < cRows; i++) {
- etRows[i] = (EditText **)calloc(cCols, sizeof(EditText *));
- if(etRows[i]) for(j = 0; j < cCols; j++) {
-#ifdef _DEBUG
- char text[20];
- sprintf (text, "%.2f", i*10.0 + j);
- etRows[i][j] = new EditText(this, text, i, j);
-#else
- etRows[i][j] = new EditText(this, 0L, i, j);
-#endif
- }
- }
- if (LoadFile) {
- strcpy(TmpTxt, LoadFile); //we will reenter by recursion !
- free(LoadFile);
- LoadFile = 0L;
- Disp->Command(CMD_DROPFILE, TmpTxt, w);
- }
- else DoPlot(w);
- return true;
-}
-
-bool
-SpreadData::mpos2dpos(POINT *mp, POINT *dp)
-{
- if(mp->x < (FirstWidth+10) && mp->x > FirstWidth && Disp->ssOrg.x >0) {
- Disp->ssOrg.x -= 1;
- if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
- Disp->Command(CMD_SETSCROLL, 0L, w);
- mp->x += CellWidth;
- }
- if(mp->y < (w->MenuHeight + CellHeight+9) && mp->y > (w->MenuHeight + CellHeight) && Disp->ssOrg.y >0) {
- Disp->ssOrg.y -= 1;
- if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
- Disp->Command(CMD_SETSCROLL, 0L, w);
- mp->y += CellHeight;
- }
- if(mp->x > (Disp->currRC.right-w->MenuHeight-10) && Disp->ssOrg.x < (cCols-2)) {
- Disp->ssOrg.x += 1;
- if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
- Disp->Command(CMD_SETSCROLL, 0L, w);
- mp->x -= CellWidth;
- }
- if(mp->y > (Disp->currRC.bottom-10) && Disp->ssOrg.y < (cRows-5)) {
- Disp->ssOrg.y += 1;
- do {
- mp->y -= CellHeight;
- } while(mp->y > (Disp->currRC.bottom-CellHeight));
- if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
- Disp->Command(CMD_SETSCROLL, 0L, w);
- }
- dp->y = (mp->y - w->MenuHeight - CellHeight)/CellHeight + Disp->ssOrg.y;
- dp->x = (mp->x - FirstWidth)/CellWidth + Disp->ssOrg.x;
- if(dp->y >= cRows) dp->y = cRows-1;
- if(dp->x >= cCols) dp->x = cCols-1;
- return true;
+ }
+ if(etRows)FlushData();
+ etRows = (EditText ***)calloc (cRows, sizeof(EditText **));
+ if(etRows) for(i = 0; i < cRows; i++) {
+ etRows[i] = (EditText **)calloc(cCols, sizeof(EditText *));
+ if(etRows[i]) for(j = 0; j < cCols; j++) {
+#ifdef _DEBUG
+ char text[20];
+#ifdef USE_WIN_SECURE
+ sprintf_s (text, 20, "%.2f", i*10.0 + j);
+#else
+ sprintf (text, "%.2f", i*10.0 + j);
+#endif
+ etRows[i][j] = new EditText(this, text, i, j);
+#else
+ etRows[i][j] = new EditText(this, 0L, i, j);
+#endif
+ }
+ }
+ if (LoadFile) {
+ rlp_strcpy(TmpTxt, TMP_TXT_SIZE, LoadFile); //we will reenter by recursion !
+ free(LoadFile);
+ LoadFile = 0L;
+ Disp->Command(CMD_DROPFILE, TmpTxt, w);
+ }
+ else DoPlot(w);
+ return true;
}
-bool
-SpreadData::Select(POINT *p)
-{
- if(CurrText && CurrText->isInRect(p)){
- CurrText->Update(1, w, p);
+bool
+SpreadData::mpos2dpos(POINT *mp, POINT *dp, bool can_scroll)
+{
+ int mx;
+
+ CurrGO = 0L;
+ dp->y = (mp->y - w->MenuHeight - CellHeight)/CellHeight + Disp->ssOrg.y;
+ dp->x = Disp->ssOrg.x;
+ for(mx = mp->x - ri->GetFirstWidth() - ri->GetWidth(dp->x); mx > 0; dp->x++, mx -= ri->GetWidth(dp->x));
+ if(can_scroll && dp->x < cCols && mp->x < (ri->GetFirstWidth()+10) && mp->x > ri->GetFirstWidth() && Disp->ssOrg.x >0) {
+ Disp->ssOrg.x -= 1;
+ if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
+ Disp->Command(CMD_SETSCROLL, 0L, w);
+ }
+ if(can_scroll && mp->y < (w->MenuHeight + CellHeight+9) && mp->y > (w->MenuHeight + CellHeight) && Disp->ssOrg.y >0) {
+ Disp->ssOrg.y -= 1;
+ if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
+ Disp->Command(CMD_SETSCROLL, 0L, w);
+ }
+ if(can_scroll && mp->x > (Disp->currRC.right-w->MenuHeight-10) && Disp->ssOrg.x < (cCols-2)) {
+ Disp->ssOrg.x += 1;
+ if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
+ Disp->Command(CMD_SETSCROLL, 0L, w);
+ }
+ if(can_scroll && mp->y > (Disp->currRC.bottom-10) && Disp->ssOrg.y < (cRows-5)) {
+ Disp->ssOrg.y += 1;
+ do {
+ mp->y -= CellHeight;
+ } while(mp->y > (Disp->currRC.bottom-CellHeight));
+ if(CurrText) CurrText->Update(2, w, mp); CurrText = 0L;
+ Disp->Command(CMD_SETSCROLL, 0L, w); CurrText = 0L;
+ }
+ if(dp->y >= cRows) dp->y = cRows-1; if(dp->x >= cCols) dp->x = cCols-1;
+ return true;
+}
+
+bool
+SpreadData::Select(POINT *p)
+{
+ if(CurrText && CurrText->isInRect(p)){
+ CurrText->Update(1, w, p);
Disp->Command(CMD_CURRPOS, &currpos, w);
if(CurrText->isFormula() && CurrText->hasMark()) et_racc = CurrText;
- return true;
- }
- mpos2dpos(p, &currpos);
- if(currpos.y < cRows && currpos.x < cCols && currpos.y >= 0 && currpos.x >= 0) {
- if(etRows[currpos.y][currpos.x]) {
- if(etRows[currpos.y][currpos.x] == CurrText) CurrText->Update(1, w, p);
- else {
- if(CurrText) CurrText->Update(2, w, p);
- CurrText = etRows[currpos.y][currpos.x];
- DoPlot(w);
- CurrText->Update(1, w, p);
- }
+ return true;
+ }
+ mpos2dpos(p, &currpos, false);
+ if(currpos.y < cRows && currpos.x < cCols && currpos.y >= 0 && currpos.x >= 0) {
+ if(etRows[currpos.y][currpos.x]) {
+ if(etRows[currpos.y][currpos.x] == CurrText) CurrText->Update(1, w, p);
+ else {
+ if(CurrText) CurrText->Update(2, w, p);
+ CurrText = etRows[currpos.y][currpos.x];
+ DoPlot(w);
+ CurrText->Update(1, w, p);
+ }
Disp->Command(CMD_CURRPOS, &currpos, w);
- return true;
- }
- }
- if(CurrText) CurrText->Update(2, w, p); CurrText = 0L;
- return false;
-}
-
-void
-SpreadData::MarkRange(char *range, POINT *cp)
-{
- AccRange *nr, *oldr;
- int r, c;
-
- oldr = nr = 0L;
- if(m_range && range && !strcmp(m_range, range)) return; //no change
- if(m_range) oldr = new AccRange(m_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) && 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);
- }
- }
- }
- if(nr && nr->GetFirst(&c, &r)) {
- for( ; nr->GetNext(&c, &r); ) {
- if(r >= Disp->ssOrg.y && r < (r_disp +Disp->ssOrg.y) && c >= Disp->ssOrg.x
- && c < (c_disp + Disp->ssOrg.x) && r < cRows && c < cCols)
- etRows[r][c]->Mark(w, etRows[r][c] != CurrText ? 2 : 3);
- }
- }
- if(range && (m_range = (char*)realloc(m_range, strlen(range)+6)))
- strcpy(m_range, range);
+ return true;
+ }
+ }
+ if(CurrText) CurrText->Update(2, w, p); CurrText = 0L;
+ return false;
+}
+
+void
+SpreadData::MarkRange(char *range, POINT *cp)
+{
+ AccRange *nr, *oldr;
+ int r, c, cb;
+
+ oldr = nr = 0L;
+ if(m_range && range && !strcmp(m_range, range)) return; //no change
+ if(m_range) oldr = new AccRange(m_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) && 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);
+ }
+ }
+ }
+ if(nr && nr->GetFirst(&c, &r)) {
+ for( ; nr->GetNext(&c, &r); ) {
+ if(r >= Disp->ssOrg.y && r < (r_disp +Disp->ssOrg.y) && c >= Disp->ssOrg.x
+ && c < (c_disp + Disp->ssOrg.x) && r < cRows && c < cCols)
+ etRows[r][c]->Mark(w, etRows[r][c] != CurrText ? 2 : 3);
+ }
+ }
+ if(range && (m_range = (char*)realloc(m_range, cb = ((int)strlen(range)+6)))) rlp_strcpy(m_range, cb, range);
else if (m_range) m_range[0] = 0;
- if(oldr) delete(oldr); if(nr) delete(nr);
- new_mark = true; Disp->MarkButtons(m_range, cp);
-}
-
-void
-SpreadData::HideMark(bool cclp)
-{
- if(cclp && c_range && c_range != m_range){
- free(c_range); c_range = 0L;
- }
- if(m_range){
- free(m_range); m_range = 0L;
- DoPlot(w);
- }
- if(cclp) EmptyClip(); new_mark = false;
+ if(oldr) delete(oldr); if(nr) delete(nr);
+ new_mark = true; Disp->MarkButtons(m_range, cp);
+}
+
+void
+SpreadData::HideMark(bool cclp)
+{
+ if(cclp && c_range && c_range != m_range){
+ free(c_range); c_range = 0L;
+ }
+ if(m_range){
+ free(m_range); m_range = 0L;
+ DoPlot(w);
+ }
+ if(cclp) EmptyClip(); new_mark = false;
Disp->MarkButtons(m_range, 0L);
-}
-
-bool
-SpreadData::WriteData(char *FileName)
-{
- FILE *File;
- int i, j;
+}
+
+bool
+SpreadData::WriteData(char *FileName)
+{
+ FILE *File;
+ int i, j;
unsigned char *buff = 0L;
anyResult res;
- bool bErr = false;
-
+ bool bErr = false;
+
if(!cRows || !cCols || !etRows) return false;
- if(!FileName) FileName = rlw_file;
+ if(!FileName) FileName = rlw_file;
if(FileName && FileName[0]) BackupFile(FileName);
- else return false;
+ else return false;
+#ifdef USE_WIN_SECURE
+ if(fopen_s(&File, FileName, "w")) {
+#else
if(!(File = fopen(FileName, "w"))) {
+#endif
ErrorBox("An error occured during write,\n\nplease try again!");
return false;
- }
- HideMark(true);
- i = strlen(FileName);
- //test for xml extension
- if(!strcmp(".xml", FileName+i-4) || !strcmp(".XML", FileName+i-4)) {
- MemList(&buff, FF_XML);
- if(buff){
- if(fprintf(File, "%s", buff) <= 0) bErr = true;
- free(buff); fclose(File);
- return true;
- }
- return false;
- }
- //test for tsv extension
- if(!strcmp(".tsv", FileName+i-4) || !strcmp(".TSV", FileName+i-4)) {
- MemList(&buff, FF_TSV);
- if(buff){
- if(fprintf(File, "%s", buff) <= 0) bErr = true;
- free(buff); fclose(File);
- return true;
- }
- return false;
+ }
+ HideMark(true);
+ i = (int)strlen(FileName);
+ //test for xml extension
+ if(!strcmp(".xml", FileName+i-4) || !strcmp(".XML", FileName+i-4)) {
+ MemList(&buff, FF_XML);
+ if(buff){
+ if(fprintf(File, "%s", buff) <= 0) bErr = true;
+ free(buff); fclose(File);
+ return true;
+ }
+ return false;
+ }
+ //test for tsv extension
+ if(!strcmp(".tsv", FileName+i-4) || !strcmp(".TSV", FileName+i-4)) {
+ MemList(&buff, FF_TSV);
+ if(buff){
+ if(fprintf(File, "%s", buff) <= 0) bErr = true;
+ free(buff); fclose(File);
+ return true;
+ }
+ return false;
}
//test for rlw extension
if(!strcmp(".rlw", FileName+i-4) || !strcmp(".RLW", FileName+i-4)) {
MemList(&buff, FF_RLW);
if(buff){
if(rlw_file != FileName) {
- if(rlw_file) free(rlw_file); rlw_file = strdup(FileName);
+ if(rlw_file) free(rlw_file); rlw_file = _strdup(FileName);
}
if(fprintf(File, "%s", buff) <= 0) bErr = true;
free(buff); fclose(File);
@@ -1029,8 +1133,8 @@ SpreadData::WriteData(char *FileName)
}
return false;
}
- //else write csv
- for(i = 0; i < cRows; i++) {
+ //else write csv
+ for(i = 0; i < cRows; i++) {
for(j = 0; j < cCols; j++) {
if(etRows[i][j]) {
etRows[i][j]->GetResult(&res, false); TranslateResult(&res);
@@ -1044,182 +1148,185 @@ SpreadData::WriteData(char *FileName)
break;
}
}
- if(j < (cCols-1)) fprintf(File, ", ");
- }
- if(fprintf(File, "\n") <= 0) bErr = true;
- }
- fclose(File);
+ if(j < (cCols-1)) fprintf(File, ", ");
+ }
+ if(fprintf(File, "\n") <= 0) bErr = true;
+ }
+ fclose(File);
if(bErr) ErrorBox("An error occured during write,\n\nplease try again!");
- return true;
-}
-
-bool
-SpreadData::ReadData(char *FileName, unsigned char *buffer, int type)
-{
- int i, j, l;
- char ItemText[20];
- bool success;
- POINT pt;
-
+ return true;
+}
+
+bool
+SpreadData::ReadData(char *FileName, unsigned char *buffer, int type)
+{
+ int i, j;
+ char ItemText[20];
+ bool success;
+
if(FileName) { //read disk file
if(!Disp->Command(CMD_CAN_CLOSE, 0L, 0L))return false;
- if(0 == strcmp(".xml", FileName+strlen(FileName)-4) ||
+ if(0 == strcmp(".xml", FileName+strlen(FileName)-4) ||
0 == strcmp(".XML", FileName+strlen(FileName)-4) ||
0 == strcmp(".rlw", FileName+strlen(FileName)-4) ||
0 == strcmp(".RLW", FileName+strlen(FileName)-4) ||
- IsXmlFile(FileName)){
+ IsXmlFile(FileName)){
if(ReadXML(FileName, buffer, type, 0L)){
if(0 == strcmp(".rlw", FileName+strlen(FileName)-4) ||
- 0 == strcmp(".RLW", FileName+strlen(FileName)-4)) {
+ 0 == strcmp(".RLW", FileName+strlen(FileName)-4)) {
if(rlw_file) free(rlw_file);
- rlw_file = strdup(FileName);
+ rlw_file = _strdup(FileName);
}
- return true;
- }
- return false;
- }
- if(0 == strcmp(".tsv", FileName+strlen(FileName)-4) ||
- 0 == strcmp(".TSV", FileName+strlen(FileName)-4)){
- return ReadTSV(FileName, buffer, type);
- }
- if(!(Cache = new ReadCache())) return false;
- if(! Cache->Open(FileName)) {
- delete Cache;
- sprintf(TmpTxt, "Error open data file\n\"%s\"", FileName);
- ErrorBox(TmpTxt);
- return false;
- }
- if(!Init(1, 1)) goto ReadError;
- }
- else if(buffer) { //read memory buffer
- switch(type) {
- case FF_TSV:
- return ReadTSV(FileName, buffer, type);
- case FF_XML:
- return ReadXML(FileName, buffer, type, 0L);
- case FF_CSV:
- if(!(Cache = new MemCache(buffer))) return false;
- break;
- default:
- ErrorBox("Read from buffer with\nunknown format failed.");
- return false;
- }
- }
- else return false;
- i = j = 0;
- pt.x = pt.y = 0; //pt is a dummy argument only
- do {
- if((success = GetItemCSV(ItemText, sizeof(ItemText)-1)) || ItemText[0]){
- if(j >= cCols && !AddCols(j+1)) goto ReadError;
- if(i >= cRows && !AddRows(i+1)) goto ReadError;
- if(etRows[i][j]) etRows[i][j]->SetText("");
- l = strlen(ItemText);
- if(l>1 && ItemText[0] == '"') {
- ItemText[l-1] = 0;
- etRows[i][j]->SetText(ItemText+1);
- etRows[i][j]->Update(20, 0L, &pt);
- }
- else if(l){
- etRows[i][j]->SetText(ItemText);
- etRows[i][j]->Update(10, 0L, &pt);
- }
- j++;
- }
- if(!success && !Cache->IsEOF()) {i++; j = 0;} //eol
- }while (ItemText[0] || !Cache->IsEOF()); //eof
-
- Cache->Close(); delete Cache; Cache = 0L;
- Disp->ssOrg.x = Disp->ssOrg.y = 0;
- return true;
-
-ReadError:
- Cache->Close(); delete Cache; Cache = 0L;
- return false;
-
-}
-
-bool
-SpreadData::AddCols(int nCols)
-{
- EditText **NewRow;
- int i, j;
-
- if (nCols <= cCols || !etRows || !etRows[0] || !etRows[0][cCols-1]) return false;
- for(i = 0; i < cRows; i++) {
- if(NewRow = (EditText **)realloc(etRows[i], nCols * sizeof(EditText*))){
- for(j = cCols; j < nCols; j++) {
- NewRow[j] = new EditText(this, 0L, i, j);
- }
- etRows[i] = NewRow;
- }
- else return false; //memory allocation error
- }
- cCols = nCols;
- return true;
-}
-
-bool
-SpreadData::AddRows(int nRows)
-{
- int i, j;
- EditText ***NewRows;
-
- if (nRows <= cRows || !etRows || !etRows[cRows-1] || !etRows[cRows-1][0] ) return false;
- NewRows = (EditText ***)realloc(etRows, nRows * sizeof(EditText **));
- if(NewRows) etRows = NewRows;
+ return true;
+ }
+ return false;
+ }
+ if(0 == strcmp(".tsv", FileName+strlen(FileName)-4) ||
+ 0 == strcmp(".TSV", FileName+strlen(FileName)-4)){
+ return ReadTSV(FileName, buffer, type);
+ }
+ if(!(Cache = new ReadCache())) return false;
+ if(! Cache->Open(FileName)) {
+ delete Cache;
+ i = rlp_strcpy(TmpTxt, TMP_TXT_SIZE, "Error open data file\n\"");
+ i += rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, FileName);
+ i += rlp_strcpy(TmpTxt+i, TMP_TXT_SIZE-i, "\"\n");
+ ErrorBox(TmpTxt);
+ return false;
+ }
+ if(!Init(1, 1)) goto ReadError;
+ }
+ else if(buffer) { //read memory buffer
+ switch(type) {
+ case FF_TSV:
+ return ReadTSV(FileName, buffer, type);
+ case FF_XML:
+ return ReadXML(FileName, buffer, type, 0L);
+ case FF_CSV:
+ if(!(Cache = new MemCache(buffer))) return false;
+ break;
+ default:
+ ErrorBox("Read from buffer with\nunknown format failed.");
+ return false;
+ }
+ }
+ else return false;
+ i = j = 0;
+ do {
+ if((success = GetItemCSV(ItemText, sizeof(ItemText)-1)) || ItemText[0]){
+ if(j >= cCols && !AddCols(j+1)) goto ReadError;
+ if(i >= cRows && !AddRows(i+1)) goto ReadError;
+ if(!etRows[i][j]) goto ReadError;
+ if(ItemText[0] == '"') {
+ rmquot(ItemText);
+ etRows[i][j]->SetText(ItemText);
+ etRows[i][j]->Update(20, 0L, 0L);
+ }
+ else if(ItemText[0]){
+ etRows[i][j]->SetText(ItemText);
+ etRows[i][j]->Update(10, 0L, 0L);
+ }
+ else etRows[i][j]->SetText("");
+ j++;
+ }
+ if(!success && !Cache->IsEOF()) {i++; j = 0;} //eol
+ }while (ItemText[0] || !Cache->IsEOF()); //eof
+ Cache->Close(); delete Cache; Cache = 0L;
+ Disp->ssOrg.x = Disp->ssOrg.y = 0;
+ return true;
+
+ReadError:
+ Cache->Close(); delete Cache; Cache = 0L;
+ return false;
+
+}
+
+bool
+SpreadData::AddCols(int nCols)
+{
+ EditText **NewRow;
+ int i, j;
+
+ if (nCols <= cCols || !etRows || !etRows[0] || !etRows[0][cCols-1]) return false;
+ for(i = 0; i < cRows; i++) {
+ if(NewRow = (EditText **)realloc(etRows[i], nCols * sizeof(EditText*))){
+ for(j = cCols; j < nCols; j++) {
+ NewRow[j] = new EditText(this, 0L, i, j);
+ }
+ etRows[i] = NewRow;
+ }
+ else return false; //memory allocation error
+ }
+ cCols = nCols;
+ return true;
+}
+
+bool
+SpreadData::AddRows(int nRows)
+{
+ int i, j;
+ EditText ***NewRows;
+
+ if (nRows <= cRows || !etRows || !etRows[cRows-1] || !etRows[cRows-1][0] ) return false;
+ NewRows = (EditText ***)realloc(etRows, nRows * sizeof(EditText **));
+ if(NewRows) etRows = NewRows;
else return false; //memory allocation error
- for(i = cRows; i < nRows; i++){
- etRows[i] = (EditText **)calloc(cCols, sizeof(EditText *));
- if(etRows[i]) {
- for(j = 0; j < cCols; j++) etRows[i][j] = new EditText(this, 0L, i, j);
- }
- else { //memory allocation error
- cRows = i-1;
- return false;
- }
- }
- cRows = nRows;
- return true;
-}
-
-bool
-SpreadData::ChangeSize(int nCols, int nRows, bool bUndo)
-{
- int i, j;
- bool RetVal = true;
+ for(i = cRows; i < nRows; i++){
+ etRows[i] = (EditText **)calloc(cCols, sizeof(EditText *));
+ if(etRows[i]) {
+ for(j = 0; j < cCols; j++) etRows[i][j] = new EditText(this, 0L, i, j);
+ }
+ else { //memory allocation error
+ cRows = i-1;
+ return false;
+ }
+ }
+ cRows = nRows;
+ return true;
+}
+
+bool
+SpreadData::ChangeSize(int nCols, int nRows, bool bUndo)
+{
+ int i, j;
+ bool RetVal = true;
if(nCols == cCols && nRows == cRows) return true;
- if(bUndo) Undo.DataObject(Disp, w, this, 0L, 0L);
- if(nRows && nRows < cRows) {
- for (i = nRows; i < cRows; i++) {
- if(etRows[i]) for (j = 0; j < cCols; j++) {
- if(etRows[i][j]) delete etRows[i][j];
- etRows[i][j] = NULL;
- }
- free(etRows[i]);
- etRows[i] = NULL;
- }
- cRows = nRows;
- }
- if(nCols && nCols < cCols) {
- for (i = 0; i < cRows; i++) {
- for (j = nCols; j < cCols; j++) {
- if(etRows[i][j]) delete etRows[i][j];
- etRows[i][j] = NULL;
- }
- }
- cCols = nCols;
- }
- if(nCols > cCols) if(!AddCols(nCols))RetVal = false;
- if(RetVal && nRows > cRows) if(!AddRows(nRows))RetVal = false;
- if(w) {
- sprintf(TmpTxt, "%d00", nRows);
- w->oGetTextExtent(TmpTxt, 0, &i, &j);
- if(i > FirstWidth) FirstWidth = i;
- Disp->Command(CMD_SETSCROLL, 0L, w);
- }
- return RetVal;
-}
+ if(bUndo) Undo.DataObject(Disp, w, this, 0L, 0L);
+ if(nRows && nRows < cRows) {
+ for (i = nRows; i < cRows; i++) {
+ if(etRows[i]) for (j = 0; j < cCols; j++) {
+ if(etRows[i][j]) delete etRows[i][j];
+ etRows[i][j] = NULL;
+ }
+ free(etRows[i]);
+ etRows[i] = NULL;
+ }
+ cRows = nRows;
+ }
+ if(nCols && nCols < cCols) {
+ for (i = 0; i < cRows; i++) {
+ for (j = nCols; j < cCols; j++) {
+ if(etRows[i][j]) delete etRows[i][j];
+ etRows[i][j] = NULL;
+ }
+ }
+ cCols = nCols;
+ }
+ if(nCols > cCols) if(!AddCols(nCols))RetVal = false;
+ if(RetVal && nRows > cRows) if(!AddRows(nRows))RetVal = false;
+ if(w) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%d00", nRows);
+#else
+ sprintf(TmpTxt, "%d00", nRows);
+#endif
+ w->oGetTextExtent(TmpTxt, 0, &i, &j);
+ if(i > FirstWidth) FirstWidth = i;
+ Disp->Command(CMD_SETSCROLL, 0L, w);
+ }
+ return RetVal;
+}
bool
SpreadData::DeleteCols()
@@ -1284,8 +1391,8 @@ SpreadData::DeleteCols()
}
}
cCols -= dc;
- MoveFormula(this, m_range, TmpTxt, -dc, 0, -1, c0+1);
- strcpy(m_range, TmpTxt); nc--;
+ MoveFormula(this, m_range, TmpTxt, -dc, 0, -1, c0+1); free(m_range);
+ m_range = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0); nc--;
for(i = 0; i < c0; i++) for(j = 0; j < c0; j++) {
if(etRows && etRows[i] && etRows[i][j] && etRows[i][j]->type == ET_FORMULA) {
MoveFormula(this, etRows[i][j]->text, TmpTxt, -dc, 0, -1, c0);
@@ -1353,8 +1460,8 @@ SpreadData::InsertCols()
}
}
}
- MoveFormula(this, m_range, TmpTxt, dc, 0, -1, c0);
- strcpy(m_range, TmpTxt); nc--;
+ MoveFormula(this, m_range, TmpTxt, dc, 0, -1, c0); free(m_range);
+ m_range = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0); nc--;
for(i = 0; i < c0; i++) for(j = 0; j < c0; j++) {
if(etRows && etRows[i] && etRows[i][j] && etRows[i][j]->type == ET_FORMULA) {
MoveFormula(this, etRows[i][j]->text, TmpTxt, dc, 0, -1, c0);
@@ -1428,8 +1535,8 @@ SpreadData::DeleteRows()
}
}
cRows -= dr;
- MoveFormula(this, m_range, TmpTxt, 0, -dr, r0+1, -1);
- strcpy(m_range, TmpTxt); nr--;
+ MoveFormula(this, m_range, TmpTxt, 0, -dr, r0+1, -1); free(m_range);
+ m_range = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0); nr--;
for(i = 0; i < r0; i++) for(j = 0; j < cCols; j++) {
if(etRows && etRows[i] && etRows[i][j] && etRows[i][j]->type == ET_FORMULA) {
MoveFormula(this, etRows[i][j]->text, TmpTxt, 0, -dr, r0, -1);
@@ -1499,8 +1606,8 @@ SpreadData::InsertRows()
}
}
}
- MoveFormula(this, m_range, TmpTxt, 0, dr, r0, -1);
- strcpy(m_range, TmpTxt); nr--;
+ MoveFormula(this, m_range, TmpTxt, 0, dr, r0, -1); free(m_range);
+ m_range = (char*)memdup(TmpTxt, (int)strlen(TmpTxt)+1, 0); nr--;
for(i = 0; i < r0; i++) for(j = 0; j < cCols; j++) {
if(etRows && etRows[i] && etRows[i][j] && etRows[i][j]->type == ET_FORMULA) {
MoveFormula(this, etRows[i][j]->text, TmpTxt, 0, dr, r0, -1);
@@ -1510,40 +1617,47 @@ SpreadData::InsertRows()
}while(nr >= 0);
delete ar;
if(w) {
+#ifdef USE_WIN_SECURE
+ sprintf_s(TmpTxt, TMP_TXT_SIZE, "%d00", cRows);
+#else
sprintf(TmpTxt, "%d00", cRows);
+#endif
w->oGetTextExtent(TmpTxt, 0, &i, &j);
if(i > FirstWidth) FirstWidth = i;
Disp->Command(CMD_SETSCROLL, 0L, w); Disp->Command(CMD_MRK_DIRTY, 0L, w);
}
return true;
}
-
-void
-SpreadData::DoPlot(anyOutput *o)
-{
- RECT rc;
- int i, j, r, c;
- AccRange *ar;
-
- if(!w || !Disp) return;
- w->Erase(0x00e8e8e8L); w->ActualSize(&rc);
+
+void
+SpreadData::DoPlot(anyOutput *o)
+{
+ RECT rc;
+ int i, j, r, c;
+ AccRange *ar;
+
+ if(!w || !Disp) return;
+ w->Erase(0x00e8e8e8L); w->ActualSize(&rc);
w->SetTextSpec(&ssText); et_racc = 0L;
- r_disp = (rc.bottom-rc.top)/CellHeight;
- c_disp = (rc.right-rc.left)/CellWidth+1;
- Disp->ShowGrid(CellWidth, CellHeight, FirstWidth, &currpos);
- rc.top = w->MenuHeight; rc.bottom = rc.top + CellHeight;
- for(i = 0; i <= (cRows - Disp->ssOrg.y) && i <= r_disp; i++) {
- rc.left = FirstWidth; rc.right = rc.left + CellWidth;
- rc.top += CellHeight; rc.bottom += CellHeight;
- for(j = 0; j <= (cCols - Disp->ssOrg.x) && j <= c_disp; j++) {
- r = i + Disp->ssOrg.y; c = j + Disp->ssOrg.x;
- if(r < cRows && r >= 0 && c < cCols && c >=0 && etRows[r][c]){
+ r_disp = (rc.bottom-rc.top)/CellHeight;
+ for(c = Disp->ssOrg.x, j=rc.left, c_disp = 1; c < cCols && j <= rc.right; c++, c_disp++) {
+ j += ri->GetWidth(c);
+ }
+ Disp->ShowGrid(CellWidth, CellHeight, FirstWidth, &currpos);
+ rc.top = w->MenuHeight; rc.bottom = rc.top + CellHeight;
+ for(i = 0; i <= (cRows - Disp->ssOrg.y) && i <= r_disp; i++) {
+ rc.left = ri->GetFirstWidth(); rc.right = rc.left + ri->GetWidth(Disp->ssOrg.x);
+ rc.top += CellHeight; rc.bottom += CellHeight;
+ for(j = 0; j <= (cCols - Disp->ssOrg.x) && j <= c_disp; j++) {
+ r = i + Disp->ssOrg.y; c = j + Disp->ssOrg.x;
+ if(r < cRows && r >= 0 && c < cCols && c >=0 && etRows[r][c]){
etRows[r][c]->SetRec(&rc); etRows[r][c]->Update(2, 0L, 0L);
etRows[r][c]->Redraw(w, false);
- }
- rc.left += CellWidth; rc.right += CellWidth;
+ }
+ rc.left += ri->GetWidth(Disp->ssOrg.x+j);
+ rc.right += ri->GetWidth(Disp->ssOrg.x+j+1);
}
- }
+ }
if(bUpdate) {
for(i = 0; i <= (cRows - Disp->ssOrg.y) && i <= r_disp; i++) {
for(j = 0; j <= (cCols - Disp->ssOrg.x) && j <= c_disp; j++) {
@@ -1558,139 +1672,144 @@ SpreadData::DoPlot(anyOutput *o)
&& CurrText->col >= Disp->ssOrg.x && CurrText->col < (Disp->ssOrg.x +c_disp))
CurrText->Update(1, w, 0L);
bUpdate = false;
- if(m_range && (ar = new AccRange(m_range)) && ar->GetFirst(&c, &r)) {
- for( ; ar->GetNext(&c, &r); ) {
+ if(m_range && (ar = new AccRange(m_range)) && ar->GetFirst(&c, &r)) {
+ for( ; ar->GetNext(&c, &r); ) {
if(r >= Disp->ssOrg.y && r < (r_disp + Disp->ssOrg.y) && c >= Disp->ssOrg.x
- && r < cRows && c < cCols
- && c < (c_disp + Disp->ssOrg.x) && etRows[r] && etRows[r][c])
- etRows[r][c]->Mark(w, etRows[r][c] != CurrText ? 2 : 3);
- }
- delete (ar);
- }
- if(c_range) InitCopy(0, 0L, w); //move animated rectangle
- w->ActualSize(&rc); rc.bottom += CellHeight; w->UpdateRect(&rc, false);
+ && r < cRows && c < cCols
+ && c < (c_disp + Disp->ssOrg.x) && etRows[r] && etRows[r][c])
+ etRows[r][c]->Mark(w, etRows[r][c] != CurrText ? 2 : 3);
+ }
+ delete (ar);
+ }
+ if(c_range) InitCopy(0, 0L, w); //move animated rectangle
+ w->ActualSize(&rc); rc.bottom += CellHeight; w->UpdateRect(&rc, false);
if(err_msg && (!last_err || strcmp(err_msg,last_err))) {
ErrorBox(last_err = err_msg);
- }
-}
-
-bool
-SpreadData::DelRange()
-{
- AccRange *ar;
+ }
+}
+
+bool
+SpreadData::DelRange()
+{
+ AccRange *ar;
int r, c;
- RECT rec;
-
+ RECT rec;
+
if(m_range && (ar = new AccRange(m_range)) && ar->GetFirst(&c, &r)) {
- ar->BoundRec(&rec);
+ ar->BoundRec(&rec);
Undo.DataObject(Disp, w, this, &rec, 0L);
- while(ar->GetNext(&c, &r)) {
- if(r >= 0 && r < cRows && c >= 0 && c < cCols){
- if(etRows[r][c] && etRows[r][c]->text) etRows[r][c]->SetText("");
- }
- }
- delete (ar); HideTextCursor();
- }
- HideMark(false);
+ while(ar->GetNext(&c, &r)) {
+ if(r >= 0 && r < cRows && c >= 0 && c < cCols){
+ if(etRows[r][c] && etRows[r][c]->text) etRows[r][c]->SetText("");
+ }
+ }
+ delete (ar); HideTextCursor();
+ }
+ HideMark(false);
if(CurrText) CurrText->Update(1, w, 0L);
bCopyCut = false;
- return true;
-}
-
-bool
-SpreadData::PasteRange(int cmd, char *txt)
-{
- AccRange *cr;
- int i, r, c;
- RECT mrk_range;
-
- if(new_mark && m_range && (cr = new AccRange(m_range)) && cr->GetFirst(&c, &r)) {
- cr->BoundRec(&mrk_range);
- for(i = 0 ; cr->GetNext(&c, &r); i++) if(c >= 0 && c < cCols && r >= 0 && r < cRows){
- currpos.x = c; currpos.y = r;
- switch(cmd){
- case CMD_PASTE_TSV: ReadTSV(0L, (unsigned char*)txt, FF_TSV); break;
+ return true;
+}
+
+bool
+SpreadData::PasteRange(int cmd, char *txt)
+{
+ AccRange *cr;
+ int i, r, c;
+ RECT mrk_range;
+
+ if(new_mark && m_range && (cr = new AccRange(m_range)) && cr->GetFirst(&c, &r)) {
+ cr->BoundRec(&mrk_range);
+ for(i = 0 ; cr->GetNext(&c, &r); i++) if(c >= 0 && c < cCols && r >= 0 && r < cRows){
+ currpos.x = c; currpos.y = r;
+ switch(cmd){
+ case CMD_PASTE_TSV: ReadTSV(0L, (unsigned char*)txt, FF_TSV); break;
case CMD_PASTE_SSV: ReadTSV(0L, (unsigned char*)txt, FF_SSV); break;
- case CMD_PASTE_XML: ReadXML(0L, (unsigned char*)txt, FF_XML, i ? UNDO_CONTINUE : 0L); break;
- case CMD_PASTE_CSV: ReadData(0L, (unsigned char*)txt, FF_CSV); break;
- }
- if((mrk_range.right - mrk_range.left) == (cp_src_rec.right - cp_src_rec.left) &&
- (mrk_range.bottom - mrk_range.top) == (cp_src_rec.bottom - cp_src_rec.top)) break;
- if((mrk_range.right - mrk_range.left) == 1 && (cp_src_rec.right - cp_src_rec.left) > 1) break;
- if((mrk_range.bottom - mrk_range.top) == 1 && (cp_src_rec.bottom - cp_src_rec.top) > 1) break;
- }
- delete cr; return true;
- }
- else switch(cmd){
- case CMD_PASTE_TSV:
- return ReadTSV(0L, (unsigned char*)txt, FF_TSV);
+ case CMD_PASTE_XML: ReadXML(0L, (unsigned char*)txt, FF_XML, i ? UNDO_CONTINUE : 0L); break;
+ case CMD_PASTE_CSV: ReadData(0L, (unsigned char*)txt, FF_CSV); break;
+ }
+ if((mrk_range.right - mrk_range.left) == (cp_src_rec.right - cp_src_rec.left) &&
+ (mrk_range.bottom - mrk_range.top) == (cp_src_rec.bottom - cp_src_rec.top)) break;
+ if((mrk_range.right - mrk_range.left) == 1 && (cp_src_rec.right - cp_src_rec.left) > 1) break;
+ if((mrk_range.bottom - mrk_range.top) == 1 && (cp_src_rec.bottom - cp_src_rec.top) > 1) break;
+ }
+ delete cr; return true;
+ }
+ else switch(cmd){
+ case CMD_PASTE_TSV:
+ return ReadTSV(0L, (unsigned char*)txt, FF_TSV);
case CMD_PASTE_SSV:
return ReadTSV(0L, (unsigned char*)txt, FF_SSV);
- case CMD_PASTE_XML:
- return ReadXML(0L, (unsigned char*)txt, FF_XML, 0L);
- case CMD_PASTE_CSV:
- return ReadData(0L, (unsigned char*)txt, FF_CSV);
- }
- return bCopyCut = false;
-}
-
-bool
-SpreadData::InitCopy(int cmd, void *tmpl, anyOutput *o)
-{
- int r, c;
- AccRange *ar;
- RECT rc_band, rcCopy;
- bool bRet = false;
+ case CMD_PASTE_XML:
+ return ReadXML(0L, (unsigned char*)txt, FF_XML, 0L);
+ case CMD_PASTE_CSV:
+ return ReadData(0L, (unsigned char*)txt, FF_CSV);
+ }
+ return bCopyCut = false;
+}
+
+bool
+SpreadData::InitCopy(int cmd, void *tmpl, anyOutput *o)
+{
+ int i, r, c;
+ AccRange *ar;
+ 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);
- new_mark = false;
- if(m_range && m_range[0]) {
- if(c_range) free(c_range); c_range = strdup(m_range);
- if(c_range && (ar = new AccRange(c_range))) {
- ar->BoundRec(&rcCopy);
- delete ar; bRet = true;;
- }
+ rcCopy.bottom = cRows-1; rcCopy.right = cCols-1;
+ if(cmd) {
+ bCopyCut = (cmd == CMD_CUT);
+ new_mark = false;
+ if(m_range && m_range[0]) {
+ if(c_range) free(c_range);
+ c_range = (char*)memdup(m_range, (int)strlen(m_range)+1, 0);
+ if(c_range && (ar = new AccRange(c_range))) {
+ ar->BoundRec(&rcCopy);
+ delete ar; bRet = true;;
+ }
}
else if (CurrText) {
if(CurrText->hasMark()) return CurrText->Command(CMD_COPY, o, 0L);
else {
if(m_range) free(m_range); m_range=0L;
- sprintf(TmpTxt, "%s%d:%s%d", Int2ColLabel(currpos.x, false), currpos.y+1,
- Int2ColLabel(currpos.x, false), currpos.y+1);
- m_range = strdup(TmpTxt); DoPlot(o);
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt, TMP_TXT_SIZE, "%s%d:", Int2ColLabel(currpos.x, false), currpos.y+1);
+#else
+ i = sprintf(TmpTxt, "%s%d:", Int2ColLabel(currpos.x, false), currpos.y+1);
+#endif
+ m_range = (char*)malloc(i*2+2); rlp_strcpy(m_range, i+1, TmpTxt);
+ rlp_strcpy(m_range +i, i, TmpTxt); DoPlot(o);
return InitCopy(cmd, tmpl, o);
}
- }
- }
- if(bRet || !cmd) { //calculate animated mark
+ }
+ }
+ 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;
- }
- c = rcCopy.left >= Disp->ssOrg.x ? rcCopy.left : Disp->ssOrg.x;
+ if(rcCopy.right < Disp->ssOrg.x || rcCopy.bottom < Disp->ssOrg.y) {
+ 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;
- while(!etRows[r] && r) r--; while(!etRows[r][c] && c) c--;
- if(etRows[r][c]){
- rc_band.left = etRows[r][c]->GetX()-1; rc_band.top = etRows[r][c]->GetY()-1;
- }
- else return bRet;
- c = rcCopy.right < (Disp->ssOrg.x + c_disp) ? rcCopy.right : Disp->ssOrg.x + c_disp;
+ while(!etRows[r] && r) r--; while(!etRows[r][c] && c) c--;
+ if(etRows[r][c]){
+ rc_band.left = etRows[r][c]->GetX()-1; rc_band.top = etRows[r][c]->GetY()-1;
+ }
+ else return bRet;
+ c = rcCopy.right < (Disp->ssOrg.x + c_disp) ? rcCopy.right : Disp->ssOrg.x + c_disp;
r = rcCopy.bottom < (Disp->ssOrg.y + r_disp)? rcCopy.bottom : Disp->ssOrg.y + r_disp;
- if(r >= cRows) r = cRows-1; if(c >= cCols) c = cRows -1;
- if(etRows[r][c]){
- rc_band.right = etRows[r][c]->GetX()+CellWidth;
+ if(r >= cRows) r = cRows-1; if(c >= cCols) c = cRows -1;
+ if(etRows[r][c]){
+ rc_band.right = etRows[r][c]->GetX()+ri->GetWidth(c);
rc_band.bottom = etRows[r][c]->GetY()+CellHeight;
if(rc_band.left >= rc_band.right) rc_band.right = rc_band.left + CellWidth;
- if(rc_band.top >= rc_band.bottom) rc_band.bottom = rc_band.top + CellHeight;
- ShowCopyMark(o, &rc_band, 1);
- }
- }
- return bRet;
+ if(rc_band.top >= rc_band.bottom) rc_band.bottom = rc_band.top + CellHeight;
+ ShowCopyMark(o, &rc_band, 1);
+ }
+ }
+ return bRet;
}
bool
@@ -1712,84 +1831,110 @@ SpreadData::SavePos()
pos_info.ssOrg.x = Disp->ssOrg.x; pos_info.ssOrg.y = Disp->ssOrg.y;
pos_info.CurrText = CurrText;
return bRet;
-}
-
-bool
-SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
-{
- int i;
- static int move_cr = CMD_CURRDOWN;
- MouseEvent *mev;
- POINT p, cp;
-
- if(!o) o = w;
- switch(cmd) {
- case CMD_MOUSE_EVENT:
- mev = (MouseEvent *) tmpl;
- p.x = mev->x; p.y = mev->y;
- if((mev->StateFlags & 1) || mev->Action == MOUSE_LBUP) {
- mpos2dpos(&p, &cp);
- if(cp.y >= cRows || cp.x >= cCols || cp.y < 0 || cp.x < 0) return false;
- }
- switch (mev->Action) {
+}
+
+bool
+SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
+{
+ int i;
+ static int move_cr = CMD_CURRDOWN;
+ MouseEvent *mev;
+ POINT p, cp;
+
+ if(!o) o = w;
+ switch(cmd) {
+ case CMD_MOUSE_EVENT:
+ mev = (MouseEvent *) tmpl;
+ p.x = mev->x; p.y = mev->y;
+ if((mev->StateFlags & 1) || mev->Action == MOUSE_LBUP || p.y < (w->MenuHeight+CellHeight)) {
+ mpos2dpos(&p, &cp, (mev->StateFlags & 1) == 1);
+ if(cp.y >= cRows || cp.x >= cCols || cp.y < 0 || cp.x < 0) return false;
+ }
+ else cp.x = cp.y = 0;
+ switch (mev->Action) {
case MOUSE_LBDOWN:
- 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)){
- CurrText->Update(2, w, &p); CurrText = 0L;
- DoPlot(w);
- }
- if(p.x < FirstWidth) cp.x = 0;
- if(p.y < (w->MenuHeight+CellHeight)) cp.y = 0;
+ if(m_range && (mev->StateFlags & 0x18)) mrk_offs = (int)strlen(m_range);
+ else mrk_offs = 0;
+ bActive = true; new_mark = false;
+ if(!et_racc && CurrText && !CurrText->isInRect(&p)){
+ CurrText->Update(2, w, &p); CurrText = 0L;
+ DoPlot(w);
+ }
+ if(p.x < FirstWidth) cp.x = 0;
+ if(p.y < (w->MenuHeight+CellHeight)) cp.y = 0;
currpos.y = currpos2.y = cp.y;
- currpos.x = currpos2.x = cp.x;
- case MOUSE_LBDOUBLECLICK: case MOUSE_MOVE:
- if(!bActive) return false;
- if(!m_range && !CurrText && cp.y < cRows && cp.x < cCols && cp.y >= 0 && cp.x >= 0)
- CurrText = etRows[cp.y][cp.x];
- if(mev->Action == MOUSE_MOVE && (mev->StateFlags & 1)
- && !(CurrText && CurrText->isInRect(&p))) {
- //mark rectangular range
- if(!et_racc && !m_range && CurrText) {
- CurrText->Update(2, w, &p); CurrText = 0L;
- }
+ currpos.x = currpos2.x = cp.x;
+ case MOUSE_MOVE:
+ if(p.y < (w->MenuHeight+CellHeight)) {
+ if(Disp->Command(CMD_COL_MOUSE, tmpl, w)) return true;
+ }
+ else w->MouseCursor(MC_ARROW, false);
+ case MOUSE_LBDOUBLECLICK:
+ if(!bActive) return false;
+ if(!m_range && !CurrText && cp.y < cRows && cp.x < cCols && cp.y >= 0 && cp.x >= 0)
+ CurrText = etRows[cp.y][cp.x];
+ if(mev->Action == MOUSE_MOVE && (mev->StateFlags & 1)
+ && !(CurrText && CurrText->isInRect(&p))) {
+ //mark rectangular range
+ if(!et_racc && !m_range && CurrText) {
+ CurrText->Update(2, w, &p); CurrText = 0L;
+ }
if(p.x < FirstWidth || p.y < (w->MenuHeight+CellHeight)) {
- i = sprintf(TmpTxt+mrk_offs, "%s%s%d:", mrk_offs? ";" : "", Int2ColLabel(p.x < FirstWidth ? 0 : currpos.x, false),
- p.y < (w->MenuHeight+CellHeight) ? 0 : currpos.y+1);
- sprintf(TmpTxt+mrk_offs+i, "%s%d", Int2ColLabel(p.x < FirstWidth ? cCols-1 : cp.x, false),
- p.y < (w->MenuHeight+CellHeight) ? cRows : cp.y+1);
- }
- else {
- 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, &cp);
- return true;
- }
- if(mev->Action == MOUSE_LBDOUBLECLICK) bActive = false;
- if(!(mev->StateFlags & 1)) return false;
- if(CurrText && CurrText->isInRect(&p)) {
- return CurrText->Command(CMD_MOUSE_EVENT, o, (DataObj *)mev);
- }
- if(etRows[cp.y][cp.x])
- return etRows[cp.y][cp.x]->Command(CMD_MOUSE_EVENT, o, (DataObj *)mev);
- return false;
- case MOUSE_LBUP:
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt+mrk_offs, TMP_TXT_SIZE - mrk_offs, "%s%s%d:", mrk_offs? ";" : "", Int2ColLabel(p.x < FirstWidth ? 0 : currpos.x, false),
+ p.y < (w->MenuHeight+CellHeight) ? 0 : currpos.y+1);
+ sprintf_s(TmpTxt+mrk_offs+i, TMP_TXT_SIZE - mrk_offs-i, "%s%d", Int2ColLabel(p.x < FirstWidth ? cCols-1 : cp.x, false),
+ p.y < (w->MenuHeight+CellHeight) ? cRows : cp.y+1);
+#else
+ i = sprintf(TmpTxt+mrk_offs, "%s%s%d:", mrk_offs? ";" : "", Int2ColLabel(p.x < FirstWidth ? 0 : currpos.x, false),
+ p.y < (w->MenuHeight+CellHeight) ? 0 : currpos.y+1);
+ sprintf(TmpTxt+mrk_offs+i, "%s%d", Int2ColLabel(p.x < FirstWidth ? cCols-1 : cp.x, false),
+ p.y < (w->MenuHeight+CellHeight) ? cRows : cp.y+1);
+#endif
+ }
+ else {
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt+mrk_offs, TMP_TXT_SIZE - mrk_offs, "%s%s%d:", mrk_offs? ";" : "", Int2ColLabel(currpos.x, false), currpos.y+1);
+ sprintf_s(TmpTxt+mrk_offs+i, TMP_TXT_SIZE - mrk_offs-i, "%s%d", Int2ColLabel(cp.x, false), cp.y+1);
+#else
+ 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);
+#endif
+ }
+ if(!CurrText || et_racc)MarkRange(TmpTxt, &cp);
+ return true;
+ }
+ if(mev->Action == MOUSE_LBDOUBLECLICK) bActive = false;
+ if(!(mev->StateFlags & 1)) return false;
+ if(CurrText && CurrText->isInRect(&p)) {
+ return CurrText->Command(CMD_MOUSE_EVENT, o, (DataObj *)mev);
+ }
+ if(etRows[cp.y][cp.x])
+ return etRows[cp.y][cp.x]->Command(CMD_MOUSE_EVENT, o, (DataObj *)mev);
+ return false;
+ case MOUSE_LBUP:
if(bActive){
+ if(p.y < (w->MenuHeight+CellHeight)) {
+ if(Disp->Command(CMD_COL_MOUSE, tmpl, w)) return true;
+ }
isRowMark = p.x < FirstWidth;
isColMark = p.y < (w->MenuHeight+CellHeight);
- if(isRowMark || isColMark) {
- if(p.x < FirstWidth) {
- currpos.x = 0; cp.x = cCols-1;
- }
- if(p.y < (w->MenuHeight+CellHeight)) {
- currpos.y = 0; cp.y = cRows-1;
- }
- 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(isRowMark || isColMark) {
+ if(p.x < FirstWidth) {
+ currpos.x = 0; cp.x = cCols-1;
+ }
+ if(p.y < (w->MenuHeight+CellHeight)) {
+ currpos.y = 0; cp.y = cRows-1;
+ }
+#ifdef USE_WIN_SECURE
+ i = sprintf_s(TmpTxt+mrk_offs, TMP_TXT_SIZE-mrk_offs, "%s%s%d:", mrk_offs? ";" : "", Int2ColLabel(currpos.x, false), currpos.y+1);
+ sprintf_s(TmpTxt+mrk_offs+i, TMP_TXT_SIZE-mrk_offs-i, "%s%d", Int2ColLabel(cp.x, false), cp.y+1);
+#else
+ 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);
+#endif
MarkRange(TmpTxt);
- currpos2.x = cp.x; currpos2.y = cp.y + 1;
+ currpos2.x = cp.x; currpos2.y = cp.y + 1;
}
else if((m_range) && !new_mark) HideMark(false);
if(et_racc && !et_racc->isInRect(&p)) {
@@ -1799,21 +1944,25 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
}
else {
if(!m_range) m_range = (char*)malloc(20);
+#ifdef USE_WIN_SECURE
+ sprintf_s(m_range, 20, "%s%d%", Int2ColLabel(currpos.x, false), currpos.y+1);
+#else
sprintf(m_range, "%s%d%", Int2ColLabel(currpos.x, false), currpos.y+1);
+#endif
CurrText->Command(CMD_ADDTXT, o, (DataObj*) m_range);
free(m_range); m_range = 0L;
}
- }
- else if(m_range) {
- CurrText = etRows[currpos.y][currpos.x]; CurrText->Update(1, w, &p);
+ }
+ else if(m_range) {
+ CurrText = etRows[currpos.y][currpos.x]; CurrText->Update(1, w, &p);
DoPlot(w);
currpos2.x = cp.x; currpos2.y = cp.y;
- }
- else return Select(&p);
- }
- }
- break;
- case CMD_PASTE_TSV: case CMD_PASTE_XML: case CMD_PASTE_CSV: case CMD_PASTE_SSV:
+ }
+ else return Select(&p);
+ }
+ }
+ break;
+ case CMD_PASTE_TSV: case CMD_PASTE_XML: case CMD_PASTE_CSV: case CMD_PASTE_SSV:
if(PasteRange(cmd, (char*)tmpl))
return Disp->Command(CMD_SETSCROLL, 0L, w);
return false;
@@ -1829,37 +1978,41 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
return true;
}
}
- return false;
- case CMD_UNLOCK:
+ return false;
+ case CMD_UNLOCK:
HideMark(false);
- currpos2.x = currpos.x; currpos2.y = currpos.y;
- break;
- case CMD_ERROR:
- err_msg = (char*)tmpl;
+ currpos2.x = currpos.x; currpos2.y = currpos.y;
+ break;
+ case CMD_ERROR:
+ if(err_msg && err_msg[0] && tmpl && *((char*)tmpl)) {
+ if(!(strcmp((char*)tmpl, "parse error")))return false; //parse error has lowest priority
+ }
+ if(!tmpl && err_msg && err_msg[0] && strcmp(err_msg, "parse error")) return false;
+ err_msg = (char*)tmpl;
break;
case CMD_UPDATE:
bUpdate = true;
break;
case CMD_SAVEPOS:
- return SavePos();
- case CMD_CLEAR_ERROR:
- err_msg = last_err = 0L;
- break;
- case CMD_TOOLMODE: //ESC pressed
- HideMark(true);
+ return SavePos();
+ case CMD_CLEAR_ERROR:
+ err_msg = last_err = 0L;
+ break;
+ case CMD_TOOLMODE: //ESC pressed
+ HideMark(true);
if(CurrText){
CurrText->Update(2, w, 0L); CurrText->Update(1, w, 0L);
}
et_racc = 0L; w->MouseCursor(MC_ARROW, true);
- break;
- case CMD_UPDHISTORY:
- if(w) w->FileHistory();
+ break;
+ case CMD_UPDHISTORY:
+ if(w) w->FileHistory();
break;
case CMD_MRK_DIRTY:
move_cr = CMD_CURRDOWN;
err_msg = last_err = 0L;
if(Disp) return Disp->Command(cmd, tmpl, o);
- return false;
+ return false;
case CMD_ADDCHAR:
if(CurrText){
if(currpos.y < Disp->ssOrg.y) {
@@ -1872,20 +2025,20 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
if(currpos.x < Disp->ssOrg.x) {
Disp->ssOrg.x = currpos.x; Disp->Command(CMD_SETSCROLL, 0L, w);
}
- else if(currpos.x > (Disp->ssOrg.x + c_disp -3)) {
+ else if(currpos.x > (Disp->ssOrg.x + c_disp -3) && (CurrText->GetRX()+ 10) > Disp->currRC.right ) {
Disp->ssOrg.x = currpos.x - (c_disp-3);
if(Disp->ssOrg.x < 0) Disp->ssOrg.x = 0; Disp->Command(CMD_SETSCROLL, 0L, w);
}
currpos2.x = currpos.x; currpos2.y = currpos.y;
- i = *((int*)tmpl);
+ i = *((int*)tmpl);
Disp->Command(CMD_CURRPOS, &currpos, w);
- if(i == 27) return Command(CMD_TOOLMODE, tmpl, o);
- if(i !=3 && i != 22 && i != 24 && i != 26) HideMark(true); //Do not hide upon ^C, ^V, ^X, ^Z
- if(i == 13) return CurrText->Command(move_cr, w, this);
- switch(i) {
- case 8: return CurrText->Command(CMD_BACKSP, w, this); //Backspace
- default: return CurrText->AddChar(*((int*)tmpl), w, Disp);
- }
+ if(i == 27) return Command(CMD_TOOLMODE, tmpl, o);
+ if(i !=3 && i != 22 && i != 24 && i != 26) HideMark(true); //Do not hide upon ^C, ^V, ^X, ^Z
+ if(i == 13) return CurrText->Command(move_cr, w, this);
+ switch(i) {
+ case 8: return CurrText->Command(CMD_BACKSP, w, this); //Backspace
+ default: return CurrText->AddChar(*((int*)tmpl), w, Disp);
+ }
}
else {
currpos.x = currpos2.x = Disp->ssOrg.x; currpos.y = currpos2.y = Disp->ssOrg.y;
@@ -1950,13 +2103,13 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
MarkRange(TmpTxt); HideTextCursor();
}
break;
- case CMD_CURRIGHT: case CMD_CURRDOWN:
- move_cr = cmd;
+ case CMD_CURRIGHT: case CMD_CURRDOWN:
+ move_cr = cmd;
case CMD_CURRLEFT: case CMD_CURRUP: case CMD_POS_FIRST: case CMD_POS_LAST:
if(cmd == CMD_CURRUP && Disp->ssOrg.y && CurrText && currpos.y == Disp->ssOrg.y) {
Disp->ssOrg.y --; currpos.y --;
DoPlot(o);
- }
+ }
if(cmd == CMD_CURRLEFT && Disp->ssOrg.x && CurrText && (!CurrText->Cursor()) && (currpos.x == Disp->ssOrg.x)) {
Disp->ssOrg.x --; currpos.x --;
CurrText->Update(2, o, 0L);
@@ -1976,41 +2129,41 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
Disp->ssOrg.y ++; currpos.y ++; DoPlot(o);
}
Disp->Command(CMD_CURRPOS, &currpos, w);
- HideMark(false);
+ HideMark(false);
currpos2.x = currpos.x; currpos2.y = currpos.y;
- if(CurrText)return CurrText->Command(cmd, w, this);
+ if(CurrText)return CurrText->Command(cmd, w, this);
else {
currpos.x = currpos2.x = Disp->ssOrg.x; currpos.y = currpos2.y = Disp->ssOrg.y;
if(etRows[currpos.y] && (CurrText = etRows[currpos.y][currpos.x]))
CurrText->Update(1, w, &p);;
}
- return false;
- case CMD_SHTAB:
- if(currpos.y >= cRows) currpos.y = cRows-1;
- if(currpos.x == Disp->ssOrg.x && Disp->ssOrg.x > 0) {
- Disp->ssOrg.x -= 1;
- Disp->Command(CMD_SETSCROLL, 0L, w);
- }
- if(currpos.x > Disp->ssOrg.x && etRows[currpos.y][currpos.x]) {
- currpos.x -=1;
- }
- case CMD_TAB:
- if(currpos.y >= cRows) currpos.y = cRows-1;
- if(cmd == CMD_TAB && currpos.x < (cCols-1) && etRows[currpos.y][currpos.x]) {
- if((FirstWidth+(currpos.x - Disp->ssOrg.x +2)*CellWidth) > Disp->currRC.right){
- Disp->ssOrg.x += 1;
- Disp->Command(CMD_SETSCROLL, 0L, w);
- }
- currpos.x +=1;
- }
- if(CurrText) CurrText->Update(2, w, &p);
- CurrText = etRows[currpos.y][currpos.x];
- if(CurrText){
- CurrText->Update(1, w, &p);
- CurrText->Command(cmd == CMD_TAB ? CMD_POS_FIRST : CMD_POS_LAST, o, this);
- }
+ return false;
+ case CMD_SHTAB:
+ if(currpos.y >= cRows) currpos.y = cRows-1;
+ if(currpos.x == Disp->ssOrg.x && Disp->ssOrg.x > 0) {
+ Disp->ssOrg.x -= 1;
+ Disp->Command(CMD_SETSCROLL, 0L, w);
+ }
+ if(currpos.x > Disp->ssOrg.x && etRows[currpos.y][currpos.x]) {
+ currpos.x -=1;
+ }
+ case CMD_TAB:
+ if(currpos.y >= cRows) currpos.y = cRows-1;
+ if(cmd == CMD_TAB && currpos.x < (cCols-1) && etRows[currpos.y][currpos.x]) {
+ if((FirstWidth+(currpos.x - Disp->ssOrg.x +2)*CellWidth) > Disp->currRC.right){
+ Disp->ssOrg.x += 1;
+ Disp->Command(CMD_SETSCROLL, 0L, w);
+ }
+ currpos.x +=1;
+ }
+ if(CurrText) CurrText->Update(2, w, &p);
+ CurrText = etRows[currpos.y][currpos.x];
+ if(CurrText){
+ CurrText->Update(1, w, &p);
+ CurrText->Command(cmd == CMD_TAB ? CMD_POS_FIRST : CMD_POS_LAST, o, this);
+ }
Disp->Command(CMD_CURRPOS, &currpos, w);
- return true;
+ return true;
case CMD_UNDO:
if(w) {
w->MouseCursor(MC_WAIT, true);
@@ -2022,45 +2175,45 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
}
}
return true;
- case CMD_DELETE:
- if(m_range) DelRange();
- else if(CurrText) return CurrText->Command(cmd, o, this);
+ case CMD_DELETE:
+ if(m_range) DelRange();
+ else if(CurrText) return CurrText->Command(cmd, o, this);
Disp->Command(CMD_CURRPOS, &currpos, w);
- return true;
+ return true;
case CMD_QUERY_COPY: case CMD_CUT:
- et_racc = 0L;
- return InitCopy(cmd, tmpl, w);
- case CMD_GET_CELLDIMS:
- if(tmpl) {
- ((int*)tmpl)[0] = FirstWidth; ((int*)tmpl)[1] = CellWidth;
- ((int*)tmpl)[2] = CellHeight;
- }
- break;
- case CMD_SET_CELLDIMS:
- if(tmpl) {
- FirstWidth = ((int*)tmpl)[0]; CellWidth = ((int*)tmpl)[1];
- CellHeight = ((int*)tmpl)[2];
- }
+ et_racc = 0L;
+ return InitCopy(cmd, tmpl, w);
+ case CMD_GET_CELLDIMS:
+ if(tmpl) {
+ ((int*)tmpl)[0] = FirstWidth; ((int*)tmpl)[1] = CellWidth;
+ ((int*)tmpl)[2] = CellHeight;
+ }
+ break;
+ case CMD_SET_CELLDIMS:
+ if(tmpl) {
+ FirstWidth = ((int*)tmpl)[0]; CellWidth = ((int*)tmpl)[1];
+ CellHeight = ((int*)tmpl)[2];
+ }
break;
- case CMD_TEXTSIZE:
- if(tmpl) return Disp->Command(cmd, tmpl, o);
- return false;
- case CMD_COPY_TSV:
- return MemList((unsigned char**)tmpl, FF_TSV);
- case CMD_COPY_SYLK:
- return MemList((unsigned char**)tmpl, FF_SYLK);
- case CMD_COPY_XML:
+ case CMD_TEXTSIZE:
+ if(tmpl) return Disp->Command(cmd, tmpl, o);
+ return false;
+ case CMD_COPY_TSV:
+ return MemList((unsigned char**)tmpl, FF_TSV);
+ case CMD_COPY_SYLK:
+ return MemList((unsigned char**)tmpl, FF_SYLK);
+ case CMD_COPY_XML:
return MemList((unsigned char**)tmpl, FF_XML);
case CMD_DOPLOT: case CMD_REDRAW:
if(CurrText) CurrText->Update(2, 0L, 0L);
if(etRows && etRows[currpos.y] && currpos.y < cRows && currpos.x < cCols)
if(CurrText = etRows[currpos.y][currpos.x]) CurrText->Update(1,0L, 0L);
- DoPlot(o);
- break;
+ DoPlot(o);
+ break;
case CMD_FILLRANGE:
- Undo.SetDisp(w);
+ Undo.SetDisp(w);
FillSsRange(this, &m_range, Disp);
- DoPlot(o);
+ DoPlot(o);
Undo.SetDisp(w);
break;
case CMD_GETMARK:
@@ -2077,51 +2230,51 @@ SpreadData::Command(int cmd, void *tmpl, anyOutput *o)
return DeleteRows();
case CMD_DELCOL:
return DeleteCols();
- }
- return true;
-}
-
-bool
-SpreadData::ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flags)
-{
- int i, row, col, tag, cpgr, spgr, ufl = 0;
- bool bContinue, bRet = false, bUndo_done = false;
- ReadCache *XMLcache;
- POINT pt, mov;
+ }
+ return true;
+}
+
+bool
+SpreadData::ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flags)
+{
+ int i, row, col, tag, cpgr, spgr, ufl = 0;
+ bool bContinue, bRet = false, bUndo_done = false;
+ ReadCache *XMLcache;
+ POINT pt, mov;
char TmpTxt[1024], *tmp_range;
unsigned char *pgr = 0L;
- RECT rc_undo;
+ RECT rc_undo;
- if(file) {
- if(!(XMLcache = new ReadCache())) return false;
- if(! XMLcache->Open(file)) {
- delete XMLcache;
- sprintf(TmpTxt, "Error open file\n\"%s\"", file);
- ErrorBox(TmpTxt);
- return false;
+ if(file) {
+ if(!(XMLcache = new ReadCache())) return false;
+ if(! XMLcache->Open(file)) {
+ delete XMLcache;
+ sprintf(TmpTxt, "Error open file\n\"%s\"", file);
+ ErrorBox(TmpTxt);
+ return false;
}
- bUndo_done = true;
+ bUndo_done = true;
if(!Init(1, 1)) goto XMLError;
- etRows[0][0]->SetText("");
- }
- else if(buffer && type == FF_XML){
- if(!(XMLcache = new MemCache(buffer))) return false;
- if(buffer && bCopyCut) {
- tmp_range = m_range; m_range = c_range;
- c_range = 0L; DelRange();
- m_range = tmp_range;
- }
- }
- else return false;
- pt.x = pt.y = mov.x = mov.y = 0;
- cp_src_rec.left = cp_src_rec.right = cp_src_rec.top = cp_src_rec.bottom = 0;
- do {
- row = col = 0;
- do {
- TmpTxt[0] = XMLcache->Getc();
- }while(TmpTxt[0] && TmpTxt[0] != '<');
- for(i = 1; i < 5; TmpTxt[i++] = XMLcache->Getc());
- TmpTxt[i] = 0;
+ etRows[0][0]->SetText("");
+ }
+ else if(buffer && type == FF_XML){
+ if(!(XMLcache = new MemCache(buffer))) return false;
+ if(buffer && bCopyCut) {
+ tmp_range = m_range; m_range = c_range;
+ c_range = 0L; DelRange();
+ m_range = tmp_range;
+ }
+ }
+ else return false;
+ pt.x = pt.y = mov.x = mov.y = 0;
+ cp_src_rec.left = cp_src_rec.right = cp_src_rec.top = cp_src_rec.bottom = 0;
+ do {
+ row = col = 0;
+ do {
+ TmpTxt[0] = XMLcache->Getc();
+ }while(TmpTxt[0] && TmpTxt[0] != '<');
+ for(i = 1; i < 5; TmpTxt[i++] = XMLcache->Getc());
+ TmpTxt[i] = 0;
if(!strcmp("<cell", TmpTxt)){
if(!bUndo_done) {
rc_undo.left = currpos.x;
@@ -2132,8 +2285,8 @@ SpreadData::ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flag
bUndo_done = true;
}
tag = 1;
- }
- else if(!strcmp("<pos1", TmpTxt)) tag = 2;
+ }
+ else if(!strcmp("<pos1", TmpTxt)) tag = 2;
else if(!strcmp("<pos2", TmpTxt)) tag = 3;
else if(!strcmp("<RLPl", TmpTxt)) {
do {
@@ -2152,7 +2305,7 @@ SpreadData::ReadXML(char *file, unsigned char *buffer, int type, DWORD undo_flag
AddCols(col); AddRows(row);
}
row = col = -1;
- }
+ }
else if(!strcmp("<Grap", TmpTxt)){
while(XMLcache->Getc() != '[');
pgr = (unsigned char*)malloc(spgr = 1000);
@@ -2163,146 +2316,146 @@ 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, false);
+ if(cpgr >20)OpenGraph(Disp, 0L, pgr, false);
free(pgr); tag = 0;
}
- else tag = 0;
- if(tag) {
- do {
- TmpTxt[0] = XMLcache->Getc();
- }while(TmpTxt[0] && TmpTxt[0] != '"');
- if (TmpTxt[0]) for (i =0; i <10 && ('"' != (TmpTxt[i] =XMLcache->Getc())); i++){
- TmpTxt[i+1] = 0;
- row = (int)atoi(TmpTxt);
- }
- do {
- TmpTxt[0] = XMLcache->Getc();
- }while(TmpTxt[0] && TmpTxt[0] != '"');
- if (TmpTxt[0]) for (i =0; i <10 && ('"' != (TmpTxt[i] =XMLcache->Getc())); i++){
- TmpTxt[i+1] = 0;
- col = (int)atoi(TmpTxt);
- }
- if(tag ==2) {
- mov.x = col; mov.y = row;
+ else tag = 0;
+ if(tag) {
+ do {
+ TmpTxt[0] = XMLcache->Getc();
+ }while(TmpTxt[0] && TmpTxt[0] != '"');
+ if (TmpTxt[0]) for (i =0; i <10 && ('"' != (TmpTxt[i] =XMLcache->Getc())); i++){
+ TmpTxt[i+1] = 0;
+ row = (int)atoi(TmpTxt);
+ }
+ do {
+ TmpTxt[0] = XMLcache->Getc();
+ }while(TmpTxt[0] && TmpTxt[0] != '"');
+ if (TmpTxt[0]) for (i =0; i <10 && ('"' != (TmpTxt[i] =XMLcache->Getc())); i++){
+ TmpTxt[i+1] = 0;
+ col = (int)atoi(TmpTxt);
+ }
+ if(tag ==2) {
+ mov.x = col; mov.y = row;
cp_src_rec.left = col; cp_src_rec.top = row;
- ufl |= 1;
- }
- else if(tag ==3) {
+ ufl |= 1;
+ }
+ else if(tag ==3) {
cp_src_rec.right = col; cp_src_rec.bottom = row;
- ufl |= 2;
- }
- else if(row && col) do {
- do {
- TmpTxt[0] = XMLcache->Getc();
- }while(TmpTxt[0] && TmpTxt[0] != '<');
- for(i = 1; i < 6; TmpTxt[i++] = XMLcache->Getc());
- TmpTxt[i] = 0;
- if(bContinue =(0 == strcmp("<text>", TmpTxt))) {
- for(i = 0; i < 1023 && ('<' != (TmpTxt[i] =XMLcache->Getc())); i++);
- TmpTxt[i] = 0;
- //xml indices start at 1:1 !
- row += currpos.y-1; col += currpos.x-1;
- if(row >= cRows)AddRows(row+1);
- if(col >= cCols)AddCols(col+1);
- if(i && etRows[row] && etRows[row][col]) {
- if(TmpTxt[0] == '=') {
- MoveFormula(this, TmpTxt, TmpTxt, currpos.x-mov.x, currpos.y-mov.y, -1, -1);
- }
- etRows[row][col]->SetText(TmpTxt);
- etRows[row][col]->Update(20, 0L, &pt);
- }
- }
- }while(!bContinue);
- }
- }while(!XMLcache->IsEOF());
- bRet = true;
-XMLError:
- XMLcache->Close();
- delete XMLcache;
- bCopyCut = false;
- return bRet;
-}
-
-bool
-SpreadData::ReadTSV(char *file, unsigned char *buffer, int type)
-{
- int i, row, col;
- char c;
- bool bRet = false;
- ReadCache *TSVcache;
- POINT pt;
-
- if(file) {
- if(!(TSVcache = new ReadCache())) return false;
- if(! TSVcache->Open(file)) {
- delete TSVcache;
- sprintf(TmpTxt, "Error open file\n\"%s\"", file);
- ErrorBox(TmpTxt);
- return false;
- }
+ ufl |= 2;
+ }
+ else if(row && col) do {
+ do {
+ TmpTxt[0] = XMLcache->Getc();
+ }while(TmpTxt[0] && TmpTxt[0] != '<');
+ for(i = 1; i < 6; TmpTxt[i++] = XMLcache->Getc());
+ TmpTxt[i] = 0;
+ if(bContinue =(0 == strcmp("<text>", TmpTxt))) {
+ for(i = 0; i < 1023 && ('<' != (TmpTxt[i] =XMLcache->Getc())); i++);
+ TmpTxt[i] = 0;
+ //xml indices start at 1:1 !
+ row += currpos.y-1; col += currpos.x-1;
+ if(row >= cRows)AddRows(row+1);
+ if(col >= cCols)AddCols(col+1);
+ if(i && etRows[row] && etRows[row][col]) {
+ if(TmpTxt[0] == '=') {
+ MoveFormula(this, TmpTxt, TmpTxt, currpos.x-mov.x, currpos.y-mov.y, -1, -1);
+ }
+ etRows[row][col]->SetText(TmpTxt);
+ etRows[row][col]->Update(20, 0L, &pt);
+ }
+ }
+ }while(!bContinue);
+ }
+ }while(!XMLcache->IsEOF());
+ bRet = true;
+XMLError:
+ XMLcache->Close();
+ delete XMLcache;
+ bCopyCut = false;
+ return bRet;
+}
+
+bool
+SpreadData::ReadTSV(char *file, unsigned char *buffer, int type)
+{
+ int i, row, col;
+ char c;
+ bool bRet = false;
+ ReadCache *TSVcache;
+ POINT pt;
+
+ if(file) {
+ if(!(TSVcache = new ReadCache())) return false;
+ if(! TSVcache->Open(file)) {
+ delete TSVcache;
+ sprintf(TmpTxt, "Error open file\n\"%s\"", file);
+ ErrorBox(TmpTxt);
+ return false;
+ }
if(!Init(1, 1)) goto TSVError;
- etRows[0][0]->SetText("");
- }
- else if(buffer && (type == FF_TSV || type == FF_SSV)) {
- if(!(TSVcache = new MemCache(buffer))) return false;
- }
- else return false;
- row = currpos.y; col = currpos.x;
- pt.x = pt.y = 0;
- do {
- do {
- TmpTxt[0] = TSVcache->Getc();
- switch(TmpTxt[0]) {
- case 0x0d: //CR
- case 0x0a: //LF
- if(col == currpos.x) break;
- row ++; col = currpos.x; break;
- case 0x09: //tab
+ etRows[0][0]->SetText("");
+ }
+ else if(buffer && (type == FF_TSV || type == FF_SSV)) {
+ if(!(TSVcache = new MemCache(buffer))) return false;
+ }
+ else return false;
+ row = currpos.y; col = currpos.x;
+ pt.x = pt.y = 0;
+ do {
+ do {
+ TmpTxt[0] = TSVcache->Getc();
+ switch(TmpTxt[0]) {
+ case 0x0d: //CR
+ case 0x0a: //LF
+ if(col == currpos.x) break;
+ row ++; col = currpos.x; break;
+ case 0x09: //tab
col ++; break;
case ' ':
- if(type == FF_SSV) col ++; break;
- }
- }while(TmpTxt[0] && TmpTxt[0] < 33);
- for(i = 1; (TmpTxt[i] = c = TSVcache->Getc())>= (type == FF_SSV ? 33 : 32); i++)
- if(i >= 4094) i = 4094;
- if(TmpTxt[0] && row >= cRows)AddRows(row+1);
- if(TmpTxt[0] && col >= cCols)AddCols(col+1);
- TmpTxt[i] = 0;
- if(TmpTxt[0] && etRows[row] && etRows[row][col]) {
- etRows[row][col]->SetText(TmpTxt);
- etRows[row][col]->Update(20, 0L, &pt);
- switch(c) {
- case 0x0d: //CR
- case 0x0a: //LF
- row ++; col = currpos.x; break;
- case 0x09: //tab
- col ++; break;
+ if(type == FF_SSV) col ++; break;
+ }
+ }while(TmpTxt[0] && ((unsigned char)TmpTxt[0] < 33));
+ for(i = 1; ((unsigned char)(TmpTxt[i] = c = TSVcache->Getc()))>= (type == FF_SSV ? 33 : 32); i++)
+ if(i >= 4094) i = 4094;
+ if(TmpTxt[0] && row >= cRows)AddRows(row+1);
+ if(TmpTxt[0] && col >= cCols)AddCols(col+1);
+ TmpTxt[i] = 0;
+ if(TmpTxt[0] && etRows[row] && etRows[row][col]) {
+ etRows[row][col]->SetText(TmpTxt);
+ etRows[row][col]->Update(20, 0L, &pt);
+ switch(c) {
+ case 0x0d: //CR
+ case 0x0a: //LF
+ row ++; col = currpos.x; break;
+ case 0x09: //tab
+ col ++; break;
case ' ':
if(type == FF_SSV) col ++; break;
- }
- }
- }while(!TSVcache->IsEOF());
- bRet = true;
-TSVError:
- TSVcache->Close();
- delete TSVcache;
- return bRet;
-}
-
-bool
-SpreadData::MemList(unsigned char **ptr, int type)
-{
+ }
+ }
+ }while(!TSVcache->IsEOF());
+ bRet = true;
+TSVError:
+ TSVcache->Close();
+ delete TSVcache;
+ return bRet;
+}
+
+bool
+SpreadData::MemList(unsigned char **ptr, int type)
+{
int i, j, k, nc, nl, cb = 0;
- long cbd = 0, size;
- char tmptxt[8000];
- *ptr = (unsigned char *)malloc(size = 10000);
- unsigned char *tmpptr;
+ long cbd = 0, size;
+ char tmptxt[8000];
+ *ptr = (unsigned char *)malloc(size = 10000);
+ unsigned char *tmpptr;
bool bLimit = true;
AccRange *ar;
anyResult res;
- RECT rcCopy;
-
- if(!(*ptr))return false;
+ RECT rcCopy;
+
+ if(!(*ptr))return false;
if (c_range && c_range[0]) {
ar = new AccRange(c_range); ar->BoundRec(&rcCopy);
if(bCopyCut) Undo.DataObject(Disp, w, this, &rcCopy, 0L);
@@ -2311,40 +2464,40 @@ SpreadData::MemList(unsigned char **ptr, int type)
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(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);
- if(rcCopy.left || rcCopy.top || rcCopy.bottom || rcCopy.right){
- cbd += sprintf((char*)*ptr+cbd, " <pos1 row=\"%d\" "
- "column=\"%d\"></pos1>\n", rcCopy.top, rcCopy.left);
- cbd += sprintf((char*)*ptr+cbd, " <pos2 row=\"%d\" "
- "column=\"%d\"></pos2>\n", rcCopy.bottom, rcCopy.right);
- }
- }
- else if(type == FF_RLW) {
+ "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);
+ if(rcCopy.left || rcCopy.top || rcCopy.bottom || rcCopy.right){
+ cbd += sprintf((char*)*ptr+cbd, " <pos1 row=\"%d\" "
+ "column=\"%d\"></pos1>\n", rcCopy.top, rcCopy.left);
+ cbd += sprintf((char*)*ptr+cbd, " <pos2 row=\"%d\" "
+ "column=\"%d\"></pos2>\n", rcCopy.bottom, rcCopy.right);
+ }
+ }
+ else if(type == FF_RLW) {
cbd = sprintf((char*)*ptr, "<?xml version=\"1.0\"?><!DOCTYPE RLPlot-workbook>\n"
"<RLPlot-data rows=\"%d\" columns=\"%d\" >\n", cRows, cCols);
}
- 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");
+ 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]){
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)){
+ }
+ tmptxt[cb] = 0;
+ }
+ break;
+ case FF_SYLK:
+ if(etRows[i] && etRows[i][j] && etRows[i][j]->text && ((ar && ar->IsInRange(j,i)) || !ar)){
etRows[i][j]->GetResult(&res, false);
TranslateResult(&res);
switch(res.type) {
@@ -2370,38 +2523,38 @@ SpreadData::MemList(unsigned char **ptr, int type)
break;
}
if(bCopyCut) etRows[i][j]->SetText("");
- }
- break;
- case FF_RLW: case FF_XML:
+ }
+ break;
+ case FF_RLW: case FF_XML:
if(etRows[i] && etRows[i][j] && etRows[i][j]->text && ((ar && ar->IsInRange(j,i)) || !ar)
- && etRows[i][j]->text[0]){
- cb = sprintf(tmptxt, " <cell row=\"%d\" column=\"%d\" >\n", nl+1, nc+1);
- cb += sprintf(tmptxt+cb, " <text>");
- for(k = 0; k < 7880 && (etRows[i][j]->text[k]); k++)
- tmptxt[cb++] = etRows[i][j]->text[k];
+ && etRows[i][j]->text[0]){
+ cb = sprintf(tmptxt, " <cell row=\"%d\" column=\"%d\" >\n", nl+1, nc+1);
+ cb += sprintf(tmptxt+cb, " <text>");
+ for(k = 0; k < 7880 && (etRows[i][j]->text[k]); k++)
+ tmptxt[cb++] = etRows[i][j]->text[k];
cb += sprintf(tmptxt+cb, "</text>\n </cell>\n");
if(bCopyCut) etRows[i][j]->SetText("");
}
- break;
- }
- if((cbd+cb+100) > size){
- if(tmpptr = (unsigned char*)realloc(*ptr, size+10000)) {
- *ptr = tmpptr; size += 10000;
- }
- else return true; //not all but something on clipboard
- }
- memcpy(*ptr+cbd, tmptxt, cb+1);
- cbd += cb;
- }
- if(type == FF_SYLK) {
- if(!bLimit) {
- cbd += sprintf((char*)*ptr+cbd, "C;Y%d;X1;K\"long strings were"
- " truncated to 256 characters due to limitations of the SYLK format!\"\n", i+2);
- }
- sprintf((char*)*ptr+cbd, "E\n");
- }
- else if(type == FF_TSV) sprintf((char*)*ptr+cbd,"\n");
- }
+ break;
+ }
+ if((cbd+cb+100) > size){
+ if(tmpptr = (unsigned char*)realloc(*ptr, size+10000)) {
+ *ptr = tmpptr; size += 10000;
+ }
+ else return true; //not all but something on clipboard
+ }
+ memcpy(*ptr+cbd, tmptxt, cb+1);
+ cbd += cb;
+ }
+ if(type == FF_SYLK) {
+ if(!bLimit) {
+ cbd += sprintf((char*)*ptr+cbd, "C;Y%d;X1;K\"long strings were"
+ " truncated to 256 characters due to limitations of the SYLK format!\"\n", i+2);
+ }
+ sprintf((char*)*ptr+cbd, "E\n");
+ }
+ else if(type == FF_TSV) sprintf((char*)*ptr+cbd,"\n");
+ }
if(type == FF_XML) sprintf((char*)*ptr+cbd,"</spreadsheet-snippet>\n");
else if(type == FF_RLW){
Disp->Command(CMD_WRITE_GRAPHS, ptr, (anyOutput*)&cbd);
@@ -2413,16 +2566,16 @@ SpreadData::MemList(unsigned char **ptr, int type)
bCopyCut = false;
DoPlot(w);
}
- return true;
-}
-
-void SpreadMain(bool show)
-{
- static SpreadData *w = 0L;
-
- if(show) {
- if(w = new SpreadData(0L)) w->Init(50, 10);
- do_formula(w, 0L); //init mfcalc
- }
- else if (w) delete(w);
-}
+ return true;
+}
+
+void SpreadMain(bool show)
+{
+ static SpreadData *w = 0L;
+
+ if(show) {
+ if(w = new SpreadData(0L)) w->Init(50, 10);
+ do_formula(w, 0L); //init mfcalc
+ }
+ else if (w) delete(w);
+}
diff --git a/use_gui.cpp b/use_gui.cpp
index 023f00e..30dce9a 100755
--- a/use_gui.cpp
+++ b/use_gui.cpp
@@ -112,7 +112,7 @@ ssButton::Command(int cmd, void *tmpl, anyOutput *o)
switch (cmd) {
case CMD_GETTEXT:
if(TextDef.text && tmpl) {
- strcpy((char*)tmpl, TextDef.text);
+ rlp_strcpy((char*)tmpl, 10, TextDef.text);
return true;
}
return false;
@@ -132,9 +132,10 @@ ssButton::Command(int cmd, void *tmpl, anyOutput *o)
}
return true;
case CMD_SETTEXT:
- if(TextDef.text) free(TextDef.text);
- if(tmpl) TextDef.text = strdup((char*)tmpl);
- else TextDef.text = 0L;
+ if(tmpl) {
+ if(! TextDef.text) TextDef.text = (char*)malloc(10*sizeof(char));
+ rlp_strcpy(TextDef.text, 10, (char*)tmpl);
+ }
return true;
case CMD_GETTEXTDEF:
if(!tmpl) return false;
@@ -967,7 +968,7 @@ Label::AddChar(int ci, anyOutput *o)
Undo.String(this, &TextDef.text, 0L);
Undo.ValInt(this, &CursorPos, UNDO_CONTINUE);
}
- if(TextDef.text) txt1 = (char*)calloc((i = strlen(TextDef.text))+2, sizeof(char));
+ if(TextDef.text) txt1 = (char*)calloc((i = (int)strlen(TextDef.text))+2, sizeof(char));
else txt1 = (char*)calloc((i = 0)+2, sizeof(char));
if(txt1) {
for(j = k = 0; j< i && j < CursorPos; txt1[k++] = TextDef.text[j++]);
@@ -1005,7 +1006,64 @@ Label::CalcCursorPos(int x, int y, anyOutput *o)
x1 = x2;
}
if(pts[3].x < pts[2].x && x < pts[3].x) CursorPos = 0;
- else CursorPos = strlen(TextDef.text);
+ else CursorPos = (int)strlen(TextDef.text);
+}
+
+void
+TextFrame::ShowCursor(anyOutput *o)
+{
+ int cx, cy, w, h;
+
+ if(!o) return;
+ TextDef.iSize = o->un2iy(TextDef.fSize);
+#ifdef _WINDOWS
+ linc = o->un2iy(TextDef.fSize*lspc);
+#else
+ linc = o->un2iy(TextDef.fSize*lspc*1.2);
+#endif
+ o->SetTextSpec(&TextDef);
+ cy = rDims.top + linc * cur_pos.y; cx = rDims.left;
+ cx += ipad.left; cy += ipad.top;
+ if(cur_pos.y < nlines) {
+ if(lines[cur_pos.y] && lines[cur_pos.y][0] && cur_pos.x) {
+ fmt_txt.SetText(0L, (char*)lines[cur_pos.y], &cx, &cy);
+ if(!fmt_txt.oGetTextExtent(o, &w, &h, cur_pos.x))return;
+ }
+ else {
+ if(!o->oGetTextExtent("A", 1, &w, &h))return; w = 0;
+ }
+ Cursor.left = cx+w; Cursor.right = cx+w;
+ Cursor.top = cy; Cursor.bottom = cy+linc;
+ ShowTextCursor(o, &Cursor, TextDef.ColTxt);
+ }
+}
+
+void
+TextFrame::CalcCursorPos(int x, int y, anyOutput *o)
+{
+ int i, iy, ix, x1, x2, h;
+
+ if(!o) return;
+ TextDef.iSize = o->un2iy(TextDef.fSize);
+ o->SetTextSpec(&TextDef);
+ iy = (y-rDims.top-ipad.top)/linc; x1 = x2 = 0;
+ if(iy >= nlines) iy = nlines-1; cur_pos.y = iy;
+ x2 = rDims.right - rDims.left -ipad.left - ipad.right;
+ x = x - rDims.left -ipad.left;
+ fmt_txt.SetText(0L, (char*)lines[iy], &x1, &x2);
+ for(i = 0, ix = x1 = 0; lines[iy][i]; i++) {
+ if(i) fmt_txt.oGetTextExtent(o, &x1, &h, i);
+ x1 -= (TextDef.iSize >> 2);
+ if(i && x1 <= x2 && x1 >= x) {
+ if(i >1) fmt_txt.oGetTextExtent(o, &x1, &h, i-1);
+ else x1 = 0;
+ fmt_txt.oGetTextExtent(o, &x2, &h, i);
+ ix = (abs(x1-x)<abs(x2-x)) ? i = (i-1) : i;
+ break;
+ }
+ }
+ if(ix) cur_pos.x = ix;
+ else cur_pos.x = i;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1015,6 +1073,7 @@ Graph::ExecTool(MouseEvent *mev)
{
static POINT pl = {0, 0}, pc = {0, 0};
static DWORD color = 0L;
+ scaleINFO scale;
POINT line[5];
GraphObj **tmpPlots, *new_go;
TextDEF *td;
@@ -1102,7 +1161,68 @@ Graph::ExecTool(MouseEvent *mev)
}
if(ToolMode == TM_PASTE) {
switch (mev->Action) {
+ case MOUSE_LBDOWN:
+ CurrGO = 0L;
+ CurrDisp->MrkMode = MRK_NONE;
+ pl.x = pc.x = mev->x; pl.y = pc.y = mev->y;
+ rcDim.left = rcDim.right = rcUpd.left = rcUpd.right = mev->x;
+ rcDim.top = rcDim.bottom = rcUpd.top = rcUpd.bottom = mev->y;
+ return true;
+ case MOUSE_MOVE:
+ if(mev->StateFlags &1) {
+ if(rcUpd.left != rcUpd.right && rcUpd.top != rcUpd.bottom)
+ CurrDisp->UpdateRect(&rcUpd, false);
+ line[0].x = line[4].x = pl.x; line[0].y = line[4].y = pl.y;
+ line[1].x = pc.x = mev->x; line[1].y = pl.y;
+ line[2].x = mev->x; line[2].y = pc.y = mev->y;
+ line[3].x = pl.x; line[3].y = mev->y;
+ CurrDisp->ShowLine(line, 5, 0x00c0c0c0L);
+ memcpy(&rcUpd, &rcDim, sizeof(RECT));
+ UpdateMinMaxRect(&rcUpd, mev->x, mev->y);
+ IncrementMinMaxRect(&rcUpd, 2);
+ return true;
+ }
+ break;
case MOUSE_LBUP:
+ if(!PasteObj) return false;
+ pc.x = mev->x; pc.y = mev->y;
+ if((lfp = (lfPOINT*)malloc(2 * sizeof(lfPOINT)))){
+ lfp[0].fx = CurrDisp->fix2un(pl.x - CurrDisp->VPorg.fx);
+ lfp[0].fy = CurrDisp->fiy2un(pl.y - CurrDisp->VPorg.fy);
+ lfp[1].fx = CurrDisp->fix2un(pc.x - CurrDisp->VPorg.fx);
+ lfp[1].fy = CurrDisp->fiy2un(pc.y - CurrDisp->VPorg.fy);
+ if(lfp[0].fx > lfp[1].fx) {
+ x = lfp[0].fx; lfp[0].fx = lfp[1].fx; lfp[1].fx = x;
+ }
+ if(lfp[0].fy > lfp[1].fy) {
+ y = lfp[0].fy; lfp[0].fy = lfp[1].fy; lfp[1].fy = y;
+ }
+ }
+ else {
+ DeleteGO(PasteObj); PasteObj = 0L;
+ ToolMode = TM_STANDARD; CurrDisp->MouseCursor(MC_ARROW, false);
+ return true;
+ }
+ scale.sx.fx = lfp[0].fx; scale.sy.fx = lfp[0].fy; scale.sz.fx = 0.0;
+ scale.sx.fy = scale.sy.fy = scale.sz.fy = 1.0;
+ if(PasteObj->Id == GO_GRAPH) {
+ if(abs(pc.x -pl.x) > 20 && abs(pc.y -pl.y) >20) {
+ x = ((Graph*)PasteObj)->GRect.Xmax - ((Graph*)PasteObj)->GRect.Xmin;
+ y = ((Graph*)PasteObj)->GRect.Ymax - ((Graph*)PasteObj)->GRect.Ymin;
+ scale.sx.fy = (lfp[1].fx - lfp[0].fx)/x;
+ scale.sy.fy = (lfp[1].fy - lfp[0].fy)/y;
+ //preserve aspect ratio
+ scale.sx.fy = (scale.sx.fy + scale.sy.fy) /2.0;
+ scale.sy.fy = scale.sx.fy;
+ }
+ ((Graph*)PasteObj)->GRect.Xmax -= ((Graph*)PasteObj)->GRect.Xmin;
+ ((Graph*)PasteObj)->GRect.Ymax -= ((Graph*)PasteObj)->GRect.Ymin;
+ ((Graph*)PasteObj)->GRect.Ymin = ((Graph*)PasteObj)->GRect.Xmin = 0.0;
+ PasteObj->Command(CMD_SCALE, &scale, 0L);
+ Command(CMD_DROP_GRAPH, (void*)PasteObj, 0L);
+ }
+ else DeleteGO(PasteObj);
+ PasteObj = 0L;
ToolMode = TM_STANDARD; CurrDisp->MouseCursor(MC_ARROW, false);
break;
}
@@ -1319,27 +1439,84 @@ Graph::ExecTool(MouseEvent *mev)
if(Plots[NumPlots]) i = NumPlots+1;
else i = NumPlots;
switch(mev->Action) {
- case MOUSE_LBUP:
- if(!(td = (TextDEF *)calloc(1, sizeof(TextDEF))))return false;
- x = CurrDisp->fix2un(mev->x-CurrDisp->VPorg.fx);
- y = CurrDisp->fiy2un(mev->y-CurrDisp->VPorg.fy);
- td->ColTxt = defs.Color(COL_TEXT); td->ColBg = defs.Color(COL_BG);
- td->RotBL = td->RotCHAR = 0.0f; td->fSize = defs.GetSize(SIZE_TEXT);
- td->Align = TXA_VTOP | TXA_HLEFT; td->Style = TXS_NORMAL;
- td->Mode = TXM_TRANSPARENT; td->Font = FONT_HELVETICA;
- td->text = 0L;
+ case MOUSE_LBDOWN:
CurrGO = 0L;
CurrDisp->MrkMode = MRK_NONE;
Command(CMD_REDRAW, 0L, CurrDisp);
- y -= td->fSize/2.0;
- Undo.SetGO(this, &Plots[i], new Label(this, data, x, y, td, 0L), 0L);
- if(Plots[i]){
- NumPlots = i+1;
- Plots[i]->DoPlot(CurrDisp); //init
- CurrDisp->ShowMark(CurrGO = Plots[i], MRK_GODRAW); //edit
- Plots[i]->moveable = 1;
+ color = 0x00cbcbcb;
+ pl.x = pc.x = mev->x; pl.y = pc.y = mev->y;
+ rcDim.left = rcDim.right = rcUpd.left = rcUpd.right = mev->x;
+ rcDim.top = rcDim.bottom = rcUpd.top = rcUpd.bottom = mev->y;
+ return true;
+ case MOUSE_MOVE:
+ if(mev->StateFlags &1) {
+ CurrDisp->MouseCursor(MC_CROSS, false);
+ if(rcUpd.left != rcUpd.right && rcUpd.top != rcUpd.bottom)
+ CurrDisp->UpdateRect(&rcUpd, false);
+ line[0].x = line[4].x = pl.x; line[0].y = line[4].y = pl.y;
+ if((ToolMode & 0x0f)==TM_ARROW) {
+ line[1].x = pc.x = mev->x; line[1].y = pc.y = mev->y;
+ CurrDisp->ShowLine(line, 2, color);
+ }
+ else {
+ line[1].x = pc.x = mev->x; line[1].y = pl.y;
+ line[2].x = mev->x; line[2].y = pc.y = mev->y;
+ line[3].x = pl.x; line[3].y = mev->y;
+ CurrDisp->ShowLine(line, 5, color);
+ }
+ memcpy(&rcUpd, &rcDim, sizeof(RECT));
+ UpdateMinMaxRect(&rcUpd, mev->x, mev->y);
+ IncrementMinMaxRect(&rcUpd, 2);
+ return true;
+ }
+ break;
+ case MOUSE_LBUP:
+ pc.x = mev->x; pc.y = mev->y;
+ if(((abs(pc.x-pl.x) >20 && abs(pc.y-pl.y) >20)) &&
+ (lfp = (lfPOINT*)malloc(2 * sizeof(lfPOINT)))){
+ lfp[0].fx = CurrDisp->fix2un(pl.x - CurrDisp->VPorg.fx);
+ lfp[0].fy = CurrDisp->fiy2un(pl.y - CurrDisp->VPorg.fy);
+ lfp[1].fx = CurrDisp->fix2un(pc.x - CurrDisp->VPorg.fx);
+ lfp[1].fy = CurrDisp->fiy2un(pc.y - CurrDisp->VPorg.fy);
+ if(Plots[NumPlots]) i = NumPlots+1;
+ else i = NumPlots;
+ new_go = new TextFrame(this, data, &lfp[0], &lfp[1], 0L);
+ if(new_go) Undo.SetGO(this, &Plots[i], new_go, 0L);
+ if(Plots[i]){
+ NumPlots = i+1;
+ Plots[i]->DoPlot(CurrDisp); //init
+ CurrDisp->ShowMark(CurrGO = Plots[i], MRK_GODRAW); //edit
+ Plots[i]->moveable = 1;
+ bModified = true;
+ }
+ free(lfp);
+ CurrDisp->CheckMenu(ToolMode & 0x0f, false);
+ CurrDisp->CheckMenu(ToolMode = TM_STANDARD, true);
+ CurrDisp->MouseCursor(MC_ARROW, false);
+ }
+ else {
+ CurrDisp->MouseCursor(MC_TEXT, false);
+ if(!(td = (TextDEF *)calloc(1, sizeof(TextDEF))))return false;
+ x = CurrDisp->fix2un(mev->x-CurrDisp->VPorg.fx);
+ y = CurrDisp->fiy2un(mev->y-CurrDisp->VPorg.fy);
+ td->ColTxt = defs.Color(COL_TEXT); td->ColBg = defs.Color(COL_BG);
+ td->RotBL = td->RotCHAR = 0.0f; td->fSize = DefSize(SIZE_TEXT);
+ td->Align = TXA_VTOP | TXA_HLEFT; td->Style = TXS_NORMAL;
+ td->Mode = TXM_TRANSPARENT; td->Font = FONT_HELVETICA;
+ td->text = 0L;
+ CurrGO = 0L;
+ CurrDisp->MrkMode = MRK_NONE;
+ Command(CMD_REDRAW, 0L, CurrDisp);
+ y -= td->fSize/2.0;
+ Undo.SetGO(this, &Plots[i], new Label(this, data, x, y, td, 0L), 0L);
+ if(Plots[i]){
+ NumPlots = i+1;
+ Plots[i]->DoPlot(CurrDisp); //init
+ CurrDisp->ShowMark(CurrGO = Plots[i], MRK_GODRAW); //edit
+ Plots[i]->moveable = 1;
+ }
+ free(td);
}
- free(td);
return true;
}
break;
@@ -1560,10 +1737,11 @@ ObjTree::DoPlot(anyOutput *o)
if(list[i]) {
curr_obj = list[i]; n = 0;
if(i) while(curr_obj && curr_obj != list[0]) {
- if(curr_obj != list[0]) n += sprintf(TmpTxt + n, " -");
+ if(curr_obj != list[0]) n += rlp_strcpy(TmpTxt+n, TMP_TXT_SIZE -n, " -");
if(curr_obj) curr_obj = curr_obj->parent;
}
- sprintf(TmpTxt + n, "%s%s", n ? " " : "", get_name(i));
+ if(n) TmpTxt[n++] = ' ';
+ n += rlp_strcpy(TmpTxt+n, TMP_TXT_SIZE -n, get_name(i));
if(list[i]->Id >= GO_PLOT && list[i]->Id < GO_GRAPH) {
TextDef.ColTxt = ((Plot*)list[i])->hidden ? 0x00000080L : 0x00008000L;
}
@@ -1615,7 +1793,7 @@ ObjTree::CreateBitmap(int *bw, int *bh, anyOutput *tmpl)
anyOutput *bmp = 0L;
int h;
- h = tmpl->un2iy(TextDef.fSize) * count;
+ h = (tmpl->un2iy(TextDef.fSize)+_SBINC) * (count+1);
if(h > *bh) *bh = h;
if(bmp = NewBitmapClass(*bw, *bh, tmpl->hres, tmpl->vres)) DoPlot(bmp);
return bmp;
--
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