#!/usr/bin/perl # Placed in public domain by Eric Anderson use strict; use warnings; # Allow us to access the help info and the glade interface # from this same script if needed. use Inline::Files; # Glade file location use constant glade_location => '/home/eman/Development/personal/Bill_Manager/bill-manager.glade'; # Data storage locations use constant storage => $ENV{HOME} . '/.bill-manager/'; use constant bills => storage . 'bills.dbm'; use constant companies => storage . 'companies.dbm'; # Config key locations use constant app_file => '/bill-manager/'; use constant bill_key => app_file . 'database/bill-id'; use constant warn_key => app_file . 'general/warn-days'; use constant color_section => app_file . 'colors/'; #################################### # A Bill object. # # Handles the data layer for Bills # #################################### package Bill; use Persistent::DBM; use vars qw ( @ISA ); @ISA = qw( Persistent::DBM ); # Tell the data layer the fields for a Bill object sub initialize { my $self = shift; $self->SUPER::initialize(@_); $self->add_attribute( 'billid', 'i', 'number', undef, 10 ); $self->add_attribute( 'company', 'p', 'varchar', undef, 50 ); $self->add_attribute( 'amount', 'p', 'number', undef, 5, 2 ); $self->add_attribute( 'received', 'p', 'datetime', undef ); $self->add_attribute( 'due', 'p', 'datetime', undef ); } 1; ######################################## # A Company Object. # # Handles the data layer for Companies # ######################################## package Company; use Persistent::DBM; use vars qw( @ISA ); @ISA = qw( Persistent::DBM ); # Tell the data layer the fields for a Company object sub initialize { my $self = shift; $self->SUPER::initialize(@_); $self->add_attribute( 'company', 'i', 'varchar', undef, 50 ); } 1; ############################## # Start of Application Logic # ############################## package main; use Time::Local; use File::stat; use Gtk; use Gtk::GladeXML; use Gtk::XmHTML; use Gnome; use vars qw( $VERSION ); $VERSION = 0.99; init Gnome "Bill Manager", $VERSION; # Make sure we have a place to save the data unless( -e storage ) { system( 'mkdir ' . storage ); } # Init the GUI my $gui = new_from_memory Gtk::GladeXML( get_glade( glade_location ) ); $gui->signal_autoconnect_from_package('main'); # Tweak the interface $gui->get_widget( 'bill_list' )->set_column_visibility( 0, 0 ); $gui->get_widget( 'bill_list' )->set_sort_column( 2 ); $gui->get_widget( 'bill_list' )->set_compare_func( \&compare_dates ); $gui->get_widget( 'preferences' )->set_title( 'Preferences' ); init_preferences(); # Load the inital bills into the interface load_bills(); # Global to indicate what bill is selected my $selected_bill; # Enter the event loop main Gtk; ########################## # General Interface code # ########################## # About box sub show_about { $gui->get_widget('about')->show(); } sub hide_about { $gui->get_widget('about')->hide(); return 1; } sub show_help { my $window = new Gnome::Dialog 'Bill Manager Help'; $window->set_parent( $gui->get_widget('bill_window') ); $window->append_buttons( 'OK' ); $window->set_close( 1 ); $window->set_usize( 600, 400 ); $window->set_position( 1 ); # Center my $html = new Gtk::XmHTML; $window->vbox()->add($html); open( HELP ); undef $/; $html->source( ); $/ = "\n"; close( HELP ); $window->show_all(); } # Exit the program sub exit_bill_manager { exit(0); } ##################################### # Interface code dealing with Bills # ##################################### # Reads the bills and sticks them in the interface sub load_bills { my $bill_list = $gui->get_widget( 'bill_list' ); $bill_list->clear(); my $total = 0; eval { my $bill = new Bill( bills, undef ); $bill->restore_all(); my $i = 0; while( $bill->restore_next() ) { my $due_date = new Persistent::DataType::DateTime( $bill->due()); $bill_list->append( $bill->billid(), $bill->company(), $due_date->month() . '/' . $due_date->day() . '/' . $due_date->year(), format_currency($bill->amount()) ); $total += $bill->amount(); $bill_list->set_foreground($i, get_color($bill->due())); $i++; } }; if( $@ ) { display_error( "An error occured when loading the bills: $@" ); } $bill_list->sort(); $gui->get_widget('status')->set_status('Total Due: ' . format_currency($total)); } sub get_color { my $due = shift; my $type = 'normal'; my $warn_days = Gnome::Config->get_int( warn_key ) *24*60*60; my $today = new Persistent::DataType::DateTime(localtime); $today = timelocal( 0, 0, 0, $today->day(), $today->month()-1, $today->year() ); my $bill_due = new Persistent::DataType::DateTime($due); $bill_due = timelocal( 0, 0, 0, $bill_due->day(), $bill_due->month()-1, $bill_due->year() ); if( $bill_due > ($today + $warn_days) ) { $type = 'normal'; } elsif ( $bill_due > $today ) { $type = 'warn'; } elsif ( $bill_due == $today ) { $type = 'due'; } else { $type = 'late'; } my $hex = 'RGB:'; $hex .= sprintf( "%02x", Gnome::Config->get_int( color_section . $type . '-red' ) ); $hex .= '/'; $hex .= sprintf( "%02x", Gnome::Config->get_int( color_section . $type . '-green' ) ); $hex .= '/'; $hex .= sprintf( "%02x", Gnome::Config->get_int( color_section . $type . '-blue' ) ); my $color = Gtk::Gdk::Color->parse_color( $hex ); unless( defined $color ) { display_error( 'Color not allocated' ); } return $color; } # Dialog for new bill sub new_bill { $selected_bill = undef; my $bill_editor = $gui->get_widget('bill_dialog'); $bill_editor->set_title('Add new bill'); load_company_dropdown(); $bill_editor->show(); } # Dialog for edit bill sub edit_bill { unless( defined( $selected_bill ) ) { display_error( 'Please select a bill you wish to edit' ); return; } my $bill_editor = $gui->get_widget('bill_dialog'); $bill_editor->set_title('Edit bill'); load_company_dropdown(); my $bill = new Bill( bills, undef ); my $bill_list = $gui->get_widget( 'bill_list' ); $bill->restore( $selected_bill ); my $dropdown = $gui->get_widget( 'company' ); my $amount = $gui->get_widget( 'amount' ); my $received = $gui->get_widget( 'received' ); my $due = $gui->get_widget( 'due' ); set_dropdown( $dropdown, $bill->company() ); $amount->set_text( format_currency( $bill->amount() ) ); $received->set_time( time_local( $bill->received() ) ); $due->set_time( time_local( $bill->due() ) ); $bill_editor->show(); } # Canceling the editing of a bill sub cancel_bill_edit { my $bill_edit = $gui->get_widget( 'bill_dialog' ); my $dropdown = $gui->get_widget( 'company' ); my $amount = $gui->get_widget( 'amount' ); my $received = $gui->get_widget( 'received' ); my $due = $gui->get_widget( 'due' ); # Reset by to origional state for next call $dropdown->set_history( 0 ); $amount->set_text( '' ); $received->set_time( time() ); $due->set_time( time() ); my ( $selection ) = $gui->get_widget('bill_list')->selection(); if( $selection ) { $gui->get_widget('bill_list')->select_row($selection,0); $selected_bill = get_bill_id( $selection ); } $bill_edit->hide(); return 1; } sub save_bill { # Get and process values my $company = $gui->get_widget('company')->child()->get(); my $amount_value = $gui->get_widget('amount')->get_text(); $amount_value =~ s/,|\$//g; # Remove $ and commas my @receive_date = localtime($gui->get_widget('received')->get_date()); my @due_date = localtime($gui->get_widget('due')->get_date()); # Save bill object eval { my $bill = new Bill( bills, undef ); if( $selected_bill ) { $bill->restore( $selected_bill ); } else { $bill->billid( next_bill_id() ); $selected_bill = $bill->billid(); } $bill->company( $company ); $bill->amount( $amount_value ); $bill->received( @receive_date ); $bill->due( @due_date ); $bill->save(); }; if( $@ ) { display_error( 'Error saving bill: ' . $@ ); } # Reset gui to original state for next call $gui->get_widget('company')->set_history( 0 ); $gui->get_widget('amount')->set_text( '' ); $gui->get_widget('received')->set_time( time() ); $gui->get_widget('due')->set_time( time() ); load_bills(); $gui->get_widget('bill_list')->select_row(get_row( $selected_bill ),0); $gui->get_widget('bill_dialog')->hide(); } sub select_bill { my ($clist, $data, $row, $column, $event) = @_; $selected_bill = get_bill_id( $row ); if ( $event->{type} eq '2button_press' ) { edit_bill(); } } sub unselect_bill { $selected_bill = undef; } sub delete_bill { unless( defined( $selected_bill ) ) { display_error( 'Please select the bill you wish to delete' ); return; } my $bill_list = $gui->get_widget( 'bill_list' ); eval { my $old_bill = new Bill( bills, undef ); $old_bill->restore( $selected_bill ); $old_bill->delete(); }; if( $@ ) { display_error( 'Error deleting record: ' . $@ ); } my ( $selection ) = $bill_list->selection(); load_bills(); if( $selection ) { $bill_list->select_row( $selection, 0 ); $selected_bill = get_bill_id( $selection ); } else { $selected_bill = undef; } } sub get_bill_id { my $row = shift; return $gui->get_widget( 'bill_list' )->get_text( $row, 0 ); } sub get_row { my $id = shift; for my $i ( 0 .. $gui->get_widget( 'bill_list' )->rows() ) { if( $id eq $gui->get_widget( 'bill_list' )->get_text( $i, 0 )) { return $i; } } } sub format_amount { my $amount = $gui->get_widget( 'amount' ); my $new_amount = format_currency( $amount->get_text() ); $amount->set_text( $new_amount ); return 0; } ######################################## # Interface code relating to companies # ######################################## # Loads the company dropdown list sub load_company_dropdown { my $company_dropdown = $gui->get_widget('company'); $company_dropdown->remove_menu(); my $company_list = new Gtk::Menu; $company_list = fill_companies( $company_list, 'Gtk::MenuItem', 'append', 'new_with_label' ); $company_dropdown->set_menu( $company_list ); } # Shows company dialog sub manage_companies { my $mcw = $gui->get_widget( 'manage_company_window' ); load_company_list(); $mcw->show(); } # Init's the list of companies in the company dialog sub load_company_list { my $company_list = $gui->get_widget('company_list'); $company_list->clear_items( 0, -1 ); $company_list = fill_companies( $company_list, 'Gtk::ListItem', 'append_items', 'new' ); } # Lets the user add a new company sub new_company { my $company_window = $gui->get_widget( 'company_name_window' ); $company_window->show(); } # Processes the addition of a company sub add_company { my $company_name = $gui->get_widget( 'company_name' )->get_text(); eval { my $new_company = new Company( companies, undef ); $new_company->company( $company_name ); $new_company->save(); }; if( $@ ) { display_error( 'Error adding company: ' . $@ ); } $gui->get_widget('company_name')->set_text( '' ); my $company_window = $gui->get_widget( 'company_name_window' ); load_company_list(); $company_window->hide(); } # Cancels the addition of a company sub cancel_new_company { my $company_window = $gui->get_widget( 'company_name_window' ); my $company_name = $gui->get_widget( 'company_name' ); $company_window->hide(); $company_name->set_text( '' ); return 1; } # Removes a company sub delete_company { my $company_list = $gui->get_widget( 'company_list' ); my @selected_companies = $company_list->selection(); foreach my $delete_item ( @selected_companies ) { my $company = $delete_item->child()->get(); eval { my $old_company = new Company( companies, undef ); $old_company->restore( $company ); $old_company->delete() }; if( $@ ) { display_error( "Error deleting $company: $@" ); } } if( @selected_companies < 1 ) { display_error( 'Please select a company you wish to delete' ); } load_company_list(); } # Closes the company dialog sub close_company { my $mcw = $gui->get_widget( 'manage_company_window' ); load_company_dropdown(); $mcw->hide(); return 1; } # Output companies sub fill_companies { my $collection = shift; my $object_type = shift; my $append_function = shift; my $constructor = shift; eval { my $company = new Company( companies, undef ); $company->restore_all(); my @company_names; while( $company->restore_next() ) { push( @company_names, $company->company() ); } @company_names = sort( @company_names ); foreach my $company_name ( @company_names ) { my $item = $object_type->$constructor( $company_name ); $collection->$append_function( $item ); $item->show(); } }; if( $@ ) { display_error( "Error occured while loading companies: $@" ); } return $collection; } ########################### # Preference Related Code # ########################### sub init_preferences { unless( Gnome::Config->has_section( color_section ) ) { # Normal color Gnome::Config->set_int( color_section . 'normal-red', 0 ); Gnome::Config->set_int( color_section . 'normal-green', 0); Gnome::Config->set_int( color_section . 'normal-blue', 0); # Warn color Gnome::Config->set_int( color_section . 'warn-red', 205 ); Gnome::Config->set_int( color_section . 'warn-green', 205); Gnome::Config->set_int( color_section . 'warn-blue', 0); # Due color Gnome::Config->set_int( color_section . 'due-red', 255 ); Gnome::Config->set_int( color_section . 'due-green', 0); Gnome::Config->set_int( color_section . 'due-blue', 0); # Late color Gnome::Config->set_int( color_section . 'late-red', 255 ); Gnome::Config->set_int( color_section . 'late-green', 0); Gnome::Config->set_int( color_section . 'late-blue', 0); Gnome::Config->set_int( warn_key, 10 ); Gnome::Config->sync(); } $gui->get_widget('normal_color')->set_i8( Gnome::Config->get_int( color_section . 'normal-red' ), Gnome::Config->get_int( color_section . 'normal-green' ), Gnome::Config->get_int( color_section . 'normal-blue' ), 0 ); $gui->get_widget('warn_color')->set_i8( Gnome::Config->get_int( color_section . 'warn-red' ), Gnome::Config->get_int( color_section . 'warn-green' ), Gnome::Config->get_int( color_section . 'warn-blue' ), 0 ); $gui->get_widget('due_color')->set_i8( Gnome::Config->get_int( color_section . 'due-red' ), Gnome::Config->get_int( color_section . 'due-green' ), Gnome::Config->get_int( color_section . 'due-blue' ), 0 ); $gui->get_widget('late_color')->set_i8( Gnome::Config->get_int( color_section . 'late-red' ), Gnome::Config->get_int( color_section . 'late-green' ), Gnome::Config->get_int( color_section . 'late-blue' ), 0 ); $gui->get_widget('warn_days')->set_value( Gnome::Config->get_int( warn_key )) } sub show_preferences { $gui->get_widget('preferences')->show(); } sub hide_preferences { $gui->get_widget('preferences')->hide(); return 1; } sub preference_changed { $gui->get_widget('preferences')->changed(); } sub save_preferences { # Warn days Gnome::Config->set_int( warn_key, $gui->get_widget('warn_days')->get_value_as_int()); my @color; # Normal color @color = $gui->get_widget('normal_color')->get_i8(); Gnome::Config->set_int( color_section . 'normal-red', $color[0] ); Gnome::Config->set_int( color_section . 'normal-green', $color[1] ); Gnome::Config->set_int( color_section . 'normal-blue', $color[2] ); # Warn color @color = $gui->get_widget('warn_color')->get_i8(); Gnome::Config->set_int( color_section . 'warn-red', $color[0] ); Gnome::Config->set_int( color_section . 'warn-green', $color[1] ); Gnome::Config->set_int( color_section . 'warn-blue', $color[2] ); # Due color @color = $gui->get_widget('due_color')->get_i8(); Gnome::Config->set_int( color_section . 'due-red', $color[0] ); Gnome::Config->set_int( color_section . 'due-green', $color[1] ); Gnome::Config->set_int( color_section . 'due-blue', $color[2] ); # Late color @color = $gui->get_widget('late_color')->get_i8(); Gnome::Config->set_int( color_section . 'late-red', $color[0] ); Gnome::Config->set_int( color_section . 'late-green', $color[1] ); Gnome::Config->set_int( color_section . 'late-blue', $color[2] ); Gnome::Config->sync(); load_bills(); } #################### # Utility Function # #################### sub format_currency { my $old = $_[0]; $old =~ s/,|\$//g; unless( $old =~ /./ ) { $old .= '.00'; } 1 while ( $old =~ s/^([-+]?\d+)(\d{3})/$1,$2/ ); $old = '$' . $old; return $old; } sub time_local { my $time = shift; my $time_obj = new Persistent::DataType::DateTime($time); my $seconds = timelocal( $time_obj->seconds(), $time_obj->minutes(), $time_obj->hours(), $time_obj->day(), $time_obj->month()-1, $time_obj->year() ); return $seconds; } sub set_dropdown { my $dropdown = shift; my $value = shift; my $i = 0; my $item = 0; foreach my $child ( $dropdown->get_menu()->children() ) { my $label = $child->child(); if( defined($label) && $label->get() eq $value ) { $item = $i; } $i++; } $dropdown->set_history( $item ); } sub display_error { my $error_message = shift; my $error = Gnome::DialogUtil->error( $error_message ); $error->set_modal( 1 ); $error->show(); return $error; } sub next_bill_id { my $id = Gnome::Config->get_int( bill_key ); $id++; if( $id > 9999999999 ) { Gnome::Config->set_int( bill_key, 0 ); } else { Gnome::Config->set_int( bill_key, $id ); } Gnome::Config->sync(); return $id; } sub compare_dates { my @date1 = split( /\//, $_[1] ); my @date2 = split( /\//, $_[2] ); if( $date1[2] ne $date2[2] ) { return $date1[2] <=> $date2[2]; } else { if( $date1[0] ne $date2[0] ) { return $date1[0] <=> $date2[0]; } else { return $date1[1] <=> $date2[1]; } } } sub get_glade { my $glade_file = shift; # Read from glade file if accessable. Otherwise read from cache my $glade; my $read_glade_cache = 0; if( -e $glade_file ) { eval { my $cache = open( LAST_MODIFIED_TIME ); my $last_mod = ; chomp $last_mod; close( LAST_MODIFIED_TIEM ); my $meta = stat( $glade_file ); if( $meta->mtime ne $last_mod ) { open( LAST_MODIFIED_TIME, '>' ); print LAST_MODIFIED_TIME $meta->mtime; close( LAST_MODIFIED_TIME ); } else { $read_glade_cache = 1; } }; if( $@ ) { } unless( $read_glade_cache ) { eval { no warnings 'once'; open( GLADE_FILE, $glade_file ); $glade = join( '', ); close( GLADE_FILE ); use warnings 'once'; # Write to script for future cache open( GLADE, '>' ); print GLADE $glade; close( GLADE ); }; if( $@ ) { $read_glade_cache = 1; } } } else { $read_glade_cache = 1; } if( $read_glade_cache ) { open( GLADE ); undef $/; $glade = ; $/ = "\n"; close( GLADE ); } return $glade; } 1; __HELP__

Introduction

Bill Manager is an small application/script that is used to manage bills that you have received and not yet paid. It is not meant to be a large Invoice Management system that integrates with everything. It is simply a script that allows one to keep a list of what is owed.

Managing Bills

The main window is where you edit your bills. Here you can see what bills are owed, you can see when they are due, and you can see how much they are. Also at the bottom in the status bar you can see the total of all money owed on your bills. In addition to what you can see, there are three actions you can do.

Add a new Bill

You can add a bill by pressing the "Add Bill" button in the toolbar, or by selecting the "Add" menu item in the "Bill" menu on the menubar. When you do one of these actions a dialog box is brought up to allow you to set the properties of a bill.

The properties that you can set when adding a bill is the name of the company the bill is for, the amount of the bill, when the bill was received, and when the bill is due. To manage the list of companies press the "builder button" (looks like "...") that is next to the list of companies. See the section below on how to manage companies.

When you are done setting the properties on your new bill simply press the "OK" button and your new bill will be saved.

Edit an existing Bill

When you want to edit an existing bill you will want to select the bill you wish to edit first. Then you have three ways of editing that bill:

  • Double-click on the bill you wish to edit.
  • Press the "Edit Bill" button in the toolbar.
  • Select the "Edit" menu item from the "Bill" menu in the menubar.

After indicating that you wish to edit the bill selected, then a window will be brought up similiar to the one used for adding a bill. The only difference is that this dialog will have the values of the selected bill filled in. Simply change any values you wish to change and press the "OK" button to save.

Delete an existing Bill

To delete a bill select the bill you wish to delete. Then either press the "Delete Bill" button in the toolbar, or select "Delete" from the "Bill" menu in the menubar.

Managing Companies

In both the dialog displayed for editing a bill and the dialog displayed for adding a bill, there exists a "builder button" (looks like ...) which allows the user to edit the list of companies in the company list.

Once the "builder button" is selected you a new dialog will show up that allows you to add a company, remove a company, or close the dialog. To add a company simply press the "Add" button and enter the company name on the new dialog. To remove a company simply select the company you wish to add and press the "Delete" button.

Once you are done editing the company list simply press the "Close" button to close the dialog. The new companies will be reloaded in the list of companies.

Preferences

The preferences dialog allows one to edit how the application works. To view the preferences dialog simply press the "Preferences" button on the toolbar, or select "Preferences" from the "Application" menu on the menubar.

There are two tabs in the preferences dialog. One is general settings, and one is color settings.

General Settings

  • Number of warn days - This is the number of days prior to being due that a bill should be displayed in the warn color to indicate that a bill is due soon.

Color Settings

  • Normal Color - This is the color that bills are displayed in if they are not in the warn state, due state, or late state.
  • Warn Color - This is the color that bills are displayed in if they are less than or equal to the specified warn days before due
  • Due Color - This is the color that bills are displayed in if they are due on the current day
  • Late Color - This is the color that bills are displayed in if they are past due.
__GLADE__ bill-manager bill-manager src pixmaps Perl True True GtkDialog manage_company_window False delete_event close_company Thu, 07 Nov 2002 04:25:30 GMT Edit Company List GTK_WINDOW_DIALOG GTK_WIN_POS_MOUSE True 410 300 True True False GtkVBox Dialog:vbox company_box False 0 GtkHBox Dialog:action_area company_action 10 True 5 0 False True GTK_PACK_END GtkHButtonBox company_buttons GTK_BUTTONBOX_DEFAULT_STYLE 30 85 27 7 0 0 True True GtkButton add_company True True clicked new_company Thu, 07 Nov 2002 04:26:42 GMT GTK_RELIEF_NORMAL GtkButton edit_company True True clicked delete_company Thu, 07 Nov 2002 04:26:55 GMT GTK_RELIEF_NORMAL GtkButton cancel_company True True clicked close_company Thu, 07 Nov 2002 04:25:40 GMT GNOME_STOCK_BUTTON_CLOSE GTK_RELIEF_NORMAL GtkScrolledWindow scrolledwindow1 GTK_POLICY_NEVER GTK_POLICY_AUTOMATIC GTK_UPDATE_CONTINUOUS GTK_UPDATE_CONTINUOUS 0 True True GtkViewport viewport1 GTK_SHADOW_IN GtkList company_list GTK_SELECTION_SINGLE GnomeDialog company_name_window False delete_event cancel_new_company Thu, 07 Nov 2002 04:35:08 GMT Enter the Company Name GTK_WINDOW_DIALOG GTK_WIN_POS_MOUSE True False False False False False GtkVBox GnomeDialog:vbox company_name_box False 8 4 True True GtkHButtonBox GnomeDialog:action_area company_name_actions GTK_BUTTONBOX_END 8 85 27 7 0 0 False True GTK_PACK_END GtkButton ok True True clicked add_company Thu, 07 Nov 2002 04:34:33 GMT GNOME_STOCK_BUTTON_OK GtkButton cancel True True clicked cancel_new_company Thu, 07 Nov 2002 04:35:17 GMT GNOME_STOCK_BUTTON_CANCEL GtkEntry company_name True activate add_company Sat, 04 Jan 2003 21:04:17 GMT True True 0 0 True True GtkWindow bill_dialog 4 False delete_event cancel_bill_edit Sat, 04 Jan 2003 01:04:15 GMT Edit Bill GTK_WINDOW_DIALOG GTK_WIN_POS_MOUSE True 300 150 True True False GtkVBox bill_edit False 0 GtkHBox Dialog:action_area bill_action True 5 0 False False GTK_PACK_END GtkHButtonBox buttons GTK_BUTTONBOX_SPREAD 0 0 0 7 0 0 False True GtkButton ok True True clicked save_bill Thu, 07 Nov 2002 04:16:54 GMT GNOME_STOCK_BUTTON_OK GTK_RELIEF_NORMAL GtkButton cancel True True clicked cancel_bill_edit Thu, 07 Nov 2002 04:17:22 GMT GNOME_STOCK_BUTTON_CANCEL GTK_RELIEF_NORMAL GtkTable bill_properties 5 4 2 False 0 0 0 True True GtkEntry amount True focus_out_event format_amount Fri, 08 Nov 2002 01:51:17 GMT True True 0 1 2 1 2 0 0 True False False False True False GnomeDateEdit received False True False 7 19 1 2 2 3 0 0 True False False False True False GnomeDateEdit due False True False 7 19 1 2 3 4 0 0 True False False False True False GtkLabel company_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 0 1 0 0 False False False False True False GtkLabel amount_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 1 2 0 0 False False False False True False GtkLabel received_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 2 3 0 0 False False False False True False GtkLabel due_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 3 4 0 0 False False False False True False GtkHBox company_box False 0 1 2 0 1 0 0 False False False False True True GtkOptionMenu company True 0 0 True True GtkButton company_builder Edit Company List True clicked manage_companies Thu, 07 Nov 2002 04:17:45 GMT GTK_RELIEF_NORMAL 0 False True GtkHSeparator seperator 0 True True GnomeAbout about False close hide_about Sun, 05 Jan 2003 02:09:46 GMT True Copyright (C) 2002-2003 Eric Anderson <eric.anderson@cordata.net> A tool for keeping track of bills that are due. GnomePropertyBox preferences False close hide_preferences Sun, 05 Jan 2003 02:13:13 GMT apply save_preferences Sun, 05 Jan 2003 14:40:56 GMT help show_help Sun, 05 Jan 2003 20:33:58 GMT Preferences GTK_WIN_POS_MOUSE False False False False GtkNotebook GnomePropertyBox:notebook pref_notebook True True True GTK_POS_TOP False 2 2 False 0 True True GtkTable general_settings 1 2 False 0 0 GtkLabel warn_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 0 1 0 0 False False False False True False GtkSpinButton warn_days Color changes when there are this many days left until due. True changed preference_changed Sun, 05 Jan 2003 14:48:49 GMT 1 0 True GTK_UPDATE_ALWAYS False False 10 0 30 1 10 10 1 2 0 1 0 0 False False False False False False GtkLabel Notebook:tab general_label GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 GtkTable color_settings 4 2 False 0 0 GtkLabel normal_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 0 1 0 0 False False False False True False GnomeColorPicker normal_color True color_set preference_changed Sun, 05 Jan 2003 14:49:10 GMT True False Choose the normal color 1 2 0 1 0 0 False False False False True False GtkLabel warn_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 1 2 0 0 False False False False True False GnomeColorPicker warn_color True color_set preference_changed Sun, 05 Jan 2003 14:49:24 GMT True False Choose a warn color 1 2 1 2 0 0 False False False False True False GtkLabel due_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 2 3 0 0 False False False False True False GnomeColorPicker due_color True color_set preference_changed Sun, 05 Jan 2003 14:49:42 GMT True False Choose the due color 1 2 2 3 0 0 False False False False True False GtkLabel late_label GTK_JUSTIFY_CENTER False 0 0.5 0 0 0 1 3 4 0 0 False False False False True False GnomeColorPicker late_color True color_set preference_changed Sun, 05 Jan 2003 14:49:53 GMT True False Choose a late color 1 2 3 4 0 0 False False False False True False GtkLabel Notebook:tab color_label GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 GnomeApp bill_window Bill Manager GTK_WINDOW_TOPLEVEL GTK_WIN_POS_CENTER False 300 False True False True GnomeDock GnomeApp:dock general_dock True 0 True True GnomeDockItem menu_doc 2 GNOME_DOCK_TOP 0 0 0 True True False True False GTK_SHADOW_OUT GtkMenuBar menubar GTK_SHADOW_NONE GtkMenuItem application False GtkMenu application_menu GtkPixmapMenuItem preferences_menuitem activate show_preferences Sun, 05 Jan 2003 02:20:20 GMT GNOMEUIINFO_MENU_PREFERENCES_ITEM GtkPixmapMenuItem exit_menuitem activate exit_bill_manager Sun, 05 Jan 2003 02:20:20 GMT GNOMEUIINFO_MENU_EXIT_ITEM GtkMenuItem bill_menu False GtkMenu bill_menu_menu GtkPixmapMenuItem new_bill_menuitem Add a new bill activate new_bill Sun, 05 Jan 2003 02:21:15 GMT False GNOME_STOCK_MENU_NEW GtkPixmapMenuItem edit_bill_menuitem Edit an existing bill activate edit_bill Sun, 05 Jan 2003 02:22:05 GMT False GNOME_STOCK_MENU_OPEN GtkPixmapMenuItem delete_bill_menuitem Remove an existing menu item activate delete_bill Sun, 05 Jan 2003 02:22:55 GMT False GNOME_STOCK_MENU_TRASH GtkMenuItem help GNOMEUIINFO_MENU_HELP_TREE GtkMenu help_menu GtkMenuItem help_menuitem activate show_help Sun, 05 Jan 2003 15:17:23 GMT GNOMEUIINFO_MENU_HELP_TREE GtkPixmapMenuItem about_menuitem activate show_about Sun, 05 Jan 2003 02:20:20 GMT GNOMEUIINFO_MENU_ABOUT_ITEM GnomeDockItem toolbar_doc 1 GNOME_DOCK_TOP 1 0 0 False True False False False GTK_SHADOW_OUT GtkToolbar toolbar 1 GTK_ORIENTATION_HORIZONTAL GTK_TOOLBAR_BOTH 16 GTK_TOOLBAR_SPACE_LINE GTK_RELIEF_NONE True GtkButton Toolbar:button add_bill Add a new bill clicked new_bill Sun, 05 Jan 2003 02:40:40 GMT GNOME_STOCK_PIXMAP_NEW GtkButton Toolbar:button edit_bill Edit an existing bill clicked edit_bill Sun, 05 Jan 2003 02:40:51 GMT GNOME_STOCK_PIXMAP_OPEN GtkButton Toolbar:button delete_bill clicked delete_bill Sun, 05 Jan 2003 02:41:01 GMT GNOME_STOCK_PIXMAP_TRASH GtkButton Toolbar:button preferences_button clicked show_preferences Sun, 05 Jan 2003 02:41:19 GMT GNOME_STOCK_PIXMAP_PREFERENCES True GtkButton Toolbar:button exit_button clicked exit_bill_manager Sun, 05 Jan 2003 02:41:36 GMT GNOME_STOCK_PIXMAP_EXIT True GtkScrolledWindow GnomeDock:contents bills GTK_POLICY_AUTOMATIC GTK_POLICY_AUTOMATIC GTK_UPDATE_CONTINUOUS GTK_UPDATE_CONTINUOUS GtkCList bill_list True select_row select_bill Mon, 06 Jan 2003 00:35:17 GMT unselect_row unselect_bill Mon, 06 Jan 2003 00:37:15 GMT 4 5,199,90,49 GTK_SELECTION_SINGLE True GTK_SHADOW_IN GtkLabel CList:title id GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 GtkLabel CList:title bill_name_label GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 GtkLabel CList:title due_date_label GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 GtkLabel CList:title amount_label GTK_JUSTIFY_CENTER False 0.5 0.5 0 0 GnomeAppBar GnomeApp:appbar status False True 0 True True __LAST_MODIFIED_TIME__ 1041863718