#!/usr/local/bin/wish4.0 -f
#
#  'CBB' -- Check Book Balancer
#           Front end to the perl engine.
#
#  Written by Curtis Olson.  Started August 25, 1994.
#
#  Copyright (C) 1994, 1995, 1996  Curtis L. Olson  - curt@sledge.mn.org
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# $Id: cbb,v 1.58 1996/02/11 20:30:15 curt Exp $
# (Log is kept at end of this file)


#------------------------------------------------------------------------------
# lets get this out of the way right away ... increase the precision
#------------------------------------------------------------------------------
set tcl_precision 17


#------------------------------------------------------------------------------
# check command line args.
#------------------------------------------------------------------------------

if { [expr $argc > 1] } {
   puts "Usage:  [file tail $argv0]  \[ file_name \]"
   exit
}


#------------------------------------------------------------------------------
# open a two way pipe to the perl engine.
#------------------------------------------------------------------------------

set eng [open |wrapper.pl r+]


#------------------------------------------------------------------------------
# Set global variables
#------------------------------------------------------------------------------

set selected 0
set next_chk 0
set cur_date ""
set cur_file "noname.cbb"
set clean 1
set state_start 0.00
set state_end 0.00
set def_cat "default.cat"
set version "Version <not_installed>"
set lib_path [pwd]
set icon_xbm "cbb.xbm"
set author_xbm "author.xbm"
set csh_src "csh.src"
set index1 0
set index2 0
set no_more_mem 0

#------------------------------------------------------------------------------
# The following variables are over ridden by the ~/.cbbrc.tcl file
#------------------------------------------------------------------------------
set use_mems 1
set date_fmt 1
# 1000 milleseconds = 1 second (save_interval is specified in milleseconds)
set save_interval 180000
set list_width 70
set list_height 28
set max_splits 16
set auto_hilite 1
set debug 0
set msg_text_font "-adobe-new century schoolbook-bold-i-normal-*-14-*-*-*-*-*-*-*"
set button_font "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
set fixed_header_font "9x15bold"
set fixed_font "9x15"
set status_line_font "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
set menu_font "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
set dialog_font "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"
set default_font "-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-*-*"

# Ok, so lets override them if we can ...
if { [file exists "~/.cbbrc.tcl"] } {
    source "~/.cbbrc.tcl"
}


#------------------------------------------------------------------------------
# Read in other pieces
#------------------------------------------------------------------------------

source "$lib_path/common.tk"
source "$lib_path/main.tk"
source "$lib_path/bindings.tk"
source "$lib_path/menu.tk"
source "$lib_path/categories.tk"
source "$lib_path/file.tk"
source "$lib_path/filebox.tk"


#------------------------------------------------------------------------------
# Setup window parameters
#------------------------------------------------------------------------------

wm title . "[file tail $argv0] - $cur_file"
wm iconname . "[file tail $argv0] - $cur_file"
wm iconbitmap . @$lib_path/$icon_xbm
# specify absolute placement
#wm geometry . +0+0
# The following options will enable window resizing
#wm minsize . 100 50
#wm maxsize . 1000 700
option add *font $default_font


#------------------------------------------------------------------------------
# Setup container frames
#------------------------------------------------------------------------------

setup_containers


#------------------------------------------------------------------------------
# Call menu setup procedures
#------------------------------------------------------------------------------

option add *font $menu_font
setup_menubar .menubar
setup_file_menu .menubar
setup_edit_menu .menubar
setup_functions_menu .menubar
setup_extern_menu .menubar
setup_help_menu .menubar
setup_file_prefs_menu .menubar
setup_functions_goto_menu .menubar
setup_functions_cats_menu .menubar

tk_menuBar .menubar .menubar.file .menubar.edit .menubar.functions \
	.menubar.extern .menubar.help
tk_bindForTraversal .


#------------------------------------------------------------------------------
# Help menu procedures
#------------------------------------------------------------------------------

proc display_about name {
    global version author_xbm lib_path msg_text_font button_font

    option add *font $msg_text_font
    
    toplevel .aboutwin

    wm title .aboutwin "About $name"
    wm iconname .aboutwin "About $name"
    frame .aboutwin.frame -borderwidth 2 -relief raised
    frame .aboutwin.frame.a -borderwidth 2
    frame .aboutwin.frame.d -borderwidth 2

    button .aboutwin.frame.a.but -bitmap @$lib_path/$author_xbm -relief ridge 
    label .aboutwin.frame.a.l1 -text "The wise man saves for the future ..."
    label .aboutwin.frame.a.l2 -text "... the fool spends everything he gets."
    label .aboutwin.frame.a.l3 -text "Proverbs 21:20"
    label .aboutwin.frame.a.l4 -text "``$name'' -- a Check Book Balancer for X, $version"
    label .aboutwin.frame.a.l5 -text "Copyright (C) 1994 - 1996  Curtis L. Olson"
    label .aboutwin.frame.a.l6 -text "curt@sledge.mn.org"
    label .aboutwin.frame.a.l7 -text "http://www.me.umn.edu/home/clolson/main.html"
    button .aboutwin.frame.d.dismiss -text Dismiss -command "destroy .aboutwin" \
	    -font $button_font

    pack .aboutwin.frame -side top -fill both -expand 1
    pack .aboutwin.frame.a .aboutwin.frame.d -side top -fill both -expand 1
    pack .aboutwin.frame.a.but -padx 8 -pady 8 -side left -fill both -expand 1
    pack .aboutwin.frame.a.l1 .aboutwin.frame.a.l2 .aboutwin.frame.a.l3 \
	    .aboutwin.frame.a.l4 .aboutwin.frame.a.l5 \
	    .aboutwin.frame.a.l6 .aboutwin.frame.a.l7 \
    	    -ipadx 4m -side top -fill both -expand 1
    pack .aboutwin.frame.d.dismiss -side bottom -fill x -padx 8 -pady 4
}


proc display_src {} {
    global csh_src lib_path msg_text_font button_font

    option add *font $msg_text_font
    
    toplevel .srcwin

    wm title .srcwin "View Source :-)"
    wm iconname .srcwin "View Source"
    frame .srcwin.frame -borderwidth 2 -relief raised
    frame .srcwin.frame.l -borderwidth 2
    frame .srcwin.frame.d -borderwidth 2
    pack .srcwin.frame .srcwin.frame.l .srcwin.frame.d -side top \
	-fill both -expand 1

    listbox .srcwin.frame.l.list -width 35 -height 15 -relief sunken \
	-yscrollcommand ".srcwin.frame.l.scroll set"

    pack .srcwin.frame.l.list -side left -fill both -expand 1

    scrollbar .srcwin.frame.l.scroll -command ".srcwin.frame.l.list yview" \
	-relief flat
    pack .srcwin.frame.l.scroll -side left -fill y -expand 1

    button .srcwin.frame.d.dismiss -text "Dismiss" \
	    -font $button_font -command { destroy .srcwin }
    pack .srcwin.frame.d.dismiss -side top -fill x -expand 1 -padx 8 -pady 4
    set f [open $lib_path/$csh_src r]

    while { [gets $f line] >= 0 } {
	.srcwin.frame.l.list insert end $line
    }
}


#------------------------------------------------------------------------------
# Setup headers
#------------------------------------------------------------------------------

setup_headers


#------------------------------------------------------------------------------
# Setup the transaction listbox and scrollbar
#------------------------------------------------------------------------------

setup_listbox 


#------------------------------------------------------------------------------
# Setup the entry area
#------------------------------------------------------------------------------

setup_entry_area

# setup auto hiliting of entry fields if desired
if { $auto_hilite } {
    setup_auto_hilite
}


#------------------------------------------------------------------------------
# Setup the command bar
#------------------------------------------------------------------------------

setup_command_bar


#------------------------------------------------------------------------------
# Setup the status line
#------------------------------------------------------------------------------

setup_status_line


#------------------------------------------------------------------------------
# Procedures for category split processing
#------------------------------------------------------------------------------

proc open_splits {} {
    global desc cat credit debit max_splits cats coms amts fixed_font
    global fixed_header_font dialog_font button_font debug

    option add *font $dialog_font

    toplevel .splits

    wm title .splits "Category Splits"
    wm iconname .splits "Category Splits"

    frame .splits.frame -borderwidth 2 -relief raised
    pack .splits.frame -side top -fill both -expand 1

    if { $debit > 0 } {
        label .splits.frame.head \
		-text "[string range $desc 0 30] =:= \
		       [format "%.2f" [expr -1 * $debit]]"
    } else {
        label .splits.frame.head \
		-text "[string range $desc 0 30] =:= [format "%.2f" $credit]"
    }
    pack .splits.frame.head -anchor w -fill x -expand 1

    if { $debug } { puts $cat }

    set pieces [split $cat |]

    option add *font $fixed_header_font
    frame .splits.frame.label
    label .splits.frame.label.cat -text "  Category     "
    label .splits.frame.label.com -text "   Comment     "
    label .splits.frame.label.amt -text " Amount  "
    pack .splits.frame.label -side top
    pack .splits.frame.label.cat .splits.frame.label.com \
	     .splits.frame.label.amt -side left

    option add *font $fixed_font

    set i 0
    while { $i < $max_splits } {
	# setup widgets
	frame .splits.frame.line$i

	entry .splits.frame.line$i.cat$i -relief sunken -width 15 \
		-textvariable cats($i)

	bind .splits.frame.line$i.cat$i <FocusOut> {
	    leaving_cat %W
	}

	entry .splits.frame.line$i.com$i -relief sunken -width 15 \
		-textvariable coms($i)

	entry .splits.frame.line$i.amt$i -relief sunken -width 9 \
		-textvariable amts($i)

	bind .splits.frame.line$i.amt$i <FocusOut> {
	    leaving_amt %W
	}

	set cats($i) [lindex $pieces [expr 1 + $i * 3]]
	set coms($i) [lindex $pieces [expr 2 + $i * 3]]
	set amts($i) [lindex $pieces [expr 3 + $i * 3]]
	pack .splits.frame.line$i -side top
	pack .splits.frame.line$i.cat$i .splits.frame.line$i.com$i \
	     .splits.frame.line$i.amt$i -side left

	incr i
    }

    label .splits.frame.total -borderwidth 2 \
    	    -text "Sum = [sum_splits]" -font $dialog_font
    pack .splits.frame.total -side top -fill x -expand 1

    button .splits.frame.dismiss -text " Dismiss " -font $button_font \
	    -takefocus 0 -command {
	set i 0
	set cat |
	while { $i < $max_splits } {
	    if { "$amts($i)" != "" } {
		append cat $cats($i) | $coms($i) | [format "%.2f" $amts($i)] |
	    }
	    incr i
	}
	destroy .splits
    }
    pack .splits.frame.dismiss -fill x -expand 1 -padx 8 -pady 8

    focus .splits.frame.line0.cat0
    update
}

proc leaving_cat { field } {
    global eng cats add_cat debug

    # just left a split category field

    set pos [string last cat $field]
    set cur_split [string range $field [expr $pos + 3] end]

    if { $debug } { puts "$cats($cur_split)" }

    puts $eng "find_cat $cats($cur_split)"; flush $eng
    gets $eng result
    if { "$result" != "none" } {
	set cats($cur_split) $result
    } elseif { "$cats($cur_split)" == "" } {
	# do nothing ... empty category
    } else {
	set add_cat $cats($cur_split)
	add_new_cat
	tkwait window .newcat
    }
    if { $debug } { puts "Leaving $cur_split --> $cats($cur_split)" }
}

proc leaving_amt { field } {
    global debug
    # just left an amt field

    set text "Sum = [sum_splits]"
    .splits.frame.total configure -text $text
    if { $debug } { puts "Leaving amount field" }
}

proc sum_splits {} {
    global debit credit max_splits amts debug

    # set total [expr -1 * ($debit + $credit)]
    set total 0
    set i 0
    while { $i < $max_splits } {
        set amount $amts($i)
	if { "$amount" != "" } {
	    if { $debug } { puts "$i $amount" }
	    set total [expr $total + $amount]
	}
        incr i
    }

    return [format "%.2f" $total]
}


#------------------------------------------------------------------------------
# Procedures for balancing
#------------------------------------------------------------------------------

proc balance {} {
    global key eng date nicedate year month day check desc debit credit cat
    global nicecat com cleared total state_start state_end debits credits diff
    global dialog_font fixed_font button_font clean

    set debits 0.00
    set credits 0.00
    set diff [calc_diff]

    toplevel .bal
    
    option add *font $dialog_font

    wm title .bal "Balance ..."
    wm iconname .bal "Balance ..."
    frame .bal.frame -borderwidth 2 -relief raised
    frame .bal.frame.head1 -relief raised
    frame .bal.frame.head2 -relief raised
    frame .bal.frame.head3 -relief raised
    frame .bal.frame.f -relief raised
    frame .bal.frame.bar -relief sunken

    label .bal.frame.head1.label -text "Statement Starting Balance = "
    entry .bal.frame.head1.entry -textvariable state_start -relief sunken
    label .bal.frame.head2.label -text "Statement Ending Balance = "
    entry .bal.frame.head2.entry -textvariable state_end -relief sunken
    label .bal.frame.head3.label \
    	    -text "Debits = $debits  Credits = $credits  Difference = $diff"

    listbox .bal.frame.f.list -width 47 -height 15 -relief sunken \
	-exportselection false -takefocus 0 \
	-yscrollcommand ".bal.frame.f.scroll set" -font $fixed_font 

    scrollbar .bal.frame.f.scroll -takefocus 0 -relief flat \
	    -command { .bal.frame.f.list yview }
	

    button .bal.frame.bar.update -text "Update" -font $button_font \
	    -takefocus 0 \
	    -command {
	update_selected .bal.frame.f.list
	destroy .bal
    }

    button .bal.frame.bar.dismiss -text "Dismiss" -font $button_font \
	-takefocus 0 -command "destroy .bal"

    pack .bal.frame -side top -fill both -expand 1
    pack .bal.frame.head1 -side top -fill both -expand 1
    pack .bal.frame.head2 -side top -fill both -expand 1
    pack .bal.frame.head3 -side top -fill both -expand 1
    pack .bal.frame.f -side top -fill both -expand 1
    pack .bal.frame.bar -side top -fill both -expand 1

    pack .bal.frame.head1.label .bal.frame.head1.entry -side left -anchor w
    pack .bal.frame.head2.label .bal.frame.head2.entry -side left -anchor w
    pack .bal.frame.head3.label -side top -anchor w
    pack .bal.frame.f.list -side left -fill both -expand 1
    pack .bal.frame.f.scroll -side left -fill y -expand 1
    pack .bal.frame.bar.update .bal.frame.bar.dismiss -side left \
	-fill x -expand 1 -padx 8 -pady 8

    # get the statement starting balance
    puts $eng "get_cleared_bal"; flush $eng
    gets $eng state_start

    # load the list
    puts $eng "first_uncleared_trans"; flush $eng
    gets $eng result
    while { $result != "none" } {
        update_globals $result

	if { $debit > 0 } {
	    set amt [expr -1.0 * $debit]
	} else {
	    set amt $credit
	}
	set cutdesc [string range $desc 0 14]

        puts $eng "get_current_index"; flush $eng
        gets $eng index
	
        .bal.frame.f.list insert end [format "%1s %5s %8s %-15s %12.2f   %-9s %5s"\
        	$cleared $check $nicedate $cutdesc $amt $key $index]

        if { "$cleared" == "*" } {
	    if { $debit > 0 } {
	        set debits [expr $debits + $debit]
	    } else {
	        set credits [expr $credits + $credit]
	    }
        }

        puts $eng "next_uncleared_trans"; flush $eng
        gets $eng result
    }

    # avoid something like 6.5999999999999
    set debits [format "%.2f" $debits]
    set credits [format "%.2f" $credits]

    bind .bal.frame.head1.entry <FocusOut> { \
        set diff [calc_diff]; \
        .bal.frame.head3.label configure \
    	     -text "Debits = $debits  Credits = $credits  Difference = $diff"; \
    }

    bind .bal.frame.head2.entry <FocusOut> { \
        set diff [calc_diff]; \
        .bal.frame.head3.label configure \
    	     -text "Debits = $debits  Credits = $credits  Difference = $diff"; \
    }

    bind .bal.frame.f.list <Double-Button> { \
	set clean 0; \
        update_bal_list .bal.frame.f.list [.bal.frame.f.list curselection]; \
        set diff [calc_diff]; \
        .bal.frame.head3.label configure \
    	     -text "Debits = $debits  Credits = $credits  Difference = $diff" \
    }
    focus .bal.frame.head1.entry
}

proc calc_diff {} {
    global state_end state_start debits credits

    set value [expr $state_start - $state_end - $debits + $credits]
    return [format "%.2f" $value]
}

proc update_bal_list args {
    global eng debits credits diff debug

    set arglist [split $args]
    set list [lindex $arglist 0]
    set sel [lindex $arglist 1]

    if { $debug } { puts "$list $sel" }

    set line [$list get $sel]
    set key [string range $line 48 58]
    set index [expr [string range $line 60 64] * 2]
    set tail [string range $line 2 end]
    set amt [string range $line 34 45]
    if { $debug } { puts "amt = $amt" }

    $list delete $sel
    if { "[string range $line 0 0]" != "*" } {
        $list insert $sel "* $tail"
        puts $eng "select_trans $key"; flush $eng
        gets $eng result

        if { [expr $amt < 0 ] } {
            set debits [expr $debits - $amt]
        } else {
            set credits [expr $credits + $amt]
        }
    } else {
        $list insert $sel "  $tail"
        puts $eng "unselect_trans $key"; flush $eng
        gets $eng result

        if { [expr $amt < 0] } {
            set debits [expr $debits + $amt]
        } else {
            set credits [expr $credits - $amt]
        }
    }

    # avoid something like 6.5999999999999
    set debits [format "%.2f" $debits]
    set credits [format "%.2f" $credits]

    update_line $index $key

    if { $debug } { puts $line; puts $key; puts $index }
}


proc update_selected list {
    global eng list_height clean

    .status.line configure -text "Updating all cleared transactions."
    update

    set clean 0

    puts $eng "clear_trans"; flush $eng
    gets $eng result

    update_rest 0 00000000-00

    goto [.trans.list size]
}


#------------------------------------------------------------------------------
# Miscellaneous functions
#------------------------------------------------------------------------------

proc goto line {
    global debug

    if { $debug } { puts "Size = [.trans.list size]  Goto = $line" }

    if { [expr $line / 2.0] != [expr $line / 2] } {
        set line [expr $line - 1]
    }

    .trans.list see $line
    .trans.list see [expr $line + 1]
    .trans.list selection clear 0 end
    .trans.list selection set $line $line
}


# write out current ~/.cbbrc.tcl file
proc save_cbbrc {} {
    global cur_file use_mems date_fmt save_interval msg_text_font button_font
    global fixed_header_font fixed_font status_line_font menu_font dialog_font
    global default_font list_height list_width max_splits auto_hilite debug
    global version

    set datehandle [open |date r+]
    gets $datehandle now_today
    close $datehandle

    set rchandle [open "~/.cbbrc.tcl" w]
    puts $rchandle "# ~/.cbbrc.tcl file created by CBB $version on $now_today"
    puts $rchandle "# This is tcl code ... can't you tell!!!"
    puts $rchandle "# "
    puts $rchandle "# This is a machine generated file.  Please use caution"
    puts $rchandle "# when hand editing!"
    puts $rchandle ""
    puts $rchandle "# File to load when CBB initially starts."
    puts $rchandle "set cur_file $cur_file"
    puts $rchandle ""
    puts $rchandle "# Use Memorized Transactions?"
    puts $rchandle "set use_mems $use_mems"
    puts $rchandle ""
    puts $rchandle "# Date Format 1=USA 2=International"
    puts $rchandle "set date_fmt $date_fmt"
    puts $rchandle ""
    puts $rchandle "# Auto Save Interval"
    puts $rchandle "set save_interval $save_interval"
    puts $rchandle ""
    puts $rchandle "# Main List Box Dimensions"
    puts $rchandle "set list_width $list_width"
    puts $rchandle "set list_height $list_height"
    puts $rchandle ""
    puts $rchandle "# Maximum splits per entry"
    puts $rchandle "set max_splits $max_splits"
    puts $rchandle ""
    puts $rchandle "# Auto-highlight entry fields:  0 = disabled, 1 = enabled"  
    puts $rchandle "set auto_hilite $auto_hilite"
    puts $rchandle ""
    puts $rchandle "# Debugging:  0 = disabled, 1 = enabled"  
    puts $rchandle "set debug $debug"
    puts $rchandle ""
    puts $rchandle "# Fonts ..."
    puts $rchandle "set msg_text_font \"$msg_text_font\""
    puts $rchandle "set button_font \"$button_font\""
    puts $rchandle "set fixed_header_font \"$fixed_header_font\""
    puts $rchandle "set fixed_font \"$fixed_font\""
    puts $rchandle "set status_line_font \"$status_line_font\""
    puts $rchandle "set menu_font \"$menu_font\""
    puts $rchandle "set dialog_font \"$dialog_font\""
    puts $rchandle "set default_font \"$default_font\""
    close $rchandle
}


# save the current file at regular intervals in case the computer crashes
# or something
proc setup_auto_save {} {
    global eng cur_file clean save_interval

    after $save_interval {
        if { "[file extension $cur_file]" == ".cbb" } {
	    if { $clean != 1 } {
		set auto_save_file \
			"[file dirname $cur_file]/#[file tail $cur_file]#"
		.status.line configure -text \
			 "Auto saving to [file tail $auto_save_file]"
		update
	        if { $debug } {
		    puts "Auto saving to [file tail $auto_save_file]"
		}

                # tell engine to save transactions
                puts $eng "auto_save_trans $auto_save_file"
		flush $eng
	    }
	}

	# reset auto save
	setup_auto_save
    }
}


#------------------------------------------------------------------------------
# Load a data file if one is specified on command line or in the ~/.cbbrc.tcl
#------------------------------------------------------------------------------

if { [expr $argc == 1] } {
    # if file specified on command line

    set cur_file $argv
    load_file $cur_file
    cd [file dirname $cur_file]
} elseif { "$cur_file" != "noname.cbb" } {
    # if ~/.cbbrc.tcl file overwrote the default cur_file

    load_file $cur_file
    cd [file dirname $cur_file]
} elseif { [expr $argc > 1] } {
    puts "Usage: [file tail $argv0] \[ file_name \]"
}

# make sure we have a backup file being saved ... automatically
setup_auto_save

# initialize main window bindings
setup_default_binding

# initialize undo
init_undo

# Remind user to remove ~/.cbbrc if it still exists.
if { [file exists "~/.cbbrc"] } {
    ok_mesg "You can remove your ``.cbbrc'' file because it is obsolete.  \
	     It has been replaced with a ``.cbbrc.tcl'' file."
    tkwait window .ok
}

# If the user doesn't have a ~/.cbbrc.tcl file, create one for him.
if { [file exists "~/.cbbrc.tcl"] } {
} else {
    save_cbbrc
}

#------------------------------------------------------------------------------
# This should remain the last thing in the script ... it leaves a welcome
# message at the bottom of the window
#------------------------------------------------------------------------------

.status.line configure -text "Welcome to the Check Book Balancer."
update


# ----------------------------------------------------------------------------
# $Log: cbb,v $
# Revision 1.58  1996/02/11  20:30:15  curt
# Removed support for dbm files.
#
# Revision 1.57  1996/02/11  05:58:51  curt
# Modified Files: cbb file.tk menu.tk
#   Added filebox.tk ... a file select module from tkispell.  Did some more
#   interface/tk4.0 tweaking.
#
# Revision 1.56  1996/02/11  03:38:29  curt
# Modified Files:  cbb bindings.tk categories.tk file.tk main.tk menu.tk
#   Made quite a few changes all through the tk code to better support and
#   utilize the tk4.0 features.  These changes make tk3.6 support impossible,
#   but make the cbb code much simpler (and better.)
#
# Revision 1.55  1996/02/05  01:50:36  curt
# Modified "about" screen.
# Setup entry field auto highlight feature when tabbing to a field.
#
# Revision 1.54  1996/01/21  01:12:00  curt
# Modified Files: cbb bindings.tk categories.tk common.tk file.tk main.tk menu.tk
#   Updated copyright.
#   Added a debugging output (on/off) switch.
#   Removed tk3.6 support
#   Added some tweaks to better utilize tk4.0 features.
#
# Revision 1.53  1996/01/12  13:36:16  curt
# Modified Files:  bindings.tk categories.tk cbb file.tk main.tk menu.tk
#   Removed support for tk3.6 -- Note: dual support for 3.6 & 4.0 was starting
#   to get to unwieldy ... or even becoming impossible.  If you only have 3.6
#   available, please stay with cbb-0.61 or earlier.
#
# Revision 1.52  1996/01/12  13:23:17  curt
# Misc changes
#
# Revision 1.51  1995/08/09  03:22:49  curt
# One tiny tweak of listbox view stuff
#
# Revision 1.50  1995/08/09  02:51:50  curt
# tk4.0 handles listbox yview differently.  Made changes to take advantage
# of listbox "see" command.
#
# Revision 1.49  1995/08/03  22:55:57  curt
# Added support for tk4.0
#
# Revision 1.48  1995/07/20  11:18:49  curt
# Spelling fixes ...
#
# Revision 1.47  1995/07/20  02:52:51  curt
# Split out code to bindings.tk and common.tk
# Updates to handle split comment.
#
# Revision 1.46  1995/07/09  03:22:48  curt
# Updated some of the visuals ...
#
# Revision 1.45  1995/07/08  01:48:22  curt
# Added button padding and changed visuals slightly.
#
# Revision 1.44  1995/07/05  01:13:48  curt
# set lib path to current startup directory if program hasn't been installed.
#
# Revision 1.43  1995/07/04  23:03:24  curt
# Tweaked the organization a bit.
#
# Revision 1.42  1995/06/07  04:08:26  curt
# Modified Files:  FAQ cbb
#   Replace the old obsolete ~/.cbbrc file with a cool ~/.cbbrc.tcl file!
#
# Revision 1.41  1995/06/07  03:32:59  curt
# Modified Files:  Makefile cbb cbb-man.tex install.pl
# Added Files:  main.tk
#   Moved most of the main window related routines to main.tk
#
# Revision 1.40  1995/06/07  02:46:06  curt
# Modified Files:  Todo categories.tk cbb file.tk reports.tk
#   Redo font handling.  Default fonts can now be overridden in ~/.cbbrc file
#
# Revision 1.39  1995/06/06  01:34:47  curt
# Modified Files:  categories.tk cbb engine.pl file.tk
#   Added a Yes/No/Cancel dialog box, and used it in places
#   Delete temporary autosave file after user requests a real save.
#
# Revision 1.38  1995/06/05  11:41:38  curt
# Modified Files:  Todo cbb engine.pl file.tk log.pl wrapper.pl
#   Fixed transfers between files.
#   Reworked transaction logging.
#   Added an auto-save feature.
#   Reworked .cbbrc saving and loading
#   Use '.dir' now instead of '.pag'
#
# Revision 1.37  1995/06/04  13:33:55  curt
# Added support for dual file formats (text and dbm).
# Added a yes/no message procedure.
#
# Revision 1.35  1995/04/24  01:57:09  curt
# Split of menu setup functions into a separate file:  menu.tk
# Started rearranging structure to support multiple file formats.
#
# Revision 1.34  1995/04/12  12:41:29  curt
# Moved file manipulation routines from cbb to file.tk
#
# Revision 1.33  1995/02/23  05:13:12  curt
# Removed dependencies on tclX (wishx).
#
# Revision 1.32  1995/01/23  03:15:04  curt
# Fixed another 19.99999999999998 bug.
#
# Revision 1.31  1995/01/07  01:50:47  curt
# Figured out why report balance didn't match actual balance ... included
# warning now when printing mis-entered splits.
#
# Changed splits Difference -> Sum.
#
# Revision 1.30  1994/12/20  02:44:17  curt
# Added a "by category summary report"
#
# Revision 1.29  1994/12/01  12:47:49  clolson
# Added an icon bitmap
#
# Revision 1.28  1994/11/29  04:24:14  curt
# squished a precision problem [bug]
#
# Revision 1.27  1994/11/28  19:46:00  clolson
# Additional work on reporting
#
# Revision 1.26  1994/11/14  04:16:41  curt
# Eliminating 0.32999999999999901 problems.
#
# Revision 1.25  1994/11/09  21:59:22  clolson
# worked on category editing
#
# Revision 1.24  1994/11/07  23:14:14  clolson
# Working on interactive category viewing/editing
#
# Revision 1.23  1994/11/07  19:13:52  clolson
# Fixed balance bug.
# Added hypertext online help.
#
# Revision 1.22  1994/11/06  14:23:49  curt
# Fixed precision bug!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#
# Revision 1.21  1994/11/04  19:39:02  clolson
# Warning when deleting a transfer transaction.
#
# Revision 1.20  1994/11/04  19:32:53  clolson
# Added Transfers between Accounts.
#
# Revision 1.19  1994/11/04  13:51:16  clolson
# Changed from 2-digit dates to 4-digit dates.
# Look out!  Hopefully nothing broke!
#
# Revision 1.18  1994/11/02  12:57:17  curt
# Calculate the statement starting balance for the Balance operation.
#
# Revision 1.17  1994/11/01  22:41:50  clolson
# Cleaned up import code somewhat
#
# Revision 1.16  1994/10/31  23:14:43  clolson
# Started tracking towards cbbsh (the text only version).  Chris Browne has
# some good ideas, so I am trying to incorporate them, and make my stuff
# compatible with his.
#
# Revision 1.15  1994/10/31  16:04:53  curt
# Beginning some massive changes to start tracking towards cbbsh.
#
# Revision 1.14  1994/10/20  14:06:55  clolson
# Added some double quotes around things in messages.
#
# Revision 1.13  1994/10/19  13:27:23  curt
# Added export .qif files.
#
# Revision 1.12  1994/10/18  15:31:54  clolson
# $w in about window -> .aboutwin
#
# Revision 1.11  1994/10/18  12:20:39  curt
# Stubbed in a transfer button ...
#
# Revision 1.10  1994/10/17  13:24:27  curt
# Make category completion work when tabbing from category.
# Change window naming scheme.
#
# Revision 1.9  1994/10/14  19:07:48  clolson
# Added my wife's and my's picture to the about window!
#
# Revision 1.8  1994/10/14  17:05:12  clolson
# Miscellaneous cleanups in preparation for releasing version 0.40a
#
# Revision 1.7  1994/10/14  03:02:13  curt
# changes with regard to Version
#
# Revision 1.6  1994/10/13  23:57:12  curt
# Finished memorized transactions.
#
# Revision 1.5  1994/10/13  21:16:53  clolson
# Unknown categories can be added in splits window now.
# Started memorized transactions.
#
# Revision 1.4  1994/10/13  15:55:45  curt
# Added unknown category handling.
#
# Revision 1.3  1994/10/12  12:39:40  curt
# Fixed a couple of bindings glitches.
#
# Revision 1.2  1994/10/11  21:22:04  clolson
# Beat key binding into submission.
#
# Revision 1.1  1994/10/11  15:04:59  curt
# Official name is now cbb (for now)
#
# Revision 1.27  1994/10/11  13:07:08  curt
# More tweaking of key bindings.
#
# Revision 1.26  1994/10/11  12:57:39  curt
# Working on key bindings.
#
# Revision 1.25  1994/10/10  21:23:09  clolson
# Added left/right arrow key bindings to entry fields.
#
# Revision 1.24  1994/10/10  15:20:49  clolson
# Added some error checking to improve robustness ...
#
# Revision 1.23  1994/10/04  15:40:31  curt
# Categories saved when data is saved.
#
# Revision 1.22  1994/10/03  03:25:35  curt
# Add a path variable for the default.cat file.
#
# Revision 1.21  1994/10/03  01:54:03  curt
# *.dat changed to *.cbb
# Splits window wording --> total changed to difference
#
# Revision 1.20  1994/10/02  03:25:45  curt
# First stab at an undo ... functional at least.
#
# Revision 1.18  1994/09/30  19:49:29  clolson
# Working on split category completion.
#
# Revision 1.17  1994/09/30  17:54:24  clolson
# category tweaking ... exploring options for getting split category completion
# to work.
#
# Revision 1.16  1994/09/30  12:13:45  curt
# Now category is checked against the category list ... type the first few
# letters, the rest is filled in.
#
# Revision 1.15  1994/09/28  13:44:24  curt
# Restructured things so that data files look like file.dat, file.bat, file.cat
# Loading and saving are done by basename, i.e. file, data files from previous
# versions will have to be renamed to something.dat
#
# Also fixed a small bug where default tab bindings weren't being set at
# startup.
#
# Revision 1.14  1994/09/25  03:47:13  curt
# Spiffed up file operation windows (load/save as/import) ... added a cancel
#   button, generally improved operation.
# Added field tabbing to the balance window and splits window.
#
# Revision 1.13  1994/09/25  02:56:43  curt
# - Save-as function added.
# - If no file specified, defaults to noname.cbb
# - Check for "clean" before allowing an open or import.
# - <Return> in file dialog box (entry area) performs corresponding load/save/
#   import of specified file.
#
# Revision 1.11  1994/09/21  12:21:03  curt
# Added a command line option to specify data file to load.
# Added current file name to window title.
# Hooked the delete button to the right function.
#
# Revision 1.10  1994/09/20  14:12:41  clolson
# Subjected code to gnu public license :)
#
# Revision 1.9  1994/09/19  02:45:19  curt
# Menu bar cosmetic change
#
# Revision 1.8  1994/09/14  23:31:02  curt
# Added statement starting balance entry field
# Fixed balance window so, previously checked debits/credit are added in
# when list is loaded (in case we are restarting the balance procedure)
# Previously debit/credit were only updated when their line was double-clicked.
#
# Revision 1.7  1994/09/14  13:22:49  curt
# Worked on balance section -- keeping track of debits, credits, and difference
# as transactions are being checked off.
#
# Revision 1.6  1994/09/14  03:48:06  clolson
# delete_trans(), worked on balance section
#
# Revision 1.5  1994/09/12  15:21:20  curt
# Worked on balancing section.
# Miscellaneous tweaks.
#
# Revision 1.4  1994/09/09  20:26:10  clolson
# Open splits is now functional, although not polished.
#
# Revision 1.3  1994/09/08  21:51:35  clolson
# Global key bindings to menu options.
#
# Revision 1.2  1994/09/08  05:09:10  curt
# Worked on splits ...
#
# Revision 1.1  1994/09/08  03:59:03  curt
# Changed name of front.tk --> cbb
#
# Revision 1.16  1994/09/07  23:10:19  clolson
# Added a command bar, status line, and import file chooser.
# Also added initial support for a ~/.cbbrc file
#
# Revision 1.15  1994/09/07  12:51:37  curt
# clean flag, ok message, fiddle with open window
#
# Revision 1.14  1994/09/06  22:38:41  clolson
# Worked on File-->Open stuff.
#
# Revision 1.13  1994/09/06  04:37:32  curt
# File-New, File-Open, & misc tweaks
#
# Revision 1.12  1994/09/03  02:47:01  clolson
# Working on updating entries
#
# Revision 1.11  1994/09/02  03:52:03  curt
# Many changes/additions for editing transactions.
#
# Revision 1.10  1994/09/01  20:37:33  clolson
# Added a goto menu under Functions
# Added a goto command
# Gave listbox flexible dimensions
# Put cleared field at the end of tabbing order
# Added $key to listbox entries for dereferencing back to original data file
# Started work on update entry area procedure.
#
# Revision 1.9  1994/09/01  19:08:06  clolson
# Worked on key bindings for check# and date fields (+/-)
#
# Revision 1.8  1994/09/01  15:17:41  clolson
# Started work on tabbing from field to field in entry area.
#
# Revision 1.7  1994/08/30  01:53:42  clolson
# Worked on entry area.
#
# Revision 1.6  1994/08/29  03:53:38  curt
# Added header to listbox (needs tweaking)
# Category now says -Splits- if there are splits.
#
# Revision 1.5  1994/08/29  00:17:13  curt
# Worked on transaction listing format.
#
# Revision 1.4  1994/08/26  21:49:15  clolson
# More work on interface ... added list box with attached scroll bar
# Working on reading in transactions.
#
# Revision 1.3  1994/08/26  13:18:54  curt
# Experimenting with interface ...
#
# Revision 1.2  1994/08/25  20:46:43  clolson
# Appearance twiddling.
#
# Revision 1.1  1994/08/25  18:46:58  clolson
# Started stubbing in user interface.
#
