V10/cmd/visi/screen.c

Compare this file to the similar file:
Show the results in this format:

/*
 *      screen.c 1.4
 *
 *	Screen Handling Functions for Spreadsheet Program `vis'
 *
 *      A. F. Gettier
 *      Bell Laboratories
 *      Update made 11/1/82 11:13:42
 *      Retrieved 11/15/82 13:22:44
 */
#include	<math.h>
#include	<stdio.h>
#include	<signal.h>
#include	"curses.h"
#include	"vis.h"

extern int	LINES, COLS;
extern struct qheader	Fixup;

int	Width=DEFWIDTH;
int	Scale=DEFSCALE;

extern struct colhdr	Col;
extern struct rowhdr	Row;

/*
 *	Initialize the screen
 */
void
scrinit()
{
	extern quit();

	initscr();

	savetty();
	signal(SIGINT, quit);

	noecho();
	crmode();
	clear();

	/*
	 *	Set up the Heading
	 */

	setheading();

	/*
	 *	Print out the heading
	 */

	prheading();
}
/*
 *	Set the headings to the initial setting
 */
setheading()
{
	int	i;
	int	size;
	struct collabel	**c1;
	struct rowlabel	**r1;

	/*
	 *	Get the number of Rows
	 */
	size = LINES - 5;
	rowexpand( size );
	/*
	 *	Fix the print Positions Stuff
	 */
	r1 = Row.table;
	for ( i=0; i<size; i++ ) {
		r1[i]->position = i+3;
	}
	for ( i=size; i<Row.size; i++ ) {
		r1[i]->position = 0;
	}
	/*
	 *	Get the number of Columns
	 */
	size = ( COLS - 6 ) / (Width + 1);
	colexpand( size );
	/*
	 *	Fix the print Positions Stuff
	 */
	c1 = Col.table;
	for ( i=0; i<size; i++ ) {
		c1[i]->position = i * (Width + 1) + 6;
		c1[i]->cell = i;
	}
	for ( i=size; i<Col.size; i++ ) {
		c1[i]->position = 0;
		c1[i]->cell = i;
	}
}
/*
 *	Print the heading
 */
void
prheading()
{
	int	i, j, k, l;
	struct collabel	**c1;
	struct rowlabel	**r1;
	/*
	 *	Print the Frame
	 */
	erase();
	move( 2, 4 );
	printw( "------------------------------------" );
	printw( "----------------------------------------" );
	for ( i=3; i<(LINES-2); i++ ) {
		move( i, 4 );
		printw( "|" );
	}
	/*
	 *	Print the Labels
	 */
	r1 = Row.table;
	c1 = Col.table;
	/*
	 *	First the numbers on the Vertical
	 */
	for ( i=0; i<Row.size; i++ ) {
		if ( r1[i]->position < 0 )  continue;
		if ( r1[i]->position == 0 )  break;
		move( r1[i]->position, 1 );
		printw( "%d", i+1 );
	}
	/*
	 *	and the letters on the Horizontal
	 */
	l = i = 0;
	while ( i < Col.size && c1[i]->position+c1[i]->width+1 < COLS ) {
		if ( c1[i]->position <= 0 ) {
			i++;
			if ( l == 0 ) continue;
			else	break;
		}
		l = 0;
		move( 1, c1[i]->position + c1[i]->width/2 );
		j = i++;
		k = j / 26;
		if ( k > 0 )  k = k + 'A' - 1;
		else k = ' ';
		j =  j % 26 + 'A';
		printw( "%c%c", k, j );
	}
}

/*
 *	Print the Node
 */
prnode( node )
struct node	*node;
{
	int	i, j;
	struct collabel	**c1;
	struct rowlabel	**r1;

	/*
	 *	Get the print position
	 *
	 *
	 *	get the correct row
	 */
	r1 = Row.table;
	i = node->row;
	if ( i >= Row.size || r1[i]->position <= 0 ) return;
	/*
	 *	get the correct Column
	 */
	c1 = Col.table;
	j = node->col;
	if ( j >= Col.size || c1[j]->position <= 0 ) return;
	/*
	 *	Print the node
	 */
	move( r1[i]->position, c1[j]->position );
	noutput( node, c1[j]->width, c1[j]->scale );
}
/*
 *	output a single element
 *	  assume the cursor is positioned
 */
noutput( node, wid, scale )
struct node	*node;
int	wid, scale;
{
	int	i;
	char	tbuf[80], *x;

	switch( node->type ) {
	case UNDEF:
		for ( i=0; i<wid; i++ ) tbuf[i] = ' ';
		i = wid/2;
		tbuf[i++] = '*';
		tbuf[i] = '*';
		tbuf[wid] = '\0';
		break;
	case UNRES:
		for ( i=0; i<wid; i++ ) tbuf[i] = ' ';
		i = wid/2;
		tbuf[i++] = '?';
		tbuf[i] = '?';
		tbuf[wid] = '\0';
		break;
	case NUM:
		if ( (x=dtoa( node->value, wid, scale )) == 0 ) {
			for ( i=0; i<wid; i++ ) tbuf[i] = '#';
			tbuf[wid] = '\0';
		}
		else (void)strcpy( tbuf, x );
		break;
	case STRING:
		(void)strncpy( tbuf, node->svalue, wid );
		for ( i=strlen( tbuf ); i<wid; i++ ) tbuf[i] = ' ';
		tbuf[wid] = '\0';
		break;
	}
	printw( "%s", tbuf );
}

/*	dtoa.c
 *	S. Coffin, BTL Dept. 43372, FJ 1A110, x5151
 *	Apr. 15, 1982
 *
 *	Converts a double precision float to a right-justified
 *	printable character string according to the parameters
 *	size = total field width desired
 *	scale = number of digits to the right of the decimal
 *
 *	returns a pointer to the string.  If the size given
 *	is too small for the number, the routine attempts
 *	to use "e" notation.  If it still will not fit, NULL
 *	is returned.
 */

char *
dtoa( input, size, scale )
	double input;
	int size, scale;
{
	static char output[80];
	char pattern[80];
	int j=0, i;

	output[0] = '\0';

	/* get a sample string */
	(void)sprintf( pattern, "%-39.39lf", input );

	/* if the number is near zero, then try "e" notation */
	j=0;
	while( (pattern[j]=='0' || pattern[j]=='.') && pattern[j++]!='\0' );

	if( j < size && j > size/2 ) pattern[size] = '\0';
	else if ( j>size/2 && size>=9 )
		(void)sprintf( pattern, "%9.2e", input );
	else {
		/* not too near zero, so find the decimal point */
		j=0;
		while( pattern[j++] != '.' );

		/* truncate it to the scale */
		if( scale == 0 ) pattern[j-1] = '\0';
		else pattern[j+scale] = '\0';

		/* if its still too big, try "e" notation */
		if( (j-1 > size) || (j+scale > size) )
			(void)sprintf( pattern, "%9.2e",input);
	}

	/* is it still too big? */
	i=strlen(pattern);
	if( i <= size ) {
		/* ok, so right-justify the result, and return */
		for( j = 0; j < (size-i); j++ ) output[j]=' ';
		output[j] = '\0';
		strcat( output, pattern );
		return( output );
	}
	else return( NULL );
}

/*
 *	Copy out the Standard screen to a file
 */
copyfile( fp )
FILE	*fp;
{
	int	i, j, k;
	char	bf[150];
	char	*tbf;
	(void)fprintf( fp, "\n\n" );
	for ( i=1; i<LINES-2; i++ ) {

		tbf = bf;

		j = 0;
		k = COLS - 2;
		while ( j < COLS ) {
			bf[j] = (char)(stdscr->_y[i][j]);
			if (  bf[j] > ' ' ) k = j;
			j++;
		}
		bf[k+1] = '\0';
		(void)fprintf( fp, "%s\n", bf );
	}
	(void)fprintf( fp, "\n\n" );
}
/*
 *	reset the global scale
 */
setscale( n )
int	n;
{
	int	i;
	struct collabel	**c1;
	Scale = n;
	/*
	 *	Reset the individual headings
	 */
	c1 = Col.table;
	for ( i=0; i<Col.size; i++ ) {
		c1[i]->scale = Scale;
	}
	/*
	 *	Repaint the screen
	 */
	prheading();
	repaint();
}
/*
 *	reset the global width
 */
setwidth( n )
int	n;
{
	int	i;
	struct collabel	**c1;

	Width = n;
	/*
	 *	Reset the individual headings
	 */
	c1 = Col.table;
	for ( i=0; i<Col.size; i++ ) {
		c1[i]->width = Width;
	}
	fixcolheading();
	/*
	 *	Repaint the screen
	 */
	prheading();
	repaint();
}
/*
 *	reset an individual scale
 */
isetscale( col, n )
int	col, n;
{
	struct collabel	**c1;
	/*
	 *	Make sure it's valid
	 */
	if ( col > Col.size )  colexpand( col );
	if ( col < 0 ) {
		char	bfr[64];
		lexinit();
		unput( '\n' );
		(void)sprintf( bfr, "Attempt to change scale of column %d",
		    col );
		yyerror( bfr );
		return;
	}
	/*
	 *	Reset the individual headings
	 */
	c1 = Col.table;
	c1[col]->scale = n;
	/*
	 *	Repaint the screen
	 */
	prheading();
	repaint();
}
/*
 *	reset an individual width
 */
isetwidth( col, n )
int	col, n;
{
	struct collabel	**c1;

	/*
	 *	Make sure it's valid
	 */
	if ( col > Col.size )  colexpand( col );
	if ( col < 0 ) {
		char	bfr[64];
		lexinit();
		unput( '\n' );
		(void)sprintf( bfr, "Attempt to change scale of column %d",
		    col );
		yyerror( bfr );
		return;
	}
	/*
	 *	Reset the individual headings
	 */
	c1 = Col.table;
	c1[col]->width = n;
	fixcolheading();
	/*
	 *	Repaint the screen
	 */
	prheading();
	repaint();
}
/*
 *	Repaint the Screen
 */
repaint()
{
	int	i, j;
	struct node	*n;
	struct collabel	**c1;
	struct rowlabel	**r1;

	r1 = Row.table;
	c1 = Col.table;
	for ( i=0; i<Row.size; i++ ) {
		if( r1[i]->position == 0 ) break;
		if( r1[i]->position < 0 ) continue;
		n = r1[i]->next;
		while ( n != 0 ) {
			j = n->col;
			if( c1[j]->position == 0 ) break;
			if( c1[j]->position > 0 ) prnode( n );
			n = n->next;
		}
	}
}
/*
 *	Set the new Row headings
 */
fixrowheading()
{
	int	i, start;
	int	size;
	struct rowlabel	**r1;

	size = LINES - 5;
	/*
	 *	Get the Starting position
	 */
	r1 = Row.table;
	for ( start=0; start<Row.size; start++ )
		if ( r1[start]->position >= 0 ) break;
	/*
	 *	Get more rows if needed
	 */
	rowexpand( start + size + 1 );
	r1 = Row.table;
	/*
	 *	Fix the print Positions Stuff
	 */
	for ( i=0; i<size; i++ ) {
		r1[i+start]->position = i+3;
	}
	for ( i=size+start; i<Row.size; i++ ) {
		r1[i]->position = 0;
	}
}
/*
 *	Set the new Col headings
 */
fixcolheading()
{
	int	i, j, cpos, start;
	struct collabel	**c1;
	/*
	 *	Find the First cell to print
	 */
	c1 = Col.table;
	for ( start=0; start<Col.size; start++ ) {
		if ( c1[start]->position >= 0 ) break;
	}
	/*
	 *	Fix the print Positions Stuff
	 */
	cpos = 6;
	for ( i=start; i<Col.size; i++ ) {
		c1[i]->position = cpos;
		cpos += c1[i]->width + 1;
		if ( cpos > COLS ) {
			c1[i]->position = 0;
		}
	}
	i = (COLS - cpos ) / ( Width + 1 );
	j = Col.size;
	colexpand( i+j+1 );
	c1 = Col.table;
	for ( i=j; i<Col.size; i++ ) {
		c1[i]->position = cpos;
		cpos += c1[i]->width + 1;
		if ( cpos > COLS ) {
			c1[i]->position = 0;
		}
	}
}
/*
 *	zero out all the screen stuff
 */
zeroscreen()
{
	initscr();
	erase();
	Row.size = 0;
	Col.size = 0;
	Width = DEFWIDTH;
	Scale = DEFSCALE;
	/*
	 *	Set up the Heading
	 */
	setheading();
	/*
	 *	Print out the heading
	 */
	prheading();
}

/*
 *	SCROLLING
 */
scrup( n )
int	n;
{
	int	i, j, start;
	struct rowlabel	**r1;

	r1 = Row.table;
	/*
	 *	Get the starting position
	 */
	for ( start=0; start<Row.size; start++ ) {
		if (  r1[start]->position >= 0 )  break;
	}
	/*
	 *	Fix the offending rows
	 */
	i = start - n;
	if ( i < 0 )  i = 0;
	for ( j=i; j<Row.size; j++ ) {
		r1[j]->position = 0;
	}
	/*
	 *	Redraw the screen
	 */
	fixrowheading();
	prheading();
	repaint();
}
scrdown( n )
int	n;
{
	int	i, start;
	struct rowlabel	**r1;

	r1 = Row.table;
	/*
	 *	Get the starting position
	 */
	for ( start=0; start<Row.size; start++ ) {
		if (  r1[start]->position >= 0 )  break;
	}
	/*
	 *	Increase number of rows, if needed
	 */
	rowexpand( start + n + 1 );
	r1 = Row.table;
	/*
	 *	Get rid of the offending rows
	 */
	move( 3, 0 );
	for ( i=0; i<n; i++ ) {

		r1[start+i]->position = -1;

	}
	/*
	 *	Redraw the screen
	 */
	fixrowheading();
	prheading();
	repaint();
}
scrleft( n )
int	n;
{
	int	i, j, start;
	struct collabel	**c1;

	c1 = Col.table;
	/*
	 *	Get the starting position
	 */
	for ( start=0; start<Col.size; start++ ) {
		if (  c1[start]->position >= 0 )  break;
	}
	/*
	 *	Fix the offending rows
	 */
	i = start - n;
	if ( i < 0 )  i = 0;
	for ( j=i; j<Col.size; j++ ) {
		c1[j]->position = 0;
	}
	/*
	 *	Redraw the screen
	 */
	fixcolheading();
	prheading();
	repaint();
}
scrright( n )
int	n;
{
	int	i, start;
	struct collabel	**c1;

	c1 = Col.table;
	/*
	 *	Get the starting position
	 */
	for ( start=0; start<Col.size; start++ ) {
		if (  c1[start]->position >= 0 )  break;
	}
	/*
	 *	Increase number of cols, if needed
	 */
	colexpand( start + n + 1 );
	c1 = Col.table;
	/*
	 *	Get rid of the offending rows
	 */
	for ( i=0; i<n; i++ ) {
		c1[start+i]->position = -1;
	}
	/*
	 *	Redraw the screen
	 */
	fixcolheading();
	prheading();
	repaint();
}


void beep(){}