home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
utilitys
/
chx8012b.arc
/
CHECKD.C
< prev
next >
Wrap
Text File
|
1990-07-21
|
23KB
|
716 lines
/* checkd.c -- 5th source file for check register program */
/* copyright (c) 1986 by Jim Woolley and WoolleyWare, San Jose, CA */
/* vers. 1.0, 12/85 thru 5/86
*
* vers. 1.2, 7/86
* save(): added display "Saving ... "
* reconcile() & abreviations(): added doscroll() with ^C and ^R scrolling
* and revised keyboard look ahead for scrolling
* reconcile(): added one space to end of total bars (--------- ----...)
* abreviations(): cleared text from rest of line when scrolling
* reorder(): added display "Sorting ... "
* integrated CLEARS using #ifdef
*/
/* this file contains:
* delete()
* undo()
* insert()
* ctrlqork()
* erase( c)
* abandon()
* save()
* reconcile()
* abreviations()
* char doscroll( c, scroll, i, firstline, lastline, maxline, header)
* print()
* order()
* reorder( f)
* datemax( md, d)
*/
#include "a:checks.h"
delete() /* delete Entry[ Recno] */
{
int r;
if ( Recno > Maxentry)
return;
if ( isibbf( Recno))
{
prompt( "Cannot delete ");
puts( BBF);
waitesc();
return;
}
r = Recno - First + HEAD;
movmem( &Entry[ Recno], &Entryundo, RECSIZ);
Modified = Ctrlyundo = TRUE;
#ifndef CLEARS
if ( Savrecno == Recno)
Savrecno = -1;
else if ( Savrecno > Recno)
--Savrecno;
#endif
if ( Recno < Maxentry)
movmem( &Entry[ Recno + 1], &Entry[ Recno], ( Maxentry - Recno)*RECSIZ);
--Maxentry;
if ( Maxentry < 0)
{
First = 0;
Last = Maxentry = -1;
}
else First = min( First, ( Last = min( Last, Maxentry)));
dellin( r);
update( Recno);
if ( Recno > Maxentry)
Field = 0;
putcursor( Recno, Field);
}
undo() /* undo delete for Entry[ Recno] */
{
if ( Ctrlyundo && insert())
{
movmem( &Entryundo, &Entry[ Recno], RECSIZ);
putrecord( Recno);
update( Recno);
putcursor( Recno, Field);
}
}
insert() /* insert Entry[ Recno] */
{ /* return TRUE if successful */
int i;
if ( Maxentry == ( ENTRYSIZE - 1))
{
prompt( "Number of entries is maximum allowed");
waitesc();
return ( FALSE);
}
if ( Recno <= Maxentry)
{
i = Maxentry - Recno + 1;
movmem( &Entry[ Recno], &Entry[ Recno + 1], i*RECSIZ);
movmem( &Balance[ Recno], &Balance[ Recno + 1], i*sizeof( Balance[ 0]));
}
#ifndef CLEARS
if ( Savrecno >= Recno)
++Savrecno;
#endif
++Maxentry;
newentry( Recno); /* Modified will be set TRUE */
Last = min(( Last + 1), ( First + LAST));
inslin( Recno - First + HEAD);
putcursor( Recno, Field);
return ( TRUE);
}
ctrlqork( c) /* process CTRLQ or CTRLK command */
char c;
{
char n;
int i;
cursorto( 0, 2);
n = putnext();
if ( c == CTRLQ) /* process CTRLQ command */
{
switch ( n)
{
case 'R':
gotop();
break;
case 'C':
gobottom();
break;
case 'D':
if ( Recno > Maxentry)
break;
putcursor( Recno, ( Field = MAXFIELD - 1));
break;
case 'S': case 'H':
#ifndef CLEARS
Character = 0;
#endif
putcursor( Recno, ( Field = 0));
break;
case 'E':
putcursor(( Recno = First), Field);
break;
case 'X':
Recno = min(( Maxentry + 1), ( First + ( LAST - 1)));
if ( Recno > Maxentry)
Field = 0;
putcursor( Recno, Field);
break;
case 'W': case 'Z':
goupdown( n);
break;
case 'Y': case DEL: case ( CTRL_ + CTRLTOA):
#ifdef CLEARS
prompt( Usechex);
puts( "edit entries");
waitesc();
#else
if ( Field == PAYFIELD)
{
strcpy( Savpayee, Entry[ Recno].payee);
Savrecno = Recno;
putcursor( Recno, Field);
erase( n);
}
#endif
break;
default:
putchar( BEL);
break;
}
}
else /* process CTRLK command */
{
switch ( n)
{
case 'O':
order( 0);
break;
case 'D': case 'X':
done(); /* never returns */
break;
case 'S':
save();
break;
case 'Q':
abandon(); /* may not return */
break;
case 'R':
reconcile();
break;
case 'P':
print();
break;
case 'A':
#ifdef CLEARS
prompt( Usechex);
puts( "work with abreviations");
waitesc();
#else
abreviations();
#endif
break;
default:
putchar( BEL);
break;
}
}
}
#ifndef CLEARS
erase( c) /* erase payee left or right */
char c;
{
char *p, *q;
int count;
q = Entry[ Recno].payee;
p = q + Character;
if ( c == 'Y')
{
count = strlen( p);
*p = '\0';
}
else if ( !Character)
return;
else
{
strcpy( q, p);
count = Character;
Character = 0;
putcursor( Recno, Field);
puts( q);
}
while ( count--)
putchar( PAYEEFILL);
Modified = TRUE;
}
#endif
abandon() /* abandon without resave */
{
if ( Modified)
{
prompt( "Abandon without saving changes (Y/N)? ");
if ( getyesno( NO))
aexit();
}
else
{
prompt( "Abandoning unchanged file");
aexit();
}
}
save() /* save entries and continue */
{
#ifdef CLEARS
char compdate();
reorder( 0, compdate); /* must sort by date */
#else
prompt( "Saving ... ");
#endif
if ( savedat( TRUE)) /* if error */
return;
waitesc(); /* else, wait for recognition */
Modified = FALSE;
}
reconcile() /* display summary by category */
{
char c, *spaces, *sh, *ss, scroll, nbr[ DEL];
int i, j, count, lines, firstline, lastline, maxline;
struct
{
struct calendar maxdate;
char sumcategory;
struct money beginbal, clrcheck, clrdeposit, allcheck, alldeposit;
} sum, *a, *start;
struct record *e;
struct money *m, clrendbal, allendbal;
spaces = " ";
sh =
"-------- -------- -------- -------- -------- -------- --------";
ss = "-------- - ";
prompt( "");
setmem( nbr, DEL, 0); /* initialize */
for ( j = 0; j <= Maxentry; ++j) /* count number in each category */
++nbr[ Entry[ j].category & 0x7f];
lines = 0;
for ( i = ' '; i < DEL; ++i) /* count separate categories, then */
if ( nbr[ i]) /* allocate space for each */
++lines;
if ( !lines)
return;
if ( !( a = start = alloc( lines*sizeof( *a))))
{
prompt( "Insufficient memory to reconcile all categories");
waitesc();
return;
}
recheading( ss, sh);
setmem( &sum, sizeof( sum), 0); /* initialize */
setmem( a, ( lines*sizeof( *a)), 0);
for ( i = ' '; i < DEL; ++i) /* summarize each category */
{
if ( !nbr[ i]) /* if category does not exist */
continue; /* next category */
a->sumcategory = i;
count = 0;
for ( j = 0; j <= Maxentry; ++j)
{ /* loop thru entries */
e = &Entry[ j];
if ((( c = e->category) & 0x7f) != i)
continue; /* next entry */
datemax( &( a->maxdate), &( e->date));
m = &( e->amount);
if ( c & 0x80) /* if a BBF entry */
addmoney( &a->beginbal, &a->beginbal, m, e->deposit);
else /* not a BBF entry */
{
if ( e->deposit) /* if a deposit */
{
addmoney( &a->alldeposit, &a->alldeposit, m, TRUE);
#ifdef CLEARS
if ( !e->clear)
#else
if ( e->clear)
#endif
addmoney( &a->clrdeposit, &a->clrdeposit, m, TRUE);
}
else /* not a deposit */
{
addmoney( &a->allcheck, &a->allcheck, m, TRUE);
#ifdef CLEARS
if ( !e->clear)
#else
if ( e->clear)
#endif
addmoney( &a->clrcheck, &a->clrcheck, m, TRUE);
}
}
if ( ++count == nbr[ i]) /* if all entries for this category */
break; /* break j loop over entries */
} /* end j loop over entries */
datemax( &( sum.maxdate), &( a->maxdate));
addmoney( &sum.beginbal, &sum.beginbal, &a->beginbal, TRUE);
addmoney( &sum.alldeposit, &sum.alldeposit, &a->alldeposit, TRUE);
addmoney( &sum.clrdeposit, &sum.clrdeposit, &a->clrdeposit, TRUE);
addmoney( &sum.allcheck, &sum.allcheck, &a->allcheck, TRUE);
addmoney( &sum.clrcheck, &sum.clrcheck, &a->clrcheck, TRUE);
++a; /* next summary line */
} /* end i loop over categories */
firstline = i = 0;
maxline = lines + 1;
lastline = min( maxline, ( LAST - 1));
Printing = scroll = FALSE;
FOREVER /* begin display loop */
{
cursorto((( HEAD + 1) + i - firstline), 0);
if ( i == lines)
{
puts( spaces);
puts( sh);
putchar( ' '); /* clear ')' from negative balance */
}
else
{
if ( i < lines)
{
a = start + i;
c = a->sumcategory;
}
else
{
a = ∑
c = ' ';
}
putdate( &( a->maxdate));
putchar( c);
addmoney( &clrendbal, &a->beginbal, &a->clrcheck, FALSE);
addmoney( &clrendbal, &clrendbal, &a->clrdeposit, TRUE);
addmoney( &allendbal, &a->beginbal, &a->allcheck, FALSE);
addmoney( &allendbal, &allendbal, &a->alldeposit, TRUE);
putchar( ' ');
putmoney( &a->beginbal);
putchar( ' ');
putmoney( &a->clrcheck);
putchar( ' ');
putmoney( &a->clrdeposit);
putchar( ' ');
putmoney( &clrendbal);
putchar( ' ');
putmoney( &a->allcheck);
putchar( ' ');
putmoney( &a->alldeposit);
putchar( ' ');
putmoney( &allendbal);
}
if ( Printing)
{
if ( ++i > maxline)
{
resetlst();
i = count; /* reset line index */
}
}
else if ( !( scroll = ( scroll || i == lastline)))
{
++i; /* fill screen */
if ( kbhit()) /* look ahead */
{
ungetch( c = getchar());
switch ( c)
{
case CTRLZ:
scroll = ( !( *Lindel) && lastline != maxline);
break;
case CTRLW:
scroll = ( !( *Linins) && firstline);
break;
case CTRLC:
scroll = ( lastline != maxline);
break;
case CTRLR:
scroll = ( firstline != 0);
break;
default: /* scroll is already FALSE */
break;
}
}
}
else
{
prompt( "");
if ( firstline) /* if line 0 is off screen */
puts( "^W/^R to see prior, ");
if ( lastline < maxline) /* if final line is off screen */
puts( "^Z/^C to see next, ");
puts( "^P to print, ESCAPE to see full register");
FOREVER /* loop until valid key */
{
if (( c = getchar()) == CTRLP)
{
if ( setlst())
{
recheading( ss, sh);
count = i; /* save current line index */
i = 0;
}
break; /* break FOREVER loop */
}
if ( c == ESC)
{
free( start);
clrscr();
disheading();
display( First);
return;
}
if (( c = doscroll( c, &scroll, &i, &firstline, &lastline,
maxline, (HEAD + 1))) == 1)
break; /* break FOREVER loop */
if ( c == 2)
putchar( BEL);
} /* end FOREVER loop until valid key */
} /* end if ... else scroll test */
} /* end FOREVER display loop */
} /* end reconcile() */
#ifndef CLEARS
abreviations() /* display installed abreviations */
{
char c, scroll;
int i, lines, hashval, firstline, lastline, compabrev();
struct nlist *np, **start;
prompt( "");
lines = 0; /* allocate abrev pointer space */
for ( hashval = 0; hashval < HASHSIZE; ++hashval)
for ( np = Hashtab[ hashval]; np; np = np->next)
++lines; /* count abreviations */
if ( !lines)
{
prompt( "There are no abreviations installed");
goto quit;
}
if ( !( start = alloc( lines*sizeof( np))))
{
prompt( "Insufficient memory to display all abreviations");
quit: waitesc();
return;
}
clrscr();
putscr( Ivon);
puttitle();
puts(
" Abreviation Payee "
);
putchar( '\n');
puts(
" ----------- ------------------------------------------ "
);
putscr( Ivoff);
i = 0;
for ( hashval = 0; hashval < HASHSIZE; ++hashval)
for ( np = Hashtab[ hashval]; np; np = np->next)
*( start + ( i++)) = np; /* save pointer to each abreviation */
qsort( start, lines, sizeof( np), compabrev);
firstline = i = 0;
lastline = min( --lines, LAST);
scroll = FALSE;
FOREVER /* begin display loop */
{
cursorto(( HEAD + i - firstline), 0);
np = *( start + i);
puts( " "); /* 16 spaces */
puts( np->abrev); /* 3 chars */
puts( " "); /* 6 spaces */
puts( np->fullname);
clreol(( COLS - 25) - strlen( np->fullname));
if ( !( scroll = ( scroll || i == lastline)))
{
++i; /* fill screen */
if ( kbhit()) /* look ahead */
{
ungetch( c = getchar());
switch ( c)
{
case CTRLZ:
scroll = ( !( *Lindel) && lastline != lines);
break;
case CTRLW:
scroll = ( !( *Linins) && firstline);
break;
case CTRLC:
scroll = ( lastline != lines);
break;
case CTRLR:
scroll = ( firstline != 0);
break;
default: /* scroll is already FALSE */
break;
}
}
}
else
{
prompt( "");
if ( firstline) /* if line 0 is off screen */
puts( "^W/^R to see prior, ");
if ( lastline < lines) /* if final line is off screen */
puts( "^Z/^C to see next, ");
puts( "ESCAPE to see full register");
FOREVER /* loop until valid key */
{
if (( c = getchar()) == ESC)
{
free( start);
clrscr();
disheading();
display( First);
return;
}
if (( c = doscroll( c, &scroll, &i, &firstline, &lastline,
lines, HEAD)) == 1)
break; /* break FOREVER loop */
if ( c == 2)
putchar( BEL);
} /* end FOREVER loop until valid key */
} /* end if ... else scroll test */
} /* end FOREVER display loop */
} /* end abreviations() */
#endif
char doscroll( c, scroll, i, firstline, lastline, maxline, header)
char c, *scroll; /* used by reconcile() */
int *i, *firstline, *lastline; /* and by abreviations() */
int maxline, header; /* return 1 if valid key, */
{ /* 2 if invalid key, */
/* 0 if valid key at wrong time */
switch ( c)
{
case CTRLW:
if ( *firstline)
{
*i = --( *firstline);
--( *lastline);
if ( !linins( header))
*scroll = FALSE;
return ( 1);
}
break;
case CTRLR:
if ( *firstline)
{
*i = min( *firstline, PAGE);
*lastline -= *i;
*i = ( *firstline -= *i);
*scroll = FALSE;
return ( 1);
}
break;
case CTRLZ:
if ( *lastline < maxline)
{
++( *firstline);
*i = ++( *lastline);
if ( !lindel( header))
{
*i = *firstline;
*scroll = FALSE;
}
return ( 1);
}
break;
case CTRLC:
if ( *lastline < maxline)
{
*i = min(( maxline - *lastline), PAGE);
*lastline += *i;
*i = ( *firstline += *i);
*scroll = FALSE;
return ( 1);
}
break;
default:
return ( 2);
break;
}
return ( 0);
}
print() /* print entries */
{
int i;
if ( setlst())
{
disheading();
for ( i = 0; i <= Maxentry; ++i)
putrecord( i); /* cannot use display() */
resetlst();
}
}
order( i) /* reorder entries i to Maxentry */
int i;
{
char c;
int compdate(), comppayee(), compcateg(), compamount(), ( *f)();
prompt(
"Order entries by Date, Payee, Category, Amount, or Neither (D/P/C/A/N)? N"
);
putchar( '\b');
switch ( c = toupper( getchar()))
{
case 'D':
f = compdate;
break;
case 'P':
f = comppayee;
break;
case 'C':
f = compcateg;
break;
case 'A':
f = compamount;
break;
default:
c = 0;
break;
}
if ( c)
{
putchar( c);
reorder( i, f);
}
}
reorder( i, f) /* reorder from i using function f */
int i, ( *f)();
{
prompt( "Sorting ... ");
qsort( &Entry[ i], ( Maxentry - i + 1), RECSIZ, f);
for ( ; i <= Maxentry; ++i) /* update balance and display */
{
newbalance( i);
if ( First <= i && i <= Last)
putrecord( i);
}
#ifndef CLEARS
Character = 0; /* avoid dangling cursor */
#endif
}
datemax( md, d) /* determine max date */
struct calendar *md; /* max date */
struct calendar *d; /* trial date */
{
if ( datecomp( md, d) < 0)
{
md->mm = d->mm;
md->dd = d->dd;
md->yy = d->yy;
}
}