gnucash master: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Sun Dec 8 07:40:59 EST 2019


Updated	 via  https://github.com/Gnucash/gnucash/commit/279a5fcd (commit)
	 via  https://github.com/Gnucash/gnucash/commit/6266ca2f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/17bbf870 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b5f9cd0b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/775200ef (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2cd69e8d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ded336f9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c06191a6 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1c643856 (commit)
	from  https://github.com/Gnucash/gnucash/commit/3b1b78d5 (commit)



commit 279a5fcde88be559634ae36201befe8696272cd7
Merge: 3b1b78d54 6266ca2f1
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 8 20:34:49 2019 +0800

    Merge branch 'maint'

diff --cc gnucash/gnome/gnc-budget-view.c
index 599b28a35,780a1f062..caa50ddb1
--- a/gnucash/gnome/gnc-budget-view.c
+++ b/gnucash/gnome/gnc-budget-view.c
@@@ -1021,19 -974,23 +1016,27 @@@ budget_col_source(Account *account, Gtk
          }
          else
          {
+             if (gnc_reverse_budget_balance (account, TRUE))
+                 numeric = gnc_numeric_neg (numeric);
+ 
              xaccSPrintAmount(amtbuff, numeric,
                               gnc_account_print_info(account, FALSE));
-             g_object_set(cell, "foreground",
-                          red && gnc_numeric_negative_p(numeric)
-                              ? get_negative_color()
-                              : NULL,
-                          NULL);
+ 
+             if (red && gnc_numeric_negative_p(numeric))
+             {
+                 gchar *color = get_negative_color ();
+                 g_object_set(cell, "foreground", color, NULL);
+                 g_free (color);
+             }
+             else
+                 g_object_set(cell, "foreground", NULL, NULL);
+ 
          }
      }
 +
 +    note = gnc_budget_get_account_period_note(budget, account, period_num);
 +    g_object_set(cell, "flagged", note != NULL, NULL);
 +
      return g_strdup(amtbuff);
  }
  
diff --cc gnucash/report/reports/standard/budget.scm
index 12c99c399,8af29a078..b97ae5fab
--- a/gnucash/report/reports/standard/budget.scm
+++ b/gnucash/report/reports/standard/budget.scm
@@@ -420,8 -406,25 +436,25 @@@
                                    (- bgt-total act-total))))
                (loop (cdr column-list)
                      (disp-cols "total-number-cell" current-col
 -                               bgt-total act-total dif-total))))
 +                               bgt-total act-total dif-total #f))))
  
+            ;; fwd-compatibility: the next cond may be removed in master
+            (unreversed?
+             (let* ((period-list (cond
+                                  ((list? (car column-list)) (car column-list))
+                                  (accumulate? (iota (1+ (car column-list))))
+                                  (else (list (car column-list)))))
+                    (bgt-val (maybe-negate
+                              (gnc:get-account-periodlist-budget-value
+                               budget acct period-list)))
+                    (act-val (maybe-negate
+                              (gnc:get-account-periodlist-actual-value
+                               budget acct period-list)))
+                    (dif-val (- bgt-val act-val)))
+               (loop (cdr column-list)
+                     (disp-cols "number-cell" current-col
+                                bgt-val act-val dif-val))))
+ 
             (else
              (let* ((period-list (cond
                                   ((list? (car column-list)) (car column-list))
diff --cc libgnucash/app-utils/gnc-ui-util.c
index 483d532bf,3ff97e105..b46914f9c
--- a/libgnucash/app-utils/gnc-ui-util.c
+++ b/libgnucash/app-utils/gnc-ui-util.c
@@@ -51,9 -51,8 +51,10 @@@
  #include "Account.h"
  #include "Transaction.h"
  #include "gnc-engine.h"
++#include "gnc-features.h"
  #include "gnc-euro.h"
  #include "gnc-hooks.h"
 +#include "gnc-locale-tax.h"
  #include "gnc-session.h"
  #include "engine-helpers.h"
  #include "gnc-locale-utils.h"

commit 6266ca2f12292836223a2cf74c9de7d97e8a258e
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Nov 29 19:48:39 2019 +0800

    g_free() output of get_negative_color
    
    because gdk_rgba_to_string() returns a newly-allocated string
    
    * get_negative_color is gchar* instead of const gchar*
    * move to dialog-utils.c
    * rename get_negative_color() to get_negative_color_str() in
    window-main-summarybar.c
    * add g_free to gnc_tree_model_account_dispose ()
    * modify code to g_free () after use

diff --git a/gnucash/gnome-utils/dialog-utils.c b/gnucash/gnome-utils/dialog-utils.c
index 3ff96017b..ca66223fe 100644
--- a/gnucash/gnome-utils/dialog-utils.c
+++ b/gnucash/gnome-utils/dialog-utils.c
@@ -894,3 +894,14 @@ gnc_cost_policy_select_new (void)
     return cost_policy_widget;
 }
 
+gchar*
+get_negative_color (void)
+{
+    GdkRGBA color;
+    GtkWidget *label = gtk_label_new ("Color");
+    GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET(label));
+    gtk_style_context_add_class (context, "negative-numbers");
+    gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
+
+    return gdk_rgba_to_string (&color);
+}
diff --git a/gnucash/gnome-utils/dialog-utils.h b/gnucash/gnome-utils/dialog-utils.h
index c30571d18..93857ef71 100644
--- a/gnucash/gnome-utils/dialog-utils.h
+++ b/gnucash/gnome-utils/dialog-utils.h
@@ -161,4 +161,6 @@ gboolean gnc_new_book_option_display (GtkWidget *parent);
 GtkWidget *
 gnc_cost_policy_select_new (void);
 
+gchar* get_negative_color (void);
+
 #endif /* DIALOG_UTILS_H */
diff --git a/gnucash/gnome-utils/gnc-tree-model-account.c b/gnucash/gnome-utils/gnc-tree-model-account.c
index 79de8f420..90e2dc983 100644
--- a/gnucash/gnome-utils/gnc-tree-model-account.c
+++ b/gnucash/gnome-utils/gnc-tree-model-account.c
@@ -32,6 +32,7 @@
 #include "gnc-tree-model-account.h"
 #include "gnc-component-manager.h"
 #include "Account.h"
+#include "dialog-utils.h"
 #include "gnc-accounting-period.h"
 #include "gnc-commodity.h"
 #include "gnc-prefs.h"
@@ -96,7 +97,7 @@ typedef struct GncTreeModelAccountPrivate
     QofBook *book;
     Account *root;
     gint event_handler_id;
-    const gchar *negative_color;
+    gchar *negative_color;
 
     GHashTable *account_values_hash;
 
@@ -109,17 +110,7 @@ typedef struct GncTreeModelAccountPrivate
 /************************************************************/
 /*           Account Tree Model - Misc Functions            */
 /************************************************************/
-static gchar*
-get_negative_color (void)
-{
-    GdkRGBA color;
-    GtkWidget *label = gtk_label_new ("Color");
-    GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET(label));
-    gtk_style_context_add_class (context, "negative-numbers");
-    gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
 
-    return gdk_rgba_to_string (&color);
-}
 
 /** Tell the GncTreeModelAccount code to update the color that it will
  *  use for negative numbers.  This function will iterate over all
@@ -144,7 +135,14 @@ gnc_tree_model_account_update_color (gpointer gsettings, gchar *key, gpointer us
                                                        g_free, g_free);
 
     use_red = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
-    priv->negative_color = use_red ? get_negative_color () : NULL;
+
+    if (priv->negative_color)
+        g_free (priv->negative_color);
+
+    if (use_red)
+        priv->negative_color = get_negative_color ();
+    else
+        priv->negative_color = NULL;
 }
 
 /************************************************************/
@@ -190,7 +188,14 @@ gnc_tree_model_account_init (GncTreeModelAccount *model)
     priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
     priv->book = NULL;
     priv->root = NULL;
-    priv->negative_color = red ? get_negative_color () : NULL;
+
+    if (priv->negative_color)
+        g_free (priv->negative_color);
+
+    if (red)
+        priv->negative_color = get_negative_color ();
+    else
+        priv->negative_color = NULL;
 
     // create the account values cache hash
     priv->account_values_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
@@ -244,6 +249,9 @@ gnc_tree_model_account_dispose (GObject *object)
         priv->event_handler_id = 0;
     }
 
+    if (priv->negative_color)
+        g_free (priv->negative_color);
+
     // destroy the cached acount values
     g_hash_table_destroy (priv->account_values_hash);
 
diff --git a/gnucash/gnome-utils/window-main-summarybar.c b/gnucash/gnome-utils/window-main-summarybar.c
index 9262bded3..14b992835 100644
--- a/gnucash/gnome-utils/window-main-summarybar.c
+++ b/gnucash/gnome-utils/window-main-summarybar.c
@@ -443,7 +443,7 @@ gnc_main_window_summary_refresh (GNCMainSummary * summary)
 }
 
 static gchar*
-get_negative_color (void)
+get_negative_color_str (void)
 {
     GdkRGBA color;
     GdkRGBA *rgba;
@@ -467,7 +467,7 @@ summarybar_update_color (gpointer gsettings, gchar *key, gpointer user_data)
 {
     GNCMainSummary *summary = user_data;
 
-    summary->negative_color = get_negative_color();
+    summary->negative_color = get_negative_color_str();
     summary->show_negative_color = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
 
     gnc_main_window_summary_refresh (summary);
@@ -640,7 +640,7 @@ gnc_main_window_summary_new (void)
     retval->totals_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (retval->datamodel));
     g_object_unref (retval->datamodel);
 
-    retval->negative_color = get_negative_color();
+    retval->negative_color = get_negative_color_str();
     retval->show_negative_color = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
     gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED,
                           summarybar_update_color, retval);
diff --git a/gnucash/gnome/gnc-budget-view.c b/gnucash/gnome/gnc-budget-view.c
index 02ace74b9..780a1f062 100644
--- a/gnucash/gnome/gnc-budget-view.c
+++ b/gnucash/gnome/gnc-budget-view.c
@@ -911,18 +911,6 @@ gbv_get_accumulated_budget_amount(GncBudget* budget, Account* account, guint per
     return info.total;
 }
 
-static gchar*
-get_negative_color (void)
-{
-    GdkRGBA color;
-    GtkWidget *label = gtk_label_new ("Color");
-    GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET(label));
-    gtk_style_context_add_class (context, "negative-numbers");
-    gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color);
-    gtk_widget_destroy(label);
-    
-    return gdk_rgba_to_string(&color);
-}
 
 /** \brief Calculates and displays budget amount for a period in a defined account.
 
@@ -991,11 +979,16 @@ budget_col_source(Account *account, GtkTreeViewColumn *col,
 
             xaccSPrintAmount(amtbuff, numeric,
                              gnc_account_print_info(account, FALSE));
-            g_object_set(cell, "foreground",
-                         red && gnc_numeric_negative_p(numeric)
-                             ? get_negative_color()
-                             : NULL,
-                         NULL);
+
+            if (red && gnc_numeric_negative_p(numeric))
+            {
+                gchar *color = get_negative_color ();
+                g_object_set(cell, "foreground", color, NULL);
+                g_free (color);
+            }
+            else
+                g_object_set(cell, "foreground", NULL, NULL);
+
         }
     }
     return g_strdup(amtbuff);
@@ -1078,8 +1071,16 @@ budget_total_col_source(Account *account, GtkTreeViewColumn *col,
     total = bgv_get_total_for_account(account, budget, NULL);
     xaccSPrintAmount(amtbuff, total,
                      gnc_account_print_info(account, TRUE));
-    g_object_set(cell, "foreground",
-                 red && gnc_numeric_negative_p(total) ? get_negative_color () : NULL, NULL);
+
+    if (red && gnc_numeric_negative_p(total))
+    {
+        gchar *color = get_negative_color ();
+        g_object_set(cell, "foreground", color, NULL);
+        g_free (color);
+    }
+    else
+        g_object_set(cell, "foreground", NULL, NULL);
+
     return g_strdup(amtbuff);
 }
 
@@ -1218,8 +1219,14 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell,
     xaccSPrintAmount(amtbuff, total,
                      gnc_commodity_print_info(total_currency,
                                               period_num < 0 ? TRUE : FALSE));
-    g_object_set(cell, "foreground",
-                 red && gnc_numeric_negative_p(total) ? get_negative_color () : NULL, NULL);
+    if (red && gnc_numeric_negative_p(total))
+    {
+        gchar *color = get_negative_color ();
+        g_object_set(cell, "foreground", color, NULL);
+        g_free (color);
+    }
+    else
+        g_object_set(cell, "foreground", NULL, NULL);
 
     g_object_set(G_OBJECT(cell), "text", amtbuff, "xalign", 1.0, NULL);
 }

commit 17bbf870e5bdacf96114a8ef2aa5a763bc880877
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Nov 29 21:50:47 2019 +0800

    Bug 797401 - Invoice Reports need an overall page width set
    
    Use html5 @media to set main-table to page width.

diff --git a/gnucash/report/business-reports/invoice.scm b/gnucash/report/business-reports/invoice.scm
index 84bf7eedb..a56dcdec4 100644
--- a/gnucash/report/business-reports/invoice.scm
+++ b/gnucash/report/business-reports/invoice.scm
@@ -43,6 +43,7 @@
 .company-table > table * { padding: 0px; }
 .client-table > table * { padding: 0px; }
 .invoice-details-table > table * { padding: 0px; }
+ at media print { .main-table > table { width: 100%; }}
 ")
 
 (define (date-col columns-used)

commit b5f9cd0b32398fe5668e4f140cc91a7324436e01
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Oct 19 16:21:43 2019 +0800

    [budgets.scm] budget reports handle both natural & reversed budgets

diff --git a/gnucash/report/standard-reports/budget-balance-sheet.scm b/gnucash/report/standard-reports/budget-balance-sheet.scm
index 0b24b26e1..38c89ee9d 100644
--- a/gnucash/report/standard-reports/budget-balance-sheet.scm
+++ b/gnucash/report/standard-reports/budget-balance-sheet.scm
@@ -256,7 +256,8 @@
       (gnc:report-options report-obj) pagename optname)))
 
   (define (get-budget-account-budget-balance budget account)
-    (gnc:budget-account-get-net budget account #f #f))
+    (let ((bal (gnc:budget-account-get-net budget account #f #f)))
+      (if (gnc-reverse-budget-balance account #t) (gnc:collector- bal) bal)))
 
   (define (get-budget-account-initial-balance budget account)
     (gnc:budget-account-get-initial-balance budget account))
diff --git a/gnucash/report/standard-reports/budget-income-statement.scm b/gnucash/report/standard-reports/budget-income-statement.scm
index a2393037c..07618edfc 100644
--- a/gnucash/report/standard-reports/budget-income-statement.scm
+++ b/gnucash/report/standard-reports/budget-income-statement.scm
@@ -308,7 +308,8 @@
                    (get-balance-fn budget account period-start period-end))))
 
   (define (get-budget-account-budget-balance budget account period-start period-end)
-    (gnc:budget-account-get-net budget account period-start period-end))
+    (let ((bal (gnc:budget-account-get-net budget account period-start period-end)))
+      (if (gnc-reverse-budget-balance account #t) (gnc:collector- bal) bal)))
 
   (gnc:report-starting reportname)
   
diff --git a/gnucash/report/standard-reports/budget.scm b/gnucash/report/standard-reports/budget.scm
index 80b98dd6a..8af29a078 100644
--- a/gnucash/report/standard-reports/budget.scm
+++ b/gnucash/report/standard-reports/budget.scm
@@ -331,6 +331,9 @@
              column-list exchange-fn)
       (let* ((comm (xaccAccountGetCommodity acct))
              (reverse-balance? (gnc-reverse-balance acct))
+             (maybe-negate (lambda (amt) (if reverse-balance? (- amt) amt)))
+             (unreversed? (gnc-using-unreversed-budgets
+                           (gnc-get-current-book))) ;fwd-compatibility
              (allperiods (filter number? (gnc:list-flatten column-list)))
              (total-periods (if (and accumulate? (not (null? allperiods)))
                                 (iota (1+ (apply max allperiods)))
@@ -379,6 +382,19 @@
            ((null? column-list)
             #f)
 
+           ;; fwd-compatibility: the next cond may be removed in master
+           ((and (eq? (car column-list) 'total) unreversed?)
+            (let* ((bgt-total (maybe-negate
+                               (gnc:get-account-periodlist-budget-value
+                                budget acct total-periods)))
+                   (act-total (maybe-negate
+                               (gnc:get-account-periodlist-actual-value
+                                budget acct total-periods)))
+                   (dif-total (- bgt-total act-total)))
+              (loop (cdr column-list)
+                    (disp-cols "total-number-cell" current-col
+                               bgt-total act-total dif-total))))
+
            ((eq? (car column-list) 'total)
             (let* ((bgt-total (gnc:get-account-periodlist-budget-value
                                budget acct total-periods))
@@ -392,6 +408,23 @@
                     (disp-cols "total-number-cell" current-col
                                bgt-total act-total dif-total))))
 
+           ;; fwd-compatibility: the next cond may be removed in master
+           (unreversed?
+            (let* ((period-list (cond
+                                 ((list? (car column-list)) (car column-list))
+                                 (accumulate? (iota (1+ (car column-list))))
+                                 (else (list (car column-list)))))
+                   (bgt-val (maybe-negate
+                             (gnc:get-account-periodlist-budget-value
+                              budget acct period-list)))
+                   (act-val (maybe-negate
+                             (gnc:get-account-periodlist-actual-value
+                              budget acct period-list)))
+                   (dif-val (- bgt-val act-val)))
+              (loop (cdr column-list)
+                    (disp-cols "number-cell" current-col
+                               bgt-val act-val dif-val))))
+
            (else
             (let* ((period-list (cond
                                  ((list? (car column-list)) (car column-list))

commit 775200ef348f8579a3e0258988ae25a8026dbd6d
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Oct 22 23:19:28 2019 +0800

    [gnc-budget-view.c] totals - 5 fundamental types
    
    previous showed income/expense/transfers/totals budget totals, of
    uncertain meaning. now shows income/expense/asset/liability/equity
    budget totals.
    
    the 5 lines also become sensitive to global sign-reverses property

diff --git a/gnucash/gnome/gnc-budget-view.c b/gnucash/gnome/gnc-budget-view.c
index f8972910a..02ace74b9 100644
--- a/gnucash/gnome/gnc-budget-view.c
+++ b/gnucash/gnome/gnc-budget-view.c
@@ -94,8 +94,9 @@ enum
 {
     TOTALS_TYPE_INCOME, /**< This total is Income type*/
     TOTALS_TYPE_EXPENSES, /**< This total is Expenses type*/
-    TOTALS_TYPE_TRANSFERS, /**< This total is Transfers type*/
-    TOTALS_TYPE_TOTAL /**< This total is for Totals*/
+    TOTALS_TYPE_ASSET, /**< This total is Assets type*/
+    TOTALS_TYPE_LIABILITY, /**< This total is Liabilities type*/
+    TOTALS_TYPE_EQUITY /**< This total is for Equity type*/
 };
 /**< \brief ENUM for different budget totals types.
 
@@ -420,9 +421,11 @@ gbv_create_widget(GncBudgetView *view)
     gtk_list_store_append(totals_tree_model, &iter);
     gtk_list_store_set(totals_tree_model, &iter, 0, _("Expenses"), 1, TOTALS_TYPE_EXPENSES, -1);
     gtk_list_store_append(totals_tree_model, &iter);
-    gtk_list_store_set(totals_tree_model, &iter, 0, _("Transfers"), 1, TOTALS_TYPE_TRANSFERS, -1);
+    gtk_list_store_set(totals_tree_model, &iter, 0, _("Assets"), 1, TOTALS_TYPE_ASSET, -1);
     gtk_list_store_append(totals_tree_model, &iter);
-    gtk_list_store_set(totals_tree_model, &iter, 0, _("Total"), 1, TOTALS_TYPE_TOTAL, -1);
+    gtk_list_store_set(totals_tree_model, &iter, 0, _("Liabilities"), 1, TOTALS_TYPE_LIABILITY, -1);
+    gtk_list_store_append(totals_tree_model, &iter);
+    gtk_list_store_set(totals_tree_model, &iter, 0, _("Equity"), 1, TOTALS_TYPE_EQUITY, -1);
 
     totals_tree_view = GTK_TREE_VIEW(gtk_tree_view_new());
     priv->totals_tree_view = totals_tree_view;
@@ -1172,24 +1175,23 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell,
         switch (xaccAccountGetType(account))
         {
         case ACCT_TYPE_INCOME:
-            if (row_type != TOTALS_TYPE_INCOME &&
-                row_type != TOTALS_TYPE_TOTAL)
-                continue;
-            break;
-        case ACCT_TYPE_LIABILITY:
-        case ACCT_TYPE_EQUITY:
-            if (row_type != TOTALS_TYPE_TRANSFERS &&
-                row_type != TOTALS_TYPE_TOTAL)
+            if (row_type != TOTALS_TYPE_INCOME)
                 continue;
             break;
         case ACCT_TYPE_EXPENSE:
-            if ((row_type != TOTALS_TYPE_EXPENSES) &&
-                (row_type != TOTALS_TYPE_TOTAL))
+            if (row_type != TOTALS_TYPE_EXPENSES)
                 continue;
             break;
         case ACCT_TYPE_ASSET:
-            if (row_type != TOTALS_TYPE_TRANSFERS &&
-                row_type != TOTALS_TYPE_TOTAL)
+            if (row_type != TOTALS_TYPE_ASSET)
+                continue;
+            break;
+        case ACCT_TYPE_LIABILITY:
+            if (row_type != TOTALS_TYPE_LIABILITY)
+                continue;
+            break;
+        case ACCT_TYPE_EQUITY:
+            if (row_type != TOTALS_TYPE_EQUITY)
                 continue;
             break;
         default:
@@ -1203,20 +1205,14 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell,
         }
         else
         {
-            value =
-                gbv_get_accumulated_budget_amount(budget, account, period_num);
+            value = gbv_get_accumulated_budget_amount(budget, account, period_num);
 
             value = gnc_pricedb_convert_balance_nearest_price_t64(
                         pdb, value, currency, total_currency,
                         gnc_budget_get_period_start_date(budget, period_num));
         }
 
-        if (gnc_reverse_budget_balance (account, TRUE))
-            total = gnc_numeric_sub(total, value, GNC_DENOM_AUTO,
-                                    GNC_HOW_DENOM_LCD);
-        else
-            total = gnc_numeric_add(total, value, GNC_DENOM_AUTO,
-                                    GNC_HOW_DENOM_LCD);
+        total = gnc_numeric_add(total, value, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD);
     }
 
     xaccSPrintAmount(amtbuff, total,

commit 2cd69e8d85f8f1538409deeb657a379a0bc36c92
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Oct 19 16:19:11 2019 +0800

    [budgets.c] handle both natural & reversed signs budgets
    
    introduce new API
    * gnc_using_unreversed_budgets - queries book's unreversed feature
    * gnc_reverse_budget_balance - check if book unreversal status matches
      2nd argument. if so, return account's reversal status. else, return
      FALSE.
    
    * gnome-budget-view can now show both natural and reversed budgets
    * gnome-plugin-page-budget will now read&write both natural and
      reversed budgets.

diff --git a/gnucash/gnome/gnc-budget-view.c b/gnucash/gnome/gnc-budget-view.c
index 9846e5e3f..f8972910a 100644
--- a/gnucash/gnome/gnc-budget-view.c
+++ b/gnucash/gnome/gnc-budget-view.c
@@ -901,6 +901,10 @@ gbv_get_accumulated_budget_amount(GncBudget* budget, Account* account, guint per
     {
         info.total = gnc_budget_get_account_period_value(budget, account, period_num);
     }
+
+    if (gnc_reverse_budget_balance (account, TRUE))
+        info.total = gnc_numeric_neg (info.total);
+
     return info.total;
 }
 
@@ -979,6 +983,9 @@ budget_col_source(Account *account, GtkTreeViewColumn *col,
         }
         else
         {
+            if (gnc_reverse_budget_balance (account, TRUE))
+                numeric = gnc_numeric_neg (numeric);
+
             xaccSPrintAmount(amtbuff, numeric,
                              gnc_account_print_info(account, FALSE));
             g_object_set(cell, "foreground",
@@ -1019,6 +1026,9 @@ bgv_get_total_for_account(Account* account, GncBudget* budget, gnc_commodity *ne
             {
                 numeric = gbv_get_accumulated_budget_amount(budget, account, period_num);
 
+                if (gnc_reverse_budget_balance (account, TRUE))
+                    numeric = gnc_numeric_neg (numeric);
+
                 if (new_currency)
                 {
                     numeric = gnc_pricedb_convert_balance_nearest_price_t64(
@@ -1043,6 +1053,10 @@ bgv_get_total_for_account(Account* account, GncBudget* budget, gnc_commodity *ne
             }
         }
     }
+
+    if (gnc_reverse_budget_balance (account, TRUE))
+        total = gnc_numeric_neg(total);
+
     return total;
 }
 
@@ -1093,8 +1107,12 @@ budget_col_edited(Account *account, GtkTreeViewColumn *col,
     if (new_text && *new_text == '\0')
         gnc_budget_unset_account_period_value(budget, account, period_num);
     else
+    {
+        if (gnc_reverse_budget_balance (account, TRUE))
+            numeric = gnc_numeric_neg(numeric);
         gnc_budget_set_account_period_value(budget, account, period_num,
                                             numeric);
+    }
 }
 
 /** \brief Function to find the total in a column of budget provided and
@@ -1124,7 +1142,7 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell,
     gchar amtbuff[100]; //FIXME: overkill, where's the #define?
     gint i;
     gint num_top_accounts;
-    gboolean neg, red;
+    gboolean red;
     GNCPriceDB *pdb;
     gnc_commodity *total_currency, *currency;
 
@@ -1150,7 +1168,6 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell,
     {
         account  = gnc_account_nth_child(priv->rootAcct, i);
         currency = gnc_account_get_currency_or_parent(account);
-        neg      = FALSE;
 
         switch (xaccAccountGetType(account))
         {
@@ -1166,16 +1183,14 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell,
                 continue;
             break;
         case ACCT_TYPE_EXPENSE:
-            if (row_type == TOTALS_TYPE_TOTAL)
-                neg = TRUE;
-            else if (row_type != TOTALS_TYPE_EXPENSES)
+            if ((row_type != TOTALS_TYPE_EXPENSES) &&
+                (row_type != TOTALS_TYPE_TOTAL))
                 continue;
             break;
         case ACCT_TYPE_ASSET:
             if (row_type != TOTALS_TYPE_TRANSFERS &&
                 row_type != TOTALS_TYPE_TOTAL)
                 continue;
-            neg = TRUE;
             break;
         default:
             continue;
@@ -1196,7 +1211,7 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell,
                         gnc_budget_get_period_start_date(budget, period_num));
         }
 
-        if (neg)
+        if (gnc_reverse_budget_balance (account, TRUE))
             total = gnc_numeric_sub(total, value, GNC_DENOM_AUTO,
                                     GNC_HOW_DENOM_LCD);
         else
diff --git a/gnucash/gnome/gnc-plugin-page-budget.c b/gnucash/gnome/gnc-plugin-page-budget.c
index ca77b4893..d7ae5352d 100644
--- a/gnucash/gnome/gnc-plugin-page-budget.c
+++ b/gnucash/gnome/gnc-plugin-page-budget.c
@@ -902,7 +902,7 @@ estimate_budget_helper(GtkTreeModel *model, GtkTreePath *path,
                               GNC_HOW_DENOM_SIGFIGS(priv->sigFigs) | 
                               GNC_HOW_RND_ROUND_HALF_UP);
 
-        if (gnc_reverse_balance(acct))
+        if (gnc_reverse_budget_balance(acct, FALSE))
             num = gnc_numeric_neg(num);
 
         for (i = 0; i < num_periods; i++)
@@ -920,7 +920,7 @@ estimate_budget_helper(GtkTreeModel *model, GtkTreePath *path,
 
             if (!gnc_numeric_check(num))
             {
-                if (gnc_reverse_balance(acct))
+                if (gnc_reverse_budget_balance(acct, FALSE))
                     num = gnc_numeric_neg(num);
 
                 num = gnc_numeric_convert(num, GNC_DENOM_AUTO,
@@ -1020,7 +1020,7 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path,
 {
     Account *acct;
     guint num_periods, i;
-    gnc_numeric num;
+    gnc_numeric num, allvalue;
     GncPluginPageBudgetPrivate *priv;
     GncPluginPageBudget *page = data;
 
@@ -1028,7 +1028,9 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path,
     priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
     acct = gnc_budget_view_get_account_from_path(priv->budget_view, path);
     num_periods = gnc_budget_get_num_periods(priv->budget);
-    num = priv->allValue;
+    allvalue = priv->allValue;
+    if (gnc_reverse_budget_balance(acct, TRUE))
+        allvalue = gnc_numeric_neg(allvalue);
 
     for (i = 0; i < num_periods; i++)
     {
@@ -1036,7 +1038,7 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path,
         {
         case ADD:
             num = gnc_budget_get_account_period_value(priv->budget, acct, i);
-            num = gnc_numeric_add(num, priv->allValue, GNC_DENOM_AUTO,
+            num = gnc_numeric_add(num, allvalue, GNC_DENOM_AUTO,
                                   GNC_HOW_DENOM_SIGFIGS(priv->sigFigs) |
                                   GNC_HOW_RND_ROUND_HALF_UP);
             gnc_budget_set_account_period_value(priv->budget, acct, i, num);
@@ -1053,7 +1055,7 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path,
             break;
         default:
             gnc_budget_set_account_period_value(priv->budget, acct, i,
-                                                priv->allValue);
+                                                allvalue);
             break;
         }
     }
diff --git a/libgnucash/app-utils/app-utils.i b/libgnucash/app-utils/app-utils.i
index 7ded4efa8..2da48b375 100644
--- a/libgnucash/app-utils/app-utils.i
+++ b/libgnucash/app-utils/app-utils.i
@@ -116,6 +116,8 @@ const char * xaccPrintAmount (gnc_numeric val, GNCPrintAmountInfo info);
 gchar *number_to_words(gdouble val, gint64 denom);
 const gchar *printable_value (gdouble val, gint denom);
 
+gboolean gnc_using_unreversed_budgets (QofBook* book);
+gboolean gnc_reverse_budget_balance (const Account *account, gboolean unreversed);
 gboolean gnc_reverse_balance (const Account *account);
 
 gboolean gnc_is_euro_currency(const gnc_commodity * currency);
diff --git a/libgnucash/app-utils/gnc-ui-util.c b/libgnucash/app-utils/gnc-ui-util.c
index bae5f388b..3ff97e105 100644
--- a/libgnucash/app-utils/gnc-ui-util.c
+++ b/libgnucash/app-utils/gnc-ui-util.c
@@ -179,6 +179,23 @@ gnc_reverse_balance (const Account *account)
     return reverse_type[type];
 }
 
+gboolean gnc_using_unreversed_budgets (QofBook* book)
+{
+    return gnc_features_check_used (book, GNC_FEATURE_BUDGET_UNREVERSED);
+}
+
+/* similar to gnc_reverse_balance but also accepts a gboolean
+   unreversed which specifies the reversal strategy - FALSE = pre-4.x
+   always-assume-credit-accounts, TRUE = all amounts unreversed */
+gboolean
+gnc_reverse_budget_balance (const Account *account, gboolean unreversed)
+{
+    if (unreversed == gnc_using_unreversed_budgets(gnc_account_get_book(account)))
+        return gnc_reverse_balance (account);
+
+    return FALSE;
+}
+
 
 gchar *
 gnc_get_default_directory (const gchar *section)
diff --git a/libgnucash/app-utils/gnc-ui-util.h b/libgnucash/app-utils/gnc-ui-util.h
index 4601f3b8b..472ee4dbc 100644
--- a/libgnucash/app-utils/gnc-ui-util.h
+++ b/libgnucash/app-utils/gnc-ui-util.h
@@ -46,6 +46,16 @@ typedef QofSession * (*QofSessionCB) (void);
 gchar *gnc_normalize_account_separator (const gchar* separator);
 gboolean gnc_reverse_balance(const Account *account);
 
+/* Backward compatibility *******************************************
+ * Return book's UNREVERSED_BUDGET feature check. */
+gboolean gnc_using_unreversed_budgets (QofBook* book);
+
+/* Backward compatibility *******************************************
+ * Compare book's UNREVERSED_BUDGET with unreverse_check. If they
+ * match, return account reversal according to global pref. If they
+ * don't match, return FALSE. */
+gboolean gnc_reverse_budget_balance (const Account *account, gboolean unreversed);
+
 /* Default directory sections ***************************************/
 #define GNC_PREFS_GROUP_OPEN_SAVE    "dialogs.open-save"
 #define GNC_PREFS_GROUP_EXPORT       "dialogs.export-accounts"

commit ded336f987ccd6b23c14d79a721ca115a4bb95dc
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Oct 19 16:06:20 2019 +0800

    [gnc-features] enable reading of unreversed budgets

diff --git a/libgnucash/engine/gnc-features.c b/libgnucash/engine/gnc-features.c
index 453ecfc6e..98e8d50b2 100644
--- a/libgnucash/engine/gnc-features.c
+++ b/libgnucash/engine/gnc-features.c
@@ -49,6 +49,7 @@ static gncFeature known_features[] =
     { GNC_FEATURE_GUID_FLAT_BAYESIAN, "Use account GUID as key for bayesian data and store KVP flat (requires at least Gnucash 2.6.19)" },
     { GNC_FEATURE_SQLITE3_ISO_DATES, "Use ISO formatted date-time strings in SQLite3 databases (requires at least GnuCash 2.6.20)"},
     { GNC_FEATURE_REG_SORT_FILTER, "Store the register sort and filter settings in .gcm metadata file (requires at least GnuCash 3.3)"},
+    { GNC_FEATURE_BUDGET_UNREVERSED, "Store budget amounts unreversed (i.e. natural) signs (requires at least Gnucash 3.8)"},
     { NULL },
 };
 
diff --git a/libgnucash/engine/gnc-features.h b/libgnucash/engine/gnc-features.h
index a53be433f..bb2efe10b 100644
--- a/libgnucash/engine/gnc-features.h
+++ b/libgnucash/engine/gnc-features.h
@@ -53,6 +53,7 @@ extern "C" {
 #define GNC_FEATURE_GUID_FLAT_BAYESIAN "Account GUID based bayesian with flat KVP"
 #define GNC_FEATURE_SQLITE3_ISO_DATES "ISO-8601 formatted date strings in SQLite3 databases."
 #define GNC_FEATURE_REG_SORT_FILTER "Register sort and filter settings stored in .gcm file"
+#define GNC_FEATURE_BUDGET_UNREVERSED "Use natural signs in budget amounts"
 
 /** @} */
 

commit c06191a6562d68a6151561936f487a6176d8045f
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Dec 5 10:16:45 2019 +0800

    Transaction.c: avoid slow g_list_nth_data

diff --git a/libgnucash/engine/Transaction.c b/libgnucash/engine/Transaction.c
index 0a2243747..477ecb034 100644
--- a/libgnucash/engine/Transaction.c
+++ b/libgnucash/engine/Transaction.c
@@ -676,15 +676,25 @@ Transaction *
 xaccTransClone (const Transaction *from)
 {
     Transaction *to = xaccTransCloneNoKvp (from);
-    int i = 0;
-    int length = g_list_length (from->splits);
+    GList *lfrom, *lto;
 
     xaccTransBeginEdit (to);
     qof_instance_copy_kvp (QOF_INSTANCE (to), QOF_INSTANCE (from));
-    g_assert (g_list_length (to->splits) == length);
-    for (i = 0; i < length; ++i)
-	xaccSplitCopyKvp (g_list_nth_data (from->splits, i),
-			    g_list_nth_data (to->splits, i));
+    g_return_val_if_fail (g_list_length (to->splits) == g_list_length (from->splits),
+                          NULL);
+
+    lfrom = from->splits;
+    lto = to->splits;
+
+    /* lfrom and lto are known to be of equal length via above
+       g_return_val_if_fail */
+    while (lfrom != NULL)
+    {
+        xaccSplitCopyKvp (lfrom->data, lto->data);
+        lfrom = lfrom->next;
+        lto = lto->next;
+    }
+
     xaccTransCommitEdit (to);
     return to;
 }

commit 1c64385614ec8a14912b577fe6b2d4a4ba09627a
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Dec 5 09:57:23 2019 +0800

    base-typemaps: avoid slow g_list_nth_data
    
    scan GList via glist pointer links rather than incrementing index.

diff --git a/common/base-typemaps.i b/common/base-typemaps.i
index 33e9dffb7..98fbe3027 100644
--- a/common/base-typemaps.i
+++ b/common/base-typemaps.i
@@ -268,12 +268,12 @@ typedef char gchar;
 
 %typemap(out) GList *, CommodityList *, SplitList *, AccountList *, LotList *,
     MonetaryList *, PriceList *, EntryList * {
-    guint i;
     gpointer data;
+    GList *l;
     PyObject *list = PyList_New(0);
-    for (i = 0; i < g_list_length($1); i++)
+    for (l = $1; l != NULL; l = l->next)
     {
-        data = g_list_nth_data($1, i);
+        data = l->data;
         if (GNC_IS_ACCOUNT(data))
             PyList_Append(list, SWIG_NewPointerObj(data, SWIGTYPE_p_Account, 0));
         else if (GNC_IS_SPLIT(data))



Summary of changes:
 common/base-typemaps.i                             |   6 +-
 gnucash/gnome-utils/dialog-utils.c                 |  11 ++
 gnucash/gnome-utils/dialog-utils.h                 |   2 +
 gnucash/gnome-utils/gnc-tree-model-account.c       |  34 +++---
 gnucash/gnome-utils/window-main-summarybar.c       |   6 +-
 gnucash/gnome/gnc-budget-view.c                    | 116 ++++++++++++---------
 gnucash/gnome/gnc-plugin-page-budget.c             |  14 +--
 .../reports/standard/budget-balance-sheet.scm      |   3 +-
 .../reports/standard/budget-income-statement.scm   |   3 +-
 gnucash/report/reports/standard/budget.scm         |  33 ++++++
 gnucash/report/reports/standard/invoice.scm        |   1 +
 libgnucash/app-utils/app-utils.i                   |   2 +
 libgnucash/app-utils/gnc-ui-util.c                 |  18 ++++
 libgnucash/app-utils/gnc-ui-util.h                 |  10 ++
 libgnucash/engine/Transaction.c                    |  22 ++--
 libgnucash/engine/gnc-features.c                   |   1 +
 libgnucash/engine/gnc-features.h                   |   1 +
 17 files changed, 201 insertions(+), 82 deletions(-)



More information about the gnucash-changes mailing list