|
|
1.1 root 1: /*
2: * screen.c 1.4
3: *
4: * Screen Handling Functions for Spreadsheet Program `vis'
5: *
6: * A. F. Gettier
7: * Bell Laboratories
8: * Update made 11/1/82 11:13:42
9: * Retrieved 11/15/82 13:22:44
10: */
11: #include <math.h>
12: #include <stdio.h>
13: #include <signal.h>
14: #include "curses.h"
15: #include "vis.h"
16:
17: extern int LINES, COLS;
18: extern struct qheader Fixup;
19:
20: int Width=DEFWIDTH;
21: int Scale=DEFSCALE;
22:
23: extern struct colhdr Col;
24: extern struct rowhdr Row;
25:
26: /*
27: * Initialize the screen
28: */
29: void
30: scrinit()
31: {
32: extern quit();
33:
34: initscr();
35:
36: savetty();
37: signal(SIGINT, quit);
38:
39: noecho();
40: crmode();
41: clear();
42:
43: /*
44: * Set up the Heading
45: */
46:
47: setheading();
48:
49: /*
50: * Print out the heading
51: */
52:
53: prheading();
54: }
55: /*
56: * Set the headings to the initial setting
57: */
58: setheading()
59: {
60: int i;
61: int size;
62: struct collabel **c1;
63: struct rowlabel **r1;
64:
65: /*
66: * Get the number of Rows
67: */
68: size = LINES - 5;
69: rowexpand( size );
70: /*
71: * Fix the print Positions Stuff
72: */
73: r1 = Row.table;
74: for ( i=0; i<size; i++ ) {
75: r1[i]->position = i+3;
76: }
77: for ( i=size; i<Row.size; i++ ) {
78: r1[i]->position = 0;
79: }
80: /*
81: * Get the number of Columns
82: */
83: size = ( COLS - 6 ) / (Width + 1);
84: colexpand( size );
85: /*
86: * Fix the print Positions Stuff
87: */
88: c1 = Col.table;
89: for ( i=0; i<size; i++ ) {
90: c1[i]->position = i * (Width + 1) + 6;
91: c1[i]->cell = i;
92: }
93: for ( i=size; i<Col.size; i++ ) {
94: c1[i]->position = 0;
95: c1[i]->cell = i;
96: }
97: }
98: /*
99: * Print the heading
100: */
101: void
102: prheading()
103: {
104: int i, j, k, l;
105: struct collabel **c1;
106: struct rowlabel **r1;
107: /*
108: * Print the Frame
109: */
110: erase();
111: move( 2, 4 );
112: printw( "------------------------------------" );
113: printw( "----------------------------------------" );
114: for ( i=3; i<(LINES-2); i++ ) {
115: move( i, 4 );
116: printw( "|" );
117: }
118: /*
119: * Print the Labels
120: */
121: r1 = Row.table;
122: c1 = Col.table;
123: /*
124: * First the numbers on the Vertical
125: */
126: for ( i=0; i<Row.size; i++ ) {
127: if ( r1[i]->position < 0 ) continue;
128: if ( r1[i]->position == 0 ) break;
129: move( r1[i]->position, 1 );
130: printw( "%d", i+1 );
131: }
132: /*
133: * and the letters on the Horizontal
134: */
135: l = i = 0;
136: while ( i < Col.size && c1[i]->position+c1[i]->width+1 < COLS ) {
137: if ( c1[i]->position <= 0 ) {
138: i++;
139: if ( l == 0 ) continue;
140: else break;
141: }
142: l = 0;
143: move( 1, c1[i]->position + c1[i]->width/2 );
144: j = i++;
145: k = j / 26;
146: if ( k > 0 ) k = k + 'A' - 1;
147: else k = ' ';
148: j = j % 26 + 'A';
149: printw( "%c%c", k, j );
150: }
151: }
152:
153: /*
154: * Print the Node
155: */
156: prnode( node )
157: struct node *node;
158: {
159: int i, j;
160: struct collabel **c1;
161: struct rowlabel **r1;
162:
163: /*
164: * Get the print position
165: *
166: *
167: * get the correct row
168: */
169: r1 = Row.table;
170: i = node->row;
171: if ( i >= Row.size || r1[i]->position <= 0 ) return;
172: /*
173: * get the correct Column
174: */
175: c1 = Col.table;
176: j = node->col;
177: if ( j >= Col.size || c1[j]->position <= 0 ) return;
178: /*
179: * Print the node
180: */
181: move( r1[i]->position, c1[j]->position );
182: noutput( node, c1[j]->width, c1[j]->scale );
183: }
184: /*
185: * output a single element
186: * assume the cursor is positioned
187: */
188: noutput( node, wid, scale )
189: struct node *node;
190: int wid, scale;
191: {
192: int i;
193: char tbuf[80], *x;
194:
195: switch( node->type ) {
196: case UNDEF:
197: for ( i=0; i<wid; i++ ) tbuf[i] = ' ';
198: i = wid/2;
199: tbuf[i++] = '*';
200: tbuf[i] = '*';
201: tbuf[wid] = '\0';
202: break;
203: case UNRES:
204: for ( i=0; i<wid; i++ ) tbuf[i] = ' ';
205: i = wid/2;
206: tbuf[i++] = '?';
207: tbuf[i] = '?';
208: tbuf[wid] = '\0';
209: break;
210: case NUM:
211: if ( (x=dtoa( node->value, wid, scale )) == 0 ) {
212: for ( i=0; i<wid; i++ ) tbuf[i] = '#';
213: tbuf[wid] = '\0';
214: }
215: else (void)strcpy( tbuf, x );
216: break;
217: case STRING:
218: (void)strncpy( tbuf, node->svalue, wid );
219: for ( i=strlen( tbuf ); i<wid; i++ ) tbuf[i] = ' ';
220: tbuf[wid] = '\0';
221: break;
222: }
223: printw( "%s", tbuf );
224: }
225:
226: /* dtoa.c
227: * S. Coffin, BTL Dept. 43372, FJ 1A110, x5151
228: * Apr. 15, 1982
229: *
230: * Converts a double precision float to a right-justified
231: * printable character string according to the parameters
232: * size = total field width desired
233: * scale = number of digits to the right of the decimal
234: *
235: * returns a pointer to the string. If the size given
236: * is too small for the number, the routine attempts
237: * to use "e" notation. If it still will not fit, NULL
238: * is returned.
239: */
240:
241: char *
242: dtoa( input, size, scale )
243: double input;
244: int size, scale;
245: {
246: static char output[80];
247: char pattern[80];
248: int j=0, i;
249:
250: output[0] = '\0';
251:
252: /* get a sample string */
253: (void)sprintf( pattern, "%-39.39lf", input );
254:
255: /* if the number is near zero, then try "e" notation */
256: j=0;
257: while( (pattern[j]=='0' || pattern[j]=='.') && pattern[j++]!='\0' );
258:
259: if( j < size && j > size/2 ) pattern[size] = '\0';
260: else if ( j>size/2 && size>=9 )
261: (void)sprintf( pattern, "%9.2e", input );
262: else {
263: /* not too near zero, so find the decimal point */
264: j=0;
265: while( pattern[j++] != '.' );
266:
267: /* truncate it to the scale */
268: if( scale == 0 ) pattern[j-1] = '\0';
269: else pattern[j+scale] = '\0';
270:
271: /* if its still too big, try "e" notation */
272: if( (j-1 > size) || (j+scale > size) )
273: (void)sprintf( pattern, "%9.2e",input);
274: }
275:
276: /* is it still too big? */
277: i=strlen(pattern);
278: if( i <= size ) {
279: /* ok, so right-justify the result, and return */
280: for( j = 0; j < (size-i); j++ ) output[j]=' ';
281: output[j] = '\0';
282: strcat( output, pattern );
283: return( output );
284: }
285: else return( NULL );
286: }
287:
288: /*
289: * Copy out the Standard screen to a file
290: */
291: copyfile( fp )
292: FILE *fp;
293: {
294: int i, j, k;
295: char bf[150];
296: char *tbf;
297: (void)fprintf( fp, "\n\n" );
298: for ( i=1; i<LINES-2; i++ ) {
299:
300: tbf = bf;
301:
302: j = 0;
303: k = COLS - 2;
304: while ( j < COLS ) {
305: bf[j] = (char)(stdscr->_y[i][j]);
306: if ( bf[j] > ' ' ) k = j;
307: j++;
308: }
309: bf[k+1] = '\0';
310: (void)fprintf( fp, "%s\n", bf );
311: }
312: (void)fprintf( fp, "\n\n" );
313: }
314: /*
315: * reset the global scale
316: */
317: setscale( n )
318: int n;
319: {
320: int i;
321: struct collabel **c1;
322: Scale = n;
323: /*
324: * Reset the individual headings
325: */
326: c1 = Col.table;
327: for ( i=0; i<Col.size; i++ ) {
328: c1[i]->scale = Scale;
329: }
330: /*
331: * Repaint the screen
332: */
333: prheading();
334: repaint();
335: }
336: /*
337: * reset the global width
338: */
339: setwidth( n )
340: int n;
341: {
342: int i;
343: struct collabel **c1;
344:
345: Width = n;
346: /*
347: * Reset the individual headings
348: */
349: c1 = Col.table;
350: for ( i=0; i<Col.size; i++ ) {
351: c1[i]->width = Width;
352: }
353: fixcolheading();
354: /*
355: * Repaint the screen
356: */
357: prheading();
358: repaint();
359: }
360: /*
361: * reset an individual scale
362: */
363: isetscale( col, n )
364: int col, n;
365: {
366: struct collabel **c1;
367: /*
368: * Make sure it's valid
369: */
370: if ( col > Col.size ) colexpand( col );
371: if ( col < 0 ) {
372: char bfr[64];
373: lexinit();
374: unput( '\n' );
375: (void)sprintf( bfr, "Attempt to change scale of column %d",
376: col );
377: yyerror( bfr );
378: return;
379: }
380: /*
381: * Reset the individual headings
382: */
383: c1 = Col.table;
384: c1[col]->scale = n;
385: /*
386: * Repaint the screen
387: */
388: prheading();
389: repaint();
390: }
391: /*
392: * reset an individual width
393: */
394: isetwidth( col, n )
395: int col, n;
396: {
397: struct collabel **c1;
398:
399: /*
400: * Make sure it's valid
401: */
402: if ( col > Col.size ) colexpand( col );
403: if ( col < 0 ) {
404: char bfr[64];
405: lexinit();
406: unput( '\n' );
407: (void)sprintf( bfr, "Attempt to change scale of column %d",
408: col );
409: yyerror( bfr );
410: return;
411: }
412: /*
413: * Reset the individual headings
414: */
415: c1 = Col.table;
416: c1[col]->width = n;
417: fixcolheading();
418: /*
419: * Repaint the screen
420: */
421: prheading();
422: repaint();
423: }
424: /*
425: * Repaint the Screen
426: */
427: repaint()
428: {
429: int i, j;
430: struct node *n;
431: struct collabel **c1;
432: struct rowlabel **r1;
433:
434: r1 = Row.table;
435: c1 = Col.table;
436: for ( i=0; i<Row.size; i++ ) {
437: if( r1[i]->position == 0 ) break;
438: if( r1[i]->position < 0 ) continue;
439: n = r1[i]->next;
440: while ( n != 0 ) {
441: j = n->col;
442: if( c1[j]->position == 0 ) break;
443: if( c1[j]->position > 0 ) prnode( n );
444: n = n->next;
445: }
446: }
447: }
448: /*
449: * Set the new Row headings
450: */
451: fixrowheading()
452: {
453: int i, start;
454: int size;
455: struct rowlabel **r1;
456:
457: size = LINES - 5;
458: /*
459: * Get the Starting position
460: */
461: r1 = Row.table;
462: for ( start=0; start<Row.size; start++ )
463: if ( r1[start]->position >= 0 ) break;
464: /*
465: * Get more rows if needed
466: */
467: rowexpand( start + size + 1 );
468: r1 = Row.table;
469: /*
470: * Fix the print Positions Stuff
471: */
472: for ( i=0; i<size; i++ ) {
473: r1[i+start]->position = i+3;
474: }
475: for ( i=size+start; i<Row.size; i++ ) {
476: r1[i]->position = 0;
477: }
478: }
479: /*
480: * Set the new Col headings
481: */
482: fixcolheading()
483: {
484: int i, j, cpos, start;
485: struct collabel **c1;
486: /*
487: * Find the First cell to print
488: */
489: c1 = Col.table;
490: for ( start=0; start<Col.size; start++ ) {
491: if ( c1[start]->position >= 0 ) break;
492: }
493: /*
494: * Fix the print Positions Stuff
495: */
496: cpos = 6;
497: for ( i=start; i<Col.size; i++ ) {
498: c1[i]->position = cpos;
499: cpos += c1[i]->width + 1;
500: if ( cpos > COLS ) {
501: c1[i]->position = 0;
502: }
503: }
504: i = (COLS - cpos ) / ( Width + 1 );
505: j = Col.size;
506: colexpand( i+j+1 );
507: c1 = Col.table;
508: for ( i=j; i<Col.size; i++ ) {
509: c1[i]->position = cpos;
510: cpos += c1[i]->width + 1;
511: if ( cpos > COLS ) {
512: c1[i]->position = 0;
513: }
514: }
515: }
516: /*
517: * zero out all the screen stuff
518: */
519: zeroscreen()
520: {
521: initscr();
522: erase();
523: Row.size = 0;
524: Col.size = 0;
525: Width = DEFWIDTH;
526: Scale = DEFSCALE;
527: /*
528: * Set up the Heading
529: */
530: setheading();
531: /*
532: * Print out the heading
533: */
534: prheading();
535: }
536:
537: /*
538: * SCROLLING
539: */
540: scrup( n )
541: int n;
542: {
543: int i, j, start;
544: struct rowlabel **r1;
545:
546: r1 = Row.table;
547: /*
548: * Get the starting position
549: */
550: for ( start=0; start<Row.size; start++ ) {
551: if ( r1[start]->position >= 0 ) break;
552: }
553: /*
554: * Fix the offending rows
555: */
556: i = start - n;
557: if ( i < 0 ) i = 0;
558: for ( j=i; j<Row.size; j++ ) {
559: r1[j]->position = 0;
560: }
561: /*
562: * Redraw the screen
563: */
564: fixrowheading();
565: prheading();
566: repaint();
567: }
568: scrdown( n )
569: int n;
570: {
571: int i, start;
572: struct rowlabel **r1;
573:
574: r1 = Row.table;
575: /*
576: * Get the starting position
577: */
578: for ( start=0; start<Row.size; start++ ) {
579: if ( r1[start]->position >= 0 ) break;
580: }
581: /*
582: * Increase number of rows, if needed
583: */
584: rowexpand( start + n + 1 );
585: r1 = Row.table;
586: /*
587: * Get rid of the offending rows
588: */
589: move( 3, 0 );
590: for ( i=0; i<n; i++ ) {
591:
592: r1[start+i]->position = -1;
593:
594: }
595: /*
596: * Redraw the screen
597: */
598: fixrowheading();
599: prheading();
600: repaint();
601: }
602: scrleft( n )
603: int n;
604: {
605: int i, j, start;
606: struct collabel **c1;
607:
608: c1 = Col.table;
609: /*
610: * Get the starting position
611: */
612: for ( start=0; start<Col.size; start++ ) {
613: if ( c1[start]->position >= 0 ) break;
614: }
615: /*
616: * Fix the offending rows
617: */
618: i = start - n;
619: if ( i < 0 ) i = 0;
620: for ( j=i; j<Col.size; j++ ) {
621: c1[j]->position = 0;
622: }
623: /*
624: * Redraw the screen
625: */
626: fixcolheading();
627: prheading();
628: repaint();
629: }
630: scrright( n )
631: int n;
632: {
633: int i, start;
634: struct collabel **c1;
635:
636: c1 = Col.table;
637: /*
638: * Get the starting position
639: */
640: for ( start=0; start<Col.size; start++ ) {
641: if ( c1[start]->position >= 0 ) break;
642: }
643: /*
644: * Increase number of cols, if needed
645: */
646: colexpand( start + n + 1 );
647: c1 = Col.table;
648: /*
649: * Get rid of the offending rows
650: */
651: for ( i=0; i<n; i++ ) {
652: c1[start+i]->position = -1;
653: }
654: /*
655: * Redraw the screen
656: */
657: fixcolheading();
658: prheading();
659: repaint();
660: }
661:
662:
663: void beep(){}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.