|
IntroductionProgramming CBB is quite simple. Even if you have never worked with Tcl/Tk or Perl, it is fairly easy to get started because of the 'natural' aspect of these languages and the fact that they do not require compiliation - that means instant results.CBB consists of two major components: the Tcl/Tk graphical front end and the Perl database backend. We have tried to make these two components as independent of each other as possible. It is possible to run CBB as a text-only program just using the Perl backend, though the commands would be rather cumbersome! The CBB DatafilesThe CBB datafiles consists of three types of files (or tables in the language of databases). The CBB database files are all human readable text, and can be edited with a simple text editor, if just a little care is taken. All of the CBB database files, version 0.9 and later, consist of a header portion marked by lines starting with a hash mark. The header contains notes and meta-data, stored in the fashion of a keyword = value pair. Following the header portion is the data portion of the file, consisting of lines, separated by return characters (0x0a) with a fixed number of entries, each separated by tabs (0x09). In principal, these two characters are the only reserved characters for the data in the datafiles, although the category entry in the account file has two additional reserved characters.The 'group' file contains information about the various accounts. The important meta-data in the header is the associated category file for this group. Each line in the group file contains the following information about a single account: nickname, filename, description, balance, current balance. The nickname is a single work used to refer to the account, particularly for transfer transactions. These must each be unique. The file name is the complete name of the file which contains the account data. The description is a mulit-word description of the account. The balance is the ending balance in the account, while the current balance is the balance for the current date. A single collection of accounts should have a single group file. It also makes no sense for an account to belong to more than one group -- at least this is not currently implemented. The 'category' file lists the valid category terms for the given group. The important meta-data here is the associated group file for the given category file. The lines in this file consist of: the category, description, and a flag to note if the category is tax-related. Again, there should be only one category per group. The 'account' file contains the meat of the database - the actual financial transactions. The meta-data in this file include the CBB version, the group file name, various balances, the date saved, and the user. In fact, we are not currently double checking any of these values except for the group and version. The data lines consist of the following entries: date, check number, description, debit, credit, category, comment, cleared. The date is written in the format YYYYMMDD. The category word corresponds to an entry in the category list. Note that if the category is surrounded by [], then the transaction is a transfer. The word in the brackets must the correspond to an account nickname in the accounts file. It is also possible for the category entry to be a list, for the purpose of splitting a single transaction into multiple sub-transactions. In this case, the category is written: |CAT|COM|AMT| - the verticle bar (0x7c) separates the entries. There is always a multiple of three entries. In each group of three, the first entry is the category, followed by the comment, followed by the transaction amount. Note that the transaction has a total amount, which should be the sum of the entries in the split, but this fact is not double checked by the perl engine. There is also a transaction comment which is independent of the split comments. The Perl database engineCBB is started by starting the Tcl/Tk frontend. The front end launches the Perl backend, which continues to run for the entire CBB session. The perl engine interacts with the front end gui by a series of command / response interactions over stdin / stdout. There are essentially three types of commands. Commands which perform an action and either succeed or fail return either 'ok' (for success) or an error messageq, which may simply be the word 'error' or may be a slightly more descriptive error. Commands which return a useful value either provide the value or provide an error message. Finally, a few commands return a list of values. These lists are terminated with the word 'none'.The typical interaction with the perl engine consists of loading the group, category, and account data, making requests, and updating the values. In the current (CBB 0.9) implementation, the perl engine does enforce consistency between the account, group, and category explicitly. It is up to the front end to check that the currently loaded account has the correct group, etc. The Perl engine, called by the main perl program wrapper.pl is a the top level a continuous loop which waits for commands from standard input. The engine the identifies the command, finds the appropriate subroutine for that command, executes the subroutine, and prints to standard output whatever value the subroutine returns. The perl engine maintains a set of global internal variables that track the current state of the database interaction. These variables includes such things as the current path, account file, group file, category file, the complete list of account transactions, the list of account files, and so forth. There are not a huge number of internal variables, since Perl does not need to know about anything other than the values in the accounts. It does not need to know anything about the user's display perferences, for instance, or the gui itself. The Tcl/Tk GUI front endThe Tcl/Tk front end consists of a main account window, and several supporting windows, most of which are only visible for short periods to the user. The main account window contains three main portions, in addition to the basic menu bar. On top, there is a large region listing all of the transactions of the currently loaded account. In the middle are the elements for creating / editing transactions. The bottom portion consists of a list of all accounts in the account group.Most of the Tcl/Tk programming goes into defining and drawing the various windows and responding to the various user actions. There are a few aspects of interest to note. One is the interaction with the Perl engine. This is started by the Tcl/Tk components simply by opening a read/write connection to the program, with the global variable for the file descriptor, $eng. Throughout the Tcl/Tk frontend, interactions with the engine take place as 'puts $eng (command)' followed by 'gets $eng (answer)'. In some cases, the perl engine returns more than a single line, either a fixed number of lines, of which Tcl/Tk is aware, or a list of lines ending with a fixed word, 'none'. Another imporant detail of the tcl/tk engine is the process which takes care of TAB completion in the various locations. There are two types of TAB completion: filling in of the category names and filling in of a complete, memorized transaction. The perl engine maintains an internal list of unique transaction descriptions, along with their complete associated transactions. If the user types part of a transaction description and then types tab, cbb attempts to fill in the rest of the description, and then fill in various other fields. There are a few possible outcomes to this process. First, if there is nothing in the description field, the tab just moves the cursor to the next field. If the description exactly matches a memorized description, the comlete transaction is filled in and the cursor moves to the next field. If the description partially matches a memorized description, or if there are more than one possible match, the transaction is filled in, but the cursor is not advanced. At that point, typing Control Tab cycles through the possible completions as well as the original characters entered. This lets the user easily return to the initial start without alot of extra typing, in case they didn't want the completion suggestion. Also, if there are multiple choices, the multiple options are listed on the status line in the CBB window. The CBB tcl/tk front end also has some interesting details related to the choice of date formats. The user defines their date format choice in the preference menu. There are many possible options, with all combinations of YYYY/MM/DD, DD/MM/YYYY, MM/DD/YYYY, etc, as well as different choices for separators. CBB encapsulates the conversion between internal and external date formats and provides conversion APIs to and from the internal format. This lets us easily change or add to the list of date format options. |