diff --git a/src/register/ledger-core/split-register-layout.c b/src/register/ledger-core/split-register-layout.c index 26879b865b..3092240c97 100644 --- a/src/register/ledger-core/split-register-layout.c +++ b/src/register/ledger-core/split-register-layout.c @@ -248,7 +248,7 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 5); gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 6); } - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); curs_last = curs; curs = gnc_table_layout_get_cursor (layout, @@ -268,7 +268,8 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) gnc_table_layout_set_cell (layout, curs, DESC_CELL, 0, 2); gnc_table_layout_set_cell (layout, curs, TDEBT_CELL, 0, 5); gnc_table_layout_set_cell (layout, curs, TCRED_CELL, 0, 6); - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RBALN_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); curs_last = curs; curs = gnc_table_layout_get_cursor (layout, @@ -296,7 +297,7 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 5); gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 6); } - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); break; } @@ -459,7 +460,7 @@ gnc_split_register_layout_add_cursors (SplitRegister *reg, case INCOME_LEDGER: case GENERAL_LEDGER: case SEARCH_LEDGER: - num_cols = 8; + num_cols = 9; break; case STOCK_REGISTER: @@ -702,6 +703,15 @@ gnc_split_register_layout_add_cells (SplitRegister *reg, CELL_ALIGN_LEFT, FALSE, FALSE); + + gnc_register_add_cell (layout, + RBALN_CELL, + PRICE_CELL_TYPE_NAME, + N_("sample:999,999.000") + 7, + CELL_ALIGN_RIGHT, + FALSE, + FALSE); + } TableLayout * diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c index 6bbc67dfb2..40273ceec8 100644 --- a/src/register/ledger-core/split-register-model.c +++ b/src/register/ledger-core/split-register-model.c @@ -56,6 +56,67 @@ static QofLogModule log_module = GNC_MOD_LEDGER; static gboolean use_red_for_negative = TRUE; +static gnc_numeric +gnc_split_register_get_rbaln (VirtualLocation virt_loc, gpointer user_data) +{ + SplitRegister *reg = user_data; + Split *split; + SRInfo *info = gnc_split_register_get_info (reg); + gnc_numeric value = gnc_numeric_zero(), balance = gnc_numeric_zero(); + Account *account; + Transaction *trans; + GList *node, *children, *child; + int i, row; + + /* This function calculates the register balance for a particular split at runtime. + * It works regardless of the sort order. */ + balance = gnc_numeric_zero(); + + /* Return NULL if this is a blank transaction. */ + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + if (split == xaccSplitLookup (&info->blank_split_guid, + gnc_get_current_book ())) + return gnc_numeric_zero(); + + trans = xaccSplitGetParent (split); + if (!trans) + return gnc_numeric_zero(); + + /* Get a list of all subaccounts for matching */ + children = gnc_account_get_descendants(gnc_split_register_get_default_account(reg)); + children = g_list_append(children, gnc_split_register_get_default_account(reg)); + + /* Get the row number we're on, then start with the first row. */ + row = virt_loc.vcell_loc.virt_row; + virt_loc.vcell_loc.virt_row=0; + + while (virt_loc.vcell_loc.virt_row <= row ) { + /* Get new temporary split and its parent transaction */ + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + trans = xaccSplitGetParent (split); + + i = 1; + for (node = xaccTransGetSplitList (trans); node; node = node->next) { + Split *secondary = node->data; + i++; + + /* Add up the splits that belong to the transaction if they are + * from the lead account or one of the subaccounts. */ + account = xaccSplitGetAccount (secondary); + + for (child = children; child; child = child->next) { + if (account == child->data) { + balance = gnc_numeric_add_fixed(balance, xaccSplitGetAmount(secondary)); + break; + } + } + } + virt_loc.vcell_loc.virt_row+=i; + } + + return balance; +} + static gboolean gnc_split_register_use_security_cells (SplitRegister *reg, VirtualLocation virt_loc) @@ -402,6 +463,8 @@ gnc_split_register_get_balance_fg_color (VirtualLocation virt_loc, if (gnc_cell_name_equal (cell_name, BALN_CELL)) balance = xaccSplitGetBalance (split); + else if (gnc_cell_name_equal (cell_name, RBALN_CELL)) + balance = gnc_split_register_get_rbaln (virt_loc,user_data); else balance = get_trans_total_balance (reg, xaccSplitGetParent (split)); @@ -1304,6 +1367,25 @@ gnc_split_register_get_mxfrm_help (VirtualLocation virt_loc, return g_strdup (help); } +/* Return the total amount of the transaction for splits of default account + * and all subaccounts of the register. */ +static gnc_numeric +get_trans_total_amount_subaccounts (SplitRegister *reg, Transaction *trans) +{ + GList *children, *child; + gnc_numeric total = gnc_numeric_zero(); + + /* Get a list of all subaccounts for matching */ + children = gnc_account_get_descendants(gnc_split_register_get_default_account(reg)); + children = g_list_append(children, gnc_split_register_get_default_account(reg)); + + for (child = children; child; child = child->next) { + total = gnc_numeric_add_fixed(total, xaccTransGetAccountAmount(trans, child->data)); + } + + return total; +} + static const char * gnc_split_register_get_tdebcred_entry (VirtualLocation virt_loc, gboolean translate, @@ -1321,7 +1403,16 @@ gnc_split_register_get_tdebcred_entry (VirtualLocation virt_loc, cell_name = gnc_table_get_cell_name (reg->table, virt_loc); - total = get_trans_total_amount (reg, xaccSplitGetParent (split)); + switch (reg->type) + { + case GENERAL_LEDGER: + case INCOME_LEDGER: + total = get_trans_total_amount_subaccounts (reg, xaccSplitGetParent (split)); + break; + default: + total = get_trans_total_amount (reg, xaccSplitGetParent (split)); + } + if (gnc_numeric_zero_p (total)) return NULL; @@ -1499,6 +1590,43 @@ gnc_split_register_get_debcred_entry (VirtualLocation virt_loc, } } +/* Calculates the register balance for each split at runtime. + * This works regardless of the sort order. */ +static const char * +gnc_split_register_get_rbaln_entry (VirtualLocation virt_loc, + gboolean translate, + gboolean *conditionally_changed, + gpointer user_data) +{ + SplitRegister *reg = user_data; + SRInfo *info = gnc_split_register_get_info (reg); + Split *split; + Transaction *trans; + gnc_numeric balance; + Account *account; + + /* Return NULL if this is a blank transaction. */ + split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); + if (split == xaccSplitLookup (&info->blank_split_guid, + gnc_get_current_book ())) + return NULL; + + trans = xaccSplitGetParent (split); + if (!trans) + return NULL; + + balance = gnc_split_register_get_rbaln (virt_loc,user_data); + + account = xaccSplitGetAccount (split); + if (!account) + account = gnc_split_register_get_default_account (reg); + + if (gnc_reverse_balance (account)) + balance = gnc_numeric_neg (balance); + + return xaccPrintAmount (balance, gnc_account_print_info (account, FALSE)); +} + static gboolean gnc_split_register_cursor_is_readonly (VirtualLocation virt_loc, gpointer user_data) @@ -2006,6 +2134,10 @@ gnc_split_register_model_new (void) gnc_split_register_get_debcred_entry, CRED_CELL); + gnc_table_model_set_entry_handler (model, + gnc_split_register_get_rbaln_entry, + RBALN_CELL); + gnc_table_model_set_label_handler (model, gnc_split_register_get_date_label, @@ -2095,6 +2227,10 @@ gnc_split_register_model_new (void) gnc_split_register_get_fcredit_label, FCRED_CELL); + gnc_table_model_set_label_handler (model, + gnc_split_register_get_tbalance_label, + RBALN_CELL); + gnc_table_model_set_default_help_handler( model, gnc_split_register_get_default_help); @@ -2225,6 +2361,9 @@ gnc_split_register_model_new (void) gnc_table_model_set_fg_color_handler( model, gnc_split_register_get_balance_fg_color, TBALN_CELL); + gnc_table_model_set_fg_color_handler( + model, gnc_split_register_get_balance_fg_color, RBALN_CELL); + gnc_table_model_set_default_bg_color_handler( model, gnc_split_register_get_bg_color); diff --git a/src/register/ledger-core/split-register.h b/src/register/ledger-core/split-register.h index faa753f146..8f7c7b1824 100644 --- a/src/register/ledger-core/split-register.h +++ b/src/register/ledger-core/split-register.h @@ -209,6 +209,7 @@ typedef enum #define TYPE_CELL "split-type" #define XFRM_CELL "account" #define VNOTES_CELL "void-notes" +#define RBALN_CELL "reg-run-balance" /** @} */ /** @name Cursor Names