From 110d61b9d682732457e28cb610e867361b5bf973 Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Fri, 24 Aug 2001 09:01:34 +0000 Subject: [PATCH] Implement per-cell entry handlers in register. Add test for printing & parsing amounts. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@5227 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/app-utils/test/Makefile.am | 10 +- src/app-utils/test/test-print-parse-amount.c | 90 +++++++++++++ src/backend/file/test/test-xml-pricedb.c | 3 +- .../ledger-core/split-register-model.c | 7 +- src/register/register-core/datecell.h | 2 +- src/register/register-core/pricecell.h | 4 +- src/register/register-core/recncell.h | 4 +- src/register/register-core/table-allgui.c | 25 +++- src/register/register-core/table-model.c | 120 ++++++++++++++++++ src/register/register-core/table-model.h | 11 +- 10 files changed, 257 insertions(+), 19 deletions(-) create mode 100644 src/app-utils/test/test-print-parse-amount.c diff --git a/src/app-utils/test/Makefile.am b/src/app-utils/test/Makefile.am index 8a8f4013b8..3bd5dd8ef0 100644 --- a/src/app-utils/test/Makefile.am +++ b/src/app-utils/test/Makefile.am @@ -1,7 +1,8 @@ TESTS = \ test-link-module \ test-load-module \ - test-exp-parser + test-exp-parser \ + test-print-parse-amount TESTS_ENVIRONMENT= \ GNC_MODULE_PATH=../../engine:../../gnc-module:../../calculation:.. \ @@ -18,17 +19,20 @@ LDADD = \ ../libgncmod-app-utils.la \ ../../engine/libgw-engine.la \ ${top_srcdir}/src/engine/libgw-glib.la \ - ${top_srcdir}/src/test-core/libgncmod-test.la + ${top_srcdir}/src/test-core/libgncmod-test.la \ + ${top_srcdir}/src/engine/test-core/libgncmod-test-engine.la bin_PROGRAMS = \ test-link-module \ - test-exp-parser + test-exp-parser \ + test-print-parse-amount EXTRA_DIST = test-load-module INCLUDES = \ -I${top_srcdir}/src/test-core \ -I${top_srcdir}/src/engine \ + -I${top_srcdir}/src/engine/test-core \ -I.. CFLAGS = @CFLAGS@ ${GLIB_CFLAGS} diff --git a/src/app-utils/test/test-print-parse-amount.c b/src/app-utils/test/test-print-parse-amount.c new file mode 100644 index 0000000000..c97d124cf9 --- /dev/null +++ b/src/app-utils/test/test-print-parse-amount.c @@ -0,0 +1,90 @@ +#include +#include + +#include "gnc-ui-util.h" +#include "gnc-numeric.h" +#include "test-engine-stuff.h" +#include "test-stuff.h" + + +static void +test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info) +{ + gnc_numeric n_parsed; + const char *s; + gboolean ok; + + s = xaccPrintAmount (n, print_info); + + ok = xaccParseAmount (s, print_info.monetary, &n_parsed, NULL); + + do_test_args (ok, "parsing failure", __FILE__, __LINE__, + "num: %s, string %s", gnc_numeric_to_string (n), s); + + ok = gnc_numeric_equal (n, n_parsed); + + do_test_args (ok, "not equal", __FILE__, __LINE__, + "start: %s, string %s, finish: %s", + gnc_numeric_to_string (n), s, + gnc_numeric_to_string (n_parsed)); +} + +static void +test_num (gnc_numeric n) +{ + GNCPrintAmountInfo print_info; + int fraction; + int i; + + print_info.commodity = NULL; + print_info.min_decimal_places = 0; + print_info.use_locale = 1; + print_info.use_symbol = 0; + + for (i = 1, fraction = 10; i < 9; i++, fraction *= 10) + { + gnc_numeric n1; + + print_info.use_separators = 1; + print_info.monetary = 1; + print_info.max_decimal_places = i; + + n1 = gnc_numeric_convert (n, fraction, GNC_RND_ROUND); + + test_num_print_info (n1, print_info); + + print_info.monetary = 0; + test_num_print_info (n1, print_info); + + print_info.use_separators = 0; + test_num_print_info (n1, print_info); + } +} + +static void +run_tests (void) +{ + int i; + + for (i = 0; i < 50; i++) + { + gnc_numeric n; + + n = get_random_gnc_numeric (); + test_num (n); + + n = gnc_numeric_mul (n, n, n.denom, GNC_RND_ROUND); + test_num (n); + + n = gnc_numeric_mul (n, n, n.denom, GNC_RND_ROUND); + test_num (n); + } +} + +int +main (int argc, char **argv) +{ + run_tests (); + print_test_results (); + exit (get_rv ()); +} diff --git a/src/backend/file/test/test-xml-pricedb.c b/src/backend/file/test/test-xml-pricedb.c index e4147d49a7..106a23095c 100644 --- a/src/backend/file/test/test-xml-pricedb.c +++ b/src/backend/file/test/test-xml-pricedb.c @@ -111,7 +111,8 @@ test_generation (void) db = get_random_pricedb (); - test_db (i, db); + if (gnc_pricedb_get_num_prices (db)) + test_db (i, db); gnc_pricedb_destroy (db); } diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c index 5d006acc70..37b0ba3c13 100644 --- a/src/register/ledger-core/split-register-model.c +++ b/src/register/ledger-core/split-register-model.c @@ -1048,11 +1048,13 @@ gnc_split_register_model_new (void) model = gnc_table_model_new (); + gnc_table_model_set_default_entry_handler (model, + gnc_split_register_get_entry); + model->label_handler = gnc_split_register_get_label; model->fg_color_handler = gnc_split_register_get_fg_color; model->bg_color_handler = gnc_split_register_get_bg_color; model->cell_border_handler = gnc_split_register_get_border; - model->entry_handler = gnc_split_register_get_entry; model->io_flag_handler = gnc_split_register_get_io_flags; model->confirm_handler = gnc_split_register_confirm; @@ -1072,7 +1074,8 @@ gnc_template_register_model_new (void) model = gnc_split_register_model_new (); - model->entry_handler = gnc_template_register_get_entry; + gnc_table_model_set_default_entry_handler (model, + gnc_template_register_get_entry); gnc_template_register_model_add_save_handlers (model); diff --git a/src/register/register-core/datecell.h b/src/register/register-core/datecell.h index f6aa0ab3d9..4413892914 100644 --- a/src/register/register-core/datecell.h +++ b/src/register/register-core/datecell.h @@ -100,7 +100,7 @@ #include "date.h" -typedef struct _DateCell +typedef struct date_cell { BasicCell cell; } DateCell; diff --git a/src/register/register-core/pricecell.h b/src/register/register-core/pricecell.h index 93c690e0af..4114efd193 100644 --- a/src/register/register-core/pricecell.h +++ b/src/register/register-core/pricecell.h @@ -41,8 +41,8 @@ * Copyright (c) 2001 Free Software Foundation */ -#ifndef __PRICE_CELL_C__ -#define __PRICE_CELL_C__ +#ifndef PRICE_CELL_H +#define PRICE_CELL_H #include "basiccell.h" #include "gnc-common.h" diff --git a/src/register/register-core/recncell.h b/src/register/register-core/recncell.h index 1cbb09e5da..9e469ccf13 100644 --- a/src/register/register-core/recncell.h +++ b/src/register/register-core/recncell.h @@ -37,8 +37,8 @@ * Copyright (c) 2000 Dave Peticolas */ -#ifndef __RECN_CELL_C__ -#define __RECN_CELL_C__ +#ifndef RECN_CELL_H +#define RECN_CELL_H #include diff --git a/src/register/register-core/table-allgui.c b/src/register/register-core/table-allgui.c index 796498bdc6..366a640273 100644 --- a/src/register/register-core/table-allgui.c +++ b/src/register/register-core/table-allgui.c @@ -69,7 +69,6 @@ gnc_table_new (TableControl *control, TableModel *model) g_return_val_if_fail (control != NULL, NULL); g_return_val_if_fail (model != NULL, NULL); - g_return_val_if_fail (model->entry_handler, NULL); table = g_new0 (Table, 1); @@ -229,11 +228,18 @@ static const char * gnc_table_get_entry_internal (Table *table, VirtualLocation virt_loc, gboolean *conditionally_changed) { + TableGetEntryHandler entry_handler; const char *entry; + int cell_type; - entry = table->model->entry_handler (virt_loc, FALSE, - conditionally_changed, - table->model->handler_user_data); + cell_type = gnc_table_get_cell_type (table, virt_loc); + + entry_handler = gnc_table_model_get_entry_handler (table->model, cell_type); + if (!entry_handler) return ""; + + entry = entry_handler (virt_loc, FALSE, + conditionally_changed, + table->model->handler_user_data); if (!entry) entry = ""; @@ -243,8 +249,9 @@ gnc_table_get_entry_internal (Table *table, VirtualLocation virt_loc, const char * gnc_table_get_entry (Table *table, VirtualLocation virt_loc) { - BasicCell *cell; + TableGetEntryHandler entry_handler; const char *entry; + BasicCell *cell; cell = gnc_table_get_cell (table, virt_loc); if (!cell || cell->cell_type < 0) @@ -261,8 +268,12 @@ gnc_table_get_entry (Table *table, VirtualLocation virt_loc) return cell->value; } - entry = table->model->entry_handler (virt_loc, TRUE, NULL, - table->model->handler_user_data); + entry_handler = gnc_table_model_get_entry_handler (table->model, + cell->cell_type); + if (!entry_handler) return ""; + + entry = entry_handler (virt_loc, TRUE, NULL, + table->model->handler_user_data); if (!entry) entry = ""; diff --git a/src/register/register-core/table-model.c b/src/register/register-core/table-model.c index f7971fcc63..c2beb7d63f 100644 --- a/src/register/register-core/table-model.c +++ b/src/register/register-core/table-model.c @@ -24,9 +24,92 @@ #include "config.h" +#include + #include "table-model.h" +#define DEFAULT_HANDLER (-1) + +typedef struct +{ + int cell_type; + gpointer handler; +} HandlerNode; + + +static GHashTable * +gnc_table_model_handler_hash_new (void) +{ + return g_hash_table_new (g_int_hash, g_int_equal); +} + +static void +hash_destroy_helper (gpointer key, gpointer value, gpointer user_data) +{ + HandlerNode *node = value; + + g_free (node); +} + +static void +gnc_table_model_handler_hash_destroy (GHashTable *hash) +{ + if (!hash) return; + + g_hash_table_foreach (hash, hash_destroy_helper, NULL); + g_hash_table_destroy (hash); +} + +static void +gnc_table_model_handler_hash_remove (GHashTable *hash, int cell_type) +{ + HandlerNode *node; + + if (!hash) return; + + node = g_hash_table_lookup (hash, &cell_type); + if (!node) return; + + g_free (node); +} + +static void +gnc_table_model_handler_hash_insert (GHashTable *hash, int cell_type, + gpointer handler) +{ + HandlerNode *node; + + if (!hash) return; + + gnc_table_model_handler_hash_remove (hash, cell_type); + if (!handler) return; + + node = g_new0 (HandlerNode, 1); + + node->cell_type = cell_type; + node->handler = handler; + + g_hash_table_insert (hash, &node->cell_type, node); +} + +static gpointer +gnc_table_model_handler_hash_lookup (GHashTable *hash, int cell_type) +{ + HandlerNode *node; + + if (!hash) return NULL; + + node = g_hash_table_lookup (hash, &cell_type); + if (node) return node->handler; + + cell_type = DEFAULT_HANDLER; + node = g_hash_table_lookup (hash, &cell_type); + if (node) return node->handler; + + return NULL; +} + TableModel * gnc_table_model_new (void) { @@ -34,6 +117,8 @@ gnc_table_model_new (void) model = g_new0 (TableModel, 1); + model->entry_handlers = gnc_table_model_handler_hash_new (); + model->dividing_row = -1; return model; @@ -44,5 +129,40 @@ gnc_table_model_destroy (TableModel *model) { if (!model) return; + gnc_table_model_handler_hash_destroy (model->entry_handlers); + model->entry_handlers = NULL; + g_free (model); } + +void +gnc_table_model_set_entry_handler (TableModel *model, + TableGetEntryHandler entry_handler, + int cell_type) +{ + g_return_if_fail (model != NULL); + g_return_if_fail (cell_type < 0); + + gnc_table_model_handler_hash_insert (model->entry_handlers, cell_type, + entry_handler); +} + +void +gnc_table_model_set_default_entry_handler +(TableModel *model, TableGetEntryHandler entry_handler) +{ + g_return_if_fail (model != NULL); + + gnc_table_model_handler_hash_insert (model->entry_handlers, + DEFAULT_HANDLER, + entry_handler); +} + +TableGetEntryHandler +gnc_table_model_get_entry_handler (TableModel *model, int cell_type) +{ + g_return_val_if_fail (model != NULL, NULL); + + return gnc_table_model_handler_hash_lookup (model->entry_handlers, + cell_type); +} diff --git a/src/register/register-core/table-model.h b/src/register/register-core/table-model.h index bd6bb6afad..04fd99f03d 100644 --- a/src/register/register-core/table-model.h +++ b/src/register/register-core/table-model.h @@ -90,7 +90,8 @@ typedef void (*VirtCellDataCopy) (gpointer to, gconstpointer from); typedef struct { - TableGetEntryHandler entry_handler; + GHashTable *entry_handlers; + TableGetLabelHandler label_handler; TableGetCellIOFlags io_flag_handler; TableGetFGColorHandler fg_color_handler; @@ -114,4 +115,12 @@ typedef struct TableModel * gnc_table_model_new (void); void gnc_table_model_destroy (TableModel *model); +void gnc_table_model_set_entry_handler (TableModel *model, + TableGetEntryHandler entry_handler, + int cell_type); +void gnc_table_model_set_default_entry_handler +(TableModel *model, TableGetEntryHandler entry_handler); +TableGetEntryHandler gnc_table_model_get_entry_handler (TableModel *model, + int cell_type); + #endif