Attached is an update to the RC1 patch

This patch improves the original "RC1" patch in the following ways:
1. reg_run_balance_RC2.diff adds the gnc_split_register_get_rbaln() function,
whose code was originally duplicated in the
gnc_split_register_get_balance_fg_color() and
gnc_split_register_get_rbaln_entry() functions in the first patch.

2. Modified the gnc_split_register_get_tdebcred_entry() function to display the
debit/credit amount for the register's parent account and all subaccounts when
the GENERAL_LEDGER register is in use (used by Show Subaccounts feature).

3. Added the get_trans_total_amount_subaccounts() function which returns the
total amount of a transaction for the register's parent account and all
subaccounts.



On Fri, Sep 4, 2009 at 12:01 AM, Tim M <t...@filmchicago.org> wrote:

> OK, IMO the updated patch attached to this mail is ready for testing.  This
> patch does the following:
>
> 1. When opening an account register and it's subaccounts by right clicking
> it in the Accounts tab and selecting "Open Subaccounts," there is now a
> Balance column as there normally is in a single account register.
>
> 2. This new RBALN balance column tallies the balance of the splits for the
> account and all subaccounts at runtime.
>
> 3. Because the balance is calculated at runtime, this also means that the
> balance column always reflects an accurate running balance regardless of
> sort order.  This is a big benefit and could certainly be modified to work
> for single account view as well.  With the current single account register,
> when the sort order is changed the Balance displayed will only reflect the
> balance of the account associated with each split - not a running balance in
> relation to the sort order of the register, so that the 'Balance' displayed
> for each split when the sort order is not the default causes the 'Balance'
> column to be more or less unusable.
>
> I believe this should also resolve the following issue:
> http://bugzilla.gnome.org/show_bug.cgi?id=107929
>
> I resolved issue #1 in my original mailing list post.  Issue #2 remains a
> matter of testing by other users to ensure the patch doesn't have any
> unintended consequences.
>
> I've tested this patch locally by opening an account and it's subaccounts
> using the "Open Subaccounts" option.  The newly added balance column tallies
> the balance properly at runtime, and sets the balance color properly as well
> (red for negative, black positive).  I also tested different sort orders,
> and the running balance was spot on regardless.  Since this affects only the
> "Open Subaccounts" register (and possibly other similar registers?), this
> does not affect single account registers so those still do not tally Balance
> properly when using a non-default sort order.
>
> This patch is against an older version of the SVN repository (I think a
> trunk snapshot of version 3.1), so it may or may not work OK with the latest
> trunk.  Let me know if I need to make a new patch with the current trunk.
>
>
> As a side note and as matter of cleanup, it would be useful to
> functionalize the part of the new gnc_split_register_get_rbaln_entry()
> function which does the actual calculations to get the running balance of
> the register at a specific split, because the running balance also has to be
> calculated for the gnc_split_register_get_balance_fg_color() function to set
> the text color properly when the RBALN cell type is used.  Currently I've
> just copied the code from the rbaln function to the fg_color function, so it
> would be helpful to put this in a function that returns a gnu_numeric value
> of the split's running balance for the register which could then be called
> by both functions.  However, I'm not an experienced C programmer so I was
> having some trouble figuring out just where to put such a function and how
> to get it working.  I did try!
>
> Also, this is my first FOSS patch, so let me know if there is anything I
> can do differently or improve on, thanks!
>
> -Tim M.
>
>
>
> On Fri, Jul 10, 2009 at 10:53 AM, Tim M <t...@filmchicago.org> wrote:
>
>> Hello,
>>
>> I've attached a BETA svn diff patch against HEAD which creates a new cell
>> type, RBALN_CELL.  I could use some help tweaking this patch if someone is
>> able to provide answers to my questions below.
>>
>> This cell calculates the balance of all transactions in a register at
>> runtime, allowing a running balance to be displayed when using the "Open
>> Subaccounts" feature.  The cell currently calculates the running balance of
>> all splits that are going to/from the lead account and all of its
>> subaccounts, therefore it is not appropriate (currently) to use this cell
>> type in a non-subaccount register view.
>>
>> My Questions:
>>
>> 1. There is an outstanding issue with this patch where it appears the
>> return value of the gnc_split_register_get_rbaln_entry() function is printed
>> in the Balance column of the split rows.  The running Balance is correctly
>> printed on the Transaction rows, but the cells in the Balance column on the
>> lines of the split should be blank.  Instead, they display 1 (for all
>> transactions where a balance is printed) or 0 (for the blank split at the
>> bottom because the function returns NULL since we don't print the balance
>> for that txn).  How can I fix this so that the balance cell of the split
>> lines is blank?
>>
>> 2. The RBALN_CELL was added to the CURSOR_SINGLE_JOURNAL cursor of the
>> INCOME_LEDGER/GENERAL_LEDGER/SEARCH_LEDGER cases in
>> split-register-layout.c.  Will this affect other register views besides the
>> subaccount view?  I have only tested this with asset accounts (bank,
>> checking) so I'm not sure if it might cause problems with different account
>> types.
>>
>>
>> Please take a look and let me know how I can further improve it!
>>
>> Thanks,
>> -Tim M.
>>
>
>
Index: src/register/ledger-core/split-register-model.c
===================================================================
--- src/register/ledger-core/split-register-model.c	(revision 18169)
+++ src/register/ledger-core/split-register-model.c	(working copy)
@@ -56,6 +56,67 @@
 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(); /* FIXME: Should return an error code or something to indicate it's a blank trans */
+
+    trans = xaccSplitGetParent (split);
+    if (!trans)
+      return gnc_numeric_zero(); /* FIXME: Should return an error code or something to indicate it's not a transaction or? */
+
+    /* 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 @@
 
   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));
 
@@ -1313,6 +1376,25 @@
   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,
@@ -1330,7 +1412,11 @@
 
   cell_name = gnc_table_get_cell_name (reg->table, virt_loc);
 
-  total = get_trans_total_amount (reg, xaccSplitGetParent (split));
+  if (reg->type == GENERAL_LEDGER)
+    total = get_trans_total_amount_subaccounts (reg, xaccSplitGetParent (split));
+  else
+    total = get_trans_total_amount (reg, xaccSplitGetParent (split));
+
   if (gnc_numeric_zero_p (total))
     return NULL;
 
@@ -1505,6 +1591,32 @@
   }
 }
 
+/* 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;
+
+  /* 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;
+
+  return xaccPrintAmount (gnc_split_register_get_rbaln (virt_loc,user_data), gnc_split_register_print_info (reg));
+}
+
 static gboolean
 gnc_split_register_cursor_is_readonly (VirtualLocation virt_loc,
 				       gpointer user_data)
@@ -2012,7 +2124,11 @@
                                      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,
                                      DATE_CELL);
@@ -2101,7 +2217,11 @@
                                      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);
 
@@ -2231,7 +2351,10 @@
   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);
 
Index: src/register/ledger-core/split-register.h
===================================================================
--- src/register/ledger-core/split-register.h	(revision 18169)
+++ src/register/ledger-core/split-register.h	(working copy)
@@ -209,6 +209,7 @@
 #define TYPE_CELL  "split-type"
 #define XFRM_CELL  "account"
 #define VNOTES_CELL "void-notes"
+#define RBALN_CELL "reg-run-balance"
 /** @} */
 
 /** @name Cursor Names
Index: src/register/ledger-core/split-register-layout.c
===================================================================
--- src/register/ledger-core/split-register-layout.c	(revision 18169)
+++ src/register/ledger-core/split-register-layout.c	(working copy)
@@ -248,7 +248,7 @@
           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_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_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 @@
     case INCOME_LEDGER:
     case GENERAL_LEDGER:
     case SEARCH_LEDGER:
-      num_cols = 8;
+      num_cols = 9;
       break;
 
     case STOCK_REGISTER:
@@ -702,6 +703,15 @@
                          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 *
_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to