gnucash maint: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Sat Jun 23 20:48:33 EDT 2018


Updated	 via  https://github.com/Gnucash/gnucash/commit/22fb8511 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ddd06e69 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1e6627c4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/010dd04e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ae4b0bd8 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3af9acec (commit)
	 via  https://github.com/Gnucash/gnucash/commit/10e20f97 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/91af85ad (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1b4a2acb (commit)
	from  https://github.com/Gnucash/gnucash/commit/b74cc7c4 (commit)



commit 22fb85113aa1ea4cfdeea184e4707326e788cd20
Merge: ddd06e6 010dd04
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Jun 23 17:46:25 2018 -0700

    Merge Chris Lam's  'maint-fix-796614' into maint.


commit ddd06e69e8326f9236c3532465cce0a7b27ef789
Merge: 1e6627c 91af85a
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Jun 23 17:38:53 2018 -0700

    Merge Bob Fewell's 'reg-tooltips' into maint.


commit 1e6627c4c55dd824bf48e3e2893d973424120b8c
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Jun 23 17:35:42 2018 -0700

    [DBI Backend] Init and finalize the backend in setup and teardown.
    
    Xcode 9's clang creates a separate dbi_instance for each test and so
    each one needs to be initialized during its setup and finalized at
    teardown.

diff --git a/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp b/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
index 8c0d75e..7fb08a9 100644
--- a/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
+++ b/libgnucash/backend/dbi/test/test-backend-dbi-basic.cpp
@@ -53,6 +53,7 @@ extern "C"
 }
 /* For test_conn_index_functions */
 #include "../gnc-backend-dbi.hpp"
+#include "../gnc-backend-dbi.h"
 extern "C"
 {
 #include <unittest-support.h>
@@ -89,6 +90,7 @@ static void
 setup (Fixture* fixture, gconstpointer pData)
 {
     gchar* url = (gchar*)pData;
+    gnc_module_init_backend_dbi();
     fixture->session = qof_session_new ();
     /* When running distcheck the source directory is read-only, which
      * prevents creating the lock file. Force the session to get
@@ -109,7 +111,7 @@ setup (Fixture* fixture, gconstpointer pData)
 static void
 setup_memory (Fixture* fixture, gconstpointer pData)
 {
-    QofSession* session = qof_session_new ();
+    QofSession* session = nullptr;
     gchar* url = (gchar*)pData;
     QofBook* book;
     Account* root, *acct1, *acct2;
@@ -118,6 +120,7 @@ setup_memory (Fixture* fixture, gconstpointer pData)
     gnc_commodity_table* table;
     gnc_commodity* currency;
 
+    gnc_module_init_backend_dbi();
     session = qof_session_new ();
     book = qof_session_get_book (session);
     root = gnc_book_get_root_account (book);
@@ -166,6 +169,7 @@ setup_memory (Fixture* fixture, gconstpointer pData)
 static void
 setup_business (Fixture* fixture, gconstpointer pData)
 {
+    gnc_module_init_backend_dbi ();
     QofSession* session = qof_session_new ();
     gchar* url = (gchar*)pData;
     QofBook* book = qof_session_get_book (session);
@@ -349,6 +353,7 @@ teardown (Fixture* fixture, gconstpointer pData)
     g_free (lockfile);
     g_slist_free_full (fixture->hdlrs, test_free_log_handler);
     test_clear_error_list ();
+    gnc_module_finalize_backend_dbi();
 }
 
 #if 0 //temporarily disable test pending refactor.

commit 010dd04e826adc8b24636eac61dab302685cb8e5
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Jun 18 14:46:45 2018 +0800

    [TR] move options-summary to appear above subtotal-table
    
    It seems more fitting that the order of items is:
    - title
    - options summary
    - subtotal table
    - main table

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 45dab5a..f59bb52 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -2041,6 +2041,11 @@ be excluded from periodic reporting.")
                             (qof-print-date begindate)
                             (qof-print-date enddate)))))
 
+                (if (eq? infobox-display 'always)
+                    (gnc:html-document-add-object!
+                     document
+                     (gnc:html-render-options-changed options)))
+
                 (if (and (opt-val gnc:pagename-display optname-grid)
                          (if (memq primary-key DATE-SORTING-TYPES)
                              (keylist-get-info date-subtotal-list primary-date-subtotal 'renderer-fn)
@@ -2055,11 +2060,6 @@ be excluded from periodic reporting.")
                       (gnc:html-document-add-object!
                        document (grid->html-table grid list-of-rows list-of-cols))))
 
-                (if (eq? infobox-display 'always)
-                    (gnc:html-document-add-object!
-                     document
-                     (gnc:html-render-options-changed options)))
-
                 (gnc:html-document-add-object! document table)))))
 
     (gnc:report-finished)

commit ae4b0bd871a95d47582b54064eac125230fee269
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Jun 18 10:37:28 2018 +0800

    [TR] apply custom-sort after filtering.
    
    As a follow on to last commit, if a large datafile is subject to a
    reconciled date filter, the initial QofQuery date matcher would be
    skipped, causing a large number of splits sent for custom
    sorting prior to filtering.
    
    It will always be more efficient that filtering is applied
    first. Therefore custom sorting should be applied after filtering.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 0a7a4a1..45dab5a 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1977,12 +1977,6 @@ be excluded from periodic reporting.")
 
           (qof-query-destroy query)
 
-          (if custom-sort?
-              (begin
-                (set! splits (stable-sort! splits date-comparator?))
-                (set! splits (stable-sort! splits secondary-comparator?))
-                (set! splits (stable-sort! splits primary-comparator?))))
-
           ;; Combined Filter:
           ;; - include/exclude using split->date according to date options
           ;; - include/exclude splits to/from selected accounts
@@ -2013,6 +2007,11 @@ be excluded from periodic reporting.")
                                  )))
                         splits))
 
+          (when custom-sort?
+            (set! splits (stable-sort! splits date-comparator?))
+            (set! splits (stable-sort! splits secondary-comparator?))
+            (set! splits (stable-sort! splits primary-comparator?)))
+
           (if (null? splits)
 
               ;; error condition: no splits found

commit 3af9acec998403216873d55790428039e5cdb8bf
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Jun 18 10:36:11 2018 +0800

    Bug 796614 - Reconciliation report contains incorrect transactions
    
    This commit modifies the date filter for reconciliation report,
    ensuring only splits whose reconciled dates match report options.
    
    If a split is not yet reconciled, include it anyway.
    
    In a large datafile with a narrow reconciled date range, the
    datefilter is likely to be the filter with highest frequency of #f
    therefore it should be prioritised in the combined filter.
    
    I chose to add another optional keyword instead of reusing the
    existing #:custom-split-filter, because we need to detect when to
    override the QofQuery date filter.

diff --git a/gnucash/report/standard-reports/test/test-transaction.scm b/gnucash/report/standard-reports/test/test-transaction.scm
index 1418987..56f6ffc 100644
--- a/gnucash/report/standard-reports/test/test-transaction.scm
+++ b/gnucash/report/standard-reports/test/test-transaction.scm
@@ -901,13 +901,13 @@
       (set-option! options "General" "End Date" (cons 'absolute (gnc-dmy2time64 31 03 1970)))
       (let ((sxml (options->sxml options "filter reconcile date")))
         (test-equal "test reconciled amounts = $8"
-          (list "Total For Reconciled" "-$8.00")
+          (list "Total For Reconciled" "$8.00")
           (get-row-col sxml 3 #f))
         (test-equal "test cleared amounts = $29"
           (list "Total For Cleared" "$29.00")
           (get-row-col sxml 6 #f))
-        (test-equal "test unreconciled amounts = -$31"
-          (list "Total For Unreconciled" "-$31.00")
+        (test-equal "test unreconciled amounts = $31"
+          (list "Total For Unreconciled" "$31.00")
           (get-row-col sxml 11 #f))
         sxml)
       )))
diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 11c3a74..0a7a4a1 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -16,6 +16,7 @@
 ;;   and enable multiple data columns
 ;; - add support for indenting for better grouping
 ;; - add defaults suitable for a reconciliation report
+;;   including alternative date filtering strategy
 ;; - add subtotal summary grid
 ;; - by default, exclude closing transactions from the report
 ;;
@@ -446,10 +447,44 @@ Credit Card, and Income accounts."))
   (gnc:option-set-value (gnc:lookup-option options gnc:pagename-general optname-startdate) (cons 'relative 'start-prev-quarter))
   (gnc:option-set-value (gnc:lookup-option options gnc:pagename-general optname-enddate)   (cons 'relative 'today))
   (gnc:option-set-value (gnc:lookup-option options gnc:pagename-display (N_ "Reconciled Date")) #t)
-  (gnc:option-set-value (gnc:lookup-option options gnc:pagename-display (N_ "Running Balance")) #t)
+  (gnc:option-set-value (gnc:lookup-option options gnc:pagename-display (N_ "Running Balance")) #f)
   (gnc:option-set-value (gnc:lookup-option options gnc:pagename-display (N_ "Memo")) #f)
+  (gnc:option-make-internal! options gnc:pagename-display "Running Balance")
   options)
 
+(define reconcile-report-instructions
+  (gnc:make-html-text
+   (_ "The reconcile report is designed to be similar to the formal reconciliation tool.
+Please select the account from Report Options. Please note the dates specified in the options
+will apply to the Reconciliation Date.")
+   (gnc:html-markup-br)
+   (gnc:html-markup-br)))
+
+;; if split is reconciled, retrieve its reconciled date; if not yet reconciled, return #f
+(define (split->reconcile-date split)
+  (and (char=? (xaccSplitGetReconcile split) #\y)
+       (xaccSplitGetDateReconciled split)))
+
+(define (reconcile-report-calculated-cells options)
+  (define (opt-val section name)
+    (gnc:option-value (gnc:lookup-option options section name)))
+  (letrec
+      ((split-amount (lambda (s) (if (gnc:split-voided? s)
+                                     (xaccSplitVoidFormerAmount s)
+                                     (xaccSplitGetAmount s))))
+       (split-currency (lambda (s) (xaccAccountGetCommodity (xaccSplitGetAccount s))))
+       (amount (lambda (s) (gnc:make-gnc-monetary (split-currency s) (split-amount s))))
+       (debit-amount (lambda (s) (and (positive? (split-amount s))
+                                      (amount s))))
+       (credit-amount (lambda (s) (and (not (positive? (split-amount s)))
+                                       (gnc:monetary-neg (amount s))))))
+    ;; similar to default-calculated-cells but disable dual-subtotals.
+    (list (vector (_ "Funds In")
+                  debit-amount #f #t #f
+                  (const ""))
+          (vector (_ "Funds Out")
+                  credit-amount #f #t #f
+                  (const "")))))
 ;;
 ;; Default Transaction Report
 ;;
@@ -1047,11 +1082,11 @@ be excluded from periodic reporting.")
                (add-if (column-uses? 'reconciled-date)
                        (vector (_ "Reconciled Date")
                                (lambda (split transaction-row?)
-                                 (gnc:make-html-table-cell/markup
-                                  "date-cell"
-                                  (if (eqv? (xaccSplitGetReconcile split) #\y)
-                                      (qof-print-date (xaccSplitGetDateReconciled split))
-                                      "")))))
+                                 (let ((reconcile-date (split->reconcile-date split)))
+                                   (and reconcile-date
+                                        (gnc:make-html-table-cell/markup
+                                         "date-cell"
+                                         (qof-print-date reconcile-date)))))))
 
                (add-if (column-uses? 'num)
                        (vector (if (and BOOK-SPLIT-ACTION
@@ -1764,13 +1799,20 @@ be excluded from periodic reporting.")
 ;; Here comes the renderer function for this report.
 
 
-(define* (trep-renderer report-obj #:key custom-calculated-cells empty-report-message custom-split-filter)
+(define* (trep-renderer report-obj #:key custom-calculated-cells empty-report-message
+                        custom-split-filter split->date split->date-include-false?)
   ;; the trep-renderer is a define* function which, at minimum, takes the report object
   ;;
   ;; the optional arguments are:
   ;; #:custom-calculated-cells - a list of vectors to define customized data columns
-  ;; #:empty-report-message - a str which is displayed at the initial report opening
+  ;; #:empty-report-message - a str or html-object which is displayed at the initial report opening
   ;; #:custom-split-filter - a split->bool function to add to the split filter
+  ;; #:split->date - a split->time64 which overrides the default posted date filter
+  ;;     (see reconcile report)
+  ;; #:split->date-include-false? - addendum to above, specifies filter behaviour if
+  ;;     split->date returns #f. useful to include unreconciled splits in reconcile
+  ;;     report. it can be useful for alternative date filtering, e.g. filter by
+  ;;     transaction->invoice->payment date.
 
   (define options (gnc:report-options report-obj))
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
@@ -1908,7 +1950,8 @@ be excluded from periodic reporting.")
 
           (qof-query-set-book query (gnc-get-current-book))
           (xaccQueryAddAccountMatch query c_account_1 QOF-GUID-MATCH-ANY QOF-QUERY-AND)
-          (xaccQueryAddDateMatchTT query #t begindate #t enddate QOF-QUERY-AND)
+          (if (not split->date)
+              (xaccQueryAddDateMatchTT query #t begindate #t enddate QOF-QUERY-AND))
           (case void-status
             ((non-void-only) (gnc:query-set-match-non-voids-only! query (gnc-get-current-book)))
             ((void-only)     (gnc:query-set-match-voids-only! query (gnc-get-current-book)))
@@ -1941,6 +1984,7 @@ be excluded from periodic reporting.")
                 (set! splits (stable-sort! splits primary-comparator?))))
 
           ;; Combined Filter:
+          ;; - include/exclude using split->date according to date options
           ;; - include/exclude splits to/from selected accounts
           ;; - substring/regex matcher for Transaction Description/Notes/Memo
           ;; - custom-split-filter, a split->bool function for derived reports
@@ -1951,7 +1995,12 @@ be excluded from periodic reporting.")
                                            (if transaction-matcher-regexp
                                                (regexp-exec transaction-matcher-regexp str)
                                                (string-contains str transaction-matcher)))))
-                            (and (case filter-mode
+                            (and (or (not split->date)                  ; #f = ignore custom date filter
+                                     (let ((date (split->date split)))  ; cache split->date time64 or #f.
+                                       (if date                         ; if a split->date exists,
+                                           (<= begindate date enddate)  ; then check for inclusion;
+                                           split->date-include-false?))); else behave according to parameter
+                                 (case filter-mode
                                    ((none) #t)
                                    ((include) (is-filter-member split c_account_2))
                                    ((exclude) (not (is-filter-member split c_account_2))))
@@ -2029,7 +2078,13 @@ be excluded from periodic reporting.")
  'name (_ "Reconciliation Report")
  'report-guid "e45218c6d76f11e7b5ef0800277ef320"
  'options-generator reconcile-report-options-generator
- 'renderer trep-renderer)
+ ;; the renderer is the same as trep, however we're using a different split-date strategy.
+ ;; we're comparing reconcile date for inclusion, and if split is unreconciled, include it anyway.
+ 'renderer (lambda (rpt) (trep-renderer rpt
+                                        #:custom-calculated-cells reconcile-report-calculated-cells
+                                        #:split->date split->reconcile-date
+                                        #:split->date-include-false? #t
+                                        #:empty-report-message reconcile-report-instructions)))
 
 ;; Define the report.
 (gnc:define-report

commit 10e20f97c644997ba8697d5ff3c48ce4e48a5fb3
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Jun 22 15:23:06 2018 +0800

    [test-TR] add tests for reconcile report, date filter

diff --git a/gnucash/report/standard-reports/test/test-transaction.scm b/gnucash/report/standard-reports/test/test-transaction.scm
index b60226f..1418987 100644
--- a/gnucash/report/standard-reports/test/test-transaction.scm
+++ b/gnucash/report/standard-reports/test/test-transaction.scm
@@ -39,6 +39,7 @@
 
 ;; copied from transaction.scm
 (define trep-uuid "2fe3b9833af044abb929a88d5a59620f")
+(define reconcile-uuid "e45218c6d76f11e7b5ef0800277ef320")
 
 ;; Explicitly set locale to make the report output predictable
 (setlocale LC_ALL "C")
@@ -64,6 +65,7 @@
   (test-begin "transaction.scm")
   (null-test)
   (trep-tests)
+  (reconcile-tests)
   ;; (test-end) must be run as the last function, it will
   ;; return #f if any of the tests have failed.
   (test-end "transaction.scm"))
@@ -860,3 +862,52 @@
           (get-row-col sxml #f 6))))
     (test-end "subtotal table")
     ))
+
+(define (reconcile-tests)
+  (let* ((env (create-test-env))
+         (account-alist (env-create-account-structure-alist env structure))
+         (bank (cdr (assoc "Bank" account-alist)))
+         (income (cdr (assoc "Income" account-alist)))
+         (liability (cdr (assoc "Liabilities" account-alist)))
+         (expense (cdr (assoc "Expenses" account-alist)))
+         (YEAR (gnc:time64-get-year (gnc:get-today)))
+         )
+
+    (define (options->sxml options test-title)
+      (gnc:options->sxml reconcile-uuid options "test-reconcile" test-title))
+
+    (define (default-testing-options)
+      (let ((options (gnc:make-report-options reconcile-uuid)))
+        (set-option! options "Accounts" "Accounts" (list bank liability))
+        options))
+
+    ;; old transactions for testing reconcile date options
+    (env-transfer env 01 01 1970 bank expense       5   #:description "desc-1" #:num "trn1" #:memo "memo-3")
+    (env-transfer env 31 12 1969 income bank       10   #:description "desc-2" #:num "trn2" #:void-reason "void" #:notes "notes3")
+    (env-transfer env 31 12 1969 income bank       29   #:description "desc-3" #:num "trn3"
+                  #:reconcile (cons #\c (gnc-dmy2time64 01 03 1970)))
+    (env-transfer env 01 02 1970 bank expense      15   #:description "desc-4" #:num "trn4" #:notes "notes2" #:memo "memo-1")
+    (env-transfer env 10 01 1970 liability expense 10   #:description "desc-5" #:num "trn5" #:void-reason "any")
+    (env-transfer env 10 01 1970 liability expense 11   #:description "desc-6" #:num "trn6" #:notes "notes1")
+    (env-transfer env 10 02 1970 bank expense       8   #:description "desc-7" #:num "trn7" #:notes "notes1" #:memo "memo-2"
+                  #:reconcile (cons #\y (gnc-dmy2time64 01 03 1970)))
+
+
+    (let* ((options (default-testing-options)))
+      (let ((sxml (options->sxml options "null test")))
+        (test-assert "sxml"
+          sxml))
+      (set-option! options "General" "Start Date" (cons 'absolute (gnc-dmy2time64 01 03 1970)))
+      (set-option! options "General" "End Date" (cons 'absolute (gnc-dmy2time64 31 03 1970)))
+      (let ((sxml (options->sxml options "filter reconcile date")))
+        (test-equal "test reconciled amounts = $8"
+          (list "Total For Reconciled" "-$8.00")
+          (get-row-col sxml 3 #f))
+        (test-equal "test cleared amounts = $29"
+          (list "Total For Cleared" "$29.00")
+          (get-row-col sxml 6 #f))
+        (test-equal "test unreconciled amounts = -$31"
+          (list "Total For Unreconciled" "-$31.00")
+          (get-row-col sxml 11 #f))
+        sxml)
+      )))

commit 91af85ad14bf202a0ce37f5fa38bd56cbce9b732
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Sat Jun 16 11:29:38 2018 +0100

    Add a couple of tooltips to the register
    
    One for the reconcile cell which displays the reconciled date when
    reconciled or the void reason if voided. Also for the association cell
    to display the uri.

diff --git a/gnucash/register/ledger-core/split-register-model.c b/gnucash/register/ledger-core/split-register-model.c
index 8782d3c..b579548 100644
--- a/gnucash/register/ledger-core/split-register-model.c
+++ b/gnucash/register/ledger-core/split-register-model.c
@@ -508,6 +508,72 @@ gnc_split_register_get_default_tooltip (VirtualLocation virt_loc,
     return g_strdup (tooltip);
 }
 
+static char *
+gnc_split_register_get_recn_tooltip (VirtualLocation virt_loc,
+                                     gpointer user_data)
+{
+    SplitRegister *reg = user_data;
+    Split *split;
+
+    split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
+    if (!split)
+        return NULL;
+
+    if (xaccSplitGetReconcile (split) == YREC)
+    {
+        Timespec     ts = {0,0};
+        const char *str_rec_date;
+        xaccSplitGetDateReconciledTS (split, &ts);
+        str_rec_date = gnc_print_date (ts);
+        return g_strdup_printf (_("Reconciled on %s"), str_rec_date);
+    }
+    else if (xaccSplitGetReconcile (split) == VREC)
+    {
+        Transaction *trans = xaccSplitGetParent (split);
+        return g_strdup (xaccTransGetVoidReason (trans));
+    }
+    else
+        return NULL;
+}
+
+static char *
+gnc_split_register_get_associate_tooltip (VirtualLocation virt_loc,
+                                          gpointer user_data)
+{
+    SplitRegister *reg = user_data;
+    Transaction *trans;
+    const char *uri;
+
+    trans = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
+    if (!trans)
+        return NULL;
+
+    // get the existing uri
+    uri = xaccTransGetAssociation (trans);
+
+    // Check for uri is empty or NULL
+    if (g_strcmp0 (uri, "") != 0 && g_strcmp0 (uri, NULL) != 0)
+    {
+        gboolean valid_path_head = FALSE;
+        gchar *path_head = gnc_prefs_get_string (GNC_PREFS_GROUP_GENERAL, "assoc-head");
+
+        if ((path_head != NULL) && (g_strcmp0 (path_head, "") != 0)) // not default entry
+            valid_path_head = TRUE;
+
+        if (valid_path_head && g_str_has_prefix (uri,"file:/") && !g_str_has_prefix (uri,"file://"))
+        {
+            const gchar *part = uri + strlen ("file:");
+            gchar *new_uri = g_strconcat (path_head, part, NULL);
+            g_free (path_head);
+            return g_strdup (new_uri);
+        }
+        else
+            return g_strdup (uri);
+    }
+    else
+        return NULL;
+}
+
 static gnc_numeric
 get_trans_total_amount (SplitRegister *reg, Transaction *trans)
 {
@@ -2564,6 +2630,13 @@ gnc_split_register_model_new (void)
 //    gnc_table_model_set_default_tooltip_handler(
 //        model, gnc_split_register_get_default_tooltip);
 
+    gnc_table_model_set_tooltip_handler (model,
+                                       gnc_split_register_get_recn_tooltip,
+                                       RECN_CELL);
+
+    gnc_table_model_set_tooltip_handler (model,
+                                       gnc_split_register_get_associate_tooltip,
+                                       ASSOC_CELL);
 
 
     // help handlers

commit 1b4a2acb4509ba6974045865767b8a529c4a36c0
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Sat Jun 16 10:31:14 2018 +0100

    Add the ability to have register cell tooltips
    
    Add the ability to display tooltips on the register sheet based on type
    of cell.

diff --git a/gnucash/register/ledger-core/split-register-model.c b/gnucash/register/ledger-core/split-register-model.c
index bd13295..8782d3c 100644
--- a/gnucash/register/ledger-core/split-register-model.c
+++ b/gnucash/register/ledger-core/split-register-model.c
@@ -497,6 +497,17 @@ gnc_split_register_get_fcredit_label (VirtualLocation virt_loc,
     return _("Credit Formula");
 }
 
+
+static char *
+gnc_split_register_get_default_tooltip (VirtualLocation virt_loc,
+                                     gpointer user_data)
+{
+    SplitRegister *reg = user_data;
+    const char *tooltip = gnc_table_get_entry(reg->table, virt_loc);
+
+    return g_strdup (tooltip);
+}
+
 static gnc_numeric
 get_trans_total_amount (SplitRegister *reg, Transaction *trans)
 {
@@ -2343,6 +2354,7 @@ gnc_split_register_model_new (void)
 
     model = gnc_table_model_new ();
 
+    // entry handlers
     gnc_table_model_set_entry_handler (model,
                                        gnc_split_register_get_date_entry,
                                        DATE_CELL);
@@ -2443,7 +2455,7 @@ gnc_split_register_model_new (void)
                                        gnc_split_register_get_rbaln_entry,
                                        RBALN_CELL);
 
-
+    // label handlers
     gnc_table_model_set_label_handler (model,
                                        gnc_split_register_get_date_label,
                                        DATE_CELL);
@@ -2548,7 +2560,13 @@ gnc_split_register_model_new (void)
                                        gnc_split_register_get_tbalance_label,
                                        RBALN_CELL);
 
+    // tooltip handlers
+//    gnc_table_model_set_default_tooltip_handler(
+//        model, gnc_split_register_get_default_tooltip);
 
+
+
+    // help handlers
     gnc_table_model_set_default_help_handler(
         model, gnc_split_register_get_default_help);
 
@@ -2612,7 +2630,7 @@ gnc_split_register_model_new (void)
                                       gnc_split_register_get_fdebt_help,
                                       FDEBT_CELL);
 
-
+    // io flag handlers
     gnc_table_model_set_io_flags_handler(
         model, gnc_split_register_get_standard_io_flags, DATE_CELL);
 
diff --git a/gnucash/register/register-core/table-allgui.c b/gnucash/register/register-core/table-allgui.c
index 038d3b0..88d31eb 100644
--- a/gnucash/register/register-core/table-allgui.c
+++ b/gnucash/register/register-core/table-allgui.c
@@ -297,6 +297,25 @@ gnc_table_get_entry (Table *table, VirtualLocation virt_loc)
     return entry;
 }
 
+char *
+gnc_table_get_tooltip (Table *table, VirtualLocation virt_loc)
+{
+    TableGetTooltipHandler tooltip_handler;
+    BasicCell *cell;
+
+    cell = gnc_table_get_cell (table, virt_loc);
+    if (!cell || !cell->cell_name)
+        return NULL;
+
+    tooltip_handler = gnc_table_model_get_tooltip_handler (table->model,
+                         cell->cell_name);
+
+    if (!tooltip_handler)
+        return NULL;
+
+    return  tooltip_handler (virt_loc, table->model->handler_user_data);
+}
+
 CellIOFlags
 gnc_table_get_io_flags (Table *table, VirtualLocation virt_loc)
 {
diff --git a/gnucash/register/register-core/table-allgui.h b/gnucash/register/register-core/table-allgui.h
index 1487058..5c0396b 100644
--- a/gnucash/register/register-core/table-allgui.h
+++ b/gnucash/register/register-core/table-allgui.h
@@ -238,6 +238,8 @@ VirtualCell *  gnc_table_get_virtual_cell (Table *table,
 
 const char *   gnc_table_get_entry (Table *table, VirtualLocation virt_loc);
 
+char *         gnc_table_get_tooltip (Table *table, VirtualLocation virt_loc);
+
 const char *   gnc_table_get_label (Table *table, VirtualLocation virt_loc);
 
 CellIOFlags    gnc_table_get_io_flags (Table *table, VirtualLocation virt_loc);
diff --git a/gnucash/register/register-core/table-model.c b/gnucash/register/register-core/table-model.c
index a5baee2..b295263 100644
--- a/gnucash/register/register-core/table-model.c
+++ b/gnucash/register/register-core/table-model.c
@@ -133,6 +133,7 @@ gnc_table_model_new (void)
     model->entry_handlers = gnc_table_model_handler_hash_new ();
     model->label_handlers = gnc_table_model_handler_hash_new ();
     model->help_handlers = gnc_table_model_handler_hash_new ();
+    model->tooltip_handlers = gnc_table_model_handler_hash_new ();
     model->io_flags_handlers = gnc_table_model_handler_hash_new ();
     model->cell_color_handlers = gnc_table_model_handler_hash_new ();
     model->cell_border_handlers = gnc_table_model_handler_hash_new ();
@@ -158,6 +159,9 @@ gnc_table_model_destroy (TableModel *model)
     gnc_table_model_handler_hash_destroy (model->label_handlers);
     model->label_handlers = NULL;
 
+    gnc_table_model_handler_hash_destroy (model->tooltip_handlers);
+    model->tooltip_handlers = NULL;
+
     gnc_table_model_handler_hash_destroy (model->help_handlers);
     model->help_handlers = NULL;
 
@@ -262,6 +266,39 @@ gnc_table_model_get_label_handler (TableModel *model, const char * cell_name)
 }
 
 void
+gnc_table_model_set_tooltip_handler (TableModel *model,
+                                   TableGetTooltipHandler tooltip_handler,
+                                   const char * cell_name)
+{
+    g_return_if_fail (model != NULL);
+    g_return_if_fail (cell_name != NULL);
+
+    gnc_table_model_handler_hash_insert (model->tooltip_handlers,
+                                         cell_name,
+                                         tooltip_handler);
+}
+
+void
+gnc_table_model_set_default_tooltip_handler
+(TableModel *model, TableGetTooltipHandler tooltip_handler)
+{
+    g_return_if_fail (model != NULL);
+
+    gnc_table_model_handler_hash_insert (model->tooltip_handlers,
+                                         DEFAULT_HANDLER,
+                                         tooltip_handler);
+}
+
+TableGetTooltipHandler
+gnc_table_model_get_tooltip_handler (TableModel *model, const char * cell_name)
+{
+    g_return_val_if_fail (model != NULL, NULL);
+
+    return gnc_table_model_handler_hash_lookup (model->tooltip_handlers,
+            cell_name);
+}
+
+void
 gnc_table_model_set_help_handler (TableModel *model,
                                   TableGetHelpHandler help_handler,
                                   const char * cell_name)
diff --git a/gnucash/register/register-core/table-model.h b/gnucash/register/register-core/table-model.h
index 2d489a6..55aee0b 100644
--- a/gnucash/register/register-core/table-model.h
+++ b/gnucash/register/register-core/table-model.h
@@ -41,7 +41,7 @@ typedef enum
     XACC_CELL_ALLOW_SHADOW     = 1 << 1,
     XACC_CELL_ALLOW_ALL        = XACC_CELL_ALLOW_INPUT | XACC_CELL_ALLOW_SHADOW,
     XACC_CELL_ALLOW_EXACT_ONLY = 1 << 2,
-    XACC_CELL_ALLOW_ENTER	     = 1 << 3,
+    XACC_CELL_ALLOW_ENTER      = 1 << 3,
     XACC_CELL_ALLOW_READ_ONLY  = XACC_CELL_ALLOW_SHADOW | XACC_CELL_ALLOW_ENTER
 } CellIOFlags;
 
@@ -73,6 +73,9 @@ typedef const char * (*TableGetLabelHandler) (VirtualLocation virt_loc,
 typedef char * (*TableGetHelpHandler) (VirtualLocation virt_loc,
                                        gpointer user_data);
 
+typedef char * (*TableGetTooltipHandler) (VirtualLocation virt_loc,
+        gpointer user_data);
+
 typedef CellIOFlags (*TableGetCellIOFlagsHandler) (VirtualLocation virt_loc,
         gpointer user_data);
 
@@ -103,6 +106,7 @@ typedef struct
     GHashTable *entry_handlers;
     GHashTable *label_handlers;
     GHashTable *help_handlers;
+    GHashTable *tooltip_handlers;
     GHashTable *io_flags_handlers;
     GHashTable *cell_color_handlers;
     GHashTable *cell_border_handlers;
@@ -174,6 +178,17 @@ TableGetHelpHandler gnc_table_model_get_help_handler
 (TableModel *model,
  const char * cell_name);
 
+void gnc_table_model_set_tooltip_handler
+(TableModel *model,
+ TableGetTooltipHandler tooltip_handler,
+ const char * cell_name);
+void gnc_table_model_set_default_tooltip_handler
+(TableModel *model,
+ TableGetTooltipHandler tooltip_handler);
+TableGetTooltipHandler gnc_table_model_get_tooltip_handler
+(TableModel *model,
+ const char * cell_name);
+
 void gnc_table_model_set_io_flags_handler
 (TableModel *model,
  TableGetCellIOFlagsHandler io_flags_handler,
diff --git a/gnucash/register/register-gnome/gnucash-sheet.c b/gnucash/register/register-gnome/gnucash-sheet.c
index 2ba4ad6..bb32e93 100644
--- a/gnucash/register/register-gnome/gnucash-sheet.c
+++ b/gnucash/register/register-gnome/gnucash-sheet.c
@@ -2620,6 +2620,66 @@ gnucash_sheet_get_type (void)
     return gnucash_sheet_type;
 }
 
+
+static gboolean
+gnucash_sheet_tooltip (GtkWidget  *widget, gint x, gint y,
+               gboolean    keyboard_mode, GtkTooltip *tooltip,
+               gpointer    user_data)
+{
+    GnucashSheet *sheet = GNUCASH_SHEET (widget);
+    GnucashCursor *cursor = sheet->cursor;
+    Table *table = sheet->table;
+    VirtualLocation virt_loc;
+    gchar *tooltip_text;
+    gint cx, cy, cw, ch;
+    GdkRectangle rect;
+    SheetBlock *block;
+    gint bx, by;
+    gint hscroll_val, vscroll_val;
+
+    if (keyboard_mode)
+        return FALSE;
+
+    // get the scroll window values
+    hscroll_val = (gint) gtk_adjustment_get_value (sheet->hadj);
+    vscroll_val = (gint) gtk_adjustment_get_value (sheet->vadj);
+
+    if (!gnucash_sheet_find_loc_by_pixel (sheet, x + hscroll_val, y + vscroll_val, &virt_loc))
+        return FALSE;
+
+    tooltip_text = gnc_table_get_tooltip (table, virt_loc);
+
+    // if tooltip_text empty, clear tooltip and return FALSE
+    if ((tooltip_text == NULL) || (g_strcmp0 (tooltip_text,"") == 0))
+    {
+        gtk_tooltip_set_text (tooltip, NULL);
+        return FALSE;
+    }
+
+    block = gnucash_sheet_get_block (sheet, virt_loc.vcell_loc);
+    if (block == NULL)
+        return FALSE;
+
+    bx = block->origin_x;
+    by = block->origin_y;
+
+    // get the cell location and dimensions
+    gnucash_sheet_style_get_cell_pixel_rel_coords (cursor->style,
+            virt_loc.phys_row_offset, virt_loc.phys_col_offset,
+            &cx, &cy, &cw, &ch);
+
+     rect.x = cx + bx - hscroll_val;
+     rect.y = cy + by - vscroll_val;
+     rect.width = cw;
+     rect.height = ch;
+
+     gtk_tooltip_set_tip_area (tooltip, &rect);
+     gtk_tooltip_set_text (tooltip, tooltip_text);
+     g_free (tooltip_text);
+     return TRUE;
+}
+
+
 GtkWidget *
 gnucash_sheet_new (Table *table)
 {
@@ -2640,6 +2700,11 @@ gnucash_sheet_new (Table *table)
                                    g_int_equal,
                                    g_free, NULL);
 
+    /* add tooltips to sheet */
+    gtk_widget_set_has_tooltip (GTK_WIDGET(sheet), TRUE);
+    g_signal_connect(G_OBJECT(sheet), "query-tooltip",
+                     G_CALLBACK(gnucash_sheet_tooltip), NULL);
+
     gnucash_sheet_refresh_from_prefs(sheet);
 
     return GTK_WIDGET(sheet);



Summary of changes:
 .../register/ledger-core/split-register-model.c    | 95 ++++++++++++++++++++-
 gnucash/register/register-core/table-allgui.c      | 19 +++++
 gnucash/register/register-core/table-allgui.h      |  2 +
 gnucash/register/register-core/table-model.c       | 37 ++++++++
 gnucash/register/register-core/table-model.h       | 17 +++-
 gnucash/register/register-gnome/gnucash-sheet.c    | 65 ++++++++++++++
 .../standard-reports/test/test-transaction.scm     | 51 +++++++++++
 gnucash/report/standard-reports/transaction.scm    | 98 +++++++++++++++++-----
 .../backend/dbi/test/test-backend-dbi-basic.cpp    |  7 +-
 9 files changed, 365 insertions(+), 26 deletions(-)



More information about the gnucash-changes mailing list