#!/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-managerbill-managersrcpixmapsPerlTrueTrueGtkDialogmanage_company_windowFalsedelete_eventclose_companyThu, 07 Nov 2002 04:25:30 GMTEdit Company ListGTK_WINDOW_DIALOGGTK_WIN_POS_MOUSETrue410300TrueTrueFalseGtkVBoxDialog:vboxcompany_boxFalse0GtkHBoxDialog:action_areacompany_action10True50FalseTrueGTK_PACK_ENDGtkHButtonBoxcompany_buttonsGTK_BUTTONBOX_DEFAULT_STYLE308527700TrueTrueGtkButtonadd_companyTrueTrueclickednew_companyThu, 07 Nov 2002 04:26:42 GMTGTK_RELIEF_NORMALGtkButtonedit_companyTrueTrueclickeddelete_companyThu, 07 Nov 2002 04:26:55 GMTGTK_RELIEF_NORMALGtkButtoncancel_companyTrueTrueclickedclose_companyThu, 07 Nov 2002 04:25:40 GMTGNOME_STOCK_BUTTON_CLOSEGTK_RELIEF_NORMALGtkScrolledWindowscrolledwindow1GTK_POLICY_NEVERGTK_POLICY_AUTOMATICGTK_UPDATE_CONTINUOUSGTK_UPDATE_CONTINUOUS0TrueTrueGtkViewportviewport1GTK_SHADOW_INGtkListcompany_listGTK_SELECTION_SINGLEGnomeDialogcompany_name_windowFalsedelete_eventcancel_new_companyThu, 07 Nov 2002 04:35:08 GMTEnter the Company NameGTK_WINDOW_DIALOGGTK_WIN_POS_MOUSETrueFalseFalseFalseFalseFalseGtkVBoxGnomeDialog:vboxcompany_name_boxFalse84TrueTrueGtkHButtonBoxGnomeDialog:action_areacompany_name_actionsGTK_BUTTONBOX_END88527700FalseTrueGTK_PACK_ENDGtkButtonokTrueTrueclickedadd_companyThu, 07 Nov 2002 04:34:33 GMTGNOME_STOCK_BUTTON_OKGtkButtoncancelTrueTrueclickedcancel_new_companyThu, 07 Nov 2002 04:35:17 GMTGNOME_STOCK_BUTTON_CANCELGtkEntrycompany_nameTrueactivateadd_companySat, 04 Jan 2003 21:04:17 GMTTrueTrue00TrueTrueGtkWindowbill_dialog4Falsedelete_eventcancel_bill_editSat, 04 Jan 2003 01:04:15 GMTEdit BillGTK_WINDOW_DIALOGGTK_WIN_POS_MOUSETrue300150TrueTrueFalseGtkVBoxbill_editFalse0GtkHBoxDialog:action_areabill_actionTrue50FalseFalseGTK_PACK_ENDGtkHButtonBoxbuttonsGTK_BUTTONBOX_SPREAD000700FalseTrueGtkButtonokTrueTrueclickedsave_billThu, 07 Nov 2002 04:16:54 GMTGNOME_STOCK_BUTTON_OKGTK_RELIEF_NORMALGtkButtoncancelTrueTrueclickedcancel_bill_editThu, 07 Nov 2002 04:17:22 GMTGNOME_STOCK_BUTTON_CANCELGTK_RELIEF_NORMALGtkTablebill_properties542False000TrueTrueGtkEntryamountTruefocus_out_eventformat_amountFri, 08 Nov 2002 01:51:17 GMTTrueTrue0121200TrueFalseFalseFalseTrueFalseGnomeDateEditreceivedFalseTrueFalse719122300TrueFalseFalseFalseTrueFalseGnomeDateEditdueFalseTrueFalse719123400TrueFalseFalseFalseTrueFalseGtkLabelcompany_labelGTK_JUSTIFY_CENTERFalse00.500010100FalseFalseFalseFalseTrueFalseGtkLabelamount_labelGTK_JUSTIFY_CENTERFalse00.500011200FalseFalseFalseFalseTrueFalseGtkLabelreceived_labelGTK_JUSTIFY_CENTERFalse00.500012300FalseFalseFalseFalseTrueFalseGtkLabeldue_labelGTK_JUSTIFY_CENTERFalse00.500013400FalseFalseFalseFalseTrueFalseGtkHBoxcompany_boxFalse0120100FalseFalseFalseFalseTrueTrueGtkOptionMenucompanyTrue00TrueTrueGtkButtoncompany_builderEdit Company ListTrueclickedmanage_companiesThu, 07 Nov 2002 04:17:45 GMTGTK_RELIEF_NORMAL0FalseTrueGtkHSeparatorseperator0TrueTrueGnomeAboutaboutFalseclosehide_aboutSun, 05 Jan 2003 02:09:46 GMTTrueCopyright (C) 2002-2003Eric Anderson <eric.anderson@cordata.net>
A tool for keeping track of bills that are due.GnomePropertyBoxpreferencesFalseclosehide_preferencesSun, 05 Jan 2003 02:13:13 GMTapplysave_preferencesSun, 05 Jan 2003 14:40:56 GMThelpshow_helpSun, 05 Jan 2003 20:33:58 GMTPreferencesGTK_WIN_POS_MOUSEFalseFalseFalseFalseGtkNotebookGnomePropertyBox:notebookpref_notebookTrueTrueTrueGTK_POS_TOPFalse22False0TrueTrueGtkTablegeneral_settings12False00GtkLabelwarn_labelGTK_JUSTIFY_CENTERFalse00.500010100FalseFalseFalseFalseTrueFalseGtkSpinButtonwarn_daysColor changes when there are this many days left until due.Truechangedpreference_changedSun, 05 Jan 2003 14:48:49 GMT10TrueGTK_UPDATE_ALWAYSFalseFalse1003011010120100FalseFalseFalseFalseFalseFalseGtkLabelNotebook:tabgeneral_labelGTK_JUSTIFY_CENTERFalse0.50.500GtkTablecolor_settings42False00GtkLabelnormal_labelGTK_JUSTIFY_CENTERFalse00.500010100FalseFalseFalseFalseTrueFalseGnomeColorPickernormal_colorTruecolor_setpreference_changedSun, 05 Jan 2003 14:49:10 GMTTrueFalseChoose the normal color120100FalseFalseFalseFalseTrueFalseGtkLabelwarn_labelGTK_JUSTIFY_CENTERFalse00.500011200FalseFalseFalseFalseTrueFalseGnomeColorPickerwarn_colorTruecolor_setpreference_changedSun, 05 Jan 2003 14:49:24 GMTTrueFalseChoose a warn color121200FalseFalseFalseFalseTrueFalseGtkLabeldue_labelGTK_JUSTIFY_CENTERFalse00.500012300FalseFalseFalseFalseTrueFalseGnomeColorPickerdue_colorTruecolor_setpreference_changedSun, 05 Jan 2003 14:49:42 GMTTrueFalseChoose the due color122300FalseFalseFalseFalseTrueFalseGtkLabellate_labelGTK_JUSTIFY_CENTERFalse00.500013400FalseFalseFalseFalseTrueFalseGnomeColorPickerlate_colorTruecolor_setpreference_changedSun, 05 Jan 2003 14:49:53 GMTTrueFalseChoose a late color123400FalseFalseFalseFalseTrueFalseGtkLabelNotebook:tabcolor_labelGTK_JUSTIFY_CENTERFalse0.50.500GnomeAppbill_windowBill ManagerGTK_WINDOW_TOPLEVELGTK_WIN_POS_CENTERFalse300FalseTrueFalseTrueGnomeDockGnomeApp:dockgeneral_dockTrue0TrueTrueGnomeDockItemmenu_doc2GNOME_DOCK_TOP000TrueTrueFalseTrueFalseGTK_SHADOW_OUTGtkMenuBarmenubarGTK_SHADOW_NONEGtkMenuItemapplicationFalseGtkMenuapplication_menuGtkPixmapMenuItempreferences_menuitemactivateshow_preferencesSun, 05 Jan 2003 02:20:20 GMTGNOMEUIINFO_MENU_PREFERENCES_ITEMGtkPixmapMenuItemexit_menuitemactivateexit_bill_managerSun, 05 Jan 2003 02:20:20 GMTGNOMEUIINFO_MENU_EXIT_ITEMGtkMenuItembill_menuFalseGtkMenubill_menu_menuGtkPixmapMenuItemnew_bill_menuitemAdd a new billactivatenew_billSun, 05 Jan 2003 02:21:15 GMTFalseGNOME_STOCK_MENU_NEWGtkPixmapMenuItemedit_bill_menuitemEdit an existing billactivateedit_billSun, 05 Jan 2003 02:22:05 GMTFalseGNOME_STOCK_MENU_OPENGtkPixmapMenuItemdelete_bill_menuitemRemove an existing menu itemactivatedelete_billSun, 05 Jan 2003 02:22:55 GMTFalseGNOME_STOCK_MENU_TRASHGtkMenuItemhelpGNOMEUIINFO_MENU_HELP_TREEGtkMenuhelp_menuGtkMenuItemhelp_menuitemactivateshow_helpSun, 05 Jan 2003 15:17:23 GMTGNOMEUIINFO_MENU_HELP_TREEGtkPixmapMenuItemabout_menuitemactivateshow_aboutSun, 05 Jan 2003 02:20:20 GMTGNOMEUIINFO_MENU_ABOUT_ITEMGnomeDockItemtoolbar_doc1GNOME_DOCK_TOP100FalseTrueFalseFalseFalseGTK_SHADOW_OUTGtkToolbartoolbar1GTK_ORIENTATION_HORIZONTALGTK_TOOLBAR_BOTH16GTK_TOOLBAR_SPACE_LINEGTK_RELIEF_NONETrueGtkButtonToolbar:buttonadd_billAdd a new billclickednew_billSun, 05 Jan 2003 02:40:40 GMTGNOME_STOCK_PIXMAP_NEWGtkButtonToolbar:buttonedit_billEdit an existing billclickededit_billSun, 05 Jan 2003 02:40:51 GMTGNOME_STOCK_PIXMAP_OPENGtkButtonToolbar:buttondelete_billclickeddelete_billSun, 05 Jan 2003 02:41:01 GMTGNOME_STOCK_PIXMAP_TRASHGtkButtonToolbar:buttonpreferences_buttonclickedshow_preferencesSun, 05 Jan 2003 02:41:19 GMTGNOME_STOCK_PIXMAP_PREFERENCESTrueGtkButtonToolbar:buttonexit_buttonclickedexit_bill_managerSun, 05 Jan 2003 02:41:36 GMTGNOME_STOCK_PIXMAP_EXITTrueGtkScrolledWindowGnomeDock:contentsbillsGTK_POLICY_AUTOMATICGTK_POLICY_AUTOMATICGTK_UPDATE_CONTINUOUSGTK_UPDATE_CONTINUOUSGtkCListbill_listTrueselect_rowselect_billMon, 06 Jan 2003 00:35:17 GMTunselect_rowunselect_billMon, 06 Jan 2003 00:37:15 GMT45,199,90,49GTK_SELECTION_SINGLETrueGTK_SHADOW_INGtkLabelCList:titleidGTK_JUSTIFY_CENTERFalse0.50.500GtkLabelCList:titlebill_name_labelGTK_JUSTIFY_CENTERFalse0.50.500GtkLabelCList:titledue_date_labelGTK_JUSTIFY_CENTERFalse0.50.500GtkLabelCList:titleamount_labelGTK_JUSTIFY_CENTERFalse0.50.500GnomeAppBarGnomeApp:appbarstatusFalseTrue0TrueTrue
__LAST_MODIFIED_TIME__
1041863718