extern U0 BgtRegen();
Bool BgtPutKey(CDoc *doc,U8 *,I64 ch,I64 sc)
{//ch=ASCII; sc=scan_code
no_warn sc;
CBgtEntry *tmpb,*tmpb1;
CBgtTemplate *tmpt,*tmpt1;
CDocEntry *doc_ce;
U8 *st;
switch (ch) {
case '\n':
if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
doc_ce->type_u8==DOCT_MENU_VAL) {
tmpb=doc_ce->user_data;
if (tmpt=tmpb->template) {
if (tmpt1=BgtTemplatePmt(tmpt)) {
QueRem(tmpt);
BgtTemplatePurge(tmpt);
BgtEntryDel2(&tmpt->b);
Free(tmpt);
QueIns(tmpt1,t_head.last);
BgtTemplateExpand(tmpt1);
BgtRegen;
}
} else {
if (tmpb1=BgtEntryPmt(tmpb)) {
QueRem(tmpb);
BgtEntryDel(tmpb);
BgtIns(tmpb1);
BgtRegen;
}
}
}
return TRUE;
case CH_CTRLY:
if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
doc_ce->type_u8==DOCT_MENU_VAL) {
tmpb=doc_ce->user_data;
if (tmpt=tmpb->template) {
QueRem(tmpt);
BgtTemplateDel(tmpt);
} else {
QueRem(tmpb);
BgtEntryDel(tmpb);
}
BgtRegen;
}
return TRUE;
case 'a':
PopUpOk( "Set the name and color of your accounts.\n"
"To delete accounts, manually edit\n"
"$GREEN$~/Budget/Accts.DD.Z$FG$.");
if (PopUpEd(bgt_accts_file,Fs)) {
BgtAcctsRead;
BgtRegen;
}
return TRUE;
case 'v':
if ((st=BgtPopUpAcct("View Acct\n\n",view_acct))>=0) {
StrCpy(view_acct,st);
BgtRegen;
}
return TRUE;
case 'n':
if (tmpb1=BgtEntryPmt) {
BgtIns(tmpb1);
BgtRegen;
}
return TRUE;
case 't':
if (tmpt1=BgtTemplatePmt) {
QueIns(tmpt1,t_head.last);
BgtTemplateExpand(tmpt1);
BgtRegen;
}
return TRUE;
case 'c':
if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
doc_ce->type_u8==DOCT_MENU_VAL)
tmpb=doc_ce->user_data;
else
tmpb=NULL;
if (tmpb1=BgtEntryPmt(tmpb)) {
BgtIns(tmpb1);
BgtRegen;
}
return TRUE;
case 'p':
if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
doc_ce->type_u8==DOCT_MENU_VAL) {
tmpb=doc_ce->user_data;
if (tmpt1=BgtTemplatePmt(,tmpb)) {
BgtTemplateExpand(tmpt1,TRUE);
BgtTemplateDel(tmpt1);
BgtRegen;
}
}
return TRUE;
}
return FALSE;
}
U0 BgtRegen()
{
I64 timeout_jiffy,c,color=COLOR_INVALID;
F64 balance=0;
CDoc *doc,*pdoc,*ddoc;
CDocEntry *doc_ce;
CBgtEntry *tmpb=b_head.next,*tmpb_ce;
doc=DocNew;
doc->flags|=DOCF_FORM;
while (tmpb!=&b_head) {
if (!StrCmp(view_acct,tmpb->credit))
balance-=tmpb->amount;
if (!StrCmp(view_acct,tmpb->debit))
balance+=tmpb->amount;
c=BgtAcctColor(tmpb->credit);
if (c!=color) {
color=c;
DocPrint(doc,"$FG,%d$",color);
}
tmpb->doc_e=DocPrint(doc,
"$MU-UL,\"%D %8ts %8ts:%8.2f %8.2f:%$Q\",U=0x%X$\n",
tmpb->date,tmpb->credit,tmpb->debit,balance,
tmpb->amount,tmpb->desc,tmpb);
tmpb=tmpb->next;
}
DocRecalc(doc);
if (pdoc=Fs->put_doc) {
DocLock(pdoc);
//Now, we want to preserve old position in doc, using ugly brute force.
//It's tricky -- can't use old line num because of editor filters.
//The price we pay for using the standard document editor is this kludge.
//When I originally wrote my budget program, I did not have separate budget
//and line entries, so we never had to resync.
doc_ce=pdoc->cur_entry;
timeout_jiffy=cnts.jiffies+JIFFY_FREQ; //Max one second.
while (doc_ce!=pdoc && cnts.jiffies<timeout_jiffy) {
while (doc_ce->type_u8!=DOCT_MENU_VAL || !(tmpb_ce=doc_ce->user_data)) {
doc_ce=doc_ce->next;
if (doc_ce==pdoc) goto br_cont;
}
tmpb=b_head.next;
while (tmpb!=&b_head) {
if (tmpb==tmpb_ce) {
doc->cur_entry=tmpb->doc_e;
doc->cur_col=0;
DocCenter(doc);
goto br_cont;
}
tmpb=tmpb->next;
}
doc_ce=doc_ce->next;
}
}
br_cont:
ddoc=Fs->display_doc;
Fs->put_doc =doc;
Fs->display_doc=doc;
DocDel(pdoc);
if (pdoc!=ddoc)
DocDel(ddoc);
doc->user_put_key=&BgtPutKey;
}
U0 Budget(U8 *dirname="~/Budget")
{
CDoc *pdoc,*ddoc,*old_put,*old_display;
Cd(dirname);
bgt_string_file =FileNameAbs("Strs.DD.Z");
bgt_accts_file =FileNameAbs("Accts.DD.Z");
bgt_data_file =FileNameAbs("Bgt.DATA.Z");
BgtAcctsRead;
BgtDataRead;
CBgtTemplatesExpand;
SettingsPush; //See SettingsPush
AutoComplete;
WinBorder;
WinMax;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Edit {"
" NewEntry(,'n');"
" CopyEntry(,'c');"
" PeriodicEntry(,'p');"
" EditEntry(,'\n');"
" DeleteEntry(,CH_CTRLY);"
" NewTemplate(,'t');"
" AcctsFile(,'a');"
"}"
"View {"
" ViewAcct(,'v');"
"}"
);
StrCpy(view_acct,"BANK");
DocMax;
old_put =Fs->put_doc;
old_display =Fs->display_doc;
Fs->put_doc =NULL;
Fs->display_doc=NULL;
BgtRegen;
try
if (View) {
BgtDataWrite;
BgtAcctsWrite;
}
catch
PutExcept;
pdoc=Fs->put_doc;
ddoc=Fs->display_doc;
Fs->put_doc =old_put;
Fs->display_doc=old_display;
DocDel(pdoc);
if (pdoc!=ddoc)
DocDel(ddoc);
SettingsPop;
BgtDel;
MenuPop;
}