home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 5
/
DATAFILE_PDCD5.iso
/
utilities
/
s1
/
sss
/
!SSS
/
c
/
sheet
< prev
next >
Wrap
Text File
|
1991-07-30
|
9KB
|
386 lines
/* Spreadsheet functions for SSS */
/* Tue,30 Jul 1991 */
/* Copyright C.T.Stretch 1991 */
#include "ssshdr.h"
#define YESNULL 0
entry **sheet;
wimp_w swind;
int dispwidth;
int nrows,ncols,width[NCOLS];
int sx0=0,sx1=0,sy0=0,sy1=0;
int ex0,ex1,ey0,ey1;
int bx0=0,by1=LINEHT,bw=INITWIDTH*CHWIDTH,bh=LINEHT;
int ebx0=0,eby1=LINEHT,ebw=INITWIDTH*CHWIDTH,ebh=LINEHT;
char buf[BUFLEN+16],fname[BUFLEN];
int uy;
BOOL autox,changed,fixed;
int prwidth=80;
BOOL repfirst=FALSE;
BOOL mono=FALSE;
char sep[4]=",";
static int tempsize;
void sheet_change()
{ uy=0;changed=FALSE;
event_setmask(YESNULL);
}
void sheet_box()
{ int x,bx,by,more;
int cx0=bx0,cw=bw,cy1=by1,ch=bh;
wimp_redrawstr r[1];
r->w=swind;
r->box.x0=0;r->box.y1=0;
r->box.x1=dispwidth;r->box.y0=-LINEHT*nrows;
bx0=0;bw=0;
for(x=0;x<NCOLS;x++)
{ if(x>=sx0) break;
bx0+=width[x]*CHWIDTH;
}
for(;x<NCOLS;x++)
{ bw+=width[x]*CHWIDTH;
if(x>=sx1) break;
}
by1=(sy1+1)*LINEHT;
bh=(sy1-sy0+1)*LINEHT;
wimpt_noerr(wimp_update_wind(r,&more));
bx=r->box.x0-r->scx;
by=r->box.y1-r->scy;
while(more)
{ wimp_setcolour(15+16*3);
bbc_rectanglefill(bx+bx0,by-by1,bw,bh);
bbc_rectanglefill(bx+bx0+8,by-by1+8,bw-16,bh-16);
bbc_rectanglefill(bx+cx0,by-cy1,cw,ch);
bbc_rectanglefill(bx+cx0+8,by-cy1+8,cw-16,ch-16);
wimp_get_rectangle(r,&more);
}
}
void sheet_ebox()
{ int x,bx,by,more;
int cx0=ebx0,cw=ebw,cy1=eby1,ch=ebh;
wimp_redrawstr r[1];
r->w=swind;
r->box.x0=0;r->box.y1=0;
r->box.x1=dispwidth;r->box.y0=-LINEHT*nrows;
ebx0=0;ebw=0;
for(x=0;x<NCOLS;x++)
{ if(x>=ex0) break;
ebx0+=width[x]*CHWIDTH;
}
for(;x<NCOLS;x++)
{ ebw+=width[x]*CHWIDTH;
if(x>=ex1) break;
}
eby1=(ey1+1)*LINEHT;
ebh=(ey1-ey0+1)*LINEHT;
wimpt_noerr(wimp_update_wind(r,&more));
bx=r->box.x0-r->scx;
by=r->box.y1-r->scy;
while(more)
{ wimp_setcolour(12+16*3);
bbc_rectanglefill(bx+ebx0,by-eby1,ebw,ebh);
bbc_rectanglefill(bx+cx0,by-cy1,cw,ch);
wimp_get_rectangle(r,&more);
}
}
void sheet_home()
{ ex0=ex1=0;
ey0=ey1=0;
sx0=sy0=0;
sx1=sy1=0;
sheet_box();
sheet_ebox();
}
BOOL sheet_init()
{ int i;
nrows=INITNROWS;
ncols=INITNCOLS;
if(!flex_alloc((flex_ptr)&sheet,4*NCOLS*nrows)) return FALSE;
for(i=0;i<nrows*NCOLS;i++) sheet[i]=0;
for(i=0;i<NCOLS;i++) width[i]=INITWIDTH;
strcpy(fname,"Sheet");
return TRUE;
}
void sheet_clear(int nr)
{ int i;
visdelay_begin();
for(i=0;i<nrows*NCOLS;i++) if(sheet[i]) flex_free((flex_ptr)(sheet+i));
nrows=nr;
if(!flex_extend((flex_ptr)&sheet,4*NCOLS*nrows)) werr(1,"No room");
for(i=0;i<nrows*NCOLS;i++) sheet[i]=0;
for(i=0;i<NCOLS;i++) width[i]=INITWIDTH;
visdelay_end();
}
void sheet_getentry(int x,int y,int t)
{ entry **cb=sheet+x+y*NCOLS;
int len=strlen(buf)+13;
for(expr=buf;*expr==' ';expr++);
if(!(*expr))
{ if(*cb) flex_free((flex_ptr)cb);
*cb=0;
return;
}
if(!((*cb)?flex_extend((flex_ptr)cb,len):flex_alloc((flex_ptr)cb,len)))
{ werr(0,"Out of memory");return;}
*((int *)(*cb))=t;
strcpy(&((*cb)->c),buf);
if(t>=FINT)
{ vx=x;vy=y;expr=buf;
eval();
(*cb)->v=value;
(*cb)->a=(errno!=0);
(*cb)->p=(perr!=0);
(*cb)->u=fixed;
}
}
void sheet_update()
{ entry *cb;
int ux;
for(ux=0;ux<ncols;ux++)
{ cb=sheet[ux+uy*NCOLS];
if(!cb) continue;
if(cb->u) continue;
if(cb->t<FINT) continue;
if(cb->p) continue;
vx=ux;vy=uy;expr=&(cb->c);
eval();
if(cb->v!=value)
{ changed=TRUE;
cb->v=value;
}
if(cb->a!=(errno!=0))
{ changed=TRUE;
cb->a=(errno!=0);
}
}
}
static void clear(int x,int y)
{ entry **ce=sheet+x+y*NCOLS;
if(*ce)
{ flex_free((flex_ptr)ce);
*ce=0;
}
}
static void copy(int xs,int ys,int xt,int yt)
{ entry **es=sheet+xs+ys*NCOLS,**et=sheet+xt+yt*NCOLS;
int len;
if(*es)
{ len=flex_size((flex_ptr)es);
if(!((*et)?flex_extend((flex_ptr)et,len):flex_alloc((flex_ptr)et,len)))
{ werr(0,"Out of memory");return;}
memcpy((char*)*et,(char*)*es,len);
}
else if(*et)
{ flex_free((flex_ptr)et);
*et=0;
}
}
void sheet_newrow(void)
{ int x,y;
if(!flex_extend((flex_ptr)&sheet,4*NCOLS*(nrows+1))) return;
for(x=0;x<NCOLS;x++) sheet[x+nrows*NCOLS]=0;
for(y=nrows;y>ey0;y--) for(x=0;x<ncols;x++) copy(x,y-1,x,y);
for(x=0;x<ncols;x++) clear(x,ey0);
nrows++;
if(autox) sheet_change();
}
void sheet_newcol(void)
{ int x,y;
if(ncols>=NCOLS) return;
for(x=ncols;x>ex0;x--) for(y=0;y<nrows;y++) copy(x-1,y,x,y);
for(y=0;y<nrows;y++) clear(ex0,y);
ncols++;
if(autox) sheet_change();
}
void sheet_delrow(void)
{ int x,y,d=ey1-ey0+1;
visdelay_begin();
for(x=0;x<ncols;x++)
{ for(y=ey1+1;y<nrows;y++) copy(x,y,x,y-d);
for(y=nrows-d;y<nrows;y++) clear(x,y);
}
nrows-=d;if(nrows<1) nrows=1;
flex_extend((flex_ptr)&sheet,4*NCOLS*nrows);
if(autox) sheet_change();
visdelay_end();
}
void sheet_delcol(void)
{ int x,y,d=ex1-ex0+1;
visdelay_begin();
for(y=0;y<nrows;y++)
{ for(x=ex1+1;x<ncols;x++) copy(x,y,x-d,y);
for(x=ncols-d;x<ncols;x++) clear(x,y);
}
ncols-=d;
if(ncols<1) ncols=1;
if(autox) sheet_change();
visdelay_end();
}
void sheet_bcopy(void)
{ int x,y,tx,ty;
if((ex0==ex1)&&(ey0==ey1))
{ for(y=sy0;y<=sy1;y++) for(x=sx0;x<=sx1;x++)
if((x+ex0-sx0<ncols)&&(y+ey0-sy0<nrows)) copy(x,y,x+ex0-sx0,y+ey0-sy0);
}
else
{ tx=ex0;ty=ey0;
for(y=sy0;y<=sy1;y++) for(x=sx0;x<=sx1;x++)
{ if(tx>ex1) {tx=ex0;ty++;}
if(ty>ey1) return;
copy(x,y,tx,ty);
tx++;
}
}
if(autox) sheet_change();
}
static int numcmp(const void *s,const void *t)
{ double a,b;
a=sheet[(*(int*)s)*NCOLS+sx0]->v;
b=sheet[(*(int*)t)*NCOLS+sx0]->v;
if(a<b) return -1;
return (a>b)?1:0;
}
static int textcmp(const void *s,const void *t)
{ char *a,*b;
a=&(sheet[(*(int*)s)*NCOLS+sx0]->c);
b=&(sheet[(*(int*)t)*NCOLS+sx0]->c);
return strcmp(a,b);
}
static int numcmpr(const void *s,const void *t)
{ double a,b;
a=sheet[(*(int*)s)+sy0*NCOLS]->v;
b=sheet[(*(int*)t)+sy0*NCOLS]->v;
if(a<b) return -1;
return (a>b)?1:0;
}
static int textcmpr(const void *s,const void *t)
{ char *a,*b;
a=&(sheet[(*(int*)s)+sy0*NCOLS]->c);
b=&(sheet[(*(int*)t)+sy0*NCOLS]->c);
return strcmp(a,b);
}
static void temps(int x,int y)
{ entry **e=sheet+x+y*NCOLS;
if(*e)
{ tempsize=flex_size((flex_ptr)e);
memcpy(buf,(char*)(*e),tempsize);
}
else tempsize=0;
}
static void tempr(int x,int y)
{ entry **e=sheet+x+y*NCOLS;
if(tempsize)
{ if(flex_extend((flex_ptr)e,tempsize)) memcpy((char*)(*e),buf,tempsize);
}
else if(e) flex_free((flex_ptr)e);
}
static void sortcol()
{ int x,y,z,n=sy1-sy0+1;
int *p,*q;
entry *e=sheet[sx0+sy0*NCOLS];
if(!e) return;
if((sy0!=ey0)||(sy1!=ey1))return;
if(!flex_alloc((flex_ptr)&p,4*n)) return;
if(!flex_alloc((flex_ptr)&q,4*n)) return;
for(y=0;y<n;y++) p[y]=sy0+y;
if(e->t<FINT)
{ for(y=sy0;y<=sy1;y++)
{ e=sheet[sx0+y*NCOLS];
if(!e) goto done;
if(e->t>=FINT) goto done;
}
qsort((void*)p,n,4,textcmp);
}
else
{ for(y=sy0;y<=sy1;y++)
{ e=sheet[sx0+y*NCOLS];
if(!e) goto done;
if((e->t<FINT)||(e->a)||(e->p)) goto done;
}
qsort((void*)p,n,4,numcmp);
}
for(x=ex0;x<=ex1;x++)
{ for(y=0;y<n;y++) q[y]=TRUE;
for(y=0;y<n;y++) if((q[y])&&(p[y]!=y+sy0))
{ temps(x,y+sy0);
for(z=y;p[z]!=y+sy0;z=p[z]-sy0)
{ copy(x,p[z],x,z+sy0);
q[p[z]-sy0]=FALSE;
}
tempr(x,z+sy0);
}
}
done:flex_free((flex_ptr)&p);
flex_free((flex_ptr)&q);
}
static void sortrow()
{ int x,y,z,n=sx1-sx0+1;
int *p,*q;
entry *e=sheet[sx0+sy0*NCOLS];
if(!e) return;
if((sx0!=ex0)||(sx1!=ex1))return;
if(!flex_alloc((flex_ptr)&p,4*n)) return;
if(!flex_alloc((flex_ptr)&q,4*n)) return;
for(x=0;x<n;x++) p[x]=sx0+x;
if(e->t<FINT)
{ for(x=sx0;x<=sx1;x++)
{ e=sheet[x+sy0*NCOLS];
if(!e) goto done;
if(e->t>=FINT) goto done;
}
qsort((void*)p,n,4,textcmpr);
}
else
{ for(x=sx0;x<=sx1;x++)
{ e=sheet[x+sy0*NCOLS];
if(!e) goto done;
if((e->t<FINT)||(e->a)||(e->p)) goto done;
}
qsort((void*)p,n,4,numcmpr);
}
for(y=ey0;y<=ey1;y++)