From a925e5bd5935e51f347839b5edf24b1ffc3b2ebd Mon Sep 17 00:00:00 2001 From: Derek Atkins Date: Thu, 29 Nov 2001 03:00:06 +0000 Subject: [PATCH] Abstract RecnCell to allow multiple "choice" types. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6138 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/app-utils/gnc-ui-util.c | 45 ++++++++ src/app-utils/gnc-ui-util.h | 2 + src/gnome/top-level.c | 3 - .../ledger-core/split-register-layout.c | 58 ++++++---- .../ledger-core/split-register-load.c | 38 +++++++ .../ledger-core/split-register-model.c | 70 ++++++++++-- src/register/ledger-core/split-register.h | 1 + src/register/register-core/recncell.c | 105 +++++++++--------- src/register/register-core/recncell.h | 21 +++- 9 files changed, 249 insertions(+), 94 deletions(-) diff --git a/src/app-utils/gnc-ui-util.c b/src/app-utils/gnc-ui-util.c index f07b4b7dff..cc6ed8e15e 100644 --- a/src/app-utils/gnc-ui-util.c +++ b/src/app-utils/gnc-ui-util.c @@ -706,6 +706,51 @@ gnc_get_reconcile_str (char reconciled_flag) } } +/********************************************************************\ + * gnc_get_reconcile_valid_chars * + * return a string containing the i18n'd * + * characters for the list of reconciled flags * + * * + * Returns: the i18n'd reconciled flags string * +\********************************************************************/ +const char * +gnc_get_reconcile_valid_chars (void) +{ + const char flags[4] = { NREC, CREC, YREC, FREC }; + static char str[5] = { 0, 0, 0, 0, 0 }; + int i = 0; + + for (i = 0; i < sizeof (flags); i++) { + char *s = gnc_get_reconcile_str (flags[i]); + str[i] = *s; + } + + return str; +} + +/********************************************************************\ + * gnc_get_reconcile_char_order * + * return a string containing the i18n'd * + * characters for the list of reconciled-flag order changes * + * * + * Args: reconciled_flag - the flag to stringize * + * Returns: the i18n'd reconciled string * +\********************************************************************/ +const char * +gnc_get_reconcile_char_order (void) +{ + const char flags[2] = { NREC, CREC }; + static char str[3] = { 0, 0, 0 }; + int i = 0; + + for (i = 0; i < sizeof (flags); i++) { + char *s = gnc_get_reconcile_str (flags[i]); + str[i] = *s; + } + + return str; +} + /* Get the full name of a quote source */ const char * diff --git a/src/app-utils/gnc-ui-util.h b/src/app-utils/gnc-ui-util.h index 38b2ad53a3..6a3d0438ba 100644 --- a/src/app-utils/gnc-ui-util.h +++ b/src/app-utils/gnc-ui-util.h @@ -90,6 +90,8 @@ gnc_numeric gnc_ui_account_get_balance_as_of_date (Account *account, gboolean include_children); const char * gnc_get_reconcile_str (char reconciled_flag); +const char * gnc_get_reconcile_valid_chars (void); +const char * gnc_get_reconcile_char_order (void); typedef enum { diff --git a/src/gnome/top-level.c b/src/gnome/top-level.c index 6f7a6946ab..422acebeab 100644 --- a/src/gnome/top-level.c +++ b/src/gnome/top-level.c @@ -63,7 +63,6 @@ #include "gnucash-style.h" #include "guile-util.h" #include "messages.h" -#include "recncell.h" #include "split-register.h" #include "top-level.h" #include "window-help.h" @@ -516,8 +515,6 @@ gnucash_ui_init(void) NULL, "Register", "Register hint font"); - gnc_recn_cell_set_string_getter (gnc_get_reconcile_str); - gnucash_style_init(); gnucash_color_init(); diff --git a/src/register/ledger-core/split-register-layout.c b/src/register/ledger-core/split-register-layout.c index 9e3f721d72..69138d4358 100644 --- a/src/register/ledger-core/split-register-layout.c +++ b/src/register/ledger-core/split-register-layout.c @@ -168,14 +168,15 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) CURSOR_SINGLE_LEDGER); gnc_table_layout_set_cell (layout, curs, DATE_CELL, 0, 0); - gnc_table_layout_set_cell (layout, curs, DDUE_CELL, 0, 1); - gnc_table_layout_set_cell (layout, curs, NUM_CELL, 0, 2); - gnc_table_layout_set_cell (layout, curs, DESC_CELL, 0, 3); - gnc_table_layout_set_cell (layout, curs, MXFRM_CELL, 0, 4); - gnc_table_layout_set_cell (layout, curs, RECN_CELL, 0, 5); - gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 6); - gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 7); - gnc_table_layout_set_cell (layout, curs, BALN_CELL, 0, 8); + gnc_table_layout_set_cell (layout, curs, TYPE_CELL, 0, 1); + gnc_table_layout_set_cell (layout, curs, DDUE_CELL, 0, 2); + gnc_table_layout_set_cell (layout, curs, NUM_CELL, 0, 3); + gnc_table_layout_set_cell (layout, curs, DESC_CELL, 0, 4); + gnc_table_layout_set_cell (layout, curs, MXFRM_CELL, 0, 5); + gnc_table_layout_set_cell (layout, curs, RECN_CELL, 0, 6); + gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 8); + gnc_table_layout_set_cell (layout, curs, BALN_CELL, 0, 9); curs_last = curs; curs = gnc_table_layout_get_cursor (layout, @@ -183,20 +184,21 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) copy_cursor_row (layout, curs, curs_last, 0); - gnc_table_layout_set_cell (layout, curs, ACTN_CELL, 1, 2); - gnc_table_layout_set_cell (layout, curs, NOTES_CELL, 1, 3); + gnc_table_layout_set_cell (layout, curs, ACTN_CELL, 1, 3); + gnc_table_layout_set_cell (layout, curs, NOTES_CELL, 1, 4); curs = gnc_table_layout_get_cursor (layout, CURSOR_SINGLE_JOURNAL); gnc_table_layout_set_cell (layout, curs, DATE_CELL, 0, 0); - gnc_table_layout_set_cell (layout, curs, DDUE_CELL, 0, 1); - gnc_table_layout_set_cell (layout, curs, NUM_CELL, 0, 2); - gnc_table_layout_set_cell (layout, curs, DESC_CELL, 0, 3); + gnc_table_layout_set_cell (layout, curs, TYPE_CELL, 0, 1); + gnc_table_layout_set_cell (layout, curs, DDUE_CELL, 0, 2); + gnc_table_layout_set_cell (layout, curs, NUM_CELL, 0, 3); + gnc_table_layout_set_cell (layout, curs, DESC_CELL, 0, 4); - gnc_table_layout_set_cell (layout, curs, TDEBT_CELL, 0, 6); - gnc_table_layout_set_cell (layout, curs, TCRED_CELL, 0, 7); - gnc_table_layout_set_cell (layout, curs, TBALN_CELL, 0, 8); + gnc_table_layout_set_cell (layout, curs, TDEBT_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, TCRED_CELL, 0, 8); + gnc_table_layout_set_cell (layout, curs, TBALN_CELL, 0, 9); curs_last = curs; curs = gnc_table_layout_get_cursor (layout, @@ -204,17 +206,17 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) copy_cursor_row (layout, curs, curs_last, 0); - gnc_table_layout_set_cell (layout, curs, NOTES_CELL, 1, 3); + gnc_table_layout_set_cell (layout, curs, NOTES_CELL, 1, 4); curs = gnc_table_layout_get_cursor (layout, CURSOR_SPLIT); - gnc_table_layout_set_cell (layout, curs, ACTN_CELL, 0, 2); - gnc_table_layout_set_cell (layout, curs, MEMO_CELL, 0, 3); - gnc_table_layout_set_cell (layout, curs, XFRM_CELL, 0, 4); - gnc_table_layout_set_cell (layout, curs, RECN_CELL, 0, 5); - gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 6); - gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, ACTN_CELL, 0, 3); + gnc_table_layout_set_cell (layout, curs, MEMO_CELL, 0, 4); + gnc_table_layout_set_cell (layout, curs, XFRM_CELL, 0, 5); + gnc_table_layout_set_cell (layout, curs, RECN_CELL, 0, 6); + gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 8); break; } @@ -438,7 +440,7 @@ gnc_split_register_layout_add_cursors (SplitRegister *reg, case PAYABLE_REGISTER: case RECEIVABLE_REGISTER: - num_cols = 9; + num_cols = 10; break; case INCOME_LEDGER: @@ -633,6 +635,14 @@ gnc_split_register_layout_add_cells (SplitRegister *reg, FALSE, FALSE); + gnc_register_add_cell (layout, + TYPE_CELL, + RECN_CELL_TYPE_NAME, + N_("Type:T") + 5, + CELL_ALIGN_LEFT, + FALSE, + FALSE); + gnc_register_add_cell (layout, NOTES_CELL, QUICKFILL_CELL_TYPE_NAME, diff --git a/src/register/ledger-core/split-register-load.c b/src/register/ledger-core/split-register-load.c index f8841ad3e8..c0b7ff2621 100644 --- a/src/register/ledger-core/split-register-load.c +++ b/src/register/ledger-core/split-register-load.c @@ -39,6 +39,42 @@ static short module = MOD_LEDGER; +static void +gnc_split_register_load_recn_cells (SplitRegister *reg) +{ + RecnCell *cell; + const char * s; + + if (!reg) return; + + cell = (RecnCell *) + gnc_table_layout_get_cell (reg->table->layout, RECN_CELL); + + if (!cell) return; + + s = gnc_get_reconcile_valid_chars (); + gnc_recn_cell_set_valid_chars (cell, s, *s); + gnc_recn_cell_set_char_order (cell, gnc_get_reconcile_char_order ()); +} + +static void +gnc_split_register_load_type_cells (SplitRegister *reg) +{ + RecnCell *cell; + const char * s; + + if (!reg) return; + + cell = (RecnCell *) + gnc_table_layout_get_cell (reg->table->layout, TYPE_CELL); + + if (!cell) return; + + /* FIXME: These should get moved to an i18n function */ + gnc_recn_cell_set_valid_chars (cell, "IP", 'I'); + gnc_recn_cell_set_char_order (cell, "IP"); +} + static void gnc_split_register_add_transaction (SplitRegister *reg, Transaction *trans, @@ -518,6 +554,8 @@ gnc_split_register_load (SplitRegister *reg, GList * slist, gnc_table_control_allow_move (table->control, TRUE); gnc_split_register_load_xfer_cells (reg, default_account); + gnc_split_register_load_recn_cells (reg); + gnc_split_register_load_type_cells (reg); } static void diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c index 683b9d134f..7570ddde82 100644 --- a/src/register/ledger-core/split-register-model.c +++ b/src/register/ledger-core/split-register-model.c @@ -188,6 +188,13 @@ gnc_split_register_get_memo_label (VirtualLocation virt_loc, return _("Memo"); } +static const char * +gnc_split_register_get_type_label (VirtualLocation virt_loc, + gpointer user_data) +{ + return _("Type"); +} + static const char * gnc_split_register_get_debit_label (VirtualLocation virt_loc, gpointer user_data) @@ -625,18 +632,29 @@ gnc_split_register_get_due_date_entry (VirtualLocation virt_loc, gpointer user_data) { SplitRegister *reg = user_data; - Transaction *trans; - Split *split; - Timespec ts; + char type; - split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); - trans = xaccSplitGetParent (split); - if (!trans) + type = gnc_recn_cell_get_flag + ((RecnCell *) gnc_table_layout_get_cell (reg->table->layout, TYPE_CELL)); + + /* Only print the due date for invoice transactions */ + if (type != 'I') return NULL; - xaccTransGetDateDueTS (trans, &ts); + { + Transaction *trans; + Split *split; + Timespec ts; - return gnc_print_date (ts); + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + trans = xaccSplitGetParent (split); + if (!trans) + return NULL; + + xaccTransGetDateDueTS (trans, &ts); + + return gnc_print_date (ts); + } } static const char * @@ -815,6 +833,29 @@ gnc_split_register_get_recn_entry (VirtualLocation virt_loc, } } +static const char * +gnc_split_register_get_type_entry (VirtualLocation virt_loc, + gboolean translate, + gboolean *conditionally_changed, + gpointer user_data) +{ + SplitRegister *reg = user_data; + Split *split; + + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + if (!split) + return NULL; + + { + static char s[2]; + + s[0] = 'I'; + s[1] = '\0'; + + return s; + } +} + static const char * gnc_split_register_get_action_entry (VirtualLocation virt_loc, gboolean translate, @@ -1604,6 +1645,10 @@ gnc_split_register_model_new (void) gnc_split_register_get_tdebcred_entry, TCRED_CELL); + gnc_table_model_set_entry_handler (model, + gnc_split_register_get_type_entry, + TYPE_CELL); + gnc_table_model_set_entry_handler (model, gnc_split_register_get_debcred_entry, DEBT_CELL); @@ -1685,6 +1730,10 @@ gnc_split_register_model_new (void) gnc_split_register_get_tbalance_label, TBALN_CELL); + gnc_table_model_set_label_handler (model, + gnc_split_register_get_type_label, + TYPE_CELL); + gnc_table_model_set_label_handler (model, gnc_split_register_get_notes_label, NOTES_CELL); @@ -1819,6 +1868,11 @@ gnc_split_register_model_new (void) gnc_split_register_get_recn_io_flags, RECN_CELL); + gnc_table_model_set_io_flags_handler + (model, + gnc_split_register_get_recn_io_flags, + TYPE_CELL); + gnc_table_model_set_io_flags_handler (model, gnc_split_register_get_security_io_flags, diff --git a/src/register/ledger-core/split-register.h b/src/register/ledger-core/split-register.h index 3775fe2e80..21c1eb5128 100644 --- a/src/register/ledger-core/split-register.h +++ b/src/register/ledger-core/split-register.h @@ -88,6 +88,7 @@ typedef enum #define TCRED_CELL "trans-credit" #define TDEBT_CELL "trans-debit" #define TSHRS_CELL "trans-shares" +#define TYPE_CELL "split-type" #define XFRM_CELL "account" /* Cursor Names */ diff --git a/src/register/register-core/recncell.c b/src/register/register-core/recncell.c index 1a221dad2c..a32b0031e5 100644 --- a/src/register/register-core/recncell.c +++ b/src/register/register-core/recncell.c @@ -31,6 +31,7 @@ * HISTORY: * Copyright (c) 1998 Linas Vepstas * Copyright (c) 2000 Dave Peticolas + * Copyright (c) 2001 Derek Atkins */ #include "config.h" @@ -43,35 +44,12 @@ #include "gnc-engine-util.h" #include "recncell.h" -/* hack alert -- I am uncomfortable with including engine - * stuff here; all code in this directory should really be - * independent of the engine. Its just that we need the - * defs for YREC, CREC, etc. This is some cleanup we should - * do some day. - */ -#include "Transaction.h" - -static RecnCellStringGetter string_getter = NULL; - /* This static indicates the debugging module that this .o belongs to. */ static short module = MOD_REGISTER; static void gnc_recn_cell_set_value (BasicCell *_cell, const char *value); -static const char * -gnc_recn_cell_get_string (char reconciled_flag) -{ - static char str[2] = { 0, 0 }; - - if (string_getter != NULL) - return (string_getter)(reconciled_flag); - - str[0] = reconciled_flag; - - return str; -} - static gboolean gnc_recn_cell_enter (BasicCell *_cell, int *cursor_position, @@ -79,16 +57,31 @@ gnc_recn_cell_enter (BasicCell *_cell, int *end_selection) { RecnCell *cell = (RecnCell *) _cell; + char * this_flag; if (cell->confirm_cb && ! (cell->confirm_cb (cell->reconciled_flag, cell->confirm_data))) return FALSE; - if (cell->reconciled_flag == NREC) - cell->reconciled_flag = CREC; - else - cell->reconciled_flag = NREC; + /* Find the current flag in the list of flags */ + this_flag = strchr (cell->char_order, cell->reconciled_flag); + if (this_flag == NULL || *this_flag == '\0') { + /* If it's not there (or the list is empty) use default_flag */ + cell->reconciled_flag = cell->default_flag; + + } else { + /* It is in the list -- choose the -next- item in the list (wrapping + * around as necessary). + */ + this_flag++; + if (*this_flag != '\0') + cell->reconciled_flag = *this_flag; + else + cell->reconciled_flag = *(cell->char_order); + } + + /* And set the display */ gnc_recn_cell_set_flag (cell, cell->reconciled_flag); return FALSE; @@ -99,8 +92,10 @@ gnc_recn_cell_init (RecnCell *cell) { gnc_basic_cell_init (&cell->cell); - gnc_recn_cell_set_flag (cell, NREC); + gnc_recn_cell_set_flag (cell, ' '); cell->confirm_cb = NULL; + cell->valid_chars = ""; + cell->char_order = ""; cell->cell.enter_cell = gnc_recn_cell_enter; cell->cell.set_value = gnc_recn_cell_set_value; @@ -127,25 +122,14 @@ gnc_recn_cell_set_value (BasicCell *_cell, const char *value) if (!value || *value == '\0') { - cell->reconciled_flag = NREC; + cell->reconciled_flag = cell->default_flag; gnc_basic_cell_set_value_internal (_cell, ""); return; } - switch (*value) - { - case NREC: - case CREC: - case YREC: - case FREC: - flag = *value; - break; - - default: - PWARN ("unexpected recn flag"); - flag = NREC; - break; - } + flag = cell->default_flag; + if (strchr (cell->valid_chars, *value) != NULL) + flag = *value; gnc_recn_cell_set_flag (cell, flag); } @@ -153,13 +137,11 @@ gnc_recn_cell_set_value (BasicCell *_cell, const char *value) void gnc_recn_cell_set_flag (RecnCell *cell, char reconciled_flag) { - const char *string; + static char string[2] = { 0 , 0 }; g_return_if_fail (cell != NULL); - cell->reconciled_flag = reconciled_flag; - - string = gnc_recn_cell_get_string (reconciled_flag); + string[0] = cell->reconciled_flag = reconciled_flag; gnc_basic_cell_set_value_internal (&cell->cell, string); } @@ -167,17 +149,11 @@ gnc_recn_cell_set_flag (RecnCell *cell, char reconciled_flag) char gnc_recn_cell_get_flag (RecnCell *cell) { - g_return_val_if_fail (cell != NULL, NREC); + g_return_val_if_fail (cell != NULL, '\0'); return cell->reconciled_flag; } -void -gnc_recn_cell_set_string_getter (RecnCellStringGetter getter) -{ - string_getter = getter; -} - void gnc_recn_cell_set_confirm_cb (RecnCell *cell, RecnCellConfirm confirm_cb, gpointer data) @@ -187,3 +163,24 @@ gnc_recn_cell_set_confirm_cb (RecnCell *cell, RecnCellConfirm confirm_cb, cell->confirm_cb = confirm_cb; cell->confirm_data = data; } + +void +gnc_recn_cell_set_valid_chars (RecnCell *cell, const char *chars, + char default_flag) +{ + g_return_if_fail (cell != NULL); + g_return_if_fail (chars != NULL); + + cell->valid_chars = (char *)chars; + cell->default_flag = default_flag; +} + +void +gnc_recn_cell_set_char_order (RecnCell *cell, const char *chars) +{ + g_return_if_fail (cell != NULL); + g_return_if_fail (chars != NULL); + + cell->char_order = (char *)chars; +} + diff --git a/src/register/register-core/recncell.h b/src/register/register-core/recncell.h index 30cf5c62e5..472d98a336 100644 --- a/src/register/register-core/recncell.h +++ b/src/register/register-core/recncell.h @@ -29,12 +29,10 @@ * that will cycle through a series of single-character * values when clicked upon by the mouse. * - * hack alert -- there should be a way of specifying what these values - * are, instead of having them hard coded as they currently are. - * * HISTORY: * Copyright (c) 1998 Linas Vepstas * Copyright (c) 2000 Dave Peticolas + * Copyright (c) 2001 Derek Atkins */ #ifndef RECN_CELL_H @@ -44,7 +42,6 @@ #include "basiccell.h" -typedef const char * (*RecnCellStringGetter) (char flag); typedef gboolean (*RecnCellConfirm) (char old_flag, gpointer data); typedef struct @@ -53,6 +50,10 @@ typedef struct char reconciled_flag; /* The actual flag value */ + char * valid_chars; /* The list of valid flag types */ + char * char_order; /* The order of automatic flag selection */ + char default_flag; /* The default flag for unknown user input */ + RecnCellConfirm confirm_cb; gpointer confirm_data; } RecnCell; @@ -66,6 +67,16 @@ void gnc_recn_cell_set_confirm_cb (RecnCell *cell, RecnCellConfirm confirm_cb, gpointer data); -void gnc_recn_cell_set_string_getter (RecnCellStringGetter getter); +/* + * note that chars is copied into the RecnCell directly, but remains + * the "property" of the caller. The caller must maintain the chars + * pointer, and the caller must setup a mechanism to 'free' the chars + * pointer. The rationale is that you may have many RecnCell objects + * that use the same set of flags -- this saves you an alloc/free for + * each cell. - warlord 2001-11-28 + */ +void gnc_recn_cell_set_valid_chars (RecnCell *cell, const char *chars, + char default_flag); +void gnc_recn_cell_set_char_order (RecnCell *cell, const char *chars); #endif