From f55d4caaa1762658c9a3484f110b11fb4ed64cdd Mon Sep 17 00:00:00 2001 From: Derek Atkins Date: Fri, 14 Jun 2002 17:08:19 +0000 Subject: [PATCH] * business-core/gncTaxTable*: Create a preliminary implementation of Tax Tables. They are currently not saved, and nothing uses them. Link the initialization into the module. * business-gnome/dialog-tax-table*: Create a tax table GUI to create and edit tax tables. G-wrap the editor-window create routine. * business-gnome.scm: add the Tax Table gui; rename the 'Invoice' option page to "Business". Fix dialog-invoice to use the new option name. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6963 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 14 + src/business/business-core/Makefile.am | 3 + src/business/business-core/businessmod-core.c | 1 + src/business/business-core/gncTaxTable.c | 486 +++++++++++++ src/business/business-core/gncTaxTable.h | 70 ++ src/business/business-core/gncTaxTableP.h | 22 + src/business/business-gnome/Makefile.am | 3 + .../business-gnome/business-gnome.scm | 12 +- src/business/business-gnome/dialog-invoice.c | 2 +- .../business-gnome/dialog-tax-table.c | 680 ++++++++++++++++++ .../business-gnome/dialog-tax-table.h | 20 + .../business-gnome/gw-business-gnome-spec.scm | 13 + src/business/business-gnome/tax-tables.glade | 584 +++++++++++++++ 13 files changed, 1907 insertions(+), 3 deletions(-) create mode 100644 src/business/business-core/gncTaxTable.c create mode 100644 src/business/business-core/gncTaxTable.h create mode 100644 src/business/business-core/gncTaxTableP.h create mode 100644 src/business/business-gnome/dialog-tax-table.c create mode 100644 src/business/business-gnome/dialog-tax-table.h create mode 100644 src/business/business-gnome/tax-tables.glade diff --git a/ChangeLog b/ChangeLog index ed28b80271..05c6fe0b3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2002-06-14 Derek Atkins + + * business-core/gncTaxTable*: Create a preliminary implementation + of Tax Tables. They are currently not saved, and nothing uses + them. Link the initialization into the module. + + * business-gnome/dialog-tax-table*: Create a tax table GUI to + create and edit tax tables. G-wrap the editor-window create + routine. + + * business-gnome.scm: add the Tax Table gui; rename the 'Invoice' + option page to "Business". Fix dialog-invoice to use the new + option name. + 2002-06-11 David Hampton * src/gnome/druid-stock-split.c: Add automatic focusing on a diff --git a/src/business/business-core/Makefile.am b/src/business/business-core/Makefile.am index e106a3b39d..3562f2f80b 100644 --- a/src/business/business-core/Makefile.am +++ b/src/business/business-core/Makefile.am @@ -21,6 +21,7 @@ libgncmod_business_core_la_SOURCES = \ gncJob.c \ gncOrder.c \ gncOwner.c \ + gncTaxTable.c \ gncVendor.c noinst_HEADERS = \ @@ -42,6 +43,8 @@ noinst_HEADERS = \ gncOrderP.h \ gncOwner.h \ gncOwnerP.h \ + gncTaxTable.h \ + gncTaxTableP.h \ gncVendor.h \ gncVendorP.h diff --git a/src/business/business-core/businessmod-core.c b/src/business/business-core/businessmod-core.c index f43c958e6f..af5bb027f4 100644 --- a/src/business/business-core/businessmod-core.c +++ b/src/business/business-core/businessmod-core.c @@ -62,6 +62,7 @@ gnc_module_init(int refcount) gncJobRegister (); gncOrderRegister (); gncOwnerRegister (); + gncTaxTableRegister (); gncVendorRegister (); } diff --git a/src/business/business-core/gncTaxTable.c b/src/business/business-core/gncTaxTable.c new file mode 100644 index 0000000000..042bd3603d --- /dev/null +++ b/src/business/business-core/gncTaxTable.c @@ -0,0 +1,486 @@ +/* + * gncTaxTable.c -- the Gnucash Tax Table interface + * Copyright (C) 2002 Derek Atkins + * Author: Derek Atkins + */ + +#include "config.h" + +#include + +#include "messages.h" +#include "gnc-numeric.h" +#include "gnc-engine-util.h" +#include "gnc-book-p.h" +#include "GNCIdP.h" +#include "QueryObject.h" +#include "gnc-event-p.h" + +#include "gncBusiness.h" +#include "gncTaxTableP.h" + + +struct _gncTaxTable { + GUID guid; + char * name; + GList * entries; + + gint64 refcount; + GNCBook * book; + GncTaxTable * parent; /* if non-null, we are an immutable child */ + GncTaxTable * child; /* if non-null, we have not changed */ + gboolean invisible; + gboolean dirty; +}; + +struct _gncTaxTableEntry { + GncTaxTable * table; + Account * account; + GncTaxType type; + gnc_numeric amount; +}; + +struct _book_info { + GncBookInfo bi; + GList * tables; /* visible tables */ +}; + +#define _GNC_MOD_NAME GNC_TAXTABLE_MODULE_NAME + +#define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str)); +#define CACHE_REMOVE(str) g_cache_remove(gnc_engine_get_string_cache(), (str)); + +#define SET_STR(member, str) { \ + char * tmp; \ + \ + if (!safe_strcmp (member, str)) return; \ + tmp = CACHE_INSERT (str); \ + CACHE_REMOVE (member); \ + member = tmp; \ + } + +static void add_or_rem_object (GncTaxTable *table, gboolean add); +static void addObj (GncTaxTable *table); +static void remObj (GncTaxTable *table); + +G_INLINE_FUNC void mark_table (GncTaxTable *table); +G_INLINE_FUNC void +mark_table (GncTaxTable *table) +{ + table->dirty = TRUE; + + gnc_engine_generate_event (&table->guid, GNC_EVENT_MODIFY); +} + +/* Create/Destroy Functions */ +GncTaxTable * gncTaxTableCreate (GNCBook *book) +{ + GncTaxTable *table; + if (!book) return NULL; + + table = g_new0 (GncTaxTable, 1); + table->book = book; + table->name = CACHE_INSERT (""); + xaccGUIDNew (&table->guid, book); + addObj (table); + gnc_engine_generate_event (&table->guid, GNC_EVENT_CREATE); + return table; +} + +void gncTaxTableDestroy (GncTaxTable *table) +{ + GList *list; + if (!table) return; + + gnc_engine_generate_event (&table->guid, GNC_EVENT_DESTROY); + CACHE_REMOVE (table->name); + remObj (table); + + for (list = table->entries; list; list=list->next) + gncTaxTableEntryDestroy (list->data); + + g_list_free (table->entries); + g_free (table); +} + +GncTaxTableEntry * gncTaxTableEntryCreate (void) +{ + GncTaxTableEntry *entry; + entry = g_new0 (GncTaxTableEntry, 1); + entry->amount = gnc_numeric_zero (); + return entry; +} + +void gncTaxTableEntryDestroy (GncTaxTableEntry *entry) +{ + if (!entry) return; + g_free (entry); +} + + +/* Set Functions */ +void gncTaxTableSetGUID (GncTaxTable *table, const GUID *guid) +{ + if (!table || !guid) return; + if (guid_equal (guid, &table->guid)) return; + + remObj (table); + table->guid = *guid; + addObj (table); +} + +void gncTaxTableSetName (GncTaxTable *table, const char *name) +{ + if (!table || !name) return; + SET_STR (table->name, name); + mark_table (table); +} + +void gncTaxTableSetParent (GncTaxTable *table, GncTaxTable *parent) +{ + if (!table) return; + table->parent = parent; + gncTaxTableMakeInvisible (table); +} + +void gncTaxTableSetChild (GncTaxTable *table, GncTaxTable *child) +{ + if (!table) return; + table->child = child; +} + +void gncTaxTableIncRef (GncTaxTable *table) +{ + if (!table) return; + table->refcount++; +} + +void gncTaxTableDecRef (GncTaxTable *table) +{ + if (!table) return; + table->refcount--; + g_return_if_fail (table->refcount < 0); +} + +void gncTaxTableSetRefcount (GncTaxTable *table, gint64 refcount) +{ + if (!table) return; + table->refcount = refcount; +} + +void gncTaxTableMakeInvisible (GncTaxTable *table) +{ + if (!table) return; + table->invisible = TRUE; + add_or_rem_object (table, FALSE); +} + +void gncTaxTableEntrySetAccount (GncTaxTableEntry *entry, Account *account) +{ + if (!entry || !account) return; + if (entry->account == account) return; + entry->account = account; + if (entry->table) + mark_table (entry->table); +} + +void gncTaxTableEntrySetType (GncTaxTableEntry *entry, GncTaxType type) +{ + if (!entry) return; + if (entry->type == type) return; + entry->type = type; + if (entry->table) + mark_table (entry->table); +} + +void gncTaxTableEntrySetAmount (GncTaxTableEntry *entry, gnc_numeric amount) +{ + if (!entry) return; + if (gnc_numeric_eq (entry->amount, amount)) return; + entry->amount = amount; + if (entry->table) + mark_table (entry->table); +} + +void gncTaxTableAddEntry (GncTaxTable *table, GncTaxTableEntry *entry) +{ + if (!table || !entry) return; + if (entry->table == table) return; /* already mine */ + if (entry->table) + gncTaxTableRemoveEntry (entry->table, entry); + + entry->table = table; + table->entries = g_list_insert_sorted (table->entries, entry, + (GCompareFunc)gncTaxTableEntryCompare); + mark_table (table); +} + +void gncTaxTableRemoveEntry (GncTaxTable *table, GncTaxTableEntry *entry) +{ + if (!table || !entry) return; + entry->table = NULL; + table->entries = g_list_remove (table->entries, entry); + mark_table (table); +} + +void gncTaxTableChanged (GncTaxTable *table) +{ + if (!table) return; + table->child = NULL; +} + +void gncTaxTableCommitEdit (GncTaxTable *table) +{ +} + + +/* Get Functions */ +GncTaxTable *gncTaxTableLookupByName (GNCBook *book, const char *name) +{ + GList *list = gncTaxTableGetTables (book); + + for ( ; list; list = list->next) { + GncTaxTable *table = list->data; + if (!safe_strcmp (table->name, name)) + return list->data; + } + return NULL; +} + +GList * gncTaxTableGetTables (GNCBook *book) +{ + struct _book_info *bi; + if (!book) return NULL; + + bi = gnc_book_get_data (book, _GNC_MOD_NAME); + return bi->tables; +} + + +const GUID *gncTaxTableGetGUID (GncTaxTable *table) +{ + if (!table) return NULL; + return &table->guid; +} + +GNCBook *gncTaxTableGetBook (GncTaxTable *table) +{ + if (!table) return NULL; + return table->book; +} + +const char *gncTaxTableGetName (GncTaxTable *table) +{ + if (!table) return NULL; + return table->name; +} + +static GncTaxTableEntry *gncTaxTableEntryCopy (GncTaxTableEntry *entry) +{ + GncTaxTableEntry *e; + if (!entry) return NULL; + + e = gncTaxTableEntryCreate (); + gncTaxTableEntrySetAccount (e, entry->account); + gncTaxTableEntrySetType (e, entry->type); + gncTaxTableEntrySetAmount (e, entry->amount); + + return e; +} + +static GncTaxTable *gncTaxTableCopy (GncTaxTable *table) +{ + GncTaxTable *t; + GList *list; + + if (!table) return NULL; + t = gncTaxTableCreate (table->book); + gncTaxTableSetName (t, table->name); + for (list = table->entries; list; list=list->next) { + GncTaxTableEntry *entry, *e; + entry = list->data; + e = gncTaxTableEntryCopy (entry); + gncTaxTableAddEntry (t, e); + } + return t; +} + +GncTaxTable *gncTaxTableGetChild (GncTaxTable *table, gboolean make_new) +{ + GncTaxTable *child = NULL; + + if (!table) return NULL; + if (table->child) return table->child; + if (make_new) { + child = gncTaxTableCopy (table); + gncTaxTableSetChild (table, child); + gncTaxTableSetParent (child, table); + } + return child; +} + +GncTaxTable *gncTaxTableGetParent (GncTaxTable *table) +{ + if (!table) return NULL; + return table->parent; +} + +GList *gncTaxTableGetEntries (GncTaxTable *table) +{ + if (!table) return NULL; + return table->entries; +} + +gint64 gncTaxTableGetRefcount (GncTaxTable *table) +{ + if (!table) return 0; + return table->refcount; +} + +gboolean gncTaxTableGetInvisible (GncTaxTable *table) +{ + if (!table) return FALSE; + return table->invisible; +} + +Account * gncTaxTableEntryGetAccount (GncTaxTableEntry *entry) +{ + if (!entry) return NULL; + return entry->account; +} + +GncTaxType gncTaxTableEntryGetType (GncTaxTableEntry *entry) +{ + if (!entry) return GNC_TAX_TYPE_NONE; + return entry->type; +} + +gnc_numeric gncTaxTableEntryGetAmount (GncTaxTableEntry *entry) +{ + if (!entry) return gnc_numeric_zero(); + return entry->amount; +} + +int gncTaxTableEntryCompare (GncTaxTableEntry *a, GncTaxTableEntry *b) +{ + char *name_a, *name_b; + int retval; + + if (!a && !b) return 0; + if (!a) return -1; + if (!b) return 1; + + name_a = xaccAccountGetFullName (a->account, ':'); + name_b = xaccAccountGetFullName (b->account, ':'); + /* for comparison purposes it doesn't matter what we use as a separator */ + retval = safe_strcmp(name_a, name_b); + g_free(name_a); + g_free(name_b); + + if (retval) + return retval; + + return gnc_numeric_compare (a->amount, b->amount); +} + +int gncTaxTableCompare (GncTaxTable *a, GncTaxTable *b) +{ + if (!a && !b) return 0; + if (!a) return -1; + if (!b) return 1; + return safe_strcmp (a->name, b->name); +} + +/* Package-Private functions */ + +static void add_or_rem_object (GncTaxTable *table, gboolean add) +{ + struct _book_info *bi; + + if (!table) return; + bi = gnc_book_get_data (table->book, _GNC_MOD_NAME); + + if (add) + bi->tables = g_list_insert_sorted (bi->tables, table, + (GCompareFunc)gncTaxTableCompare); + else + bi->tables = g_list_remove (bi->tables, table); +} + +static void addObj (GncTaxTable *table) +{ + gncBusinessAddObject (table->book, _GNC_MOD_NAME, table, &table->guid); + add_or_rem_object (table, TRUE); +} + +static void remObj (GncTaxTable *table) +{ + gncBusinessRemoveObject (table->book, _GNC_MOD_NAME, &table->guid); + add_or_rem_object (table, FALSE); +} + +static void _gncTaxTableCreate (GNCBook *book) +{ + struct _book_info *bi; + + if (!book) return; + + bi = g_new0 (struct _book_info, 1); + bi->bi.ht = guid_hash_table_new (); + gnc_book_set_data (book, _GNC_MOD_NAME, bi); +} + +static void _gncTaxTableDestroy (GNCBook *book) +{ + struct _book_info *bi; + + if (!book) return; + + bi = gnc_book_get_data (book, _GNC_MOD_NAME); + + /* XXX : Destroy the objects? */ + g_hash_table_destroy (bi->bi.ht); + g_list_free (bi->tables); + g_free (bi); +} + +static gboolean _gncTaxTableIsDirty (GNCBook *book) +{ + return gncBusinessIsDirty (book, _GNC_MOD_NAME); +} + +static void _gncTaxTableMarkClean (GNCBook *book) +{ + gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE); +} + +static void _gncTaxTableForeach (GNCBook *book, foreachObjectCB cb, + gpointer user_data) +{ + gncBusinessForeach (book, _GNC_MOD_NAME, cb, user_data); +} + +static GncObject_t gncTaxTableDesc = { + GNC_OBJECT_VERSION, + _GNC_MOD_NAME, + "Tax Table", + _gncTaxTableCreate, + _gncTaxTableDestroy, + _gncTaxTableIsDirty, + _gncTaxTableMarkClean, + _gncTaxTableForeach, + NULL /* printable */ +}; + +gboolean gncTaxTableRegister (void) +{ + static QueryObjectDef params[] = { + { QUERY_PARAM_BOOK, GNC_ID_BOOK, (QueryAccess)gncTaxTableGetBook }, + { QUERY_PARAM_GUID, QUERYCORE_GUID, (QueryAccess)gncTaxTableGetGUID }, + { NULL }, + }; + + gncQueryObjectRegister (_GNC_MOD_NAME, (QuerySort)gncTaxTableCompare, params); + + return gncObjectRegister (&gncTaxTableDesc); +} diff --git a/src/business/business-core/gncTaxTable.h b/src/business/business-core/gncTaxTable.h new file mode 100644 index 0000000000..36c9c28688 --- /dev/null +++ b/src/business/business-core/gncTaxTable.h @@ -0,0 +1,70 @@ +/* + * gncTaxTable.h -- the Gnucash Tax Table interface + * Copyright (C) 2002 Derek Atkins + * Author: Derek Atkins + */ + +#ifndef GNC_TAXTABLE_H_ +#define GNC_TAXTABLE_H_ + +typedef struct _gncTaxTable GncTaxTable; +typedef struct _gncTaxTableEntry GncTaxTableEntry; + +#include "gnc-numeric.h" +#include "gnc-book.h" +#include "Account.h" + +#define GNC_TAXTABLE_MODULE_NAME "gncTaxTable" + +/* + * How to interpret the amount. + * You can interpret it as a VALUE or a PERCENT. + */ +typedef enum { + GNC_TAX_TYPE_VALUE = 0, + GNC_TAX_TYPE_PERCENT = 1, + GNC_TAX_TYPE_NONE = 2, +} GncTaxType; + +/* Create/Destroy Functions */ +GncTaxTable * gncTaxTableCreate (GNCBook *book); +void gncTaxTableDestroy (GncTaxTable *table); +GncTaxTableEntry * gncTaxTableEntryCreate (void); +void gncTaxTableEntryDestroy (GncTaxTableEntry *entry); + +/* Set Functions */ +void gncTaxTableSetName (GncTaxTable *table, const char *name); +void gncTaxTableIncRef (GncTaxTable *table); +void gncTaxTableDecRef (GncTaxTable *table); + +void gncTaxTableEntrySetAccount (GncTaxTableEntry *entry, Account *account); +void gncTaxTableEntrySetType (GncTaxTableEntry *entry, GncTaxType type); +void gncTaxTableEntrySetAmount (GncTaxTableEntry *entry, gnc_numeric amount); + +void gncTaxTableAddEntry (GncTaxTable *table, GncTaxTableEntry *entry); +void gncTaxTableRemoveEntry (GncTaxTable *table, GncTaxTableEntry *entry); + +void gncTaxTableChanged (GncTaxTable *table); +void gncTaxTableCommitEdit (GncTaxTable *table); + +/* Get Functions */ +GncTaxTable *gncTaxTableLookupByName (GNCBook *book, const char *name); +GList * gncTaxTableGetTables (GNCBook *book); + +const GUID *gncTaxTableGetGUID (GncTaxTable *table); +GNCBook *gncTaxTableGetBook (GncTaxTable *table); +const char *gncTaxTableGetName (GncTaxTable *table); +GncTaxTable *gncTaxTableGetParent (GncTaxTable *table); +GncTaxTable *gncTaxTableGetChild (GncTaxTable *table, gboolean make_new); +#define gncTaxTableReturnChild(t) gncTaxTableGetChild((t),FALSE) +GList *gncTaxTableGetEntries (GncTaxTable *table); +gint64 gncTaxTableGetRefcount (GncTaxTable *table); + +Account * gncTaxTableEntryGetAccount (GncTaxTableEntry *entry); +GncTaxType gncTaxTableEntryGetType (GncTaxTableEntry *entry); +gnc_numeric gncTaxTableEntryGetAmount (GncTaxTableEntry *entry); + +int gncTaxTableCompare (GncTaxTable *a, GncTaxTable *b); +int gncTaxTableEntryCompare (GncTaxTableEntry *a, GncTaxTableEntry *b); + +#endif /* GNC_TAXTABLE_H_ */ diff --git a/src/business/business-core/gncTaxTableP.h b/src/business/business-core/gncTaxTableP.h new file mode 100644 index 0000000000..79ef6c7b7d --- /dev/null +++ b/src/business/business-core/gncTaxTableP.h @@ -0,0 +1,22 @@ +/* + * gncTaxTableP.h -- the Gnucash Tax Table interface: private interface + * Copyright (C) 2002 Derek Atkins + * Author: Derek Atkins + */ + +#ifndef GNC_TAXTABLEP_H_ +#define GNC_TAXTABLEP_H_ + +#include "gncTaxTable.h" + +gboolean gncTaxTableRegister (void); + +void gncTaxTableSetGUID (GncTaxTable *table, const GUID *guid); +void gncTaxTableSetParent (GncTaxTable *table, GncTaxTable *parent); +void gncTaxTableSetChild (GncTaxTable *table, GncTaxTable *child); +void gncTaxTableSetRefcount (GncTaxTable *table, gint64 refcount); +void gncTaxTableMakeInvisible (GncTaxTable *table); + +gboolean gncTaxTableGetInvisible (GncTaxTable *table); + +#endif /* GNC_TAXTABLEP_H_ */ diff --git a/src/business/business-gnome/Makefile.am b/src/business/business-gnome/Makefile.am index 20679380b4..5680a38118 100644 --- a/src/business/business-gnome/Makefile.am +++ b/src/business/business-gnome/Makefile.am @@ -33,6 +33,7 @@ libgncmod_business_gnome_la_SOURCES = \ dialog-job.c \ dialog-order.c \ dialog-payment.c \ + dialog-tax-table.c \ dialog-vendor.c \ search-owner.c \ gnc-business-utils.c @@ -46,6 +47,7 @@ noinst_HEADERS = \ dialog-job.h \ dialog-order.h \ dialog-payment.h \ + dialog-tax-table.h \ dialog-vendor.h \ search-owner.h \ gnc-business-utils.h @@ -86,6 +88,7 @@ glade_DATA = \ job.glade \ order.glade \ payment.glade \ + tax-tables.glade \ vendor.glade gwmoddir = ${GNC_GWRAP_LIBDIR} diff --git a/src/business/business-gnome/business-gnome.scm b/src/business/business-gnome/business-gnome.scm index b772c24adf..973c67b980 100644 --- a/src/business/business-gnome/business-gnome.scm +++ b/src/business/business-gnome/business-gnome.scm @@ -176,6 +176,13 @@ ;;(gnc:add-extension find) ;;(gnc:add-extension new) + (gnc:add-extension + (gnc:make-menu-item (N_ "Tax Tables") + (N_ "View and Edit the available Tax Tables") + (list top-level "") + (lambda () + (gnc:tax-table-new (gnc:get-current-book))))) + (add-vendor-items) (add-customer-items) ) @@ -325,8 +332,8 @@ (gnc:register-configuration-option (gnc:make-number-range-option - (N_ "Invoice") (N_ "Number of Rows") - "d" (N_ "Default number of register rows to display.") + (N_ "Business") (N_ "Number of Rows") + "a" (N_ "Default number of register rows to display in Invoices.") 10.0 ;; default 1.0 ;; lower bound 200.0 ;; upper bound @@ -334,4 +341,5 @@ 1.0 ;; step size )) + (load-from-path "business-options.scm") diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c index cbbeba5db7..29a3d1ed0b 100644 --- a/src/business/business-gnome/dialog-invoice.c +++ b/src/business/business-gnome/dialog-invoice.c @@ -1223,7 +1223,7 @@ gnc_invoice_new_window (GNCBook *bookp, InvoiceDialogType type, GtkWidget *popup; guint num_rows; - num_rows = (guint) gnc_lookup_number_option ("Invoice", + num_rows = (guint) gnc_lookup_number_option ("Business", "Number of Rows", 10.0); gnucash_register_set_initial_rows( num_rows ); diff --git a/src/business/business-gnome/dialog-tax-table.c b/src/business/business-gnome/dialog-tax-table.c new file mode 100644 index 0000000000..d82e22150a --- /dev/null +++ b/src/business/business-gnome/dialog-tax-table.c @@ -0,0 +1,680 @@ +/* + * dialog-tax-table.c -- Dialog to create and edit tax-tables + * Copyright (C) 2002 Derek Atkins + * Author: Derek Atkins + */ + +#include "config.h" + +#include + +#include "dialog-utils.h" +#include "global-options.h" +#include "gnc-component-manager.h" +#include "gnc-ui.h" +#include "gnc-gui-query.h" +#include "gnc-ui-util.h" +#include "gnc-engine-util.h" +#include "gnc-amount-edit.h" +#include "gnc-account-tree.h" +#include "gnc-numeric.h" + +#include "gncTaxTable.h" +#include "dialog-tax-table.h" + +#define DIALOG_TAX_TABLE_CM_CLASS "tax-table-dialog" + +struct _taxtable_window { + GtkWidget * dialog; + GtkWidget * names_clist; + GtkWidget * entries_clist; + + GncTaxTable * current_table; + GncTaxTableEntry * current_entry; + GNCBook * book; + gint component_id; +}; + +typedef struct _new_taxtable { + GtkWidget * dialog; + GtkWidget * name_entry; + GtkWidget * amount_entry; + GtkWidget * acct_tree; + + TaxTableWindow * ttw; + GncTaxTableEntry * entry; + gint type; + gboolean new_table; +} NewTaxTable; + + +static void +new_tax_table_ok_cb (GtkWidget *widget, gpointer data) +{ + NewTaxTable *ntt = data; + TaxTableWindow *ttw; + char *name = NULL; + char *message; + Account *acc; + gnc_numeric amount; + + g_return_if_fail (ntt); + ttw = ntt->ttw; + + /* Verify that we've got real, valid data */ + + /* verify the name, maybe */ + if (ntt->new_table) { + name = gtk_entry_get_text (GTK_ENTRY (ntt->name_entry)); + if (name == NULL || *name == '\0') { + message = _("You must provide a name for this Tax Table."); + gnc_error_dialog_parented (GTK_WINDOW (ntt->dialog), message); + return; + } + if (gncTaxTableLookupByName (ttw->book, name)) { + message = g_strdup_printf(_( + "You must provide a unique name for this Tax Table.\n" + "Your choice \"%s\" is already in use."), name); + gnc_error_dialog_parented (GTK_WINDOW (ntt->dialog), message); + g_free (message); + return; + } + } + + /* verify the amount */ + amount = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (ntt->amount_entry)); + if (gnc_numeric_negative_p (amount)) { + message = _("Negative amounts are not allowed."); + gnc_error_dialog_parented (GTK_WINDOW (ntt->dialog), message); + return; + } + if (ntt->type == GNC_TAX_TYPE_PERCENT && + gnc_numeric_compare (amount, + gnc_numeric_create (100, 1)) > 0) { + message = _("Percentage amount must be between 0 and 100."); + gnc_error_dialog_parented (GTK_WINDOW (ntt->dialog), message); + return; + } + + /* verify the account */ + acc = + gnc_account_tree_get_current_account (GNC_ACCOUNT_TREE (ntt->acct_tree)); + if (acc == NULL) { + message = _("You must choose a Tax Account."); + gnc_error_dialog_parented (GTK_WINDOW (ntt->dialog), message); + return; + } + + gnc_suspend_gui_refresh (); + + /* Ok, it's all valid, now either change to add this thing */ + if (ntt->new_table) { + GncTaxTable *table = gncTaxTableCreate (ttw->book); + gncTaxTableSetName (table, name); + /* Reset the current table */ + ttw->current_table = table; + } + + /* Create/edit the entry */ + { + GncTaxTableEntry *entry; + + if (ntt->entry) { + entry = ntt->entry; + } else { + entry = gncTaxTableEntryCreate (); + gncTaxTableAddEntry (ttw->current_table, entry); + ttw->current_entry = entry; + } + + gncTaxTableEntrySetAccount (entry, acc); + gncTaxTableEntrySetType (entry, ntt->type); + gncTaxTableEntrySetAmount (entry, amount); + } + + /* Mark the table as changed and commit it */ + gncTaxTableChanged (ttw->current_table); + gncTaxTableCommitEdit (ttw->current_table); + + gnc_resume_gui_refresh(); + + /* Then close/refresh the dialog/window */ + gnome_dialog_close (GNOME_DIALOG (ntt->dialog)); +} + +static void +new_tax_table_cancel_cb (GtkWidget *widget, gpointer data) +{ + NewTaxTable *ntt = data; + g_return_if_fail (ntt); + gnome_dialog_close (GNOME_DIALOG (ntt->dialog)); +} + +static void +new_tax_table_dialog_destroy_cb (GtkWidget *widget, gpointer data) +{ + NewTaxTable *ntt = data; + + if (!ntt) return; + g_free (ntt); +} + +static void +optionmenu_changed (GtkWidget *widget, NewTaxTable *ntt) +{ + g_return_if_fail (ntt); + ntt->type = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), + "option")); +} + +static GtkWidget * +add_menu_item (GtkWidget *menu, NewTaxTable *ntt, char *label, gint type) + +{ + GtkWidget *item; + + item = gtk_menu_item_new_with_label (label); + gtk_object_set_data (GTK_OBJECT (item), "option", GINT_TO_POINTER (type)); + gtk_signal_connect (GTK_OBJECT (item), "activate", optionmenu_changed, ntt); + gtk_menu_append (GTK_MENU (menu), item); + gtk_widget_show (item); + return item; +} + +static GtkWidget * +make_menu (GtkWidget *omenu, NewTaxTable *ntt) +{ + GtkWidget *menu, *value, *percent; + int current = ntt->type; + + menu = gtk_menu_new (); + value= add_menu_item (menu, ntt, _("Value $"), GNC_TAX_TYPE_VALUE); + percent = add_menu_item (menu, ntt, _("Percent %"), GNC_TAX_TYPE_PERCENT); + + gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); + + gtk_signal_emit_by_name (GTK_OBJECT ((current == GNC_TAX_TYPE_VALUE ? + value : percent)), "activate", ntt); + gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), current); + return menu; +} + +static NewTaxTable * +new_tax_table_dialog (TaxTableWindow *ttw, gboolean new_table, + GncTaxTableEntry *entry) +{ + NewTaxTable *ntt; + GladeXML *xml; + GtkWidget *box, *widget; + + if (!ttw) return NULL; + if (new_table && entry) return NULL; + + ntt = g_new0 (NewTaxTable, 1); + ntt->ttw = ttw; + ntt->entry = entry; + ntt->new_table = new_table; + + if (entry) + ntt->type = gncTaxTableEntryGetType (entry); + else + ntt->type = GNC_TAX_TYPE_PERCENT; + + /* Open and read the XML */ + xml = gnc_glade_xml_new ("tax-tables.glade", "New Tax Table Dialog"); + ntt->dialog = glade_xml_get_widget (xml, "New Tax Table Dialog"); + ntt->name_entry = glade_xml_get_widget (xml, "name_entry"); + + /* Create the menu */ + make_menu (glade_xml_get_widget (xml, "type_menu"), ntt); + + /* Attach our own widgets */ + box = glade_xml_get_widget (xml, "amount_box"); + ntt->amount_entry = widget = gnc_amount_edit_new (); + gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (widget), TRUE); + gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0); + + box = glade_xml_get_widget (xml, "account_frame"); + ntt->acct_tree = widget = gnc_account_tree_new (); + gtk_clist_column_titles_hide (GTK_CLIST (widget)); + gnc_account_tree_hide_all_but_name (GNC_ACCOUNT_TREE (widget)); + gtk_container_add (GTK_CONTAINER (box), widget); + gnc_account_tree_refresh(GNC_ACCOUNT_TREE(ntt->acct_tree)); + + /* Make 'enter' do the right thing */ + gnome_dialog_set_default (GNOME_DIALOG (ntt->dialog), 0); + gnome_dialog_editable_enters (GNOME_DIALOG (ntt->dialog), + GTK_EDITABLE (ntt->name_entry)); + gnome_dialog_editable_enters (GNOME_DIALOG (ntt->dialog), + GTK_EDITABLE (gnc_amount_edit_gtk_entry + (GNC_AMOUNT_EDIT (ntt->amount_entry)))); + + /* Connect the dialog buttons */ + gnome_dialog_button_connect (GNOME_DIALOG (ntt->dialog), 0, + new_tax_table_ok_cb, ntt); + + gnome_dialog_button_connect (GNOME_DIALOG (ntt->dialog), 1, + new_tax_table_cancel_cb, ntt); + + /* Fill in the widgets appropriately */ + if (entry) { + gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (ntt->amount_entry), + gncTaxTableEntryGetAmount (entry)); + gnc_account_tree_select_account (GNC_ACCOUNT_TREE (ntt->acct_tree), + gncTaxTableEntryGetAccount (entry), TRUE); + } + + /* Set our modality */ + gnome_dialog_set_parent (GNOME_DIALOG (ntt->dialog), + GTK_WINDOW (ttw->dialog)); + gtk_window_set_modal (GTK_WINDOW (ntt->dialog), TRUE); + + gtk_signal_connect (GTK_OBJECT (ntt->dialog), "destroy", + new_tax_table_dialog_destroy_cb, ntt); + + /* Show what we should */ + gtk_widget_show_all (ntt->dialog); + if (new_table == FALSE) { + widget = glade_xml_get_widget (xml, "table_frame"); + gtk_widget_hide_all (widget); + gtk_widget_grab_focus (gnc_amount_edit_gtk_entry + (GNC_AMOUNT_EDIT (ntt->amount_entry))); + } else + gtk_widget_grab_focus (ntt->name_entry); + + return ntt; +} + +/***********************************************************************/ + +static void +tax_table_entries_refresh (TaxTableWindow *ttw, gboolean new_table) +{ + GList *list; + GtkAdjustment *vadjustment = NULL; + GtkCList *clist; + gfloat save_value = 0.0; + + g_return_if_fail (ttw); + + clist = GTK_CLIST (ttw->entries_clist); + + if (!new_table) { + vadjustment = gtk_clist_get_vadjustment (clist); + if (vadjustment) + save_value = vadjustment->value; + } + + /* Clear the list */ + gtk_clist_freeze (clist); + gtk_clist_clear (clist); + + /* Add the items to the list */ + list = gncTaxTableGetEntries (ttw->current_table); + for ( ; list; list = list->next) { + char *row_text[3]; + gint row; + GncTaxTableEntry *entry = list->data; + Account *acc = gncTaxTableEntryGetAccount (entry); + gnc_numeric amount = gncTaxTableEntryGetAmount (entry); + + row_text[0] = xaccAccountGetFullName (acc, gnc_get_account_separator ()); + switch (gncTaxTableEntryGetType (entry)) { + case GNC_TAX_TYPE_PERCENT: + row_text[1] = + g_strdup_printf ("%s%%", + xaccPrintAmount (amount, + gnc_default_print_info (FALSE))); + break; + default: + row_text[1] = + g_strdup_printf ("%s", + xaccPrintAmount (amount, + gnc_default_print_info (TRUE))); + break; + } + row_text[2] = NULL; + + row = gtk_clist_prepend (clist, row_text); + gtk_clist_set_row_data (clist, row, entry); + gtk_clist_set_selectable (clist, row, TRUE); + + g_free (row_text[0]); + g_free (row_text[1]); + } + + if (!new_table) { + if (vadjustment) { + save_value = CLAMP (save_value, vadjustment->lower, + vadjustment->upper - vadjustment->page_size); + gtk_adjustment_set_value (vadjustment, save_value); + } + } + + gtk_clist_thaw (clist); + + { + gint row = gtk_clist_find_row_from_data (clist, ttw->current_entry); + + if (row < 0) + row = 0; + + gtk_clist_select_row (clist, row, 0); + + /* If this row isn't visible, move it to the center */ + if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_FULL) + gtk_clist_moveto (clist, row, 0, 0.5, 0); + } +} + +static void +tax_table_window_refresh (TaxTableWindow *ttw) +{ + GList *list; + GtkAdjustment *vadjustment; + GtkCList *clist; + gfloat save_value = 0.0; + + g_return_if_fail (ttw); + clist = GTK_CLIST (ttw->names_clist); + + vadjustment = gtk_clist_get_vadjustment (clist); + if (vadjustment) + save_value = vadjustment->value; + + /* Clear the list */ + gtk_clist_freeze (clist); + gtk_clist_clear (clist); + + gnc_gui_component_clear_watches (ttw->component_id); + + /* Add the items to the list */ + list = gncTaxTableGetTables (ttw->book); + + /* If there are no tables, clear the entries list */ + if (list == NULL) + gtk_clist_clear (GTK_CLIST (ttw->entries_clist)); + + for ( ; list; list = list->next) { + char *row_text[2]; + gint row; + GncTaxTable *table = list->data; + + gnc_gui_component_watch_entity (ttw->component_id, + gncTaxTableGetGUID (table), + GNC_EVENT_MODIFY); + + row_text[0] = (char *)gncTaxTableGetName (table); + row_text[1] = NULL; + + row = gtk_clist_prepend (clist, row_text); + gtk_clist_set_row_data (clist, row, table); + gtk_clist_set_selectable (clist, row, TRUE); + } + + gnc_gui_component_watch_entity_type (ttw->component_id, + GNC_TAXTABLE_MODULE_NAME, + GNC_EVENT_CREATE | GNC_EVENT_DESTROY); + + if (vadjustment) { + save_value = CLAMP (save_value, vadjustment->lower, + vadjustment->upper - vadjustment->page_size); + gtk_adjustment_set_value (vadjustment, save_value); + } + + gtk_clist_thaw (clist); + + { + gint row = gtk_clist_find_row_from_data (clist, ttw->current_table); + + if (row < 0) + row = 0; + + gtk_clist_select_row (clist, row, 0); + + /* If this row isn't visible, move it to the center */ + if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_FULL) + gtk_clist_moveto (clist, row, 0, 0.5, 0); + } + /* select_row() above will refresh the entries window */ +} + +static void +tax_table_row_selected (GtkCList *clist, gint row, gint column, + GdkEventButton *event, gpointer user_data) +{ + TaxTableWindow *ttw = user_data; + GncTaxTable *table = gtk_clist_get_row_data (clist, row); + + g_return_if_fail (ttw); + g_return_if_fail (table); + + /* If we've changed, then reset the entry list */ + if (table != ttw->current_table) { + ttw->current_table = table; + ttw->current_entry = NULL; + } + /* And force a refresh of the entries */ + tax_table_entries_refresh (ttw, TRUE); +} + +static void +tax_table_entry_row_selected (GtkCList *clist, gint row, gint column, + GdkEventButton *event, gpointer user_data) +{ + TaxTableWindow *ttw = user_data; + GncTaxTableEntry *entry = gtk_clist_get_row_data (clist, row); + + g_return_if_fail (ttw); + g_return_if_fail (entry); + + ttw->current_entry = entry; + + /* If we double-click an item, then pop up an 'edit' window */ + if (event && event->type == GDK_2BUTTON_PRESS) + new_tax_table_dialog (ttw, FALSE, entry); +} + +static void +tax_table_new_table_cb (GtkButton *button, TaxTableWindow *ttw) +{ + g_return_if_fail (ttw); + new_tax_table_dialog (ttw, TRUE, NULL); +} + +static void +tax_table_delete_table_cb (GtkButton *button, TaxTableWindow *ttw) +{ + g_return_if_fail (ttw); + + if (!ttw->current_table) + return; + + if (gncTaxTableGetRefcount (ttw->current_table) > 0) { + char *message = + g_strdup_printf (_("Tax table \"%s\" is in use. You cannot delete it."), + gncTaxTableGetName (ttw->current_table)); + gnc_error_dialog_parented (GTK_WINDOW (ttw->dialog), message); + g_free (message); + return; + } + + if (gnc_verify_dialog_parented (ttw->dialog, FALSE, + _("Are you sure you want to delete \"%s\"?"), + gncTaxTableGetName (ttw->current_table))) { + /* Ok, let's remove it */ + gnc_suspend_gui_refresh (); + gncTaxTableDestroy (ttw->current_table); + gncTaxTableCommitEdit (ttw->current_table); + ttw->current_table = NULL; + gnc_resume_gui_refresh (); + } +} + +static void +tax_table_new_entry_cb (GtkButton *button, TaxTableWindow *ttw) +{ + g_return_if_fail (ttw); + if (!ttw->current_table) + return; + new_tax_table_dialog (ttw, FALSE, NULL); +} + +static void +tax_table_edit_entry_cb (GtkButton *button, TaxTableWindow *ttw) +{ + g_return_if_fail (ttw); + if (!ttw->current_entry) + return; + new_tax_table_dialog (ttw, FALSE, ttw->current_entry); +} + +static void +tax_table_delete_entry_cb (GtkButton *button, TaxTableWindow *ttw) +{ + g_return_if_fail (ttw); + if (!ttw->current_table || !ttw->current_entry) + return; + + if (gnc_verify_dialog_parented (ttw->dialog, FALSE, + _("Are you sure you want to delete this entry?"))) { + /* Ok, let's remove it */ + gnc_suspend_gui_refresh (); + gncTaxTableRemoveEntry (ttw->current_table, ttw->current_entry); + gncTaxTableEntryDestroy (ttw->current_entry); + gncTaxTableChanged (ttw->current_table); + gncTaxTableCommitEdit (ttw->current_table); + ttw->current_entry = NULL; + gnc_resume_gui_refresh (); + } +} + +static void +tax_table_window_refresh_handler (GHashTable *changes, gpointer data) +{ + TaxTableWindow *ttw = data; + + g_return_if_fail (data); + tax_table_window_refresh (ttw); +} + +static void +tax_table_window_close_handler (gpointer data) +{ + TaxTableWindow *ttw = data; + g_return_if_fail (ttw); + gnome_dialog_close (GNOME_DIALOG (ttw->dialog)); +} + +static void +tax_table_window_close (GtkWidget *widget, gpointer data) +{ + TaxTableWindow *ttw = data; + + gnc_ui_tax_table_window_destroy (ttw); +} + +static void +tax_table_window_destroy_cb (GtkWidget *widget, gpointer data) +{ + TaxTableWindow *ttw = data; + + if (!ttw) return; + + gnc_unregister_gui_component (ttw->component_id); + + g_free (ttw); +} + +static gboolean +find_handler (gpointer find_data, gpointer user_data) +{ + TaxTableWindow *ttw = user_data; + GNCBook *book = find_data; + + return (ttw != NULL && ttw->book == book); +} + +/* Create a tax-table window */ +TaxTableWindow * +gnc_ui_tax_table_window_new (GNCBook *book) +{ + TaxTableWindow *ttw; + GladeXML *xml; + GtkWidget *button; + + if (!book) return NULL; + + /* + * Find an existing tax-tab;e window. If found, bring it to + * the front. If we have an actual owner, then set it in + * the window. + */ + ttw = gnc_find_first_gui_component (DIALOG_TAX_TABLE_CM_CLASS, find_handler, + book); + if (ttw) { + gtk_window_present (GTK_WINDOW(ttw->dialog)); + return ttw; + } + + /* Didn't find one -- create a new window */ + ttw = g_new0 (TaxTableWindow, 1); + ttw->book = book; + + /* Open and read the XML */ + xml = gnc_glade_xml_new ("tax-tables.glade", "Tax Table Window"); + ttw->dialog = glade_xml_get_widget (xml, "Tax Table Window"); + ttw->names_clist = glade_xml_get_widget (xml, "tax_tables_clist"); + ttw->entries_clist = glade_xml_get_widget (xml, "tax_table_entries"); + + /* Connect all the buttons */ + button = glade_xml_get_widget (xml, "new_table_button"); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + tax_table_new_table_cb, ttw); + button = glade_xml_get_widget (xml, "delete_table_button"); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + tax_table_delete_table_cb, ttw); + button = glade_xml_get_widget (xml, "new_entry_button"); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + tax_table_new_entry_cb, ttw); + button = glade_xml_get_widget (xml, "edit_entry_button"); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + tax_table_edit_entry_cb, ttw); + button = glade_xml_get_widget (xml, "delete_entry_button"); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + tax_table_delete_entry_cb, ttw); + + /* Set the row-select callbacks */ + gtk_signal_connect (GTK_OBJECT (ttw->names_clist), "select-row", + tax_table_row_selected, ttw); + gtk_signal_connect (GTK_OBJECT (ttw->entries_clist), "select-row", + tax_table_entry_row_selected, ttw); + + /* Connect the dialog buttons */ + gnome_dialog_button_connect (GNOME_DIALOG (ttw->dialog), 0, + tax_table_window_close, ttw); + + gtk_signal_connect (GTK_OBJECT (ttw->dialog), "destroy", + tax_table_window_destroy_cb, ttw); + + /* register with component manager */ + ttw->component_id = + gnc_register_gui_component (DIALOG_TAX_TABLE_CM_CLASS, + tax_table_window_refresh_handler, + tax_table_window_close_handler, + ttw); + + tax_table_window_refresh (ttw); + gtk_widget_show_all (ttw->dialog); + return ttw; +} + +/* Destroy a tax-table window */ +void +gnc_ui_tax_table_window_destroy (TaxTableWindow *ttw) +{ + if (!ttw) + return; + + gnc_close_gui_component (ttw->component_id); +} diff --git a/src/business/business-gnome/dialog-tax-table.h b/src/business/business-gnome/dialog-tax-table.h new file mode 100644 index 0000000000..ae50d520dc --- /dev/null +++ b/src/business/business-gnome/dialog-tax-table.h @@ -0,0 +1,20 @@ +/* + * dialog-tax-table.h -- Dialog to create and edit tax-tables + * Copyright (C) 2002 Derek Atkins + * Author: Derek Atkins + */ + +#ifndef _DIALOG_TAX_TABLE_H +#define _DIALOG_TAX_TABLE_H + +typedef struct _taxtable_window TaxTableWindow; + +#include "gnc-book.h" + +/* Create a tax-table window */ +TaxTableWindow * gnc_ui_tax_table_window_new (GNCBook *book); + +/* Destroy a tax-table window */ +void gnc_ui_tax_table_window_destroy (TaxTableWindow *ttw); + +#endif /* _DIALOG_TAX-TABLE_H */ diff --git a/src/business/business-gnome/gw-business-gnome-spec.scm b/src/business/business-gnome/gw-business-gnome-spec.scm index a23b5b004e..9f39cd2170 100644 --- a/src/business/business-gnome/gw-business-gnome-spec.scm +++ b/src/business/business-gnome/gw-business-gnome-spec.scm @@ -38,6 +38,7 @@ "#include \n" "#include \n" "#include \n" + "#include \n" "#include \n" ))) @@ -205,6 +206,18 @@ '(( owner) ( book)) "Dialog: Enter a payment. The owner may be NULL.") + ;; + ;; dialog-tax-table.h + ;; + + (gw:wrap-function + ws + 'gnc:tax-table-new + ' + "gnc_ui_tax_table_window_new" + '(( book)) + "Dialog: Edit the Tax Tables.") + ;; ;; dialog-vendor.h ;; diff --git a/src/business/business-gnome/tax-tables.glade b/src/business/business-gnome/tax-tables.glade new file mode 100644 index 0000000000..23245d5c45 --- /dev/null +++ b/src/business/business-gnome/tax-tables.glade @@ -0,0 +1,584 @@ + + + + + Tax Tables + tax-tables + + src + pixmaps + C + True + True + False + False + False + + + + GnomeDialog + Tax Table Window + Tax Tables + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox1 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area1 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + close_button + True + True + GNOME_STOCK_BUTTON_CLOSE + + + + + GtkHBox + hbox1 + False + 0 + + 0 + True + True + + + + GtkFrame + frame1 + 1 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkVBox + vbox1 + 2 + False + 0 + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkCList + tax_tables_clist + True + 1 + 80 + GTK_SELECTION_SINGLE + False + GTK_SHADOW_IN + + + GtkLabel + CList:title + label1 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkHBox + hbox2 + True + 0 + + 0 + False + True + + + + GtkButton + new_table_button + True + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + delete_table_button + True + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + + + + GtkFrame + frame2 + 1 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkVBox + vbox2 + 2 + False + 0 + + + GtkScrolledWindow + scrolledwindow2 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkCList + tax_table_entries + True + 2 + 80,80 + GTK_SELECTION_SINGLE + False + GTK_SHADOW_IN + + + GtkLabel + CList:title + label8 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label9 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkHBox + hbox3 + True + 0 + + 0 + False + True + + + + GtkButton + new_entry_button + True + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + edit_entry_button + True + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + delete_entry_button + True + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + + + + + + + GnomeDialog + New Tax Table Dialog + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox2 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area2 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + ok_button + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + cancel_button + True + True + GNOME_STOCK_BUTTON_CANCEL + + + + + GtkVBox + vbox3 + False + 0 + + 0 + True + True + + + + GtkFrame + table_frame + 2 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkHBox + hbox4 + 3 + False + 0 + + + GtkLabel + label5 + + GTK_JUSTIFY_RIGHT + False + 1 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + name_entry + True + True + True + 0 + + + 0 + True + True + + + + + + + GtkFrame + frame4 + 3 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkVBox + vbox4 + 3 + False + 0 + + + GtkHBox + hbox5 + False + 0 + + 0 + False + True + + + + GtkVBox + vbox5 + True + 0 + + 0 + False + True + + + + GtkLabel + label6 + + GTK_JUSTIFY_RIGHT + False + 1 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkLabel + label7 + + GTK_JUSTIFY_RIGHT + False + 1 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + GtkVBox + vbox6 + True + 0 + + 0 + True + True + + + + GtkHBox + hbox7 + False + 0 + + 0 + False + False + + + + GtkOptionMenu + type_menu + True + Value ($) +Percent (%) + + 1 + + 0 + False + False + + + + + + GtkHBox + amount_box + False + 0 + + 0 + True + True + + + + Placeholder + + + + + + + GtkFrame + account_frame + 4 + + 0 + GTK_SHADOW_NONE + + 0 + True + True + + + + Placeholder + + + + + + + + +