From 2e15b07299c2ce8a1c802aeead91988e693e80b4 Mon Sep 17 00:00:00 2001 From: Derek Atkins Date: Sat, 18 Jan 2003 21:48:16 +0000 Subject: [PATCH] * src/business/business-core/gncTaxTable.[ch]: add functions to get the GUID and lookup by direct GUID (suitable for wrapping) * src/business/business-core/gw-business-core-spec.scm: wrap the taxtable get-guid and lookup methods * src/business/business-gnome/business-utils.[ch]: re-implement the "generic option menu" code to allow get_value(), set_value(), and changed_callback() functions. * src/business/business-gnome/business-options.c: create a taxtable option type using the new generic optionmenu code * src/business/business-gnome/business-options.scm: define a taxtable option. Also fix all the other options when using a KVP storage to actually load and save the options properly * src/business/business-gnome/business-prefs.scm: create a default customer and default vendor taxtable option for the "File Properties" option menu. Initial fix for #93462. Next commit will actually use the values. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7843 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 20 +++ src/business/business-core/gncTaxTable.c | 13 ++ src/business/business-core/gncTaxTable.h | 2 + .../business-core/gw-business-core-spec.scm | 20 +++ .../business-gnome/business-options.c | 76 ++++++++++ .../business-gnome/business-options.scm | 89 ++++++++++-- .../business-gnome/business-prefs.scm | 15 +- src/business/business-gnome/business-utils.c | 136 +++++++++++++++--- src/business/business-gnome/business-utils.h | 14 ++ 9 files changed, 356 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f9cd38363..9f8c4fd285 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2003-01-18 Derek Atkins + + * src/business/business-core/gncTaxTable.[ch]: add functions to + get the GUID and lookup by direct GUID (suitable for wrapping) + * src/business/business-core/gw-business-core-spec.scm: wrap + the taxtable get-guid and lookup methods + * src/business/business-gnome/business-utils.[ch]: re-implement + the "generic option menu" code to allow get_value(), set_value(), + and changed_callback() functions. + * src/business/business-gnome/business-options.c: create a taxtable + option type using the new generic optionmenu code + * src/business/business-gnome/business-options.scm: define a taxtable + option. Also fix all the other options when using a KVP storage + to actually load and save the options properly + * src/business/business-gnome/business-prefs.scm: create a default + customer and default vendor taxtable option for the "File Properties" + option menu. + + Initial fix for #93462. Next commit will actually use the values. + 2003-01-16 Derek Atkins * src/engine/commodity-table.scm: move gnc:commodity-is-currency? here diff --git a/src/business/business-core/gncTaxTable.c b/src/business/business-core/gncTaxTable.c index 6b3aa19104..e40c68b780 100644 --- a/src/business/business-core/gncTaxTable.c +++ b/src/business/business-core/gncTaxTable.c @@ -603,6 +603,19 @@ void gncAccountValueDestroy (GList *list) g_list_free (list); } +GUID gncTaxTableRetGUID (GncTaxTable *table) +{ + if (!table) + return *xaccGUIDNULL(); + + return table->guid; +} + +GncTaxTable *gncTaxTableLookupDirect (GUID guid, GNCBook *book) +{ + if (!book) return NULL; + return gncTaxTableLookup (book, &guid); +} /* Package-Private functions */ diff --git a/src/business/business-core/gncTaxTable.h b/src/business/business-core/gncTaxTable.h index 3101f89d9d..d6a2dbffc9 100644 --- a/src/business/business-core/gncTaxTable.h +++ b/src/business/business-core/gncTaxTable.h @@ -84,6 +84,8 @@ gnc_numeric gncTaxTableEntryGetAmount (GncTaxTableEntry *entry); int gncTaxTableCompare (GncTaxTable *a, GncTaxTable *b); int gncTaxTableEntryCompare (GncTaxTableEntry *a, GncTaxTableEntry *b); +GUID gncTaxTableRetGUID (GncTaxTable *table); +GncTaxTable *gncTaxTableLookupDirect (GUID guid, GNCBook *book); /************************************************/ diff --git a/src/business/business-core/gw-business-core-spec.scm b/src/business/business-core/gw-business-core-spec.scm index 07c4d3666a..3f69131618 100644 --- a/src/business/business-core/gw-business-core-spec.scm +++ b/src/business/business-core/gw-business-core-spec.scm @@ -1039,6 +1039,26 @@ '(( owner)) "Return the owner's currency") + ;; + ;; gncTaxTable.h + ;; + + (gw:wrap-function + ws + 'gnc:taxtable-get-guid + ' + "gncTaxTableRetGUID" + '(( taxtable)) + "Return the GUID of the taxtable") + + (gw:wrap-function + ws + 'gnc:taxtable-lookup + ' + "gncTaxTableLookupDirect" + '(( guid) ( book)) + "Lookup the tax table with GUID guid.") + ;; ;; gncVendor.h ;; diff --git a/src/business/business-gnome/business-options.c b/src/business/business-gnome/business-options.c index a3346323ab..bdda7b75f7 100644 --- a/src/business/business-gnome/business-options.c +++ b/src/business/business-gnome/business-options.c @@ -352,6 +352,81 @@ invoice_get_value (GNCOption *option, GtkWidget *widget) } +/********************************************************************/ +/* "Tax Table" Option functions */ + + +static GtkWidget * +create_taxtable_widget (GNCOption *option, GtkWidget *hbox) +{ + GtkWidget *widget; + + widget = gtk_option_menu_new (); + + gnc_ui_taxtables_optionmenu (widget, gnc_get_current_book (), TRUE, NULL); + + gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0); + gnc_option_set_widget (option, widget); + + gnc_ui_optionmenu_set_changed_callback (widget, + (void(*)(GtkWidget*,gpointer))option_changed_cb, + option); + + return widget; +} + +/* Function to set the UI widget based upon the option */ +static GtkWidget * +taxtable_set_widget (GNCOption *option, GtkBox *page_box, + GtkTooltips *tooltips, + char *name, char *documentation, + /* Return values */ + GtkWidget **enclosing, gboolean *packed) +{ + GtkWidget *value; + GtkWidget *label; + + *enclosing = gtk_hbox_new (FALSE, 5); + label = make_name_label (name); + gtk_box_pack_start (GTK_BOX (*enclosing), label, FALSE, FALSE, 0); + + value = create_taxtable_widget (option, *enclosing); + + gnc_option_set_ui_value (option, FALSE); + + gtk_widget_show_all (*enclosing); + return value; +} + +/* Function to set the UI Value for a particular option */ +static gboolean +taxtable_set_value (GNCOption *option, gboolean use_default, + GtkWidget *widget, SCM value) +{ + GncTaxTable *taxtable; + + if (!gw_wcp_p (value)) + scm_misc_error("business_options:taxtable_set_value", + "Item is not a gw:wcp.", value); + + taxtable = gw_wcp_get_ptr (value); + + widget = gnc_option_get_widget (option); + gnc_ui_optionmenu_set_value (widget, taxtable); + return FALSE; +} + +/* Function to get the UI Value for a particular option */ +static SCM +taxtable_get_value (GNCOption *option, GtkWidget *widget) +{ + GncTaxTable *taxtable; + + taxtable = gnc_ui_optionmenu_get_value (widget); + return gw_wcp_assimilate_ptr (taxtable, gh_eval_str("")); +} + + void @@ -364,6 +439,7 @@ gnc_business_options_initialize (void) customer_get_value }, { "vendor", vendor_set_widget, vendor_set_value, vendor_get_value }, { "invoice", invoice_set_widget, invoice_set_value, invoice_get_value }, + { "taxtable", taxtable_set_widget, taxtable_set_value, taxtable_get_value }, { NULL } }; diff --git a/src/business/business-gnome/business-options.scm b/src/business/business-gnome/business-options.scm index 02b8b24868..3e2a81ccc0 100644 --- a/src/business/business-gnome/business-options.scm +++ b/src/business/business-gnome/business-options.scm @@ -71,11 +71,13 @@ (gnc:error "Illegal invoice value set")))) (lambda () (convert-to-invoice (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (gnc:kvp-frame-set-slot-path f value p)) + (lambda (f p) (gnc:kvp-frame-set-slot-path f option p)) (lambda (f p) (let ((v (gnc:kvp-frame-get-slot-path f p))) (if (and v (string? v)) - (set! value v)))) + (begin + (set! option v) + (set! option-set #t))))) validator #f #f #f #f))) @@ -130,11 +132,13 @@ (gnc:error "Illegal customer value set")))) (lambda () (convert-to-customer (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (gnc:kvp-frame-set-slot-path f value p)) + (lambda (f p) (gnc:kvp-frame-set-slot-path f option p)) (lambda (f p) (let ((v (gnc:kvp-frame-get-slot-path f p))) (if (and v (string? v)) - (set! value v)))) + (begin + (set! option v) + (set! option-set #t))))) validator #f #f #f #f))) @@ -189,11 +193,13 @@ (gnc:error "Illegal vendor value set")))) (lambda () (convert-to-vendor (default-getter))) (gnc:restore-form-generator value->string) - (lambda (f p) (gnc:kvp-frame-set-slot-path f value p)) + (lambda (f p) (gnc:kvp-frame-set-slot-path f option p)) (lambda (f p) (let ((v (gnc:kvp-frame-get-slot-path f p))) (if (and v (string? v)) - (set! value v)))) + (begin + (set! option v) + (set! option-set #t))))) validator #f #f #f #f))) @@ -283,19 +289,84 @@ (lambda () (convert-to-owner (default-getter))) (gnc:restore-form-generator value->string) (lambda (f p) - (gnc:kvp-frame-set-slot-path f (symbol->string (car value)) + (gnc:kvp-frame-set-slot-path f (symbol->string (car option)) (append p '("type"))) - (gnc:kvp-frame-set-slot-path f (cdr value) + (gnc:kvp-frame-set-slot-path f (cdr option) (append p '("value")))) (lambda (f p) (let ((t (gnc:kvp-frame-get-slot-path f (append p '("type")))) (v (gnc:kvp-frame-get-slot-path f (append p '("value"))))) (if (and t v (string? t) (string? v)) - (set! value (cons (string->symbol t) v))))) + (begin + (set! option (cons (string->symbol t) v)) + (set! option-set #t))))) validator owner-type #f #f #f)))) + +;; Internally, values are always a guid. Externally, both guids and +;; taxtable pointers may be used to set the value of the option. The +;; option always returns a single taxtable pointer. + +(define (gnc:make-taxtable-option + section + name + sort-tag + documentation-string + default-getter + value-validator) + + (define (convert-to-guid item) + (if (string? item) + item + (gnc:taxtable-get-guid item))) + + (define (convert-to-taxtable item) + (if (string? item) + (gnc:taxtable-lookup item (gnc:get-current-book)) + item)) + + (let* ((option (convert-to-guid (default-getter))) + (option-set #f) + (getter (lambda () (convert-to-taxtable + (if option-set + option + (default-getter))))) + (value->string (lambda () + (string-append + "'" (gnc:value->string (if option-set option #f))))) + (validator + (if (not value-validator) + (lambda (taxtable) (list #t taxtable)) + (lambda (taxtable) + (value-validator (convert-to-taxtable taxtable)))))) + (gnc:make-option + section name sort-tag 'taxtable documentation-string getter + (lambda (taxtable) + (if (not taxtable) (set! taxtable (default-getter))) + (set! taxtable (convert-to-taxtable taxtable)) + (let* ((result (validator taxtable)) + (valid (car result)) + (value (cadr result))) + (if valid + (begin + (set! option (convert-to-guid value)) + (set! option-set #t)) + (gnc:error "Illegal taxtable value set")))) + (lambda () (convert-to-taxtable (default-getter))) + (gnc:restore-form-generator value->string) + (lambda (f p) (gnc:kvp-frame-set-slot-path f option p)) + (lambda (f p) + (let ((v (gnc:kvp-frame-get-slot-path f p))) + (if (and v (string? v)) + (begin + (set! option v) + (set! option-set #t))))) + validator + #f #f #f #f))) + (export gnc:make-invoice-option) (export gnc:make-customer-option) (export gnc:make-vendor-option) (export gnc:make-owner-option) +(export gnc:make-taxtable-option) diff --git a/src/business/business-gnome/business-prefs.scm b/src/business/business-gnome/business-prefs.scm index 9e97d04758..f7c1739317 100644 --- a/src/business/business-gnome/business-prefs.scm +++ b/src/business/business-gnome/business-prefs.scm @@ -66,6 +66,19 @@ (reg-option (gnc:make-text-option gnc:*business-label* gnc:*company-addy* - "b" (N_ "The address of your business") ""))) + "b" (N_ "The address of your business") "")) + + (reg-option + (gnc:make-taxtable-option + gnc:*business-label* (N_ "Default Customer TaxTable") + "e" (N_ "The default tax table to apply to customers.") + (lambda () #f) #f)) + + (reg-option + (gnc:make-taxtable-option + gnc:*business-label* (N_ "Default Vendor TaxTable") + "f" (N_ "The default tax table to apply to vendors.") + (lambda () #f) #f)) +) (gnc:register-kvp-option-generator gnc:id-book book-options-generator) diff --git a/src/business/business-gnome/business-utils.c b/src/business/business-gnome/business-utils.c index 048c0a4a9e..d2afee8847 100644 --- a/src/business/business-gnome/business-utils.c +++ b/src/business/business-gnome/business-utils.c @@ -225,33 +225,49 @@ typedef struct { gint component_id; GtkWidget * omenu; GNCBook * book; - gpointer * result; gboolean none_ok; const char * (*get_name)(gpointer); GList * (*get_list)(GNCBook*); + + gboolean building_menu; + gpointer result; + gpointer * result_p; + + void (*changed_cb)(GtkWidget*, gpointer); + gpointer cb_arg; } OpMenuData; #define DO_ADD_ITEM(s,o) { \ - add_menu_item (menu, (s), omd->result, (o)); \ - if (*(omd->result) == (o)) current = index; \ + add_menu_item (menu, (s), omd, (o)); \ + if (omd->result == (o)) current = index; \ index++; \ } static void -business_option_changed (GtkWidget *widget, gpointer *result) +business_option_changed (GtkWidget *widget, gpointer data) { - *result = - gtk_object_get_data (GTK_OBJECT (widget), "this_item"); + OpMenuData *omd = data; + + g_return_if_fail (omd); + omd->result = gtk_object_get_data (GTK_OBJECT (widget), "this_item"); + + if (!omd->building_menu) { + if (omd->result_p) + *(omd->result_p) = omd->result; + + if (omd->changed_cb) + (omd->changed_cb)(omd->omenu, omd->cb_arg); + } } static void -add_menu_item (GtkWidget *menu, const char *label, gpointer *result, +add_menu_item (GtkWidget *menu, const char *label, OpMenuData *omd, gpointer this_item) { GtkWidget *item = gtk_menu_item_new_with_label (label); gtk_object_set_data (GTK_OBJECT (item), "this_item", this_item); gtk_signal_connect (GTK_OBJECT (item), "activate", - business_option_changed, result); + business_option_changed, omd); gtk_menu_append (GTK_MENU (menu), item); gtk_widget_show (item); } @@ -272,11 +288,18 @@ build_generic_optionmenu (OpMenuData *omd) GtkWidget *menu; int current = 0, index = 0; + /* Make sure we can "get_list" */ + if (omd->get_list == NULL) + return; + /* Get the list of items */ items = (omd->get_list)(omd->book); + /* Make a menu */ menu = gtk_menu_new (); + omd->building_menu = TRUE; + if (omd->none_ok || items == NULL) DO_ADD_ITEM (_("None"), NULL); @@ -286,6 +309,8 @@ build_generic_optionmenu (OpMenuData *omd) gtk_option_menu_set_menu (GTK_OPTION_MENU (omd->omenu), menu); gtk_option_menu_set_history (GTK_OPTION_MENU (omd->omenu), current); gtk_widget_show (menu); + + omd->building_menu = FALSE; } static void @@ -295,7 +320,7 @@ generic_omenu_refresh_handler (GHashTable *changes, gpointer user_data) build_generic_optionmenu (omd); } -static void +static OpMenuData * make_generic_optionmenu (GtkWidget *omenu, GNCBook *book, gboolean none_ok, GNCIdType type_name, GList * (*get_list)(GNCBook*), @@ -315,20 +340,25 @@ make_generic_optionmenu (GtkWidget *omenu, GNCBook *book, omd = g_new0 (OpMenuData, 1); omd->omenu = omenu; omd->book = book; - omd->result = result; + omd->result_p = result; omd->none_ok = none_ok; omd->get_name = get_name; omd->get_list = get_list; gtk_object_set_data (GTK_OBJECT (omenu), "menu-data", omd); + if (result) + omd->result = *result; + omd->component_id = gnc_register_gui_component ("generic-omenu-refresh-hook", generic_omenu_refresh_handler, NULL, omd); - gnc_gui_component_watch_entity_type (omd->component_id, - type_name, - GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); + + if (type_name) + gnc_gui_component_watch_entity_type (omd->component_id, + type_name, + GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); gtk_signal_connect (GTK_OBJECT (omenu), "destroy", generic_omenu_destroy_cb, omd); @@ -336,6 +366,68 @@ make_generic_optionmenu (GtkWidget *omenu, GNCBook *book, } build_generic_optionmenu (omd); + + return omd; +} + +void +gnc_ui_optionmenu_set_changed_callback (GtkWidget *omenu, + void (*changed_cb)(GtkWidget*,gpointer), + gpointer cb_arg) +{ + OpMenuData *omd; + + if (!omenu) return; + + omd = gtk_object_get_data (GTK_OBJECT (omenu), "menu-data"); + g_return_if_fail (omd); + + omd->changed_cb = changed_cb; + omd->cb_arg = cb_arg; +} + +gpointer +gnc_ui_optionmenu_get_value (GtkWidget *omenu) +{ + OpMenuData *omd; + + if (!omenu) return NULL; + + omd = gtk_object_get_data (GTK_OBJECT (omenu), "menu-data"); + g_return_val_if_fail (omd, NULL); + + return omd->result; +} + +void +gnc_ui_optionmenu_set_value (GtkWidget *omenu, gpointer data) +{ + OpMenuData *omd; + GtkWidget *menu; + GList *node; + gint counter; + + if (!omenu) return; + + omd = gtk_object_get_data (GTK_OBJECT (omenu), "menu-data"); + g_return_if_fail (omd); + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (omenu)); + g_return_if_fail (menu); + + /* now walk all the children until we find our object */ + for (counter = 0, node = ((GTK_MENU_SHELL (menu))->children); + node; + node = node->next, counter++) + { + GtkObject *menuitem = node->data; + gpointer this_object = gtk_object_get_data (menuitem, "this_item"); + + if (this_object == data) { + gtk_option_menu_set_history (GTK_OPTION_MENU (omd->omenu), counter); + return; + } + } } /* Create an optionmenu of available billing terms and attach it to @@ -349,7 +441,7 @@ void gnc_ui_billterms_optionmenu (GtkWidget *omenu, GNCBook *book, gboolean none_ok, GncBillTerm **choice) { - if (!omenu || !book || !choice) return; + if (!omenu || !book) return; make_generic_optionmenu (omenu, book, none_ok, GNC_BILLTERM_MODULE_NAME, gncBillTermGetTerms, @@ -361,7 +453,7 @@ void gnc_ui_taxtables_optionmenu (GtkWidget *omenu, GNCBook *book, gboolean none_ok, GncTaxTable **choice) { - if (!omenu || !book || !choice) return; + if (!omenu || !book) return; make_generic_optionmenu (omenu, book, none_ok, GNC_TAXTABLE_MODULE_NAME, gncTaxTableGetTables, @@ -373,23 +465,29 @@ void gnc_ui_taxincluded_optionmenu (GtkWidget *omenu, GncTaxIncluded *choice) { GtkWidget *menu; + OpMenuData *omd; int current = 0, index = 0; - if (!omenu || !choice) return; + if (!omenu) return; + + omd = make_generic_optionmenu (omenu, NULL, FALSE, NULL, NULL, NULL, + (gpointer *)choice); + + g_return_if_fail (omd); menu = gtk_menu_new (); - add_menu_item (menu, _("Yes"), (gpointer *)choice, + add_menu_item (menu, _("Yes"), omd, GINT_TO_POINTER (GNC_TAXINCLUDED_YES)); if (*choice == GNC_TAXINCLUDED_YES) current = index; index++; - add_menu_item (menu, _("No"), (gpointer *)choice, + add_menu_item (menu, _("No"), omd, GINT_TO_POINTER (GNC_TAXINCLUDED_NO)); if (*choice == GNC_TAXINCLUDED_NO) current = index; index++; - add_menu_item (menu, _("Use Global"), (gpointer *)choice, + add_menu_item (menu, _("Use Global"), omd, GINT_TO_POINTER (GNC_TAXINCLUDED_USEGLOBAL)); if (*choice == GNC_TAXINCLUDED_USEGLOBAL) current = index; index++; diff --git a/src/business/business-gnome/business-utils.h b/src/business/business-gnome/business-utils.h index 20a2df8955..a6eb7fd961 100644 --- a/src/business/business-gnome/business-utils.h +++ b/src/business/business-gnome/business-utils.h @@ -49,4 +49,18 @@ gnc_ui_taxtables_optionmenu (GtkWidget *omenu, GNCBook *book, /* Build an option menu for choosing a GncTaxIncluded */ void gnc_ui_taxincluded_optionmenu (GtkWidget *omenu, GncTaxIncluded *choice); + +/* Here are some "generic option menu" utilities that can be used with + * ANY of the above option-menu types. In particular the following + * functions are useful for hooking the above option menus into the + * GNC Option infrastructure. + */ + +void gnc_ui_optionmenu_set_changed_callback (GtkWidget *omenu, + void (*changed_cb)(GtkWidget*,gpointer), + gpointer cb_arg); +gpointer gnc_ui_optionmenu_get_value (GtkWidget *omenu); +void gnc_ui_optionmenu_set_value (GtkWidget *omenu, gpointer data); + + #endif /* GNC_BUSINESS_UTILS_H_ */