home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / spreadsheets / a180_1 / !SSS / c / sheet < prev    next >
Text File  |  1991-07-30  |  9KB  |  386 lines

  1. /* Spreadsheet functions for SSS */
  2. /* Tue,30 Jul 1991 */
  3. /* Copyright C.T.Stretch 1991 */
  4.  
  5. #include "ssshdr.h"
  6.  
  7. #define YESNULL 0
  8.  
  9. entry **sheet;
  10. wimp_w swind;
  11. int dispwidth;
  12. int nrows,ncols,width[NCOLS];
  13. int sx0=0,sx1=0,sy0=0,sy1=0;
  14. int ex0,ex1,ey0,ey1;
  15. int bx0=0,by1=LINEHT,bw=INITWIDTH*CHWIDTH,bh=LINEHT;
  16. int ebx0=0,eby1=LINEHT,ebw=INITWIDTH*CHWIDTH,ebh=LINEHT;
  17. char buf[BUFLEN+16],fname[BUFLEN];
  18. int uy;
  19. BOOL autox,changed,fixed;
  20. int prwidth=80;
  21. BOOL repfirst=FALSE;
  22. BOOL mono=FALSE;
  23. char sep[4]=",";
  24. static int tempsize;
  25.  
  26. void sheet_change()
  27. { uy=0;changed=FALSE;
  28.   event_setmask(YESNULL);
  29. }
  30.  
  31. void sheet_box()
  32. { int x,bx,by,more;
  33.   int cx0=bx0,cw=bw,cy1=by1,ch=bh;
  34.   wimp_redrawstr r[1];
  35.   r->w=swind;
  36.   r->box.x0=0;r->box.y1=0;
  37.   r->box.x1=dispwidth;r->box.y0=-LINEHT*nrows;
  38.   bx0=0;bw=0;
  39.   for(x=0;x<NCOLS;x++)
  40.   { if(x>=sx0) break;
  41.     bx0+=width[x]*CHWIDTH;
  42.   }
  43.   for(;x<NCOLS;x++)
  44.   { bw+=width[x]*CHWIDTH;
  45.     if(x>=sx1) break;
  46.   }
  47.   by1=(sy1+1)*LINEHT;
  48.   bh=(sy1-sy0+1)*LINEHT;
  49.   wimpt_noerr(wimp_update_wind(r,&more));
  50.   bx=r->box.x0-r->scx;
  51.   by=r->box.y1-r->scy;
  52.   while(more)
  53.   { wimp_setcolour(15+16*3);
  54.     bbc_rectanglefill(bx+bx0,by-by1,bw,bh);
  55.     bbc_rectanglefill(bx+bx0+8,by-by1+8,bw-16,bh-16);
  56.     bbc_rectanglefill(bx+cx0,by-cy1,cw,ch);
  57.     bbc_rectanglefill(bx+cx0+8,by-cy1+8,cw-16,ch-16);
  58.     wimp_get_rectangle(r,&more);
  59.   }
  60. }
  61.  
  62. void sheet_ebox()
  63. { int x,bx,by,more;
  64.   int cx0=ebx0,cw=ebw,cy1=eby1,ch=ebh;
  65.   wimp_redrawstr r[1];
  66.   r->w=swind;
  67.   r->box.x0=0;r->box.y1=0;
  68.   r->box.x1=dispwidth;r->box.y0=-LINEHT*nrows;
  69.   ebx0=0;ebw=0;
  70.   for(x=0;x<NCOLS;x++)
  71.   { if(x>=ex0) break;
  72.     ebx0+=width[x]*CHWIDTH;
  73.   }
  74.   for(;x<NCOLS;x++)
  75.   { ebw+=width[x]*CHWIDTH;
  76.     if(x>=ex1) break;
  77.   }
  78.   eby1=(ey1+1)*LINEHT;
  79.   ebh=(ey1-ey0+1)*LINEHT;
  80.   wimpt_noerr(wimp_update_wind(r,&more));
  81.   bx=r->box.x0-r->scx;
  82.   by=r->box.y1-r->scy;
  83.   while(more)
  84.   { wimp_setcolour(12+16*3);
  85.     bbc_rectanglefill(bx+ebx0,by-eby1,ebw,ebh);
  86.     bbc_rectanglefill(bx+cx0,by-cy1,cw,ch);
  87.     wimp_get_rectangle(r,&more);
  88.   }
  89. }
  90.  
  91. void sheet_home()
  92. { ex0=ex1=0;
  93.   ey0=ey1=0;
  94.   sx0=sy0=0;
  95.   sx1=sy1=0;
  96.   sheet_box();
  97.   sheet_ebox();
  98. }
  99.  
  100. BOOL sheet_init()
  101. { int i;
  102.   nrows=INITNROWS;
  103.   ncols=INITNCOLS;
  104.   if(!flex_alloc((flex_ptr)&sheet,4*NCOLS*nrows)) return FALSE;
  105.   for(i=0;i<nrows*NCOLS;i++) sheet[i]=0;
  106.   for(i=0;i<NCOLS;i++) width[i]=INITWIDTH;
  107.   strcpy(fname,"Sheet");
  108.   return TRUE;
  109. }
  110.  
  111. void sheet_clear(int nr)
  112. { int i;
  113.   visdelay_begin();
  114.   for(i=0;i<nrows*NCOLS;i++) if(sheet[i]) flex_free((flex_ptr)(sheet+i));
  115.   nrows=nr;
  116.   if(!flex_extend((flex_ptr)&sheet,4*NCOLS*nrows)) werr(1,"No room");
  117.   for(i=0;i<nrows*NCOLS;i++) sheet[i]=0;
  118.   for(i=0;i<NCOLS;i++) width[i]=INITWIDTH;
  119.   visdelay_end();
  120. }
  121.  
  122. void sheet_getentry(int x,int y,int t)
  123. { entry **cb=sheet+x+y*NCOLS;
  124.   int len=strlen(buf)+13;
  125.   for(expr=buf;*expr==' ';expr++);
  126.   if(!(*expr))
  127.   { if(*cb) flex_free((flex_ptr)cb);
  128.     *cb=0;
  129.     return;
  130.   }
  131.   if(!((*cb)?flex_extend((flex_ptr)cb,len):flex_alloc((flex_ptr)cb,len)))
  132.      { werr(0,"Out of memory");return;}
  133.   *((int *)(*cb))=t;
  134.   strcpy(&((*cb)->c),buf);
  135.   if(t>=FINT)
  136.   { vx=x;vy=y;expr=buf;
  137.     eval();
  138.     (*cb)->v=value;
  139.     (*cb)->a=(errno!=0);
  140.     (*cb)->p=(perr!=0);
  141.     (*cb)->u=fixed;
  142.   }
  143. }
  144.  
  145. void sheet_update()
  146. { entry *cb;
  147.   int ux;
  148.   for(ux=0;ux<ncols;ux++)
  149.   { cb=sheet[ux+uy*NCOLS];
  150.     if(!cb) continue;
  151.     if(cb->u) continue;
  152.     if(cb->t<FINT) continue;
  153.     if(cb->p) continue;
  154.     vx=ux;vy=uy;expr=&(cb->c);
  155.     eval();
  156.     if(cb->v!=value)
  157.     { changed=TRUE;
  158.       cb->v=value;
  159.     }
  160.     if(cb->a!=(errno!=0))
  161.     { changed=TRUE;
  162.       cb->a=(errno!=0);
  163.     }
  164.   }
  165. }
  166.  
  167. static void clear(int x,int y)
  168. { entry **ce=sheet+x+y*NCOLS;
  169.   if(*ce) 
  170.   { flex_free((flex_ptr)ce);
  171.     *ce=0;
  172.   }
  173. }
  174.  
  175. static void copy(int xs,int ys,int xt,int yt)
  176. { entry **es=sheet+xs+ys*NCOLS,**et=sheet+xt+yt*NCOLS;
  177.   int len;
  178.   if(*es)
  179.   { len=flex_size((flex_ptr)es);
  180.     if(!((*et)?flex_extend((flex_ptr)et,len):flex_alloc((flex_ptr)et,len)))
  181.      { werr(0,"Out of memory");return;}
  182.      memcpy((char*)*et,(char*)*es,len);
  183.   }
  184.   else if(*et)
  185.   { flex_free((flex_ptr)et);
  186.     *et=0;
  187.   }
  188. }
  189.  
  190. void sheet_newrow(void)
  191. { int x,y;
  192.   if(!flex_extend((flex_ptr)&sheet,4*NCOLS*(nrows+1))) return;
  193.   for(x=0;x<NCOLS;x++) sheet[x+nrows*NCOLS]=0;
  194.   for(y=nrows;y>ey0;y--) for(x=0;x<ncols;x++) copy(x,y-1,x,y);
  195.   for(x=0;x<ncols;x++) clear(x,ey0);
  196.   nrows++;
  197.   if(autox) sheet_change();
  198. }
  199.  
  200. void sheet_newcol(void)
  201. { int x,y;
  202.   if(ncols>=NCOLS) return;
  203.   for(x=ncols;x>ex0;x--) for(y=0;y<nrows;y++) copy(x-1,y,x,y);
  204.   for(y=0;y<nrows;y++) clear(ex0,y);
  205.   ncols++;
  206.   if(autox) sheet_change();
  207. }
  208.  
  209. void sheet_delrow(void)
  210. { int x,y,d=ey1-ey0+1;
  211.   visdelay_begin();
  212.   for(x=0;x<ncols;x++)
  213.   { for(y=ey1+1;y<nrows;y++) copy(x,y,x,y-d);
  214.     for(y=nrows-d;y<nrows;y++) clear(x,y);
  215.   }
  216.   nrows-=d;if(nrows<1) nrows=1;
  217.   flex_extend((flex_ptr)&sheet,4*NCOLS*nrows);
  218.   if(autox) sheet_change();
  219.   visdelay_end();
  220. }
  221.  
  222. void sheet_delcol(void)
  223. { int x,y,d=ex1-ex0+1;
  224.   visdelay_begin();
  225.   for(y=0;y<nrows;y++)
  226.   { for(x=ex1+1;x<ncols;x++) copy(x,y,x-d,y);
  227.     for(x=ncols-d;x<ncols;x++) clear(x,y);
  228.   }
  229.   ncols-=d;
  230.   if(ncols<1) ncols=1;
  231.   if(autox) sheet_change();
  232.   visdelay_end();
  233. }
  234.  
  235.  
  236. void sheet_bcopy(void)
  237. { int x,y,tx,ty;
  238.   if((ex0==ex1)&&(ey0==ey1))
  239.   { for(y=sy0;y<=sy1;y++) for(x=sx0;x<=sx1;x++)
  240.     if((x+ex0-sx0<ncols)&&(y+ey0-sy0<nrows)) copy(x,y,x+ex0-sx0,y+ey0-sy0);
  241.   }
  242.   else
  243.   { tx=ex0;ty=ey0;
  244.     for(y=sy0;y<=sy1;y++) for(x=sx0;x<=sx1;x++)
  245.     { if(tx>ex1) {tx=ex0;ty++;}
  246.       if(ty>ey1) return;
  247.       copy(x,y,tx,ty);
  248.       tx++;
  249.     }
  250.   }
  251.   if(autox) sheet_change();
  252. }
  253.  
  254. static int numcmp(const void *s,const void *t)
  255. { double a,b;
  256.   a=sheet[(*(int*)s)*NCOLS+sx0]->v;
  257.   b=sheet[(*(int*)t)*NCOLS+sx0]->v;
  258.   if(a<b) return -1;
  259.   return (a>b)?1:0;
  260. }
  261.  
  262. static int textcmp(const void *s,const void *t)
  263. { char *a,*b;
  264.   a=&(sheet[(*(int*)s)*NCOLS+sx0]->c);
  265.   b=&(sheet[(*(int*)t)*NCOLS+sx0]->c);
  266.   return strcmp(a,b);
  267. }
  268.  
  269. static int numcmpr(const void *s,const void *t)
  270. { double a,b;
  271.   a=sheet[(*(int*)s)+sy0*NCOLS]->v;
  272.   b=sheet[(*(int*)t)+sy0*NCOLS]->v;
  273.   if(a<b) return -1;
  274.   return (a>b)?1:0;
  275. }
  276.  
  277. static int textcmpr(const void *s,const void *t)
  278. { char *a,*b;
  279.   a=&(sheet[(*(int*)s)+sy0*NCOLS]->c);
  280.   b=&(sheet[(*(int*)t)+sy0*NCOLS]->c);
  281.   return strcmp(a,b);
  282. }
  283.  
  284. static void temps(int x,int y)
  285. { entry **e=sheet+x+y*NCOLS;
  286.   if(*e)
  287.   { tempsize=flex_size((flex_ptr)e);
  288.     memcpy(buf,(char*)(*e),tempsize);
  289.   }
  290.   else tempsize=0;
  291. }
  292.  
  293. static void tempr(int x,int y)
  294. { entry **e=sheet+x+y*NCOLS;
  295.   if(tempsize)
  296.   { if(flex_extend((flex_ptr)e,tempsize)) memcpy((char*)(*e),buf,tempsize);
  297.   }
  298.   else if(e) flex_free((flex_ptr)e);
  299. }
  300.  
  301. static void sortcol()
  302. { int x,y,z,n=sy1-sy0+1;
  303.   int *p,*q;
  304.   entry *e=sheet[sx0+sy0*NCOLS];
  305.   if(!e) return;
  306.   if((sy0!=ey0)||(sy1!=ey1))return;
  307.   if(!flex_alloc((flex_ptr)&p,4*n)) return;
  308.   if(!flex_alloc((flex_ptr)&q,4*n)) return;
  309.   for(y=0;y<n;y++) p[y]=sy0+y;
  310.   if(e->t<FINT)
  311.   { for(y=sy0;y<=sy1;y++)
  312.     { e=sheet[sx0+y*NCOLS];
  313.       if(!e) goto done;
  314.       if(e->t>=FINT) goto done;
  315.     }
  316.     qsort((void*)p,n,4,textcmp);
  317.   }
  318.   else
  319.   { for(y=sy0;y<=sy1;y++)
  320.     { e=sheet[sx0+y*NCOLS];
  321.       if(!e) goto done;
  322.       if((e->t<FINT)||(e->a)||(e->p)) goto done;
  323.     }
  324.     qsort((void*)p,n,4,numcmp);
  325.   }
  326.   for(x=ex0;x<=ex1;x++)
  327.   { for(y=0;y<n;y++) q[y]=TRUE;
  328.     for(y=0;y<n;y++) if((q[y])&&(p[y]!=y+sy0))
  329.     { temps(x,y+sy0);
  330.       for(z=y;p[z]!=y+sy0;z=p[z]-sy0)
  331.       { copy(x,p[z],x,z+sy0);
  332.         q[p[z]-sy0]=FALSE;
  333.       }
  334.       tempr(x,z+sy0);
  335.     }
  336.   }
  337.   done:flex_free((flex_ptr)&p);
  338.   flex_free((flex_ptr)&q);
  339. }
  340.  
  341. static void sortrow()
  342. { int x,y,z,n=sx1-sx0+1;
  343.   int *p,*q;
  344.   entry *e=sheet[sx0+sy0*NCOLS];
  345.   if(!e) return;
  346.   if((sx0!=ex0)||(sx1!=ex1))return;
  347.   if(!flex_alloc((flex_ptr)&p,4*n)) return;
  348.   if(!flex_alloc((flex_ptr)&q,4*n)) return;
  349.   for(x=0;x<n;x++) p[x]=sx0+x;
  350.   if(e->t<FINT)
  351.   { for(x=sx0;x<=sx1;x++)
  352.     { e=sheet[x+sy0*NCOLS];
  353.       if(!e) goto done;
  354.       if(e->t>=FINT) goto done;
  355.     }
  356.     qsort((void*)p,n,4,textcmpr);
  357.   }
  358.   else
  359.   { for(x=sx0;x<=sx1;x++)
  360.     { e=sheet[x+sy0*NCOLS];
  361.       if(!e) goto done;
  362.       if((e->t<FINT)||(e->a)||(e->p)) goto done;
  363.     }
  364.     qsort((void*)p,n,4,numcmpr);
  365.   }
  366.   for(y=ey0;y<=ey1;y++)
  367.   { for(x=0;x<n;x++) q[x]=TRUE;
  368.     for(x=0;x<n;x++) if((q[x])&&(p[x]!=x+sx0))
  369.     { temps(x+sx0,y);
  370.       for(z=x;p[z]!=x+sx0;z=p[z]-sx0)
  371.       { copy(p[z],y,z+sx0,y);
  372.         q[p[z]-sx0]=FALSE;
  373.       }
  374.       tempr(z+sx0,y);
  375.     }
  376.   }
  377.   done:flex_free((flex_ptr)&p);
  378.   flex_free((flex_ptr)&q);
  379. }
  380.  
  381. void sheet_sort(void)
  382. { if(sx0==sx1) sortcol();
  383.   else if(sy0==sy1) sortrow();
  384.   if(autox) sheet_change();
  385. }
  386.