gnucash stable: Multiple changes pushed
Christopher Lam
clam at code.gnucash.org
Mon Jun 2 20:45:39 EDT 2025
Updated via https://github.com/Gnucash/gnucash/commit/2fd89a27 (commit)
via https://github.com/Gnucash/gnucash/commit/d89792a4 (commit)
from https://github.com/Gnucash/gnucash/commit/7b5d13b3 (commit)
commit 2fd89a2748aa15f1b9bc208a74a23356948d11a9
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Sun Jun 1 21:26:29 2025 +0800
[reports] delay generation of reports from a report.
Previously a report with multiple linked reports will cause them to be
generated.
This change will delay the reports generation, simply storing the
required data report into a integer-keyed hash table, and is retrieved
when the link is clicked.
diff --git a/gnucash/gnome/gnc-plugin-page-report.cpp b/gnucash/gnome/gnc-plugin-page-report.cpp
index a700a233c2..3e21c1f195 100644
--- a/gnucash/gnome/gnc-plugin-page-report.cpp
+++ b/gnucash/gnome/gnc-plugin-page-report.cpp
@@ -674,7 +674,12 @@ gnc_plugin_page_report_load_cb (GncHtml * html, URLType type,
&& (strlen(location) > 3)
&& !strncmp("id=", location, 3))
{
- report_id = atoi(location + 3);
+ report_id = gnc_report_id_string_to_report_id (location + 3);
+ if (report_id < 0)
+ {
+ LEAVE ("id_string error %s", location);
+ return;
+ }
DEBUG( "parsed id=%d", report_id );
}
else if (!g_strcmp0( type, URL_TYPE_OPTIONS)
diff --git a/gnucash/report/gnc-report.cpp b/gnucash/report/gnc-report.cpp
index 4181ecc039..0a3974d3a7 100644
--- a/gnucash/report/gnc-report.cpp
+++ b/gnucash/report/gnc-report.cpp
@@ -257,12 +257,29 @@ gnc_report_name( SCM report )
return gnc_scm_call_1_to_string(get_name, report);
}
+gint
+gnc_report_id_string_to_report_id (const char *id_string)
+{
+ g_return_val_if_fail (id_string, -1);
+
+ char *end_ptr;
+ uint rpt_id = std::strtoul (id_string, &end_ptr, 10);
+ if (end_ptr == id_string) return -1;
+ if (*end_ptr == '\0') return rpt_id;
+ if (*end_ptr != '|') return -1;
+
+ auto anchor_str = end_ptr + 1;
+ uint anchor_id = std::strtoul (anchor_str, &end_ptr, 10);
+ if (end_ptr == anchor_str || *end_ptr != '\0') return -1;
+
+ const SCM get_linked = scm_c_eval_string ("gnc:report-get-linked-report");
+ return scm_to_uint (scm_call_2 (get_linked, scm_from_uint (rpt_id), scm_from_uint (anchor_id)));
+}
+
gboolean
gnc_run_report_id_string_with_error_handling (const char * id_string, char **data,
gchar **errmsg)
{
- gint report_id;
-
g_return_val_if_fail (id_string, FALSE);
g_return_val_if_fail (data, FALSE);
*data = NULL;
@@ -270,7 +287,8 @@ gnc_run_report_id_string_with_error_handling (const char * id_string, char **dat
if (strncmp ("id=", id_string, 3) != 0)
return FALSE;
- if (sscanf (id_string + 3, "%d", &report_id) != 1)
+ gint report_id = gnc_report_id_string_to_report_id (id_string + 3);
+ if (report_id < 0)
return FALSE;
return gnc_run_report_with_error_handling (report_id, data, errmsg);
diff --git a/gnucash/report/gnc-report.h b/gnucash/report/gnc-report.h
index 0b517eeeff..0ea9fd0b22 100644
--- a/gnucash/report/gnc-report.h
+++ b/gnucash/report/gnc-report.h
@@ -41,6 +41,7 @@ extern "C"
*/
void gnc_report_init(void);
+gint gnc_report_id_string_to_report_id (const char *id_string);
gboolean gnc_run_report_with_error_handling(gint report_id,
gchar** data,
diff --git a/gnucash/report/html-utilities.scm b/gnucash/report/html-utilities.scm
index 904184a4bd..847da82abf 100644
--- a/gnucash/report/html-utilities.scm
+++ b/gnucash/report/html-utilities.scm
@@ -167,19 +167,22 @@
;; section, name, and value of the function.
(define (gnc:make-report-anchor reportname src-report
optionlist)
- (let ((src-options (gnc:report-options src-report))
- (options (gnc:make-report-options reportname)))
- (if options
- (begin
- (gnc:options-copy-values src-options options)
- (for-each
- (lambda (l)
- (gnc-set-option (gnc:optiondb options) (car l) (cadr l) (caddr l)))
- optionlist)
- (let ((id (gnc:make-report reportname options)))
- (gnc:report-anchor-text id)))
- (warn "gnc:make-report-anchor: No such report: " reportname))))
-
+ (let ((anchor-id (gnc:report-add-anchor!
+ src-report (list reportname (gnc:report-options src-report) optionlist))))
+ (gnc-build-url URL-TYPE-REPORT (format #f "id=~a|~a" (gnc:report-id src-report) anchor-id) "")))
+
+(define-public (gnc:report-get-linked-report src-id id)
+ (match (gnc:report-get-anchor (gnc-report-find src-id) id)
+ ((reportname src-options optionlist)
+ (let* ((options (gnc:make-report-options reportname))
+ (db (gnc:optiondb options)))
+ (gnc:options-copy-values src-options options)
+ (for-each
+ (lambda (l)
+ (gnc-set-option db (car l) (cadr l) (caddr l)))
+ optionlist)
+ (gnc:make-report reportname options)))
+ (_ (gnc:error "invalid id " id))))
;; returns the account name as html-text and anchor to the register.
(define (gnc:html-account-anchor acct)
diff --git a/gnucash/report/report-core.scm b/gnucash/report/report-core.scm
index 050611ab0a..6828e39538 100644
--- a/gnucash/report/report-core.scm
+++ b/gnucash/report/report-core.scm
@@ -760,6 +760,7 @@ not found.")))
(and template
(let* ((renderer (gnc:report-template-renderer template))
(stylesheet (gnc:report-stylesheet report))
+ (_ (report-set-anchors! report (ht:make-hash-table)))
(doc (renderer report))
(html (cond
((string? doc) doc)
commit d89792a4b7d20952f0b9ba229a153359786a3352
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Sun Jun 1 21:22:45 2025 +0800
[report-core.scm] add report anchor mechanism
The <report> object contains the data for a report with options. Add a
mechanism to store the list of anchors contained in it; adding an
anchor will return the unique integer key referring to the report's
anchor; retrieval will return the anchor.
Note: each anchor will typically be: (list reportname src-options
optionlist)
whereby reportname is the desired report guid, src-options is the
originating report options object, and optionlist is a list of options to be
set.
diff --git a/gnucash/report/report-core.scm b/gnucash/report/report-core.scm
index b9735d8f91..050611ab0a 100644
--- a/gnucash/report/report-core.scm
+++ b/gnucash/report/report-core.scm
@@ -35,6 +35,7 @@
(use-modules (srfi srfi-2))
(use-modules (srfi srfi-9))
(use-modules (srfi srfi-26))
+(use-modules ((srfi srfi-69) #:prefix ht:)) ;for O(1) hash-table-size
(use-modules (gnucash report report-register-hooks))
(use-modules (gnucash report html-style-sheet))
(use-modules (gnucash report html-document))
@@ -75,6 +76,7 @@
(export gnc:report-embedded-list)
(export gnc:report-export-thunk)
(export gnc:report-export-types)
+(export gnc:report-get-anchor) ;return anchor by key
(export gnc:report-id)
(export gnc:report-is-invoice-report?)
(export gnc:report-menu-name)
@@ -84,6 +86,7 @@
(export gnc:report-render-html)
(export gnc:render-report)
(export gnc:report-serialize)
+(export gnc:report-add-anchor!) ;add anchor, returns the integer key
(export gnc:report-set-ctext!)
(export gnc:report-set-dirty?!)
(export gnc:report-set-editor-widget!)
@@ -324,7 +327,7 @@ not found.")))
;; A <report> represents an instantiation of a particular report type.
(define-record-type <report>
- (make-report type id options dirty? needs-save? editor-widget ctext custom-template)
+ (make-report type id options dirty? needs-save? editor-widget ctext custom-template anchors)
report?
(type report-type report-set-type!)
(id report-id report-set-id!)
@@ -333,6 +336,7 @@ not found.")))
(needs-save? report-needs-save? report-set-needs-save?!)
(editor-widget report-editor-widget report-set-editor-widget!)
(ctext report-ctext report-set-ctext!)
+ (anchors report-get-anchors report-set-anchors!)
(custom-template report-custom-template report-set-custom-template!))
(define gnc:report-type report-type)
@@ -352,6 +356,18 @@ not found.")))
(define gnc:report-custom-template report-custom-template)
(define gnc:report-set-custom-template! report-set-custom-template!)
+;; add an anchor to the report instance list of anchors. return the
+;; integer key to the anchor.
+(define (gnc:report-add-anchor! report anchor)
+ (let* ((hash (report-get-anchors report))
+ (size (ht:hash-table-size hash)))
+ (ht:hash-table-set! hash size anchor)
+ size))
+
+;; retrieve the anchor from the report instance list of anchors.
+(define (gnc:report-get-anchor report id)
+ (ht:hash-table-ref (report-get-anchors report) id))
+
(define (gnc:report-set-dirty?! report val)
(gnc:report-set-dirty?-internal! report val)
(let* ((template (hash-ref *gnc:_report-templates_* (gnc:report-type report)))
@@ -377,6 +393,7 @@ not found.")))
#f ;; editor-widget
#f ;; ctext
custom-template ;; custom-template
+ (ht:make-hash-table)
))
(id (gnc-report-add r))) ;returns an integer
(gnc:report-set-id! r id)
@@ -385,7 +402,8 @@ not found.")))
(define (gnc:restore-report-by-guid-with-custom-template
id template-id template-name custom-template-id options)
(if options
- (let* ((r (make-report template-id id options #t #t #f #f custom-template-id))
+ (let* ((r (make-report template-id id options #t #t #f #f custom-template-id
+ (ht:make-hash-table)))
(report-id (gnc-report-add r)))
(if (number? report-id)
(gnc:report-set-id! r report-id))
Summary of changes:
gnucash/gnome/gnc-plugin-page-report.cpp | 7 ++++++-
gnucash/report/gnc-report.cpp | 24 +++++++++++++++++++++---
gnucash/report/gnc-report.h | 1 +
gnucash/report/html-utilities.scm | 29 ++++++++++++++++-------------
gnucash/report/report-core.scm | 23 +++++++++++++++++++++--
5 files changed, 65 insertions(+), 19 deletions(-)
More information about the gnucash-changes
mailing list