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; }