gnucash master: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Thu Aug 12 10:51:39 EDT 2021


Updated	 via  https://github.com/Gnucash/gnucash/commit/37895bfd (commit)
	 via  https://github.com/Gnucash/gnucash/commit/eafc2900 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5ced0d93 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/fa666e73 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/40d886fa (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4c37f6d4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e8454992 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8fc15639 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/071bd209 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/6a8372af (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b1c1272f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/339f6681 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/be6fb1ab (commit)
	 via  https://github.com/Gnucash/gnucash/commit/bedc85af (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0420ae6a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/67bd5135 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/17953441 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5698b67b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/09e2e761 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/bebc366e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f0926d66 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e6c33a39 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d2db4301 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/86bc9d93 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/de1ad936 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/7a0ea190 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/de0af2dc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c9db5516 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d099d39a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/fd56512c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9062be3d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f6766d42 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ddc423a5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/79d6154c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c2bc31fa (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a6b7a4cb (commit)
	 via  https://github.com/Gnucash/gnucash/commit/351ae62c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b31b8dbd (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a5edacf0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5f721614 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/23bd7164 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/67ecb107 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a3177e8b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e0d953bf (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b247c105 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3ed6b4da (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ba4852a9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ad3895fa (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c789b0c1 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5be0795f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/613f639a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b9d6fc9f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3dceb086 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2ee89f66 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3f1e2499 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/621704eb (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4a5b5f3b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/320df7e4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/41329396 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/bf8fe112 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f15402a9 (commit)
	from  https://github.com/Gnucash/gnucash/commit/08bf3ec5 (commit)



commit 37895bfdad7abbab705925dd947f876cdaa1a878
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Aug 12 22:30:39 2021 +0800

    [reports] remove deprecated owner-report creation functions

diff --git a/gnucash/report/reports/reports.scm b/gnucash/report/reports/reports.scm
index 0f1d8306f..0a71066fc 100644
--- a/gnucash/report/reports/reports.scm
+++ b/gnucash/report/reports/reports.scm
@@ -42,7 +42,6 @@
 (export gnc:invoice-report-create)
 (export gnc:payables-report-create)
 (export gnc:receivables-report-create)
-(export gnc:owner-report-create)        ;deprecate
 (export gnc:owner-report-create-with-enddate)
 
 (let ((loc-spec (if (string-prefix? "de_DE" (gnc-locale-name)) 'de_DE 'us)))
@@ -90,5 +89,4 @@
 
 (define gnc:payables-report-create payables-report-create-internal)
 (define gnc:receivables-report-create receivables-report-create-internal)
-(define gnc:owner-report-create owner-report-create) ;deprecated
 (define gnc:owner-report-create-with-enddate owner-report-create-with-enddate)
diff --git a/gnucash/report/reports/standard/new-owner-report.scm b/gnucash/report/reports/standard/new-owner-report.scm
index 490e43483..a7f4de258 100644
--- a/gnucash/report/reports/standard/new-owner-report.scm
+++ b/gnucash/report/reports/standard/new-owner-report.scm
@@ -1240,10 +1240,6 @@ and do not match the transaction."))))))))
              (guid (assv-ref guid-alist type)))
     (owner-report-create-internal guid owner type enddate)))
 
-(define (owner-report-create owner account)
-  (issue-deprecation-warning "owner-report-create is not used anymore. call owner-report-create-with-enddate instead")
-  (owner-report-create-with-enddate owner account #f))
-
 (define (gnc:owner-report-create-internal
          account split query journal? double? title debit-string credit-string)
 
@@ -1256,5 +1252,4 @@ and do not match the transaction."))))))))
 
 (gnc:register-report-hook ACCT-TYPE-RECEIVABLE #t gnc:owner-report-create-internal)
 (gnc:register-report-hook ACCT-TYPE-PAYABLE #t gnc:owner-report-create-internal)
-(export owner-report-create)            ;deprecate
 (export owner-report-create-with-enddate)

commit eafc290034daba8ae6f4efe1df4fa6a61af4a091
Merge: 08bf3ec5b 5ced0d932
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Aug 12 22:28:58 2021 +0800

    Merge branch 'maint'


commit 5ced0d932a942526ef962f0748614c52cade1ac7
Merge: fa666e736 40d886fa9
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Aug 12 17:39:45 2021 +0800

    Merge branch 'maint-account-cpp' into maint #1107


commit fa666e7367f008666b203fc0918d4236cbb15162
Author: Frank H. Ellenberger <frank.h.ellenberger at gmail.com>
Date:   Thu Aug 12 06:27:57 2021 +0200

    L10N:sv:Update to PO-Revision-Date: 2021-08-03 from TP
    
    5229 translated messages, 133 fuzzy translations.

diff --git a/po/sv.po b/po/sv.po
index 78f1f9beb..0b2e463d6 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -16,7 +16,7 @@ msgstr ""
 "Project-Id-Version: gnucash 4.6-pre1\n"
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug.cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-13 14:59-0700\n"
-"PO-Revision-Date: 2021-07-26 14:45+0200\n"
+"PO-Revision-Date: 2021-08-03 19:10+0200\n"
 "Last-Translator: Arve Eriksson <031299870 at telia.com>\n"
 "Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -2491,9 +2491,9 @@ msgid "Gain/Loss"
 msgstr "Vinst/förlust"
 
 #: gnucash/gnome/dialog-lot-viewer.c:1048
-#, fuzzy, c-format
+#, c-format
 msgid "Lots in Account %s"
-msgstr "Aktieandelar i konto %s"
+msgstr "Partier i konto %s"
 
 #: gnucash/gnome/dialog-order.c:171
 msgid "The Order must be given an ID."
@@ -3845,16 +3845,14 @@ msgstr "Mata in en aktiesplit eller aktiesammanslagning"
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:321
 #: gnucash/gnome/gnc-plugin-page-register2.c:372
 #: gnucash/gnome/gnc-plugin-page-register.c:490
-#, fuzzy
 msgid "View _Lots..."
-msgstr "Visa aktieande_lar..."
+msgstr "Visa parti_er..."
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:322
 #: gnucash/gnome/gnc-plugin-page-register2.c:373
 #: gnucash/gnome/gnc-plugin-page-register.c:491
-#, fuzzy
 msgid "Bring up the lot viewer/editor window"
-msgstr "Öppna fönstret för att visa/redigera aktieandelar"
+msgstr "Öppna fönstret för att visa/redigera partier"
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:326
 msgid "Check & Repair A_ccount"
@@ -3884,9 +3882,8 @@ msgstr "Leta efter och reparera obalanserade transaktioner och föräldralösa d
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:342
 #: gnucash/gnome/gnc-plugin-register2.c:64
-#, fuzzy
 msgid "_Register2"
-msgstr "Öppna fönst_ret för att visa/redigera aktieandelar"
+msgstr "_Register2"
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:405
 msgid "Open2"
@@ -7175,9 +7172,8 @@ msgid "Book currency"
 msgstr "Bokens valuta"
 
 #: gnucash/gnome-utils/dialog-options.c:1303
-#, fuzzy
 msgid "Default lot tracking policy"
-msgstr "Förvald policy för aktieandelsspårning"
+msgstr "Förvald policy för partispårning"
 
 #: gnucash/gnome-utils/dialog-options.c:1326
 msgid "Default gain/loss account"
@@ -9975,9 +9971,8 @@ msgstr "Visa valutor i dialogrutan"
 #: gnucash/gschemas/org.gnucash.dialogs.import.qif.gschema.xml.in:27
 #: gnucash/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in:55
 #: gnucash/import-export/ofx/gschemas/org.gnucash.dialogs.import.ofx.gschema.xml.in:5
-#, fuzzy
 msgid "Last pathname used"
-msgstr "Senaste sökväg som använts"
+msgstr "Senast använda sökväg"
 
 #: gnucash/gschemas/org.gnucash.dialogs.export.csv.gschema.xml.in:13
 #: gnucash/gschemas/org.gnucash.dialogs.gschema.xml.in:143
@@ -14147,13 +14142,12 @@ msgstr "Jobb aktivt"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:7
 #: gnucash/report/reports/standard/lot-viewer.scm:34
-#, fuzzy
 msgid "Lot Viewer"
-msgstr "Andelsvisare"
+msgstr "Partivisare"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:25
 msgid "_New Lot"
-msgstr "_Nya aktieandelar"
+msgstr "_Nytt parti"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:40
 msgid "Scrub _Account"
@@ -14164,19 +14158,16 @@ msgid "_Scrub"
 msgstr "_Städa upp"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:61
-#, fuzzy
 msgid "Scrub the highlighted lot"
-msgstr "Städa upp de markerade aktieandelarna"
+msgstr "Städa upp markerat parti"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:78
-#, fuzzy
 msgid "Delete the highlighted lot"
-msgstr "Ta bort de markerade aktieandelarna"
+msgstr "Ta bort markerat parti"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:135
-#, fuzzy
 msgid "Enter a name for the highlighted lot."
-msgstr "Ange ett namn för de markerade aktieandelarna."
+msgstr "Ange ett namn för markerat parti."
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:150
 #: gnucash/gtkbuilder/dialog-print-check.glade:746
@@ -14185,31 +14176,28 @@ msgid "_Notes"
 msgstr "_Anteckningar"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:173
-#, fuzzy
 msgid "Enter any notes you want to make about this lot."
-msgstr "Skriv in de anteckningar du vill använda om dessa aktieandelar."
+msgstr "Skriv in de anteckningar du vill använda om detta parti."
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:192
 msgid "<b>_Title</b>"
 msgstr "<b>_Titel</b>"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:221
-#, fuzzy
 msgid "<b>_Lots in This Account</b>"
-msgstr "<b>Aktieande_lar i detta konto</b>"
+msgstr "<b>_Partier i detta konto</b>"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:259
 msgid "Show only open lots"
-msgstr "Visa endast öppna andelar"
+msgstr "Visa endast öppna partier"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:302
 msgid "<b>Splits _free</b>"
 msgstr "<b>_Fria splitar</b>"
 
 #: gnucash/gtkbuilder/dialog-lot-viewer.glade:357
-#, fuzzy
 msgid "<b>Splits _in lot</b>"
-msgstr "<b>Splitar _i andelar</b>"
+msgstr "<b>Splitar _i partier</b>"
 
 #: gnucash/gtkbuilder/dialog-new-user.glade:25
 msgid "_No"
@@ -15691,7 +15679,7 @@ msgstr "P_åminn i förväg"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:724
 msgid "Set 'Re_view Created Transactions' as default"
-msgstr "Sätt \"Granska skapade transaktioner\" som förval"
+msgstr "Sätt \"G_ranska skapade transaktioner\" som förval"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:728
 msgid "Set 'Review Created Transactions' as the default in the 'Since Last Run' dialog."
@@ -16694,7 +16682,7 @@ msgstr "Sortera efter beskrivning."
 
 #: gnucash/gtkbuilder/gnc-plugin-page-register.glade:996
 msgid "_Action"
-msgstr "_Handling"
+msgstr "_Åtgärd"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-register.glade:1000
 msgid "Sort by action field."
@@ -19454,7 +19442,6 @@ msgid "Description of an Entry"
 msgstr "Beskrivning på en post"
 
 #: gnucash/register/ledger-core/gncEntryLedgerLayout.c:92
-#, fuzzy
 msgctxt "sample"
 msgid "Action"
 msgstr "Åtgärd"
@@ -21905,7 +21892,6 @@ msgid "Display the ticker symbols."
 msgstr "Visa ticker-symbolerna."
 
 #: gnucash/report/reports/standard/advanced-portfolio.scm:118
-#, fuzzy
 msgid "Display exchange listings."
 msgstr "Visa börsnoteringar."
 
@@ -24060,9 +24046,8 @@ msgid "Click on the \"Options\" button to select a company."
 msgstr "Klicka på \"Alternativ\"-knappen för att välja ett företag."
 
 #: gnucash/report/reports/standard/lot-viewer.scm:60
-#, fuzzy
 msgid "The account to search for lots."
-msgstr "Kontot som ska sökas på efter aktieandelar."
+msgstr "Kontot som ska sökas på efter partier."
 
 #: gnucash/report/reports/standard/net-charts.scm:48
 msgid "Show Net Profit"
@@ -24631,9 +24616,8 @@ msgstr "Avstämningsrapport"
 #: gnucash/report/reports/standard/register.scm:148
 #: gnucash/report/reports/standard/register.scm:388
 #: libgnucash/engine/gnc-lot.c:781
-#, fuzzy
 msgid "Lot"
-msgstr "Andelar"
+msgstr "Parti"
 
 #: gnucash/report/reports/standard/register.scm:160
 #, fuzzy
@@ -24672,9 +24656,8 @@ msgid "Display the number of shares?"
 msgstr "Visa antalet andelar?"
 
 #: gnucash/report/reports/standard/register.scm:389
-#, fuzzy
 msgid "Display the name of lot the shares are in?"
-msgstr "Visa namnet på aktieandelarna som aktierna tillhör?"
+msgstr "Visa namnet på partierna som aktieandelarna tillhör?"
 
 #: gnucash/report/reports/standard/register.scm:394
 #: gnucash/report/trep-engine.scm:930
@@ -26762,37 +26745,32 @@ msgid "Offset between documents: "
 msgstr "Förskjutning mellan dokument:"
 
 #: libgnucash/engine/gncOwner.c:1127
-#, fuzzy
 msgid "Lot Link"
-msgstr "Länk till aktieandelar"
+msgstr "Länk till parti"
 
 #: libgnucash/engine/policy.c:52
 msgid "First In, First Out"
 msgstr "Först in, först ut"
 
 #: libgnucash/engine/policy.c:53
-#, fuzzy
 msgid "Use oldest lots first."
-msgstr "Använd äldsta andelar först."
+msgstr "Använd äldsta partier först."
 
 #: libgnucash/engine/policy.c:55
 msgid "Last In, First Out"
 msgstr "Sist in, först ut"
 
 #: libgnucash/engine/policy.c:56
-#, fuzzy
 msgid "Use newest lots first."
-msgstr "Använd nyaste andelar först."
+msgstr "Använd nyaste partier först."
 
 #: libgnucash/engine/policy.c:59
-#, fuzzy
 msgid "Average cost of open lots."
-msgstr "Genomsnittlig kostnad för öppna andelar."
+msgstr "Genomsnittlig kostnad för öppna partier."
 
 #: libgnucash/engine/policy.c:62
-#, fuzzy
 msgid "Manually select lots."
-msgstr "Välj samlingar manuellt."
+msgstr "Välj partier manuellt."
 
 #: libgnucash/engine/qofbookslots.h:66
 msgid "Use Trading Accounts"
@@ -26877,9 +26855,9 @@ msgid "Please delete this transaction. Explanation at https://wiki.gnucash.org/w
 msgstr "Var god radera denna transaktion. Förklaring på https://wiki.gnucash.org/wiki/Business_Features_Issues#I_can.27t_delete_a_transaction_of_type_.22I.22_from_the_AR.2FAP_account"
 
 #: libgnucash/engine/ScrubBusiness.c:616
-#, fuzzy, c-format
+#, c-format
 msgid "Checking business lots in account %s: %u of %u"
-msgstr "Kontrollerar företagets aktieandelar i konto %s: %u av %u"
+msgstr "Kontrollerar företagets partier i konto %s: %u av %u"
 
 #: libgnucash/engine/ScrubBusiness.c:670
 #, c-format

commit 40d886fa9d54d556efbd6f150fd82a5a92d48fd1
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Aug 11 09:28:26 2021 +0800

    gnc_account_list_name_violations elements must be freed

diff --git a/gnucash/gnome-utils/dialog-preferences.c b/gnucash/gnome-utils/dialog-preferences.c
index 2e374bdea..62d40ddcd 100644
--- a/gnucash/gnome-utils/dialog-preferences.c
+++ b/gnucash/gnome-utils/dialog-preferences.c
@@ -132,7 +132,7 @@ static gchar *gnc_account_separator_is_valid (const gchar *separator,
         message = gnc_account_name_violations_errmsg (*normalized_separator,
                                                       conflict_accts);
 
-    g_list_free (conflict_accts);
+    g_list_free_full (conflict_accts, g_free);
     return message;
 }
 
diff --git a/gnucash/gnome-utils/gnc-file.c b/gnucash/gnome-utils/gnc-file.c
index d76698e59..677125c1e 100644
--- a/gnucash/gnome-utils/gnc-file.c
+++ b/gnucash/gnome-utils/gnc-file.c
@@ -1101,6 +1101,7 @@ RESTART:
                          invalid_account_names );
         gnc_warning_dialog(parent, "%s", message);
         g_free ( message );
+        g_list_free_full (invalid_account_names, g_free);
     }
 
     // Fix account color slots being set to 'Not Set', should run once on a book
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index 910d96fdf..72f525a03 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -283,8 +283,8 @@ gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invali
  *  @param book Pointer to the book with accounts to verify
  *  @param separator The separator character to verify against
  *
- *  @return A GList of invalid account names. Should be freed with g_list_free
- *          if no longer needed.
+ *  @return A GList of invalid account names. Should be freed with
+ *          g_list_free_full (value, g_free) when no longer needed.
  */
 GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator);
 

commit 4c37f6d4ef1de455dd24839ab4a126c6f71c6c70
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Aug 11 09:28:22 2021 +0800

    [account.cpp] gnc_g_list_stringjoin instead of repeated allocations

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 78755e38d..ba0942758 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -227,26 +227,12 @@ gnc_set_account_separator (const gchar *separator)
 
 gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invalid_account_names)
 {
-    GList *node;
     gchar *message = NULL;
-    gchar *account_list = NULL;
 
     if ( !invalid_account_names )
         return NULL;
 
-    for ( node = invalid_account_names;  node; node = g_list_next(node))
-    {
-        if ( !account_list )
-            account_list = static_cast<gchar *>(node->data);
-        else
-        {
-            gchar *tmp_list = NULL;
-
-            tmp_list = g_strconcat (account_list, "\n", node->data, nullptr);
-            g_free ( account_list );
-            account_list = tmp_list;
-        }
-    }
+    auto account_list {gnc_g_list_stringjoin (invalid_account_names, "\n")};
 
     /* Translators: The first %s will be the account separator character,
        the second %s is a list of account names.
diff --git a/libgnucash/engine/test/utest-Account.cpp b/libgnucash/engine/test/utest-Account.cpp
index b54163cd0..8deea5fcf 100644
--- a/libgnucash/engine/test/utest-Account.cpp
+++ b/libgnucash/engine/test/utest-Account.cpp
@@ -29,6 +29,7 @@ extern "C"
 #include <gnc-event.h>
 #include <gnc-date.h>
 /* Add specific headers for this class */
+#include "gnc-glib-utils.h"
 #include "../Account.h"
 #include "../AccountP.h"
 #include "../Split.h"
@@ -429,24 +430,12 @@ test_gnc_account_name_violations_errmsg ()
 {
     GList *badnames = NULL, *nonames = NULL, *node = NULL;
     auto separator = ":";
-    char *account_list = NULL;
     /* FUT wants to free the strings, so we alloc them */
     badnames = g_list_prepend (badnames, g_strdup ("Foo:bar"));
     badnames = g_list_prepend (badnames, g_strdup ("baz"));
     badnames = g_list_prepend (badnames, g_strdup ("waldo:pepper"));
     auto message = gnc_account_name_violations_errmsg (separator, nonames);
-    for (node = badnames; node; node = g_list_next (node))
-    {
-        if (!account_list)
-            account_list = g_strdup (static_cast<char*>(node->data));
-        else
-        {
-            auto tmp_list = g_strconcat ( account_list, "\n",
-                                          static_cast<char*>(node->data), NULL);
-            g_free (account_list);
-            account_list = tmp_list;
-        }
-    }
+    auto account_list = gnc_g_list_stringjoin (badnames, "\n");
     message = gnc_account_name_violations_errmsg (separator, nonames);
     g_assert (message == NULL);
     auto validation_message = g_strdup_printf (
@@ -455,6 +444,7 @@ test_gnc_account_name_violations_errmsg ()
         "Either change the account names or choose another separator "
         "character.\n\nBelow you will find the list of invalid account names:\n"
         "%s", separator, account_list);
+    g_free (account_list);
     message = gnc_account_name_violations_errmsg (separator, badnames);
     g_assert_cmpstr ( message, == , validation_message);
     g_free (validation_message);

commit e84549926bbeaf6f19428f1aeac1b96eeb860b6e
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 10 12:55:47 2021 +0800

    [gnc-glib-utils] gnc_g_list_stringjoin to join a GList of strings
    
    It traverses the GList twice (once to calculate the length) but
    allocates only once.
    
    Includes snippet from
    https://www.joelonsoftware.com/2001/12/11/back-to-basics/

diff --git a/libgnucash/core-utils/gnc-glib-utils.c b/libgnucash/core-utils/gnc-glib-utils.c
index b45292151..c15e1dd8d 100644
--- a/libgnucash/core-utils/gnc-glib-utils.c
+++ b/libgnucash/core-utils/gnc-glib-utils.c
@@ -327,3 +327,35 @@ void gnc_gpid_kill(GPid pid)
     }
 #endif /* G_OS_WIN32 */
 }
+
+static inline char*
+gnc_strcat (char* dest, const char* src)
+{
+    while (*dest) dest++;
+    while ((*dest++ = *src++));
+    return --dest;
+}
+
+gchar *
+gnc_g_list_stringjoin (GList *list_of_strings, const gchar *sep)
+{
+    gint seplen = sep ? strlen(sep) : 0;
+    gint length = -seplen;
+    gchar *retval, *p;
+
+    if (!list_of_strings)
+        return NULL;
+
+    for (GList *n = list_of_strings; n; n = n->next)
+        length += strlen ((gchar*)n->data) + seplen;
+
+    p = retval = (gchar*) g_malloc0 (length * sizeof (gchar) + 1);
+    for (GList *n = list_of_strings; n; n = n->next)
+    {
+        p = gnc_strcat (p, (gchar*)n->data);
+        if (n->next && sep)
+            p = gnc_strcat (p, sep);
+    }
+
+    return retval;
+}
diff --git a/libgnucash/core-utils/gnc-glib-utils.h b/libgnucash/core-utils/gnc-glib-utils.h
index 7f1d1dd2e..97e36c53d 100644
--- a/libgnucash/core-utils/gnc-glib-utils.h
+++ b/libgnucash/core-utils/gnc-glib-utils.h
@@ -183,6 +183,22 @@ void gnc_scm_log_debug(const gchar *msg);
  @{
 */
 
+
+/**
+ * @brief Return a string joining a GList whose elements are gchar*
+ * strings. Returns NULL if an empty GList* is passed through. The
+ * optional sep string will be used as separator. Must be g_freed when
+ * not needed anymore.
+ *
+ * @param list_of_strings A GList of chars*
+ *
+ * @param sep a separator or NULL
+ *
+ * @return A newly allocated string that has to be g_free'd by the
+ * caller.
+ **/
+gchar * gnc_g_list_stringjoin (GList *list_of_strings, const gchar *sep);
+
 /** Kill a process.  On UNIX send a SIGKILL, on Windows call TerminateProcess.
  *
  *  @param pid The process ID. */
diff --git a/libgnucash/core-utils/test/test-gnc-glib-utils.c b/libgnucash/core-utils/test/test-gnc-glib-utils.c
index 390d6b0fa..e4423baaa 100644
--- a/libgnucash/core-utils/test/test-gnc-glib-utils.c
+++ b/libgnucash/core-utils/test/test-gnc-glib-utils.c
@@ -53,6 +53,62 @@ test_gnc_utf8_strip_invalid_and_controls (gconstpointer data)
     g_free (msg1);
 }
 
+static void
+test_g_list_stringjoin (gconstpointer data)
+{
+    GList *test = NULL;
+    gchar *ret;
+
+    ret = gnc_g_list_stringjoin (NULL, NULL);
+    g_assert (ret == NULL);
+
+    ret = gnc_g_list_stringjoin (NULL, ":");
+    g_assert (ret == NULL);
+
+    test = g_list_prepend (test, "one");
+
+    ret = gnc_g_list_stringjoin (test, NULL);
+    g_assert_cmpstr (ret, ==, "one");
+    g_free (ret);
+
+    ret = gnc_g_list_stringjoin (test, "");
+    g_assert_cmpstr (ret, ==, "one");
+    g_free (ret);
+
+    ret = gnc_g_list_stringjoin (test, ":");
+    g_assert_cmpstr (ret, ==, "one");
+    g_free (ret);
+
+    test = g_list_prepend (test, "two");
+
+    ret = gnc_g_list_stringjoin (test, NULL);
+    g_assert_cmpstr (ret, ==, "twoone");
+    g_free (ret);
+
+    ret = gnc_g_list_stringjoin (test, "");
+    g_assert_cmpstr (ret, ==, "twoone");
+    g_free (ret);
+
+    ret = gnc_g_list_stringjoin (test, ":");
+    g_assert_cmpstr (ret, ==, "two:one");
+    g_free (ret);
+
+    test = g_list_prepend (test, "three");
+
+    ret = gnc_g_list_stringjoin (test, NULL);
+    g_assert_cmpstr (ret, ==, "threetwoone");
+    g_free (ret);
+
+    ret = gnc_g_list_stringjoin (test, "");
+    g_assert_cmpstr (ret, ==, "threetwoone");
+    g_free (ret);
+
+    ret = gnc_g_list_stringjoin (test, ":");
+    g_assert_cmpstr (ret, ==, "three:two:one");
+    g_free (ret);
+
+    g_list_free (test);
+}
 
 int
 main (int argc, char *argv[])
@@ -62,6 +118,7 @@ main (int argc, char *argv[])
     g_test_init (&argc, &argv, NULL); // initialize test program
     g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls invalid utf8", (gconstpointer)invalid_utf8, test_gnc_utf8_strip_invalid_and_controls);
     g_test_add_data_func ("/core-utils/gnc_utf8_strip_invalid_and_controls control chars", (gconstpointer)controls, test_gnc_utf8_strip_invalid_and_controls);
+    g_test_add_data_func ("/core-utils/gnc_g_list_stringjoin", NULL, test_g_list_stringjoin);
 
     return g_test_run();
 }

commit 8fc15639116ade23d9aea574676c668f7cd71885
Author: TianXing_Yi <ytx.cash at gmail.com>
Date:   Wed Aug 11 11:34:24 2021 +0200

    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5351 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Co-authored-by: TianXing_Yi <ytx.cash at gmail.com>

diff --git a/po/zh_CN.po b/po/zh_CN.po
index b43b27017..24d7c041d 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -23,8 +23,8 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-08-11 06:35+0000\n"
-"Last-Translator: Eric <spice2wolf at gmail.com>\n"
+"PO-Revision-Date: 2021-08-11 09:34+0000\n"
+"Last-Translator: TianXing_Yi <ytx.cash at gmail.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "gnucash/gnucash/zh_Hans/>\n"
 "Language: zh_CN\n"
@@ -15190,7 +15190,7 @@ msgstr "何时支付 / 支付时"
 #: gnucash/gtkbuilder/dialog-find-account.glade:25
 #: gnucash/gtkbuilder/dialog-find-account.glade:96
 msgid "Search the Account List"
-msgstr "结果"
+msgstr "列表"
 
 #: gnucash/gtkbuilder/dialog-find-account.glade:38
 msgid "Close _on Jump"

commit 071bd209ac0571e5e6a34473ad1df6e256c1cb15
Author: Avi Markovitz <avi.markovitz at gmail.com>
Date:   Wed Aug 11 11:34:24 2021 +0200

    Translation update  by Avi Markovitz <avi.markovitz at gmail.com> using Weblate
    
    po/he.po: 100.0% (5364 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Hebrew)
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/he/
    
    Co-authored-by: Avi Markovitz <avi.markovitz at gmail.com>

diff --git a/po/he.po b/po/he.po
index d933efe09..7243557b2 100644
--- a/po/he.po
+++ b/po/he.po
@@ -11,7 +11,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-08-04 16:32+0000\n"
+"PO-Revision-Date: 2021-08-11 09:34+0000\n"
 "Last-Translator: Avi Markovitz <avi.markovitz at gmail.com>\n"
 "Language-Team: Hebrew <https://hosted.weblate.org/projects/gnucash/gnucash/"
 "he/>\n"
@@ -4466,7 +4466,7 @@ msgstr "העברת הרשומה הנוכחית שורה אחת מטה"
 
 #: gnucash/gnome/gnc-plugin-page-invoice.c:238
 msgid "_Company Report"
-msgstr "_דוח ספק"
+msgstr "_דוח ישות"
 
 #: gnucash/gnome/gnc-plugin-page-invoice.c:247
 msgid "_Standard"
@@ -8746,6 +8746,7 @@ msgstr "חשבונאות לאנשים פרטיים ועסקים קטנים."
 msgid "translator-credits"
 msgstr ""
 "אבי מרקוביץ avi.markovitz at gmail.com ,2021, 2020, 2019\n"
+"ירון שהרבני 2021\n"
 "אורי הוך 2006"
 
 #: gnucash/gnome-utils/gnc-main-window.c:4739

commit 6a8372affca19940a9f4b5626d73a3dca82c5080
Author: Eric <spice2wolf at gmail.com>
Date:   Wed Aug 11 11:34:23 2021 +0200

    Translation update  by Eric <spice2wolf at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5351 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Co-authored-by: Eric <spice2wolf at gmail.com>

diff --git a/po/zh_CN.po b/po/zh_CN.po
index df2850501..b43b27017 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -23,8 +23,8 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-08-10 10:35+0000\n"
-"Last-Translator: TianXing_Yi <ytx.cash at gmail.com>\n"
+"PO-Revision-Date: 2021-08-11 06:35+0000\n"
+"Last-Translator: Eric <spice2wolf at gmail.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "gnucash/gnucash/zh_Hans/>\n"
 "Language: zh_CN\n"
@@ -22321,7 +22321,6 @@ msgstr "欠款总额"
 
 #: gnucash/report/reports/aging.scm:350
 #: gnucash/report/reports/standard/new-aging.scm:97
-#, fuzzy
 msgid "Bracket Total Owed"
 msgstr "把总欠款归为一类"
 

commit b1c1272f35bb4495a8f480cb10cd442184c2af93
Author: Christian Wehling <christian.wehling at web.de>
Date:   Tue Aug 10 19:35:05 2021 +0200

    Translation update  by Christian Wehling <christian.wehling at web.de> using Weblate
    
    po/de.po: 99.8% (5357 of 5364 strings; 7 fuzzy)
    250 failing checks (4.6%)
    Translation: GnuCash/Program (German)
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/de/
    
    Co-authored-by: Christian Wehling <christian.wehling at web.de>

diff --git a/po/de.po b/po/de.po
index d569bc135..f1e3f9de6 100644
--- a/po/de.po
+++ b/po/de.po
@@ -36,7 +36,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-07-01 19:33+0000\n"
+"PO-Revision-Date: 2021-08-10 17:35+0000\n"
 "Last-Translator: Christian Wehling <christian.wehling at web.de>\n"
 "Language-Team: German <https://hosted.weblate.org/projects/gnucash/gnucash/"
 "de/>\n"
@@ -11517,16 +11517,16 @@ msgid ""
 "Set \"Review Created Transactions\" as the default for the \"since last run"
 "\" dialog."
 msgstr ""
-"Legen Sie \"Erstellte Transaktionen überprüfen\" als Standard für den Dialog "
-"\"seit dem letzten Aufruf\" fest."
+"Legen Sie \"Erzeugte Buchungen durchsehen\" als Standard für den Dialog "
+"\"seit letzten Aufruf\" fest."
 
 #: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:28
 msgid ""
 "This setting controls whether as default the \"review created transactions\" "
 "is set for the \"since last run\" dialog."
 msgstr ""
-"Diese Einstellung steuert, ob für den Dialog \"seit dem letzten Aufruf\" "
-"standardmäßig die \"Überprüfung erstellter Transaktionen\" eingestellt ist."
+"Diese Einstellung steuert, ob für den Dialog \"seit letzten Aufruf\" "
+"standardmäßig die \"Überprüfung erzeugter Buchungen\" eingestellt ist."
 
 #: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:35
 msgid "Set the \"auto create\" flag by default"
@@ -17361,17 +17361,13 @@ msgstr ""
 
 #. Preferences->Online Banking:Generic
 #: gnucash/gtkbuilder/dialog-preferences.glade:2291
-#, fuzzy
-#| msgid "Match _display threshold"
 msgid "Likely match _day threshold"
-msgstr "Entscheidungsschwelle für Anzeige in Zu_ordnung"
+msgstr "Entscheidungsschwelle für _wahrscheinliche Datumsübereinstimmung"
 
 #. Preferences->Online Banking:Generic
 #: gnucash/gtkbuilder/dialog-preferences.glade:2304
-#, fuzzy
-#| msgid "Match _display threshold"
 msgid "_Unlikely match day threshold"
-msgstr "Entscheidungsschwelle für Anzeige in Zu_ordnung"
+msgstr "Entscheidungsschwelle für u_nwahrscheinliche Datumsübereinstimmung"
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:2318
 msgid ""
@@ -18402,8 +18398,8 @@ msgid ""
 "Set 'Review Created Transactions' as the default in the 'Since Last Run' "
 "dialog."
 msgstr ""
-"Legen Sie \"Erstellte Transaktionen überprüfen\" als Standard im Dialogfeld "
-"\"Seit letztem Lauf\" fest."
+"Legen Sie \"Erzeugte Buchungen durchsehen\" als Standard im Dialogfeld \"Seit"
+" letztem Lauf\" fest."
 
 #: gnucash/gtkbuilder/dialog-sx.glade:765
 msgid "Edit Scheduled Transaction"

commit 339f66810f4e4ab20fc4d63d07eff63d25069349
Author: TianXing_Yi <ytx.cash at gmail.com>
Date:   Tue Aug 10 19:35:05 2021 +0200

    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5350 of 5364 strings; 1 fuzzy)
    1 failing checks (0.1%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5350 of 5364 strings; 1 fuzzy)
    1 failing checks (0.1%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5350 of 5364 strings; 1 fuzzy)
    1 failing checks (0.1%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5350 of 5364 strings; 1 fuzzy)
    1 failing checks (0.1%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5350 of 5364 strings; 1 fuzzy)
    1 failing checks (0.1%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Co-authored-by: TianXing_Yi <ytx.cash at gmail.com>

diff --git a/po/zh_CN.po b/po/zh_CN.po
index e04e43eba..df2850501 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -23,7 +23,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-08-02 07:52+0000\n"
+"PO-Revision-Date: 2021-08-10 10:35+0000\n"
 "Last-Translator: TianXing_Yi <ytx.cash at gmail.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "gnucash/gnucash/zh_Hans/>\n"
@@ -687,11 +687,10 @@ msgid ""
 "\n"
 "Douglas Adams, \"The Restaurant at the End of the Universe\""
 msgstr ""
-"一种理论认为,如果有人发现了宇宙是什么,为什么会出现在这里,那么它就会立刻消"
-"失,取而代之的是更加诡异和莫名其妙的东西。\n"
+"一种理论认为,如果有人发现了宇宙是什么,为什么会出现在这里,那么它就会立刻消失,取而代之的是更加诡异和莫名其妙的东西。\n"
 "还有一种说法,这事情已经发生了。\n"
 "\n"
-"道格拉斯-亚当斯,“宇宙尽头的餐厅”"
+"道格拉斯-亚当斯,《宇宙尽头的餐厅》"
 
 #: gnucash/gnome/assistant-acct-period.c:188
 msgid "The book was closed successfully."
@@ -2501,7 +2500,7 @@ msgstr[0] "%d 份到期应付"
 
 #: gnucash/gnome/dialog-invoice.c:3720
 msgid "Due Bills Reminder"
-msgstr "到期应付提醒"
+msgstr "应付提醒"
 
 #. Translators: %d is the number of invoices/credit notes due. This is a
 #. ngettext(3) message.
@@ -2513,7 +2512,7 @@ msgstr[0] "%d 份到期应收"
 
 #: gnucash/gnome/dialog-invoice.c:3731
 msgid "Due Invoices Reminder"
-msgstr "到期应收提醒"
+msgstr "应收提醒"
 
 #: gnucash/gnome/dialog-job.c:139
 msgid "The Job must be given a name."
@@ -3430,11 +3429,11 @@ msgstr "计划交易列表"
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:171
 msgid "Since _Last Run..."
-msgstr "自上次运行(_L)..."
+msgstr "待处理计划交易(_L)..."
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:172
 msgid "Create Scheduled Transactions since the last time run"
-msgstr "创建自上次运行后的计划交易"
+msgstr "创建尚未执行的计划交易"
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:176
 msgid "_Mortgage & Loan Repayment..."
@@ -3769,7 +3768,7 @@ msgstr "查看并编辑帐期"
 
 #: gnucash/gnome/gnc-plugin-business.c:293
 msgid "Bills _Due Reminder"
-msgstr "到期应付提醒(_D)"
+msgstr "应付提醒(_D)"
 
 #: gnucash/gnome/gnc-plugin-business.c:294
 msgid "Open the Bills Due Reminder dialog"
@@ -3777,7 +3776,7 @@ msgstr "打开到期应付提醒对话框"
 
 #: gnucash/gnome/gnc-plugin-business.c:298
 msgid "Invoices _Due Reminder"
-msgstr "到期应收提醒(_D)"
+msgstr "应收提醒(_D)"
 
 #: gnucash/gnome/gnc-plugin-business.c:299
 msgid "Open the Invoices Due Reminder dialog"
@@ -6393,7 +6392,7 @@ msgstr "显示 ~a 报表"
 #: gnucash/gnome/report-menus.scm:90
 #: gnucash/gtkbuilder/dialog-custom-report.glade:8
 msgid "Saved Report Configurations"
-msgstr "已保存的报表模板"
+msgstr "已保存模板"
 
 #: gnucash/gnome/report-menus.scm:92
 msgid "Manage and run saved report configurations"
@@ -9500,7 +9499,7 @@ msgstr "A"
 
 #: gnucash/gnome-utils/gnc-tree-view-price.c:396
 msgid "Security"
-msgstr "证券"
+msgstr "币种"
 
 #: gnucash/gnome-utils/gnc-tree-view-split-reg.c:762
 msgid "Status Bar"
@@ -10845,7 +10844,7 @@ msgstr ""
 
 #: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:17
 msgid "Run \"since last run\" dialog when a file is opened."
-msgstr "文件打开时启动“自从上一次运行”对话框。"
+msgstr "文件打开时启动“待处理计划交易”对话框。"
 
 #: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:18
 msgid ""
@@ -10860,7 +10859,7 @@ msgstr ""
 
 #: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:22
 msgid "Show \"since last run\" notification dialog when a file is opened."
-msgstr "文件打开时显示“自从上一次运行”通知对话框。"
+msgstr "文件打开时显示“待处理计划交易”对话框。"
 
 #: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:23
 msgid ""
@@ -14819,7 +14818,7 @@ msgstr "含税"
 #: gnucash/gtkbuilder/dialog-vendor.glade:546
 #: gnucash/register/ledger-core/gncEntryLedgerModel.c:97
 msgid "Tax Table"
-msgstr "税率表"
+msgstr "税率"
 
 #: gnucash/gtkbuilder/dialog-customer.glade:594
 #: gnucash/gtkbuilder/dialog-vendor.glade:616
@@ -16768,7 +16767,7 @@ msgstr "日期之前(_D)"
 #: gnucash/gtkbuilder/dialog-price.glade:795
 #: gnucash/report/reports/standard/price-scatter.scm:82
 msgid "Price Database"
-msgstr "价格数据库"
+msgstr "汇率数据库"
 
 #: gnucash/gtkbuilder/dialog-price.glade:842
 msgid "Add a new price."
@@ -17144,7 +17143,7 @@ msgstr "循环次数"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:512
 msgid "<b>Since Last Run</b>"
-msgstr "<b>自上次运行</b>"
+msgstr "<b>待处理计划交易</b>"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:535
 msgid "<b>Transaction Editor Defaults</b>"
@@ -17156,7 +17155,7 @@ msgstr "打开文件时运行(_R)"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:549
 msgid "Run the \"since last run\" process when a file is opened."
-msgstr "文件打开时,执行“自上次运行”进程。"
+msgstr "文件打开时,执行“待处理计划交易”进程。"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:562
 msgid "_Show notification window"
@@ -17166,7 +17165,7 @@ msgstr "显示通知(_S)"
 msgid ""
 "Show the notification window for the \"since last run\" process when a file "
 "is opened."
-msgstr "文件打开时,显示“自上次运行”进程的通知。"
+msgstr "文件打开时,显示“待处理计划交易”进程的通知。"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:579
 msgid "_Auto-create new transactions"
@@ -17268,7 +17267,7 @@ msgstr "模板"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:1454
 msgid "Since Last Run..."
-msgstr "自上次运行..."
+msgstr "待处理计划交易"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:1554
 msgid "_Review created transactions"
@@ -23489,7 +23488,7 @@ msgstr "此报表包含合计余额为零(递归)的科目。"
 #: gnucash/report/reports/standard/budget-income-statement.scm:90
 #: gnucash/report/reports/standard/income-statement.scm:77
 msgid "Omit zero balance figures"
-msgstr "排除零余额科目"
+msgstr "余额为零科目不显示零"
 
 #: gnucash/report/reports/standard/account-summary.scm:108
 #: gnucash/report/reports/standard/balance-sheet.scm:104
@@ -23498,7 +23497,7 @@ msgstr "排除零余额科目"
 #: gnucash/report/reports/standard/budget-income-statement.scm:92
 #: gnucash/report/reports/standard/income-statement.scm:79
 msgid "Show blank space in place of any zero balances which would be shown."
-msgstr "显示空白的地方,以代替任何将显示的零余额。"
+msgstr "若余额为零则显示空白。"
 
 #: gnucash/report/reports/standard/account-summary.scm:110
 #: gnucash/report/reports/standard/balance-sheet.scm:106

commit be6fb1abe2b7fac27c4aefc4b32415bd1c73ab92
Merge: bedc85afa 3dceb0868
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Aug 7 14:39:57 2021 -0700

    Merge Chris Good's 'bug798205ImpOfx' into maint.


commit bedc85afa3671b7e7a0ee2f657a89f54794371d4
Merge: f0926d66c 0420ae6a6
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 19:30:01 2021 +0800

    Merge branch 'maint-leaks' into maint #1101


commit 0420ae6a6607f32ba348dafbf57af93db9782561
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 08:01:06 2021 +0800

    [account.cpp] refactor gnc_account_list_name_violations

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index c66657b23..78755e38d 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -262,34 +262,29 @@ gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invali
     return message;
 }
 
-GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator)
+struct ViolationData
 {
-    Account *root_account = gnc_book_get_root_account(book);
-    GList   *accounts, *node;
-    GList   *invalid_list = NULL;
-
-    g_return_val_if_fail (separator != NULL, NULL);
-
-    if (root_account == NULL)
-        return NULL;
-
-    accounts = gnc_account_get_descendants (root_account);
-    for (node = accounts; node; node = g_list_next(node))
-    {
-        Account *acct      = (Account*)node->data;
-        gchar   *acct_name = g_strdup ( xaccAccountGetName ( acct ) );
+    GList *list;
+    const gchar *separator;
+};
 
-        if ( g_strstr_len ( acct_name, -1, separator ) )
-            invalid_list = g_list_prepend ( invalid_list, (gpointer) acct_name );
-        else
-            g_free ( acct_name );
-    }
-    if (accounts != NULL)
-    {
-        g_list_free(accounts);
-    }
+static void
+check_acct_name (Account *acct, gpointer user_data)
+{
+    auto cb {static_cast<ViolationData*>(user_data)};
+    auto name {xaccAccountGetName (acct)};
+    if (g_strstr_len (name, -1, cb->separator))
+        cb->list = g_list_prepend (cb->list, g_strdup (name));
+}
 
-    return invalid_list;
+GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator)
+{
+    g_return_val_if_fail (separator != NULL, nullptr);
+    if (!book) return nullptr;
+    ViolationData cb = { nullptr, separator };
+    gnc_account_foreach_descendant (gnc_book_get_root_account (book),
+                                    (AccountCb)check_acct_name, &cb);
+    return cb.list;
 }
 
 /********************************************************************\

commit 67bd513514b1490a9521b520e812a5d3f243185b
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 00:23:02 2021 +0800

    [account.cpp] rewrite gnc_account_foreach_descendant_until in C++

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index d3a64f5a8..c66657b23 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -3153,28 +3153,24 @@ gnc_account_foreach_descendant_until (const Account *acc,
                                       AccountCb2 thunk,
                                       gpointer user_data)
 {
-    const AccountPrivate *priv;
-    GList *node;
-    Account *child;
-    gpointer result;
+    gpointer result {nullptr};
 
-    g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
-    g_return_val_if_fail(thunk, NULL);
+    g_return_val_if_fail (GNC_IS_ACCOUNT(acc), nullptr);
+    g_return_val_if_fail (thunk, nullptr);
 
-    priv = GET_PRIVATE(acc);
-    for (node = priv->children; node; node = node->next)
+    auto priv{GET_PRIVATE(acc)};
+
+    for (auto node = priv->children; node; node = node->next)
     {
-        child = static_cast<Account*>(node->data);
-        result = thunk(child, user_data);
-        if (result)
-            return(result);
-
-        result = gnc_account_foreach_descendant_until(child, thunk, user_data);
-        if (result)
-            return(result);
+        auto child = static_cast<Account*>(node->data);
+        result = thunk (child, user_data);
+        if (result) break;
+
+        result = gnc_account_foreach_descendant_until (child, thunk, user_data);
+        if (result) break;
     }
 
-    return NULL;
+    return result;
 }
 
 

commit 17953441cba7ee73b2e794c9e46affd5a2955a27
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Aug 6 00:22:49 2021 +0800

    [account.cpp] refactor gnc_account_foreach_descendant

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 5dd157041..d3a64f5a8 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2695,7 +2695,6 @@ static void
 account_foreach_descendant (const Account *acc, AccountCb thunk,
                             void* user_data, bool sort)
 {
-    gpointer result = nullptr;
     GList *children;
 
     g_return_if_fail (GNC_IS_ACCOUNT(acc));
@@ -3146,20 +3145,7 @@ gnc_account_foreach_descendant (const Account *acc,
                                 AccountCb thunk,
                                 gpointer user_data)
 {
-    const AccountPrivate *priv;
-    GList *node;
-    Account *child;
-
-    g_return_if_fail(GNC_IS_ACCOUNT(acc));
-    g_return_if_fail(thunk);
-
-    priv = GET_PRIVATE(acc);
-    for (node = priv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        thunk(child, user_data);
-        gnc_account_foreach_descendant(child, thunk, user_data);
-    }
+    account_foreach_descendant (acc, thunk, user_data, FALSE);
 }
 
 gpointer

commit 5698b67bf563ec6ed6f0016a9edbd65af932ed50
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:08:21 2021 +0800

    [account.cpp] refactor gnc_account_lookup_by_code

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 9ac2a8b78..5dd157041 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2985,37 +2985,17 @@ gnc_account_lookup_by_name (const Account *parent, const char * name)
     return (Account*)gnc_account_foreach_descendant_until (parent, is_acct_name, (char*)name);
 }
 
+static gpointer
+is_acct_code (Account *account, gpointer user_data)
+{
+    auto name {static_cast<gchar*>(user_data)};
+    return (g_strcmp0 (name, xaccAccountGetCode (account)) ? nullptr : account);
+}
+
 Account *
 gnc_account_lookup_by_code (const Account *parent, const char * code)
 {
-    AccountPrivate *cpriv, *ppriv;
-    Account *child, *result;
-    GList *node;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
-    g_return_val_if_fail(code, NULL);
-
-    /* first, look for accounts hanging off the current node */
-    ppriv = GET_PRIVATE(parent);
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        cpriv = GET_PRIVATE(child);
-        if (g_strcmp0(cpriv->accountCode, code) == 0)
-            return child;
-    }
-
-    /* if we are still here, then we haven't found the account yet.
-     * Recursively search each of the child accounts next */
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        result = gnc_account_lookup_by_code (child, code);
-        if (result)
-            return result;
-    }
-
-    return NULL;
+    return (Account*)gnc_account_foreach_descendant_until (parent, is_acct_code, (char*)code);
 }
 
 static gpointer

commit 09e2e7613c47943c9f333445d75484d9744a6376
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:08:11 2021 +0800

    [account.cpp] refactor gnc_account_lookup_by_name

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 215de9751..9ac2a8b78 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2972,37 +2972,17 @@ gnc_account_get_descendants_sorted (const Account *account)
     return g_list_reverse (list);
 }
 
+static gpointer
+is_acct_name (Account *account, gpointer user_data)
+{
+    auto name {static_cast<gchar*>(user_data)};
+    return (g_strcmp0 (name, xaccAccountGetName (account)) ? nullptr : account);
+}
+
 Account *
 gnc_account_lookup_by_name (const Account *parent, const char * name)
 {
-    AccountPrivate *cpriv, *ppriv;
-    Account *child, *result;
-    GList *node;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
-    g_return_val_if_fail(name, NULL);
-
-    /* first, look for accounts hanging off the current node */
-    ppriv = GET_PRIVATE(parent);
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        cpriv = GET_PRIVATE(child);
-        if (g_strcmp0(cpriv->accountName, name) == 0)
-            return child;
-    }
-
-    /* if we are still here, then we haven't found the account yet.
-     * Recursively search each of the child accounts next */
-    for (node = ppriv->children; node; node = node->next)
-    {
-        child = static_cast<Account*>(node->data);
-        result = gnc_account_lookup_by_name (child, name);
-        if (result)
-            return result;
-    }
-
-    return NULL;
+    return (Account*)gnc_account_foreach_descendant_until (parent, is_acct_name, (char*)name);
 }
 
 Account *

commit bebc366e88344b5e226538d79908244900e19878
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:07:18 2021 +0800

    [account.cpp] refactor gnc_account_n_descendants

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index b74ca5242..215de9751 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2894,20 +2894,18 @@ gnc_account_nth_child (const Account *parent, gint num)
     return static_cast<Account*>(g_list_nth_data(GET_PRIVATE(parent)->children, num));
 }
 
+static void
+count_acct (Account *account, gpointer user_data)
+{
+    auto count {static_cast<int*>(user_data)};
+    ++*count;
+}
+
 gint
 gnc_account_n_descendants (const Account *account)
 {
-    AccountPrivate *priv;
-    GList *node;
-    gint count = 0;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
-
-    priv = GET_PRIVATE(account);
-    for (node = priv->children; node; node = g_list_next(node))
-    {
-        count += gnc_account_n_descendants(static_cast<Account*>(node->data)) + 1;
-    }
+    int count {0};
+    account_foreach_descendant (account, count_acct, &count, FALSE);
     return count;
 }
 

commit f0926d66c1ed8cf24b1fbe60810eb03a14965922
Merge: 86bc9d93a 7a0ea190c
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 5 11:45:14 2021 -0700

    Merge Simon Arlott's 'qof-instance-dispose' into maint.


commit e6c33a39bc7ead9ea0d687efd4439f1c2913ff22
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:04:55 2021 +0800

    [account.cpp] refactor gnc_account_get_descendants{_sorted}

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 85a3ce909..b74ca5242 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2951,52 +2951,27 @@ gnc_account_get_tree_depth (const Account *account)
     return depth + 1;
 }
 
+static void
+collect_acct (Account *account, gpointer user_data)
+{
+    auto listptr{static_cast<GList**>(user_data)};
+    *listptr = g_list_prepend (*listptr, account);
+}
+
 GList *
 gnc_account_get_descendants (const Account *account)
 {
-    AccountPrivate *priv;
-    GList *child, *descendants;
-
-    g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
-
-    priv = GET_PRIVATE(account);
-    if (!priv->children)
-        return NULL;
-
-    descendants = NULL;
-    for (child = priv->children; child; child = g_list_next(child))
-    {
-        descendants = g_list_append(descendants, child->data);
-        descendants = g_list_concat(descendants,
-                gnc_account_get_descendants(static_cast<Account const *>(child->data)));
-    }
-    return descendants;
+    GList* list = nullptr;
+    account_foreach_descendant (account, collect_acct, &list, FALSE);
+    return g_list_reverse (list);
 }
 
 GList *
 gnc_account_get_descendants_sorted (const Account *account)
 {
-    AccountPrivate *priv;
-    GList *child, *children, *descendants;
-
-    /* errors */
-    g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
-
-    /* optimizations */
-    priv = GET_PRIVATE(account);
-    if (!priv->children)
-        return NULL;
-
-    descendants = NULL;
-    children = g_list_sort(g_list_copy(priv->children), (GCompareFunc)xaccAccountOrder);
-    for (child = children; child; child = g_list_next(child))
-    {
-        descendants = g_list_append(descendants, child->data);
-        descendants = g_list_concat(descendants,
-                gnc_account_get_descendants_sorted(static_cast<Account const *>(child->data)));
-    }
-    g_list_free(children);
-    return descendants;
+    GList* list = nullptr;
+    account_foreach_descendant (account, collect_acct, &list, TRUE);
+    return g_list_reverse (list);
 }
 
 Account *

commit d2db43019c0be28f95233aaa7a5e97f80a1f96f8
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Aug 3 22:02:12 2021 +0800

    [account.cpp] internal function account_foreach_descendant
    
    fast and efficient

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 8f12f0c64..85a3ce909 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2691,6 +2691,36 @@ DxaccAccountSetCurrency (Account * acc, gnc_commodity * currency)
 /********************************************************************\
 \********************************************************************/
 
+static void
+account_foreach_descendant (const Account *acc, AccountCb thunk,
+                            void* user_data, bool sort)
+{
+    gpointer result = nullptr;
+    GList *children;
+
+    g_return_if_fail (GNC_IS_ACCOUNT(acc));
+    g_return_if_fail (thunk);
+
+    auto priv{GET_PRIVATE(acc)};
+    if (sort)
+    {
+        children = g_list_copy (priv->children);
+        children = g_list_sort (children, (GCompareFunc)xaccAccountOrder);
+    }
+    else
+        children = priv->children;
+
+    for (auto node = children; node; node = node->next)
+    {
+        auto child = static_cast<Account*>(node->data);
+        thunk (child, user_data);
+        account_foreach_descendant (child, thunk, user_data, sort);
+    }
+
+    if (sort)
+        g_list_free (children);
+}
+
 void
 gnc_account_append_child (Account *new_parent, Account *child)
 {

commit 86bc9d93a7be0d92f5083eced12b73eab089719c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Aug 5 22:09:24 2021 +0800

    gchar *gnc_account_get_full_name must be freed
    
    The gnc-account-sel.c one was causing a runaway leak -- leaked
    full_name for every account (except the matched account) in the
    GNCAccountSel. Interestingly the original commit[*] suggests the name
    should have been freed correctly however the braces prohibited it.
    
    [*] e5b0bdbe109abad193f8419b485ce34d45cf5cc5

diff --git a/gnucash/gnome-utils/dialog-account.c b/gnucash/gnome-utils/dialog-account.c
index cba3b531e..e7ecf2e6c 100644
--- a/gnucash/gnome-utils/dialog-account.c
+++ b/gnucash/gnome-utils/dialog-account.c
@@ -2163,7 +2163,7 @@ gnc_account_renumber_create_dialog (GtkWidget *window, Account *account)
     RenumberDialog *data;
     GtkBuilder *builder;
     GtkWidget *widget;
-    gchar *string;
+    gchar *string, *fullname;
 
     /* This is a safety check; the menu item calling this dialog
      * should be disabled if the account has no children.
@@ -2182,12 +2182,14 @@ gnc_account_renumber_create_dialog (GtkWidget *window, Account *account)
                g_object_unref);
 
     widget = GTK_WIDGET(gtk_builder_get_object (builder, "header_label"));
+    fullname = gnc_account_get_full_name (account);
     string = g_strdup_printf(_( "Renumber the immediate sub-accounts of %s? "
                                 "This will replace the account code field of "
                                 "each child account with a newly generated code."),
-                             gnc_account_get_full_name(account));
+                             fullname);
     gtk_label_set_text(GTK_LABEL(widget), string);
     g_free(string);
+    g_free (fullname);
 
     data->prefix = GTK_WIDGET(gtk_builder_get_object (builder, "prefix_entry"));
     data->interval = GTK_WIDGET(gtk_builder_get_object (builder, "interval_spin"));
@@ -2256,7 +2258,7 @@ gnc_account_cascade_properties_dialog (GtkWidget *window, Account *account)
     GtkWidget *color_box, *placeholder_box, *hidden_box;
     GtkWidget *placeholder_button, *hidden_button;
 
-    gchar *string;
+    gchar *string, *fullname;
     const char *color_string;
     gchar *old_color_string = NULL;
     GdkRGBA color;
@@ -2287,9 +2289,10 @@ gnc_account_cascade_properties_dialog (GtkWidget *window, Account *account)
     g_signal_connect (G_OBJECT(color_button_default), "clicked",
                       G_CALLBACK(default_color_button_cb), (gpointer)color_button);
 
+    fullname = gnc_account_get_full_name (account);
     string = g_strdup_printf (_( "Set the account color for account '%s' "
                                  "including all sub-accounts to the selected color"),
-                              gnc_account_get_full_name (account));
+                              fullname);
     gtk_label_set_text (GTK_LABEL(label), string);
     g_free (string);
 
@@ -2316,7 +2319,7 @@ gnc_account_cascade_properties_dialog (GtkWidget *window, Account *account)
 
     string = g_strdup_printf (_( "Set the account placeholder value for account '%s' "
                                  "including all sub-accounts"),
-                              gnc_account_get_full_name (account));
+                              fullname);
     gtk_label_set_text (GTK_LABEL(label), string);
     g_free (string);
 
@@ -2330,9 +2333,10 @@ gnc_account_cascade_properties_dialog (GtkWidget *window, Account *account)
 
     string = g_strdup_printf (_( "Set the account hidden value for account '%s' "
                                  "including all sub-accounts"),
-                              gnc_account_get_full_name (account));
+                              fullname);
     gtk_label_set_text (GTK_LABEL(label), string);
     g_free (string);
+    g_free (fullname);
 
     /* default to cancel */
     gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
diff --git a/gnucash/gnome-utils/gnc-account-sel.c b/gnucash/gnome-utils/gnc-account-sel.c
index 9174a663c..25126c4a1 100644
--- a/gnucash/gnome-utils/gnc-account-sel.c
+++ b/gnucash/gnome-utils/gnc-account-sel.c
@@ -233,10 +233,8 @@ gas_populate_list (GNCAccountSel *gas)
                             ACCT_COL_PTR,  acc,
                             -1);
         if (g_utf8_collate (name, currentSel) == 0)
-        {
             active = i;
-            g_free (name);
-        }
+        g_free (name);
     }
 
     /* If the account which was in the text box before still exists, then
diff --git a/gnucash/import-export/import-account-matcher.c b/gnucash/import-export/import-account-matcher.c
index 849e935c5..55cc3d5a7 100644
--- a/gnucash/import-export/import-account-matcher.c
+++ b/gnucash/import-export/import-account-matcher.c
@@ -148,11 +148,14 @@ static gpointer test_acct_online_id_match(Account *acct, gpointer data)
              */
             else if (partial_len == acct_len)
             {
+                gchar *name1, *name2;
                 ++match->count;
+                name1 = gnc_account_get_full_name (match->partial_match);
+                name2 = gnc_account_get_full_name (acct);
                 PERR("Accounts %s and %s have the same online-id %s",
-                     gnc_account_get_full_name(match->partial_match),
-                     gnc_account_get_full_name(acct),
-                     partial_online_id);
+                     name1, name2, partial_online_id);
+                g_free (name1);
+                g_free (name2);
             }
         }
     }
diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index 0c31c5a52..9e2f66ddd 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -735,6 +735,7 @@ gnc_gen_trans_assign_transfer_account (GtkTreeView *treeview,
                 old_acc  = gnc_import_TransInfo_get_destacc (trans_info);
                 if (*first)
                 {
+                    gchar *acc_full_name = gnc_account_get_full_name (*new_acc);
                     ok_pressed = FALSE;
                     *new_acc = gnc_import_select_account (info->main_widget,
                         NULL,
@@ -746,8 +747,9 @@ gnc_gen_trans_assign_transfer_account (GtkTreeView *treeview,
                         old_acc,
                         &ok_pressed);
                     *first = FALSE;
-                    DEBUG("account selected = %s",
-                            gnc_account_get_full_name (*new_acc));
+                    acc_full_name = gnc_account_get_full_name (*new_acc);
+                    DEBUG("account selected = %s", acc_full_name);
+                    g_free (acc_full_name);
                 }
                 if (ok_pressed)
                 {
@@ -805,19 +807,22 @@ gnc_gen_trans_assign_transfer_account_to_selection_cb (GtkMenuItem *menuitem,
         {
             gchar *path_str = gtk_tree_path_to_string (l->data);
             GtkTreeRowReference *ref = gtk_tree_row_reference_new (model, l->data);
+            gchar *fullname;
             DEBUG("passing first = %s", first ? "true" : "false");
             DEBUG("passing is_selection = %s", is_selection ? "true" : "false");
             DEBUG("passing path = %s", path_str);
             g_free (path_str);
             refs = g_list_prepend (refs, ref);
-            DEBUG("passing account value = %s",
-                        gnc_account_get_full_name (assigned_account));
+            fullname = gnc_account_get_full_name (assigned_account);
+            DEBUG("passing account value = %s", fullname);
+            g_free (fullname);
             gnc_gen_trans_assign_transfer_account (treeview,
                                                    &first, is_selection, l->data,
                                                    &assigned_account, info);
-            DEBUG("returned value of account = %s",
-                        gnc_account_get_full_name (assigned_account));
+            fullname = gnc_account_get_full_name (assigned_account);
+            DEBUG("returned value of account = %s", fullname);
             DEBUG("returned value of first = %s", first ? "true" : "false");
+            g_free (fullname);
             if (assigned_account == NULL)
                 break;
 
@@ -848,6 +853,7 @@ gnc_gen_trans_row_activated_cb (GtkTreeView *treeview,
 {
     Account *assigned_account;
     gboolean first, is_selection;
+    gchar *namestr;
 
     ENTER("");
     assigned_account = NULL;
@@ -859,7 +865,9 @@ gnc_gen_trans_row_activated_cb (GtkTreeView *treeview,
 
     gtk_tree_selection_select_path (gtk_tree_view_get_selection (treeview), path);
 
-    DEBUG("account returned = %s", gnc_account_get_full_name (assigned_account));
+    namestr = gnc_account_get_full_name (assigned_account);
+    DEBUG("account returned = %s", namestr);
+    g_free (namestr);
     LEAVE("");
 }
 

commit de1ad9367a545894783f700d6277adfa1f45fdc5
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Aug 5 21:39:49 2021 +0800

    g_free gnc_ctime which returns a new gchar*

diff --git a/bindings/engine.i b/bindings/engine.i
index e9130a248..2b567fcdb 100644
--- a/bindings/engine.i
+++ b/bindings/engine.i
@@ -191,6 +191,7 @@ const char *qof_session_get_url (QofSession *session);
 %ignore qof_print_date_time_buff;
 %ignore gnc_tm_free;
 %newobject qof_print_date;
+%newobject gnc_ctime;
 %newobject gnc_print_time64;
 %include <gnc-date.h>
 extern const char *gnc_default_strftime_date_format;
diff --git a/gnucash/gnome/assistant-acct-period.c b/gnucash/gnome/assistant-acct-period.c
index c5bba7268..714692ff5 100644
--- a/gnucash/gnome/assistant-acct-period.c
+++ b/gnucash/gnome/assistant-acct-period.c
@@ -263,7 +263,7 @@ ap_assistant_menu_prepare (GtkAssistant *assistant, gpointer user_data)
 {
     int nperiods;
     GDate period_begin, period_end, date_now;
-    char * str;
+    char *str, *earliest_str;
 
     AcctPeriodInfo *info = user_data;
 
@@ -302,8 +302,10 @@ ap_assistant_menu_prepare (GtkAssistant *assistant, gpointer user_data)
      * we may have closed books since last time. */
     info->earliest = get_earliest_in_book (gnc_get_current_book());
     info->earliest_str = qof_print_date(info->earliest);
+    earliest_str = gnc_ctime (&info->earliest);
     PINFO ("Date of earliest transaction is %" G_GINT64_FORMAT " %s",
-	   info->earliest, gnc_ctime (&info->earliest));
+	   info->earliest, earliest_str);
+    g_free (earliest_str);
 
     /* Display the results */
     str = g_strdup_printf (
@@ -536,6 +538,7 @@ ap_assistant_create (AcctPeriodInfo *info)
     GtkBuilder *builder;
     GtkWidget *window;
     GtkWidget *box;
+    gchar *earliest_str;
 
     builder = gtk_builder_new();
     gnc_builder_add_from_file  (builder , "assistant-acct-period.glade", "account_period_assistant");
@@ -566,8 +569,10 @@ ap_assistant_create (AcctPeriodInfo *info)
      * and use that to set up the freq spec widget. */
     info->earliest = get_earliest_in_book (gnc_get_current_book());
     info->earliest_str = qof_print_date(info->earliest);
+    earliest_str = gnc_ctime (&info->earliest);
     PINFO ("date of earliest transaction is %" G_GINT64_FORMAT " %s",
-           info->earliest, gnc_ctime (&info->earliest));
+           info->earliest, earliest_str);
+    g_free (earliest_str);
 
     g_date_clear (&info->closing_date, 1);
     gnc_gdate_set_time64 (&info->closing_date, info->earliest);
diff --git a/libgnucash/engine/ScrubBusiness.c b/libgnucash/engine/ScrubBusiness.c
index d775157ef..367becd9b 100644
--- a/libgnucash/engine/ScrubBusiness.c
+++ b/libgnucash/engine/ScrubBusiness.c
@@ -590,6 +590,7 @@ gncScrubBusinessSplit (Split *split)
             gchar *pdatestr = gnc_ctime (&pdate);
             PINFO ("Destroying empty split %p from transaction %s (%s)", split, pdatestr, xaccTransGetDescription(txn));
             xaccSplitDestroy (split);
+            g_free (pdatestr);
 
             // Also delete the lot containing this split if it was the last split in that lot
             if (lot && (gnc_lot_count_splits (lot) == 0))

commit 7a0ea190ca9e9b36a308960950418488324aa1f2
Author: Simon Arlott <sa.me.uk>
Date:   Sun Jul 11 15:09:45 2021 +0100

    qof_instance_dispose should always complete dispose processes
    
    If QofInstancePrivate has no collection then qof_instance_dispose() returns
    without completing the rest of its dispose processes, skipping removal of
    its type string from the string cache resulting in a reference count leak.
    
    Change the check for a collection so that it only affects the call to
    qof_collection_remove_entity().

diff --git a/libgnucash/engine/qofinstance.cpp b/libgnucash/engine/qofinstance.cpp
index 980e43bf9..7f99994a9 100644
--- a/libgnucash/engine/qofinstance.cpp
+++ b/libgnucash/engine/qofinstance.cpp
@@ -319,9 +319,8 @@ qof_instance_dispose (GObject *instp)
     QofInstance* inst = QOF_INSTANCE(instp);
 
     priv = GET_PRIVATE(instp);
-    if (!priv->collection)
-        return;
-    qof_collection_remove_entity(inst);
+    if (priv->collection)
+        qof_collection_remove_entity(inst);
 
     CACHE_REMOVE(inst->e_type);
     inst->e_type = NULL;

commit de0af2dca71125b6f666a777f0d39dc16024b0c8
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Aug 5 09:23:34 2021 +0800

    [reconcile-view.c] g_list_free a GList*

diff --git a/gnucash/gnome/reconcile-view.c b/gnucash/gnome/reconcile-view.c
index 891b59ddb..489ff7a2b 100644
--- a/gnucash/gnome/reconcile-view.c
+++ b/gnucash/gnome/reconcile-view.c
@@ -690,6 +690,7 @@ gnc_reconcile_view_finalize (GObject *object)
 {
     GNCReconcileView *view = GNC_RECONCILE_VIEW (object);
 
+    g_list_free (view->column_list);
     if (view->reconciled != NULL)
     {
         g_hash_table_destroy (view->reconciled);

commit c9db551693a26b7971feee4ab006569d36510c8c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Aug 5 09:23:28 2021 +0800

    g_free qof_print_date which returns a new char*

diff --git a/gnucash/gnome-utils/gnc-cell-renderer-popup-entry.c b/gnucash/gnome-utils/gnc-cell-renderer-popup-entry.c
index 84e385230..7e6ecbff9 100644
--- a/gnucash/gnome-utils/gnc-cell-renderer-popup-entry.c
+++ b/gnucash/gnome-utils/gnc-cell-renderer-popup-entry.c
@@ -260,6 +260,7 @@ gtk_cell_editable_key_press_event (GtkEntry      *entry,
 
     if (qof_scan_date (date_string, &day, &month, &year))
     {
+        gchar *datestr;
         when.tm_year = year - 1900;
         when.tm_mon = month - 1;
         when.tm_mday = day;
@@ -267,7 +268,10 @@ gtk_cell_editable_key_press_event (GtkEntry      *entry,
         if (!gnc_handle_date_accelerator (key_event, &when, date_string))
             return FALSE;
 
-        gtk_entry_set_text (entry, qof_print_date (gnc_mktime (&when)));
+        datestr = qof_print_date (gnc_mktime (&when));
+        gtk_entry_set_text (entry, datestr);
+        g_free (datestr);
+
         gtk_widget_grab_focus (GTK_WIDGET(entry));
         return TRUE;
     }
diff --git a/gnucash/gnome/window-reconcile.c b/gnucash/gnome/window-reconcile.c
index d7dc349f8..417707228 100644
--- a/gnucash/gnome/window-reconcile.c
+++ b/gnucash/gnome/window-reconcile.c
@@ -262,6 +262,7 @@ recnRecalculateBalance (RecnWindow *recnData)
     gnc_numeric ending;
     gnc_numeric reconciled;
     gnc_numeric diff;
+    gchar *datestr;
     GNCPrintAmountInfo print_info;
     gboolean reverse_balance, include_children;
     GtkAction *action;
@@ -289,8 +290,9 @@ recnRecalculateBalance (RecnWindow *recnData)
 
     diff = gnc_numeric_sub_fixed (ending, reconciled);
 
-    gtk_label_set_text(GTK_LABEL(recnData->recn_date),
-                       qof_print_date(recnData->statement_date));
+    datestr = qof_print_date (recnData->statement_date);
+    gtk_label_set_text (GTK_LABEL(recnData->recn_date), datestr);
+    g_free (datestr);
 
     gnc_add_colorized_amount (recnData->starting, starting, print_info, FALSE);
     gnc_add_colorized_amount (recnData->ending, ending, print_info, reverse_balance);
@@ -1866,13 +1868,16 @@ recnWindowWithBalance (GtkWidget *parent, Account *account, gnc_numeric new_endi
         {
             Split* split = n->data;
             time64 recn_date = xaccSplitGetDateReconciled (split);
+            gchar *datestr, *recnstr;
             if ((xaccSplitGetReconcile (split) != YREC) ||
                 (recn_date <= statement_date))
                 continue;
 
-            PWARN ("split posting_date=%s, recn_date=%s",
-                   qof_print_date (xaccTransGetDate (xaccSplitGetParent (split))),
-                   qof_print_date (recn_date));
+            datestr = qof_print_date (xaccTransGetDate (xaccSplitGetParent (split)));
+            recnstr = qof_print_date (recn_date);
+            PWARN ("split posting_date=%s, recn_date=%s", datestr, recnstr);
+            g_free (datestr);
+            g_free (recnstr);
 
             gtk_statusbar_push (bar, context, _("WARNING! Account contains \
 splits whose reconcile date is after statement date. Reconciliation may be \
diff --git a/libgnucash/backend/sql/gnc-transaction-sql.cpp b/libgnucash/backend/sql/gnc-transaction-sql.cpp
index 47e4c615c..f794f6702 100644
--- a/libgnucash/backend/sql/gnc-transaction-sql.cpp
+++ b/libgnucash/backend/sql/gnc-transaction-sql.cpp
@@ -656,6 +656,7 @@ GncSqlTransBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
     {
         Split* split = xaccTransGetSplit (pTx, 0);
         Account* acc = xaccSplitGetAccount (split);
+        gchar *datestr = qof_print_date (xaccTransGetDate (pTx));
         /* FIXME: This needs to be implemented
         const char *message1 = "Transaction %s dated %s in account %s not saved due to %s.%s";
         const char *message2 = "\nDatabase may be corrupted, check your data carefully.";
@@ -668,10 +669,8 @@ GncSqlTransBackend::commit (GncSqlBackend* sql_be, QofInstance* inst)
                               message2 );
         */
         PERR ("Transaction %s dated %s in account %s not saved due to %s.\n",
-              xaccTransGetDescription (pTx),
-              qof_print_date (xaccTransGetDate (pTx)),
-              xaccAccountGetName (acc),
-              err);
+              xaccTransGetDescription (pTx), datestr, xaccAccountGetName (acc), err);
+        g_free (datestr);
     }
     return is_ok;
 }

commit d099d39afd36b672a55956c34d105d940b6ea9af
Merge: fd56512cf bf8fe1123
Author: John Ralls <jralls at ceridwen.us>
Date:   Wed Aug 4 15:52:51 2021 -0700

    Merge Simon Arlott's 'commit-root-on-load' into maint.


commit fd56512cf77ad14520d7e27f8b63c13b9b023ec6
Merge: 9062be3d4 f15402a9a
Author: John Ralls <jralls at ceridwen.us>
Date:   Wed Aug 4 15:48:42 2021 -0700

    Merge Simon Arlott's 'load-test-xml' into maint.


commit 9062be3d47d669bbacf2ac4475b5243ddf416e3f
Merge: f6766d42e 413293961
Author: John Ralls <jralls at ceridwen.us>
Date:   Wed Aug 4 14:26:27 2021 -0700

    Merge Simon Arlott's 'string-cache-fixes' into maint.


commit f6766d42ece18f11e9c6ba817325a007b50cc14c
Merge: ddc423a50 4a5b5f3bf
Author: John Ralls <jralls at ceridwen.us>
Date:   Wed Aug 4 14:19:21 2021 -0700

    Merge Simon Arlott's 'string-cache-no-refcount-empty' into maint.


commit ddc423a5054f535ee56bae11a54dbb8c9a38c11b
Merge: 79d6154cb 621704ebe
Author: John Ralls <jralls at ceridwen.us>
Date:   Wed Aug 4 14:18:16 2021 -0700

    Merge Simon Arlott's 'bug-798238' into maint.


commit 79d6154cb55a5a27a2866448864ad1acc9943d0b
Author: Avi Markovitz <avi.markovitz at gmail.com>
Date:   Wed Aug 4 18:32:52 2021 +0200

    Translation update  by Avi Markovitz <avi.markovitz at gmail.com> using Weblate
    
    po/he.po: 100.0% (5364 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Hebrew)
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/he/
    
    Co-authored-by: Avi Markovitz <avi.markovitz at gmail.com>

diff --git a/po/he.po b/po/he.po
index 64655e410..d933efe09 100644
--- a/po/he.po
+++ b/po/he.po
@@ -12,7 +12,7 @@ msgstr ""
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
 "PO-Revision-Date: 2021-08-04 16:32+0000\n"
-"Last-Translator: Yaron Shahrabani <sh.yaron at gmail.com>\n"
+"Last-Translator: Avi Markovitz <avi.markovitz at gmail.com>\n"
 "Language-Team: Hebrew <https://hosted.weblate.org/projects/gnucash/gnucash/"
 "he/>\n"
 "Language: he\n"
@@ -3817,7 +3817,7 @@ msgstr "פתיחת דו־שיח חיפוש שובר הוצאות"
 
 #: gnucash/gnome/gnc-plugin-business.c:278
 msgid "Business Linked Documents"
-msgstr "מסמכים מקושרים עסקית"
+msgstr "מסמכים מקושרים – עסקי"
 
 #: gnucash/gnome/gnc-plugin-business.c:279
 msgid "View all Linked Business Documents"
@@ -4155,7 +4155,7 @@ msgstr "מחיקה"
 #: gnucash/gnome/gnc-plugin-page-register.c:1962
 #: gnucash/gnome/gnc-plugin-page-register.c:5076
 msgid "'Check & Repair' is currently running, do you want to abort it?"
-msgstr "‚בדיקה ותיקון’ רצים כרגע, לבטל?"
+msgstr "'בדיקה ותיקון’ רצים כרגע, האם לנטוש?"
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:520
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:526
@@ -28310,7 +28310,7 @@ msgstr "הצגת קוד החשבון הנגדי?"
 
 #: gnucash/report/trep-engine.scm:929
 msgid "Display the transaction linked document"
-msgstr "להציג את המסמך שמקושר לתנועה"
+msgstr "הצגת המסמך שמקושר לתנועה"
 
 #: gnucash/report/trep-engine.scm:932
 msgid "Display a subtotal summary table."

commit c2bc31fafcb9e5eae2ad39a933c9d85bb166552f
Author: Yaron Shahrabani <sh.yaron at gmail.com>
Date:   Wed Aug 4 18:32:52 2021 +0200

    Translation update  by Yaron Shahrabani <sh.yaron at gmail.com> using Weblate
    
    po/he.po: 100.0% (5364 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Hebrew)
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/he/
    
    Co-authored-by: Yaron Shahrabani <sh.yaron at gmail.com>

diff --git a/po/he.po b/po/he.po
index ab3b5a1ec..64655e410 100644
--- a/po/he.po
+++ b/po/he.po
@@ -3,7 +3,7 @@
 # Copyright (C) 2008 - 2020 by the respective translator
 # Avi Markovitz <avi.markovitz at gmail.com, 2019 - 2020
 # Ori Hoch <ori at uumpa.com>, 2008 http://www.uumpa.com/gnucash-he/
-# Yaron Shahrabani <sh.yaron at gmail.com>, 2020.
+# Yaron Shahrabani <sh.yaron at gmail.com>, 2020, 2021.
 # Avi Markovitz <avi.markovitz at gmail.com>, 2020, 2021.
 msgid ""
 msgstr ""
@@ -11,8 +11,8 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-08-04 12:35+0000\n"
-"Last-Translator: Avi Markovitz <avi.markovitz at gmail.com>\n"
+"PO-Revision-Date: 2021-08-04 16:32+0000\n"
+"Last-Translator: Yaron Shahrabani <sh.yaron at gmail.com>\n"
 "Language-Team: Hebrew <https://hosted.weblate.org/projects/gnucash/gnucash/"
 "he/>\n"
 "Language: he\n"
@@ -29443,7 +29443,7 @@ msgstr "התנועה בוטלה"
 
 #: libgnucash/tax/us/txf.scm:122
 msgid "No help available."
-msgstr "אין עזרה זמניה."
+msgstr "אין עזרה זמינה."
 
 #~ msgid ""
 #~ "You must enter a company name. If this customer is an individual (and not "

commit a6b7a4cb85f9e6666dccbd6e337fefb7e372465f
Author: Avi Markovitz <avi.markovitz at gmail.com>
Date:   Wed Aug 4 18:32:51 2021 +0200

    Translation update  by Avi Markovitz <avi.markovitz at gmail.com> using Weblate
    
    po/he.po: 100.0% (5364 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Hebrew)
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/he/
    
    Co-authored-by: Avi Markovitz <avi.markovitz at gmail.com>

diff --git a/po/he.po b/po/he.po
index 87bdc8a0a..ab3b5a1ec 100644
--- a/po/he.po
+++ b/po/he.po
@@ -11,7 +11,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-07-31 19:43+0000\n"
+"PO-Revision-Date: 2021-08-04 12:35+0000\n"
 "Last-Translator: Avi Markovitz <avi.markovitz at gmail.com>\n"
 "Language-Team: Hebrew <https://hosted.weblate.org/projects/gnucash/gnucash/"
 "he/>\n"
@@ -8745,7 +8745,7 @@ msgstr "חשבונאות לאנשים פרטיים ועסקים קטנים."
 #: gnucash/gnome-utils/gnc-main-window.c:4736
 msgid "translator-credits"
 msgstr ""
-"אבי מרקוביץ avi.markovitz at gmail.com 2022 2021, 2020, 2019\n"
+"אבי מרקוביץ avi.markovitz at gmail.com ,2021, 2020, 2019\n"
 "אורי הוך 2006"
 
 #: gnucash/gnome-utils/gnc-main-window.c:4739

commit 351ae62cedc356d6b19e0739d01a8afb95b5e9ef
Author: TianXing_Yi <ytx.cash at gmail.com>
Date:   Wed Aug 4 18:32:50 2021 +0200

    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5350 of 5364 strings; 1 fuzzy)
    1 failing checks (0.1%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Co-authored-by: TianXing_Yi <ytx.cash at gmail.com>

diff --git a/po/zh_CN.po b/po/zh_CN.po
index a624dbc42..e04e43eba 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -23,7 +23,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-08-01 11:33+0000\n"
+"PO-Revision-Date: 2021-08-02 07:52+0000\n"
 "Last-Translator: TianXing_Yi <ytx.cash at gmail.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "gnucash/gnucash/zh_Hans/>\n"
@@ -8558,13 +8558,13 @@ msgstr "未保存的账簿"
 
 #: gnucash/gnome-utils/gnc-main-window.c:1760
 msgid "Last modified on %a, %b %d, %Y at %I:%M %p"
-msgstr "%Yå¹´%b%dæ—¥, %a, %p %I:%M æ›´æ–°"
+msgstr "%Yå¹´%b%dæ—¥ %a, %p %I:%M æ›´æ–°"
 
 #. Translators: This message appears in the status bar after opening the file.
 #: gnucash/gnome-utils/gnc-main-window.c:1763
 #, c-format
 msgid "File %s opened. %s"
-msgstr "%s 已打开,%s"
+msgstr "%s ,%s"
 
 #: gnucash/gnome-utils/gnc-main-window.c:2885
 msgctxt "lower case key for short cut to 'Accounts'"
@@ -9168,7 +9168,7 @@ msgstr "股票拆分"
 #: gnucash/register/ledger-core/gncEntryLedgerModel.c:577
 #: gnucash/register/ledger-core/split-register-model.c:1006
 msgid "%A %d %B %Y"
-msgstr "%A %d %B %Y"
+msgstr "%Yå¹´%b%dæ—¥ %a"
 
 #: gnucash/gnome-utils/gnc-tree-util-split-reg.c:479
 msgid ""

commit b31b8dbd1eaf461f4471fcfa055562b6566d3511
Merge: a5edacf0f 5f721614a
Author: Frank H. Ellenberger <frank.h.ellenberger at gmail.com>
Date:   Wed Aug 4 20:15:39 2021 +0200

    Merge PR #1103 into maint


commit a5edacf0fcbfceb016b69c66d7ac9cc07342799a
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Aug 4 19:00:43 2021 +0800

    [options.scm] Rename option name to "Levels of Subaccounts"
    
    Original name "Show Accounts until level". Add backward compatibility
    missed in 08f490ee98

diff --git a/libgnucash/app-utils/options.scm b/libgnucash/app-utils/options.scm
index 7c7ddc613..5befd4743 100644
--- a/libgnucash/app-utils/options.scm
+++ b/libgnucash/app-utils/options.scm
@@ -1832,6 +1832,8 @@ the option '~a'."))
       ("Links" #f "Transaction Links")
       ;; invoice.scm, renamed November 2018
       ("Individual Taxes" #f "Use Detailed Tax Summary")
+      ;; renamed in several reports, April 2021
+      ("Show Accounts until level" #f "Levels of Subaccounts")
       ;; receipt.scm, renamed July 2021
       ("Invoice number" #f "Invoice Number")
       ;; receipt.scm and taxinvoice.scm, renamed July 2021

commit 5f721614ad08ee10d1f102382cb4fd252dfbf99b
Author: Steven Walter <stevenrwalter at gmail.com>
Date:   Sun Aug 1 22:29:00 2021 -0400

    Remove unneeded .decode() from Invoice*.tex.templ
    
    These values are already str's, don't decode them

diff --git a/bindings/python/example_scripts/Invoice.tex.tmpl b/bindings/python/example_scripts/Invoice.tex.tmpl
index a5248cca9..a16b03743 100644
--- a/bindings/python/example_scripts/Invoice.tex.tmpl
+++ b/bindings/python/example_scripts/Invoice.tex.tmpl
@@ -130,13 +130,13 @@
 \Euro
 %---------------------------------------------------------------------------
 \begin{letter}{% {% endraw %}
-{{ invoice.GetOwner().GetName().decode("UTF-8") }} \\ 
-{{ invoice.GetOwner().GetAddr().GetAddr1().decode("UTF-8") }} \\ 
-{{ invoice.GetOwner().GetAddr().GetAddr2().decode("UTF-8") }} \\ 
-{{ invoice.GetOwner().GetAddr().GetAddr3().decode("UTF-8") }} 
+{{ invoice.GetOwner().GetName() }} \\ 
+{{ invoice.GetOwner().GetAddr().GetAddr1() }} \\ 
+{{ invoice.GetOwner().GetAddr().GetAddr2() }} \\ 
+{{ invoice.GetOwner().GetAddr().GetAddr3() }} 
 {# if Addr4 is declared put a linebreak here #}
 {% if invoice.GetOwner().GetAddr().GetAddr4() %} \\ {% endif %} 
-{{ invoice.GetOwner().GetAddr().GetAddr4().decode("UTF-8") }} {% raw %}
+{{ invoice.GetOwner().GetAddr().GetAddr4() }} {% raw %}
 }
 %---------------------------------------------------------------------------
 % Weitere Optionen
@@ -156,7 +156,7 @@ Ich erlaube mir, Ihnen folgende Beträge in Rechnung zu stellen:
 {%- for ent in invoice.GetEntries() -%}
  {{- '\Artikel' -}} 
  {{- '{' -}} {{- ent.GetQuantity() -}} {{- '}' -}} 
- {{- '{' -}} {{- ent.GetDescription().decode("UTF-8") -}} {{- '}' -}} 
+ {{- '{' -}} {{- ent.GetDescription() -}} {{- '}' -}} 
  {{- '{' -}} {{- ent.GetInvPrice().to_double() -}} {{- '}' -}}
 {%- endfor -%}
 {#- **************** JINJA2 Entries END ********************** -#}
diff --git a/bindings/python/example_scripts/Invoice_2.tex.tmpl b/bindings/python/example_scripts/Invoice_2.tex.tmpl
index 0c94fc7e1..ea2e7e33e 100644
--- a/bindings/python/example_scripts/Invoice_2.tex.tmpl
+++ b/bindings/python/example_scripts/Invoice_2.tex.tmpl
@@ -134,13 +134,13 @@
 \Euro
 %---------------------------------------------------------------------------
 \begin{letter}{ {%- endraw -%}
-{{- invoice.GetOwner().GetName().decode("UTF-8") -}} \\ 
-{{- invoice.GetOwner().GetAddr().GetAddr1().decode("UTF-8") -}} \\ 
-{{- invoice.GetOwner().GetAddr().GetAddr2().decode("UTF-8") -}} \\ 
-{{- invoice.GetOwner().GetAddr().GetAddr3().decode("UTF-8") -}} 
+{{- invoice.GetOwner().GetName() -}} \\ 
+{{- invoice.GetOwner().GetAddr().GetAddr1() -}} \\ 
+{{- invoice.GetOwner().GetAddr().GetAddr2() -}} \\ 
+{{- invoice.GetOwner().GetAddr().GetAddr3() -}} 
 {# if Addr4 is declared put a linebreak here #}
 {%- if invoice.GetOwner().GetAddr().GetAddr4() -%} \\ {%- endif -%} 
-{{- invoice.GetOwner().GetAddr().GetAddr4().decode("UTF-8") -}} {%- raw -%}
+{{- invoice.GetOwner().GetAddr().GetAddr4() -}} {%- raw -%}
 }
 %---------------------------------------------------------------------------
 % Weitere Optionen
@@ -167,7 +167,7 @@ Ich erlaube mir, Ihnen folgende Beträge in Rechnung zu stellen:
  {%- for ent in invoice.GetEntries() %}
  {{ loop.index }} & 
  {{- locale.format("%.2f", ent.GetQuantity().to_double()) -}} & 
- {{- ent.GetDescription().decode("UTF-8") -}} &
+ {{- ent.GetDescription() -}} &
  \EUR{ {{- locale.format("%.2f", ent.GetInvPrice().to_double()) -}} } &
  \EUR{ {{- locale.format("%.2f", ent.GetInvPrice().to_double() * ent.GetQuantity().to_double()) -}} } \\ \hline
  {%- endfor -%}

commit 23bd7164511bf26af231097d2ee10da78fdd1fb7
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Jul 30 23:18:20 2021 +0800

    g_free gnc-path's gchar* intermediate strings

diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.cpp b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
index db4877479..11030e19d 100644
--- a/libgnucash/backend/dbi/gnc-backend-dbi.cpp
+++ b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
@@ -1100,7 +1100,9 @@ gnc_module_init_backend_dbi (void)
 #endif
     if (num_drivers <= 0)
     {
-        gchar* dir = g_build_filename (gnc_path_get_libdir (), "dbd", nullptr);
+        gchar *libdir = gnc_path_get_libdir ();
+        gchar *dir = g_build_filename (libdir, "dbd", nullptr);
+        g_free (libdir);
 #if HAVE_LIBDBI_R
         if (dbi_instance)
             return;
diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp
index d26f5fb6a..34f482d4c 100644
--- a/libgnucash/core-utils/gnc-filepath-utils.cpp
+++ b/libgnucash/core-utils/gnc-filepath-utils.cpp
@@ -1174,7 +1174,9 @@ gnc_build_data_path (const gchar *filename)
 gchar *
 gnc_build_scm_path (const gchar *filename)
 {
-    gchar *result = g_build_filename(gnc_path_get_scmdir(), filename, (gchar *)NULL);
+    gchar *scmdir = gnc_path_get_scmdir ();
+    gchar *result = g_build_filename (scmdir, filename, (gchar *)NULL);
+    g_free (scmdir);
     return result;
 }
 
@@ -1190,7 +1192,9 @@ gnc_build_scm_path (const gchar *filename)
 gchar *
 gnc_build_report_path (const gchar *filename)
 {
-    gchar *result = g_build_filename(gnc_path_get_reportdir(), filename, (gchar *)NULL);
+    gchar *rptdir = gnc_path_get_reportdir ();
+    gchar *result = g_build_filename (rptdir, filename, (gchar *)NULL);
+    g_free (rptdir);
     return result;
 }
 
@@ -1206,7 +1210,9 @@ gnc_build_report_path (const gchar *filename)
 gchar *
 gnc_build_reports_path (const gchar *dirname)
 {
-    gchar *result = g_build_filename(gnc_path_get_reportsdir(), dirname, (gchar *)NULL);
+    gchar *rptsdir = gnc_path_get_reportsdir ();
+    gchar *result = g_build_filename (rptsdir, dirname, (gchar *)NULL);
+    g_free (rptsdir);
     return result;
 }
 
@@ -1222,7 +1228,9 @@ gnc_build_reports_path (const gchar *dirname)
 gchar *
 gnc_build_stdreports_path (const gchar *filename)
 {
-    gchar *result = g_build_filename(gnc_path_get_stdreportsdir(), filename, (gchar *)NULL);
+    gchar *stdrptdir = gnc_path_get_stdreportsdir ();
+    gchar *result = g_build_filename (stdrptdir, filename, (gchar *)NULL);
+    g_free (stdrptdir);
     return result;
 }
 
@@ -1253,7 +1261,10 @@ gnc_filepath_locate_file (const gchar *default_path, const gchar *name)
 gchar *
 gnc_filepath_locate_data_file (const gchar *name)
 {
-    return gnc_filepath_locate_file (gnc_path_get_pkgdatadir(), name);
+    gchar *pkgdatadir = gnc_path_get_pkgdatadir ();
+    gchar *result = gnc_filepath_locate_file (pkgdatadir, name);
+    g_free (pkgdatadir);
+    return result;
 }
 
 gchar *
@@ -1289,7 +1300,10 @@ gnc_filepath_locate_ui_file (const gchar *name)
 gchar *
 gnc_filepath_locate_doc_file (const gchar *name)
 {
-    return gnc_filepath_locate_file (gnc_path_get_pkgdocdir(), name);
+    gchar *docdir = gnc_path_get_pkgdocdir ();
+    gchar *result = gnc_filepath_locate_file (docdir, name);
+    g_free (docdir);
+    return result;
 }
 
 

commit 67ecb1074f2a407c5c07dfbbf71a6509d92ba991
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Jul 30 23:16:45 2021 +0800

    [assistant-hierarchy.c] g_free data->gnc_accounts_dir
    
    because it is assigned to gnc_path_get_accountsdir() which is a *gchar
    and must be freed.

diff --git a/gnucash/gnome/assistant-hierarchy.c b/gnucash/gnome/assistant-hierarchy.c
index cc37ee085..38f540ed4 100644
--- a/gnucash/gnome/assistant-hierarchy.c
+++ b/gnucash/gnome/assistant-hierarchy.c
@@ -96,7 +96,7 @@ typedef struct
     GtkWidget   *region_combo;
     GtkWidget   *region_label;
 
-    const gchar *gnc_accounts_dir;
+    gchar *gnc_accounts_dir;
 
     GtkTreeView *categories_tree;
     GtkTreeRowReference *initial_category;
@@ -170,6 +170,8 @@ gnc_hierarchy_destroy_cb (GtkWidget *obj,   hierarchy_data *data)
         g_hash_table_destroy (hash);
         data->balance_hash = NULL;
     }
+
+    g_free (data->gnc_accounts_dir);
 }
 
 static gnc_numeric

commit a3177e8b6bbe8f85e4ded4d7048515c42c879041
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Aug 1 11:00:37 2021 +0800

    [swig] %newobject to g_free AccountList* functions

diff --git a/bindings/engine-common.i b/bindings/engine-common.i
index 52e62d383..b4d861dd6 100644
--- a/bindings/engine-common.i
+++ b/bindings/engine-common.i
@@ -36,10 +36,18 @@ static const GncGUID * gncAccountGetGUID(Account *x)
 
 %include <Split.h>
 
+%newobject gnc_account_get_children;
 AccountList * gnc_account_get_children (const Account *account);
+
+%newobject gnc_account_get_children_sorted;
 AccountList * gnc_account_get_children_sorted (const Account *account);
+
+%newobject gnc_account_get_descendants;
 AccountList * gnc_account_get_descendants (const Account *account);
+
+%newobject gnc_account_get_descendants_sorted;
 AccountList * gnc_account_get_descendants_sorted (const Account *account);
+
 %ignore gnc_account_get_children;
 %ignore gnc_account_get_children_sorted;
 %ignore gnc_account_get_descendants;

commit e0d953bfc895e1046e3f183d092717dd4c43b6dc
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Jul 30 23:16:01 2021 +0800

    [swig] %newobject to g_free gchar* functions

diff --git a/bindings/core-utils.i b/bindings/core-utils.i
index 288e5c1d6..e5cd3cf54 100644
--- a/bindings/core-utils.i
+++ b/bindings/core-utils.i
@@ -78,9 +78,16 @@ gchar * gnc_build_userdata_path(const gchar *);
 %newobject gnc_file_path_absolute;
 gchar *gnc_file_path_absolute (const gchar *, const gchar *);
 
+%newobject gnc_build_scm_path;
 gchar * gnc_build_scm_path(const gchar *);
+
+%newobject gnc_build_report_path;
 gchar * gnc_build_report_path(const gchar *);
+
+%newobject gnc_build_stdreports_path;
 gchar * gnc_build_stdreports_path(const gchar *);
+
+%newobject gnc_build_reports_path;
 gchar * gnc_build_reports_path(const gchar *);
 
 void gnc_scm_log_warn(const gchar *);
diff --git a/bindings/engine.i b/bindings/engine.i
index ef273a577..e9130a248 100644
--- a/bindings/engine.i
+++ b/bindings/engine.i
@@ -190,6 +190,8 @@ const char *qof_session_get_url (QofSession *session);
 
 %ignore qof_print_date_time_buff;
 %ignore gnc_tm_free;
+%newobject qof_print_date;
+%newobject gnc_print_time64;
 %include <gnc-date.h>
 extern const char *gnc_default_strftime_date_format;
 

commit b247c10516684b1955c7c9cbee4ae3a59c9f8874
Author: Frank H. Ellenberger <frank.h.ellenberger at gmail.com>
Date:   Mon Aug 2 09:45:30 2021 +0200

    L10N:sv: Update to PO-Revision-Date: 2021-07-26 from TP
    
    po/sv.po:15694: msgstr lacks the keyboard accelerator mark '_'
    msgfmt: found 1 fatal error
    5205 translated messages, 157 fuzzy translations.

diff --git a/po/sv.po b/po/sv.po
index 9cf85def3..78f1f9beb 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -16,7 +16,7 @@ msgstr ""
 "Project-Id-Version: gnucash 4.6-pre1\n"
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug.cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-13 14:59-0700\n"
-"PO-Revision-Date: 2021-07-17 08:57+0200\n"
+"PO-Revision-Date: 2021-07-26 14:45+0200\n"
 "Last-Translator: Arve Eriksson <031299870 at telia.com>\n"
 "Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -456,7 +456,7 @@ msgstr "Sändlistor är den form av kommunikation som föredras av GnuCashs geme
 
 #: doc/tip_of_the_day.list.c:9
 msgid "The GnuCash developers are easy to contact. As well as several mailing lists, you can chat to them live on IRC! Join them on #gnucash at irc.gnome.org"
-msgstr "Det är lätt att kontakta GnuCash-utvecklarna. Förutom ett flertal sändlistor kan du chatta med dem på IRC!. Du hittar dem på #gnucash på irc.gnome.org"
+msgstr "Det är lätt att kontakta GnuCash-utvecklarna. Förutom ett flertal sändlistor kan du chatta med dem på IRC! Du hittar dem på #gnucash på irc.gnome.org"
 
 #: doc/tip_of_the_day.list.c:13
 msgid "You can easily import your existing financial data from Quicken, MS Money or other programs that export QIF files or OFX files. In the File menu, click on the sub-menu Import and click on QIF or OFX file, respectively. Then, follow the instructions provided."
@@ -564,7 +564,7 @@ msgstr "Om du arbetar nattetid bör du stänga och öppna dina arbetsregister p
 
 #: doc/tip_of_the_day.list.c:115
 msgid "To search through all your transactions, start a search (Edit->Find...) from the main accounts hierarchy page. To limit your search to a single account, start the search from that account's register."
-msgstr "För att söka bland alla dina transaktioner, starta en sökning (Redigera-> Sök...) från huvudsidan med kontohierarkin. För att begränsa din sökning till ett enstaka konto, starta sökningen från det kontots register."
+msgstr "För att söka bland alla dina transaktioner, starta en sökning (Redigera->Sök...) från huvudsidan med kontohierarkin. För att begränsa din sökning till ett enstaka konto, starta sökningen från det kontots register."
 
 #: doc/tip_of_the_day.list.c:119
 msgid "To visually compare on screen the contents of 2 tabs, in one of the tabs, select Window->New Window with Page from the menu to duplicate that tab in a new window."
@@ -1106,11 +1106,11 @@ msgstr "Denna vara har prisuppgifter. Är du säker på att du vill ta bort den
 
 #: gnucash/gnome/dialog-commodities.c:204
 msgid "Are you sure you want to delete the selected commodity?"
-msgstr "Är du säker på att du vill ta bort varan?"
+msgstr "Är du säker på att du vill ta bort produkten?"
 
 #: gnucash/gnome/dialog-commodities.c:213
 msgid "Delete commodity?"
-msgstr "Ta bort varan?"
+msgstr "Ta bort produkten?"
 
 #: gnucash/gnome/dialog-commodities.c:217 gnucash/gnome/dialog-doclink.c:165
 #: gnucash/gnome/dialog-price-edit-db.c:206
@@ -1452,7 +1452,7 @@ msgstr "Välj dokument"
 #: gnucash/import-export/customer-import/dialog-customer-import-gui.c:386
 #: gnucash/import-export/customer-import/dialog-customer-import-gui.c:443
 msgid "_OK"
-msgstr "_Okej"
+msgstr "_OK"
 
 #: gnucash/gnome/dialog-doclink.c:238
 msgid "Amend URL:"
@@ -3162,7 +3162,7 @@ msgstr "Saldo"
 
 #: gnucash/gnome/gnc-plugin-account-tree.c:59
 msgid "New Accounts _Page"
-msgstr "Ny konto_sida"
+msgstr "_Ny kontosida"
 
 #: gnucash/gnome/gnc-plugin-account-tree.c:60
 msgid "Open a new Account Tree page"
@@ -3197,7 +3197,7 @@ msgstr "Spara nuvarande fil"
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:126
 msgid "Save _As..."
-msgstr "Spara s_om..."
+msgstr "Spara so_m..."
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:127
 msgid "Save this file with a different name"
@@ -3238,7 +3238,7 @@ msgstr "Hitta transaktioner med en sökning"
 #: gnucash/gnome/gnc-plugin-page-register2.c:263
 #: gnucash/gnome/gnc-plugin-page-register.c:372
 msgid "Ta_x Report Options"
-msgstr "Ska_tterapportinställningar"
+msgstr "Skattera_pportinställningar"
 
 #. Translators: currently implemented are
 #. US: income tax and
@@ -3444,7 +3444,7 @@ msgstr "Öppna dialogrutan för ny faktura"
 
 #: gnucash/gnome/gnc-plugin-business.c:180
 msgid "Find In_voice..."
-msgstr "Sök _faktura..."
+msgstr "Sök fa_ktura..."
 
 #: gnucash/gnome/gnc-plugin-business.c:181
 msgid "Open the Find Invoice dialog"
@@ -3522,7 +3522,7 @@ msgstr "Öppna dialogrutan Ny räkning"
 
 #: gnucash/gnome/gnc-plugin-business.c:223
 msgid "Find Bi_ll..."
-msgstr "Sök _räkning..."
+msgstr "Sök r_äkning..."
 
 #: gnucash/gnome/gnc-plugin-business.c:224
 msgid "Open the Find Bill dialog"
@@ -3586,7 +3586,7 @@ msgstr "Visa alla länkade dokument för verksamhet"
 #: gnucash/gnome/gnc-plugin-business.c:283
 #, fuzzy
 msgid "Sales _Tax Table"
-msgstr "Försäljningsskattetabell"
+msgstr "Försäljningsska_ttetabell"
 
 #: gnucash/gnome/gnc-plugin-business.c:284
 #, fuzzy
@@ -3603,7 +3603,7 @@ msgstr "Visa och redigera listan med betalningsvillkor"
 
 #: gnucash/gnome/gnc-plugin-business.c:293
 msgid "Bills _Due Reminder"
-msgstr "Påminnelse om förfallande räkningar"
+msgstr "Påminnelse om förfallan_de räkningar"
 
 #: gnucash/gnome/gnc-plugin-business.c:294
 msgid "Open the Bills Due Reminder dialog"
@@ -3611,7 +3611,7 @@ msgstr "Öppna dialogrutan Påminnelse om förfallande räkningar"
 
 #: gnucash/gnome/gnc-plugin-business.c:298
 msgid "Invoices _Due Reminder"
-msgstr "Påminnelse om förfallande fakturor"
+msgstr "Påminnelse om förfallan_de fakturor"
 
 #: gnucash/gnome/gnc-plugin-business.c:299
 msgid "Open the Invoices Due Reminder dialog"
@@ -3731,14 +3731,12 @@ msgid "Delete selected account"
 msgstr "Ta bort det valda kontot"
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:257
-#, fuzzy
 msgid "_Cascade Account Properties..."
-msgstr "Egenskaps_kaskad för konto..."
+msgstr "Egenskaper för _kaskadkonto..."
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:258
-#, fuzzy
 msgid "Cascade selected properties for account"
-msgstr "Verkställ egenskaper i kaskad för konto"
+msgstr "Verkställ valda egenskaper i kaskad för konto"
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:262
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:267
@@ -3798,7 +3796,7 @@ msgstr "Uppdatera detta fönster"
 #: gnucash/gnome/gnc-plugin-page-register2.c:357
 #: gnucash/gnome/gnc-plugin-page-register.c:475
 msgid "_Reconcile..."
-msgstr "_Stäm av..."
+msgstr "St_äm av..."
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:302
 #: gnucash/gnome/gnc-plugin-page-register2.c:358
@@ -3836,7 +3834,7 @@ msgstr "Överför pengar från ett konto till ett annat"
 #: gnucash/gnome/gnc-plugin-page-register2.c:367
 #: gnucash/gnome/gnc-plugin-page-register.c:485
 msgid "Stoc_k Split..."
-msgstr "Aktie_split..."
+msgstr "Akties_plit..."
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:317
 #: gnucash/gnome/gnc-plugin-page-register2.c:368
@@ -3886,8 +3884,9 @@ msgstr "Leta efter och reparera obalanserade transaktioner och föräldralösa d
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:342
 #: gnucash/gnome/gnc-plugin-register2.c:64
+#, fuzzy
 msgid "_Register2"
-msgstr "Öppna fönstret för att visa/redigera aktieandelar"
+msgstr "Öppna fönst_ret för att visa/redigera aktieandelar"
 
 #: gnucash/gnome/gnc-plugin-page-account-tree.c:405
 msgid "Open2"
@@ -4066,7 +4065,7 @@ msgstr "Redigera alternativen för budgeten."
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:169
 msgid "Esti_mate Budget..."
-msgstr "Gör budgetuppskattning..."
+msgstr "Gör b_udgetuppskattning..."
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:171
 msgid "Estimate a budget value for the selected accounts from past transactions."
@@ -4173,7 +4172,7 @@ msgstr "Klipp _ut"
 
 #: gnucash/gnome/gnc-plugin-page-invoice.c:130
 msgid "Copy"
-msgstr "_Kopiera"
+msgstr "Kopiera"
 
 #: gnucash/gnome/gnc-plugin-page-invoice.c:135
 #: gnucash/gnome/gnc-plugin-page-register2.c:240
@@ -5757,7 +5756,7 @@ msgstr[1] "Är du säker på att du vill ta bort %d schemalagda transaktioner?"
 #: gnucash/gnome/gnc-plugin-register2.c:57
 #: gnucash/gnome/gnc-plugin-register.c:58
 msgid "_General Journal"
-msgstr "A_llmän journal"
+msgstr "_Allmän journal"
 
 #: gnucash/gnome/gnc-plugin-register2.c:58
 msgid "Open a general journal window"
@@ -5786,7 +5785,7 @@ msgstr "Öppna fönster för allmän journal"
 
 #: gnucash/gnome/gnc-plugin-report-system.c:57
 msgid "St_yle Sheets"
-msgstr "_Stilmallar"
+msgstr "Sti_lmallar"
 
 #: gnucash/gnome/gnc-plugin-report-system.c:58
 msgid "Edit report style sheets"
@@ -6876,7 +6875,7 @@ msgstr "Vald kontotyp är inkompatibel med ett av de valda överliggande kontona
 
 #: gnucash/gnome-utils/dialog-account.c:896
 msgid "You must choose a commodity."
-msgstr "Du måste välja en vara."
+msgstr "Du måste välja en produkt."
 
 #: gnucash/gnome-utils/dialog-account.c:952
 msgid "You must enter a valid opening balance or leave it blank."
@@ -7058,11 +7057,11 @@ msgstr "%s är en reserverad produkttyp. Använd något annat."
 
 #: gnucash/gnome-utils/dialog-commodity.c:1294
 msgid "That commodity already exists."
-msgstr "Den varan finns redan."
+msgstr "Den produkten finns redan."
 
 #: gnucash/gnome-utils/dialog-commodity.c:1343
 msgid "You must enter a non-empty \"Full name\", \"Symbol/abbreviation\", and \"Type\" for the commodity."
-msgstr "Du måste ange ett \"Fullständigt namn\", en \"Symbol/förkortning\" och en \"Typ\" för varan."
+msgstr "Du måste ange ett \"Fullständigt namn\", en \"Symbol/förkortning\" och en \"Typ\" för produkten."
 
 #: gnucash/gnome-utils/dialog-doclink-utils.c:237
 #, fuzzy
@@ -7622,7 +7621,7 @@ msgstr "Spara"
 #: gnucash/gnome-utils/gnc-file.c:106
 #: gnucash/gnome-utils/gnc-main-window.c:287
 msgid "_Export"
-msgstr "_Exportera"
+msgstr "E_xportera"
 
 #: gnucash/gnome-utils/gnc-file.c:147
 msgid "All files"
@@ -7947,7 +7946,7 @@ msgstr "Tra_nsaktion"
 
 #: gnucash/gnome-utils/gnc-main-window.c:278
 msgid "_Reports"
-msgstr "_Rapporter"
+msgstr "Ra_pporter"
 
 #: gnucash/gnome-utils/gnc-main-window.c:279
 msgid "_Tools"
@@ -7971,7 +7970,7 @@ msgstr "Skriv ut den aktiva sidan"
 
 #: gnucash/gnome-utils/gnc-main-window.c:296
 msgid "Pa_ge Setup..."
-msgstr "_Ställ in..."
+msgstr "Sidinställnin_g..."
 
 #: gnucash/gnome-utils/gnc-main-window.c:297
 msgid "Specify the page size and orientation for printing"
@@ -7995,7 +7994,7 @@ msgstr "Avsluta programmet"
 
 #: gnucash/gnome-utils/gnc-main-window.c:334
 msgid "Pr_eferences"
-msgstr "In_ställningar"
+msgstr "_Inställningar"
 
 #: gnucash/gnome-utils/gnc-main-window.c:335
 msgid "Edit the global preferences of GnuCash"
@@ -8043,7 +8042,7 @@ msgstr "Flytta den aktuella sidan till ett nytt fönster."
 
 #: gnucash/gnome-utils/gnc-main-window.c:385
 msgid "Tutorial and Concepts _Guide"
-msgstr "Guidad visning och koncept"
+msgstr "_Guidad visning och koncept"
 
 #: gnucash/gnome-utils/gnc-main-window.c:386
 msgid "Open the GnuCash Tutorial"
@@ -8083,7 +8082,7 @@ msgstr "Visa/göm sammanfattningsraden i detta fönster"
 
 #: gnucash/gnome-utils/gnc-main-window.c:418
 msgid "Stat_us Bar"
-msgstr "_Statusrad"
+msgstr "S_tatusrad"
 
 #: gnucash/gnome-utils/gnc-main-window.c:419
 msgid "Show/hide the status bar on this window"
@@ -11509,7 +11508,7 @@ msgstr ""
 "\n"
 "Olika alternativ finns för att ange avdelaren såväl som ett alternativ för fast bredd. Med alternativet fast bredd, dubbelklicka på tabellen med rader som visas för att ange kolumnbredd, högerklicka sedan för att ändra vid behov.\n"
 "\n"
-"Exempel är \"FTSE\",\"RR.L\",\"21/11/2016,5.345,\"GBP\" och CURRENCY;SEK;- 2016-11-21;1.56;GBP\n"
+"Exempel är \"FTSE\",\"RR.L\",\"21/11/2016,5.345,\"GBP\" och CURRENCY;SEK;2016-11-21;1.56;DKK\n"
 "\n"
 "Det finns ett alternativ för att specificera startrad, slutrad, och ett alternativ för att hoppa över alternerande rader från startraden vilket kan användas om du har rubriktext. Det finns också ett alternativ för att skriva över befintliga priser för den dagen vid behov.\n"
 "\n"
@@ -11939,7 +11938,7 @@ msgstr ""
 "\n"
 "Klicka på \"Bakåt\" för att granska dina val.\n"
 "\n"
-"Klicka på \"Avsluta\" för att stänga dialogrutan utan att skapa några nya konton."
+"Klicka på \"Avbryt\" för att stänga dialogrutan utan att skapa några nya konton."
 
 #: gnucash/gtkbuilder/assistant-hierarchy.glade:594
 msgid "Finish Account Setup"
@@ -12259,11 +12258,11 @@ msgstr "_Välj..."
 
 #: gnucash/gtkbuilder/assistant-qif-import.glade:137
 msgid "Select a QIF file to load"
-msgstr "Välj en QIF-fil som ska läsas in"
+msgstr "Välj en QIF-fil att läsa in"
 
 #: gnucash/gtkbuilder/assistant-qif-import.glade:213
 msgid "_Start"
-msgstr "_Start:"
+msgstr "_Start"
 
 #: gnucash/gtkbuilder/assistant-qif-import.glade:283
 msgid "Load QIF files"
@@ -12780,27 +12779,22 @@ msgid "_Days in advance"
 msgstr "_Dagar innan"
 
 #: gnucash/gtkbuilder/dialog-account.glade:7
-#, fuzzy
 msgid "Cascade Account Values"
 msgstr "Kaskadkontovärden"
 
 #: gnucash/gtkbuilder/dialog-account.glade:69
-#, fuzzy
 msgid "Enable Cascading Account Color"
-msgstr "Aktivera kaskadkontofärg"
+msgstr "Aktivera färg för kaskadkonto"
 
 #: gnucash/gtkbuilder/dialog-account.glade:104
-#, fuzzy
 msgid "Enable Cascading Account Placeholder"
-msgstr "Aktivera kaskadkontoplatshållare"
+msgstr "Aktivera platshållare för kaskadkonto"
 
 #: gnucash/gtkbuilder/dialog-account.glade:129
-#, fuzzy
 msgid "Enable Cascading Account Hidden"
-msgstr "Aktivera kaskadkonto dolt"
+msgstr "Aktivera döljning av kaskadkonto"
 
 #: gnucash/gtkbuilder/dialog-account.glade:151
-#, fuzzy
 msgid "Enable the sections to Cascade"
 msgstr "Aktivera avsnitt för kaskad"
 
@@ -14705,7 +14699,7 @@ msgstr "Om det är aktivt visar GnuCash en bekräftelsefråga varje gång funkti
 #: gnucash/gtkbuilder/dialog-preferences.glade:1751
 #: gnucash/gtkbuilder/dialog-sx.glade:1234
 msgid "For"
-msgstr "För"
+msgstr "Upp till"
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:1769
 #: gnucash/gtkbuilder/dialog-sx.glade:1202
@@ -14784,7 +14778,7 @@ msgstr "Auto-c_learingströskel"
 #. Preferences->Online Banking:Generic
 #: gnucash/gtkbuilder/dialog-preferences.glade:2226
 msgid "Auto-_add threshold"
-msgstr "Autotilläggströskel"
+msgstr "_Autotilläggströskel"
 
 #. Preferences->Online Banking:Generic
 #: gnucash/gtkbuilder/dialog-preferences.glade:2240
@@ -14866,7 +14860,7 @@ msgstr "_Autohöj listor"
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:2531
 msgid "Automatically raise the list of accounts or actions during input."
-msgstr "Automatiskt höja listor för konton eller händelser vid inmatning."
+msgstr "Höj automatiskt listor för konton eller händelser vid inmatning."
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:2543
 msgid "Tab order in_cludes Transfer on Memorised Transactions"
@@ -15024,15 +15018,6 @@ msgstr "V_isa kalenderknapparna"
 msgid "_Move the selection to the blank split on expand"
 msgstr "Flytta _markering till den tomma delningen vid expandering"
 
-# Anteckningar:
-# Lägg till anteckning
-#
-# Extraherade kommentarer:
-# Register2 feature
-#
-#
-# Sökvägar:
-# gnucash/gtkbuilder/dialog-preferences.glade:3068
 #. Register2 feature
 #: gnucash/gtkbuilder/dialog-preferences.glade:3068
 msgid "_Show entered and reconciled dates on selection"
@@ -15939,7 +15924,7 @@ msgstr "Europa (31.12.2001)"
 
 #: gnucash/gtkbuilder/gnc-date-format.glade:21
 msgid "ISO (2001-12-31)"
-msgstr "ISO, Sverige (2001-12-31)"
+msgstr "ISO (2001-12-31)"
 
 #: gnucash/gtkbuilder/gnc-date-format.glade:27
 msgid "UTC - Coordinated Universal Time"
@@ -18139,7 +18124,7 @@ msgstr "Exportera transaktionerna till en CSV-fil"
 
 #: gnucash/import-export/csv-exp/gnc-plugin-csv-export.c:64
 msgid "Export A_ctive Register to CSV..."
-msgstr "Exportera a_ktivt register till CSV..."
+msgstr "Exportera _aktivt register till CSV..."
 
 #: gnucash/import-export/csv-exp/gnc-plugin-csv-export.c:66
 msgid "Export the Active Register to a CSV file"
@@ -18708,7 +18693,7 @@ msgstr ""
 
 #: gnucash/import-export/customer-import/gnc-plugin-customer-import.c:59
 msgid "Import _Customers & Vendors..."
-msgstr "Importera _kunder & leverantörer..."
+msgstr "Importera k_under & leverantörer..."
 
 #: gnucash/import-export/customer-import/gnc-plugin-customer-import.c:59
 msgid "Import Customers and Vendors from a CSV text file."
@@ -20397,11 +20382,11 @@ msgstr "Fakturanummer"
 
 #: gnucash/report/report-core.scm:211
 msgid "One of your reports has a report-guid that is a duplicate. Please check the report system, especially your saved reports, for a report with this report-guid: "
-msgstr "En av dina rapporter har en rapport-guid som är en dubblett. Kontrollera rapportsystemet, särskilt dina sparade rapporter, för att hitta en rapport med detta rapport-guid:"
+msgstr "En av dina rapporter har en rapport-guid som är en dubblett. Kontrollera rapportsystemet, särskilt dina sparade rapporter, för att hitta en rapport med detta rapport-guid: "
 
 #: gnucash/report/report-core.scm:212
 msgid "Wrong report definition: "
-msgstr "Fel rapportdefinition:"
+msgstr "Fel rapportdefinition: "
 
 #: gnucash/report/report-core.scm:213
 msgid " Report is missing a GUID."
@@ -21388,7 +21373,7 @@ msgstr "Närmast rapportdatum"
 
 #: gnucash/report/reports/locale-specific/us/taxtxf.scm:3326
 msgid "Tax Schedule Report & TXF Export"
-msgstr "Skattschemarapport & TXF-export"
+msgstr "Skattsc_hemarapport & TXF-export"
 
 #: gnucash/report/reports/locale-specific/us/taxtxf.scm:3328
 msgid "Taxable Income/Deductible Expenses with Transaction Detail/Export to .TXF file"
@@ -24950,7 +24935,7 @@ msgstr "Belopp att betala (inkl MOMS)"
 
 #: gnucash/report/reports/standard/taxinvoice.scm:314
 msgid "Invoice #: "
-msgstr "Faktura #:"
+msgstr "Faktura #: "
 
 #: gnucash/report/reports/standard/taxinvoice.scm:315
 msgid "Reference: "
@@ -25146,7 +25131,7 @@ msgstr "Den här rapporten är utformad endast för kundfakturor (försäljning)
 
 #: gnucash/report/reports/support/taxinvoice.eguile.scm:193
 msgid "Website"
-msgstr "Webbadress"
+msgstr "Webbplats"
 
 #: gnucash/report/reports/support/taxinvoice.eguile.scm:229
 msgid "Invoice Date"
@@ -25769,7 +25754,7 @@ msgstr ""
 #: gnucash/report/trep-engine.scm:587
 #, fuzzy
 msgid "By default the transaction filter will search substring only. Set this to true to enable full POSIX regular expressions capabilities. '#work|#family' will match both tags within description, notes or memo. "
-msgstr "Som standard kommer transaktionsfiltret endast att söka på substrängar. Sätt detta till true för att aktivera fullständig funktionalitet för POSIX-regeluttryck. \"#arbete|#familj\" kommer att matcha båda taggar i beskrivning, anteckningar eller minnesanteckning."
+msgstr "Som standard kommer transaktionsfiltret endast att söka på substrängar. Sätt detta till true för att aktivera fullständig funktionalitet för POSIX-regeluttryck. \"#arbete|#familj\" kommer att matcha båda taggar i beskrivning, anteckningar eller minnesanteckning. "
 
 #: gnucash/report/trep-engine.scm:596
 msgid "If this option is selected, transactions matching filter are excluded."

commit 3ed6b4dab9d8635c4e7616e2c135af683e29f768
Author: Steven Walter <stevenrwalter at gmail.com>
Date:   Sun Aug 1 22:17:41 2021 -0400

    latex_invoices.py: write takes string not bytes
    
    write() fails if you give it bytes, so don't encode

diff --git a/bindings/python/example_scripts/latex_invoices.py b/bindings/python/example_scripts/latex_invoices.py
index 84fd5d216..f494fb131 100644
--- a/bindings/python/example_scripts/latex_invoices.py
+++ b/bindings/python/example_scripts/latex_invoices.py
@@ -160,7 +160,7 @@ def invoice_to_lco(invoice):
         n = ent.GetQuantity()
 
         uprice = locale.currency(price).rstrip(" EUR")
-        un = unicode(
+        un = str(
             int(float(n.num()) / n.denom())
         )  # choose best way to format numbers according to locale
 
@@ -288,7 +288,6 @@ def main(argv=None):
 
         # Opening output file
         f = open(output_file_name, "w")
-        lco_str = lco_str.encode("latin1")
         f.write(lco_str)
         f.close()
 

commit ba4852a9da5912af5441facc7c7e5e7684332c2c
Author: Steven Walter <stevenrwalter at gmail.com>
Date:   Sun Aug 1 22:17:11 2021 -0400

    latex_invoices.py: use default locale
    
    Don't hardcode a locale.  Empty string means to use the user's locale
    (e.g. $LANG)

diff --git a/bindings/python/example_scripts/latex_invoices.py b/bindings/python/example_scripts/latex_invoices.py
index 52755da3d..84fd5d216 100644
--- a/bindings/python/example_scripts/latex_invoices.py
+++ b/bindings/python/example_scripts/latex_invoices.py
@@ -147,7 +147,7 @@ def invoice_to_lco(invoice):
 
     # Write the entries
     ent_str = u""
-    locale.setlocale(locale.LC_ALL, "de_DE")
+    locale.setlocale(locale.LC_ALL, "")
     for n, ent in enumerate(invoice.GetEntries()):
 
         line_str = u""

commit ad3895fa07a6c7cd8ce1d16d88dbeef6e5fc6cff
Author: Steven Walter <stevenrwalter at gmail.com>
Date:   Sun Aug 1 22:16:33 2021 -0400

    latex_invoices.py: don't decode() a str
    
    These functions all return str's not bytes.  Therefore there is no need
    to decode them.

diff --git a/bindings/python/example_scripts/latex_invoices.py b/bindings/python/example_scripts/latex_invoices.py
index 829021adf..52755da3d 100644
--- a/bindings/python/example_scripts/latex_invoices.py
+++ b/bindings/python/example_scripts/latex_invoices.py
@@ -115,19 +115,19 @@ def invoice_to_lco(invoice):
     add_str = u""
     owner = invoice.GetOwner()
     if owner.GetName() != "":
-        add_str += owner.GetName().decode("UTF-8") + "\n"
+        add_str += owner.GetName() + "\n"
 
     addr = owner.GetAddr()
     if addr.GetName() != "":
-        add_str += addr.GetName().decode("UTF-8") + "\n"
+        add_str += addr.GetName() + "\n"
     if addr.GetAddr1() != "":
-        add_str += addr.GetAddr1().decode("UTF-8") + "\n"
+        add_str += addr.GetAddr1() + "\n"
     if addr.GetAddr2() != "":
-        add_str += addr.GetAddr2().decode("UTF-8") + "\n"
+        add_str += addr.GetAddr2() + "\n"
     if addr.GetAddr3() != "":
-        add_str += addr.GetAddr3().decode("UTF-8") + "\n"
+        add_str += addr.GetAddr3() + "\n"
     if addr.GetAddr4() != "":
-        add_str += addr.GetAddr4().decode("UTF-8") + "\n"
+        add_str += addr.GetAddr4() + "\n"
 
     lco_out += write_variable("toaddress2", add_str)
 
@@ -167,7 +167,7 @@ def invoice_to_lco(invoice):
         line_str = u"\Artikel{"
         line_str += un
         line_str += u"}{"
-        line_str += descr.decode("UTF-8")
+        line_str += descr
         line_str += u"}{"
         line_str += uprice
         line_str += u"}"

commit c789b0c141d8d4bcf35d5c87c4048001c290eced
Author: TianXing_Yi <ytx.cash at gmail.com>
Date:   Sun Aug 1 13:33:01 2021 +0200

    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5350 of 5364 strings; 1 fuzzy)
    1 failing checks (0.1%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5351 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Co-authored-by: TianXing_Yi <ytx.cash at gmail.com>

diff --git a/po/zh_CN.po b/po/zh_CN.po
index 995d78a68..a624dbc42 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -23,7 +23,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-07-29 10:33+0000\n"
+"PO-Revision-Date: 2021-08-01 11:33+0000\n"
 "Last-Translator: TianXing_Yi <ytx.cash at gmail.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "gnucash/gnucash/zh_Hans/>\n"
@@ -32,7 +32,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.7.2-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
 "X-Bugs: Report translation errors to the Language-Team address.\n"
 
 #: bindings/guile/commodity-table.scm:44
@@ -2561,13 +2561,13 @@ msgstr "等级"
 #: gnucash/gnome/dialog-job.c:587 gnucash/gnome-utils/gnc-tree-view-owner.c:357
 #: gnucash/gtkbuilder/dialog-job.glade:102
 msgid "Job Number"
-msgstr "项目编号"
+msgstr "编号"
 
 #: gnucash/gnome/dialog-job.c:589 gnucash/gnome/dialog-job.c:602
 #: gnucash/gnome-utils/gnc-tree-view-owner.c:356
 #: gnucash/gtkbuilder/dialog-job.glade:115
 msgid "Job Name"
-msgstr "项目名称"
+msgstr "名称"
 
 #: gnucash/gnome/dialog-job.c:653
 msgid "Find Job"
@@ -3142,7 +3142,7 @@ msgstr "提醒"
 #: gnucash/gnome/dialog-sx-since-last-run.c:405
 #: gnucash/gnome/gnc-plugin-budget.c:168
 msgid "Created"
-msgstr "已创建"
+msgstr "创建日期"
 
 #: gnucash/gnome/dialog-sx-since-last-run.c:468
 #: gnucash/gtkbuilder/dialog-preferences.glade:1733
@@ -3422,7 +3422,7 @@ msgstr "计划交易(_S)"
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:166
 msgid "_Scheduled Transaction Editor"
-msgstr "编辑器(_S)"
+msgstr "编辑(_S)"
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:167
 msgid "The list of Scheduled Transactions"
@@ -3430,7 +3430,7 @@ msgstr "计划交易列表"
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:171
 msgid "Since _Last Run..."
-msgstr "自上次运行后(_L)..."
+msgstr "自上次运行(_L)..."
 
 #: gnucash/gnome/gnc-plugin-basic-commands.c:172
 msgid "Create Scheduled Transactions since the last time run"
@@ -3565,7 +3565,7 @@ msgstr "删除一个已有的预算。"
 
 #: gnucash/gnome/gnc-plugin-budget.c:288
 msgid "Select a Budget"
-msgstr "选择一个预算"
+msgstr "预算"
 
 #: gnucash/gnome/gnc-plugin-business.c:155
 #: gnucash/gnome/gnc-plugin-business.c:305 gnucash/report/report-core.scm:164
@@ -3753,7 +3753,7 @@ msgstr "查看所有商业关联的凭证"
 
 #: gnucash/gnome/gnc-plugin-business.c:283
 msgid "Sales _Tax Table"
-msgstr "税率表(_T)"
+msgstr "税率(_T)"
 
 #: gnucash/gnome/gnc-plugin-business.c:284
 msgid "View and edit the list of Sales Tax Tables (GST/VAT)"
@@ -3761,7 +3761,7 @@ msgstr "查看并编辑税率表(消费税/增值税)"
 
 #: gnucash/gnome/gnc-plugin-business.c:288
 msgid "_Billing Terms Editor"
-msgstr "账期编辑器(_B)"
+msgstr "账期(_B)"
 
 #: gnucash/gnome/gnc-plugin-business.c:289
 msgid "View and edit the list of Billing Terms"
@@ -4226,7 +4226,7 @@ msgstr "预算选项(_O)..."
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:165
 msgid "Edit this budget's options."
-msgstr "编辑该预算选项。"
+msgstr "编辑此预算。"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:169
 msgid "Esti_mate Budget..."
@@ -4239,7 +4239,7 @@ msgstr "从过去的交易估计选定科目的预算。"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:175
 msgid "_All Periods..."
-msgstr "所有会计期间(_A)..."
+msgstr "期间预算(_A)..."
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:177
 msgid "Edit budget for all periods for the selected accounts."
@@ -4247,7 +4247,7 @@ msgstr "编辑选定科目所有会计期间的预算。"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:181
 msgid "Edit Note"
-msgstr "信用凭证"
+msgstr "预算说明"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:183
 msgid "Edit note for the selected account and period."
@@ -4280,7 +4280,7 @@ msgstr "评估"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:224
 msgid "All Periods"
-msgstr "会计期间"
+msgstr "期间"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:225
 msgid "Note"
@@ -4313,15 +4313,15 @@ msgstr "删除 %s?"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:1028
 msgid "You must select at least one account to estimate."
-msgstr "您必须至少选择一个科目来评估。"
+msgstr "请选择需要评估的科目。"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:1154
 msgid "You must select at least one account to edit."
-msgstr "您必须至少选择一个科目来评估。"
+msgstr "请选择需要编辑的科目。"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:1252
 msgid "You must select one budget cell to edit."
-msgstr "您必须至少选择一个科目来评估。"
+msgstr "请选择需要编辑的预算单元。"
 
 #: gnucash/gnome/gnc-plugin-page-invoice.c:109
 msgid "Sort _Order"
@@ -6383,7 +6383,7 @@ msgstr "财务管理"
 #: gnucash/register/ledger-core/split-register-model.c:312
 msgctxt "Column header for 'Reconciled'"
 msgid "R"
-msgstr "核实"
+msgstr "R"
 
 #: gnucash/gnome/report-menus.scm:57
 #, scheme-format
@@ -6460,7 +6460,7 @@ msgstr "商业"
 
 #: gnucash/gnome/window-autoclear.c:115
 msgid "Cleared Transactions"
-msgstr "已创建的交易事项"
+msgstr "已核实交易"
 
 #: gnucash/gnome/window-reconcile2.c:428 gnucash/gnome/window-reconcile.c:469
 msgid "Interest Payment"
@@ -6520,7 +6520,7 @@ msgstr "期初余额"
 
 #: gnucash/gnome/window-reconcile2.c:1804 gnucash/gnome/window-reconcile.c:1997
 msgid "Ending Balance"
-msgstr "期末余额"
+msgstr "余额"
 
 #: gnucash/gnome/window-reconcile2.c:1814 gnucash/gnome/window-reconcile.c:2007
 msgid "Reconciled Balance"
@@ -7493,7 +7493,7 @@ msgstr "取消选择选中的和未选中的所有科目。"
 
 #: gnucash/gnome-utils/dialog-options.c:1506
 msgid "Select Children"
-msgstr "选择所有子科目"
+msgstr "所有子科目"
 
 #: gnucash/gnome-utils/dialog-options.c:1508
 msgid "Select all descendents of selected account."
@@ -7502,7 +7502,7 @@ msgstr "选择选中科目的所有子科目。"
 #: gnucash/gnome-utils/dialog-options.c:1514
 #: gnucash/gnome-utils/dialog-options.c:1650
 msgid "Select Default"
-msgstr "选择默认值"
+msgstr "默认值"
 
 #: gnucash/gnome-utils/dialog-options.c:1516
 msgid "Select the default account selection."
@@ -9624,7 +9624,7 @@ msgstr "资金支出"
 #: gnucash/gnome-utils/gnc-tree-view-split-reg.c:3015
 #: gnucash/register/ledger-core/split-register-model.c:505
 msgid "Credit Formula"
-msgstr "贷方公式"
+msgstr "è´·æ–¹"
 
 #: gnucash/gnome-utils/gnc-tree-view-split-reg.c:3036
 #: gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp:71
@@ -9658,7 +9658,7 @@ msgstr "资金收入"
 #: gnucash/gnome-utils/gnc-tree-view-split-reg.c:3096
 #: gnucash/register/ledger-core/split-register-model.c:498
 msgid "Debit Formula"
-msgstr "借方公式"
+msgstr "借方"
 
 #: gnucash/gnome-utils/gnc-tree-view-split-reg.c:3166
 msgid "Enter Due Date"
@@ -9753,12 +9753,12 @@ msgstr "输入有效股份价格"
 #: gnucash/gnome-utils/gnc-tree-view-split-reg.c:3324
 #: gnucash/register/ledger-core/split-register-model.c:2389
 msgid "Enter credit formula for real transaction"
-msgstr "输入实际交易事项的贷方公式"
+msgstr "输入实际交易的贷方数值"
 
 #: gnucash/gnome-utils/gnc-tree-view-split-reg.c:3334
 #: gnucash/register/ledger-core/split-register-model.c:2355
 msgid "Enter debit formula for real transaction"
-msgstr "输入实际交易事项的借方公式"
+msgstr "输入实际交易的借方数值"
 
 #: gnucash/gnome-utils/gnc-tree-view-sx-list.c:140
 #: gnucash/gtkbuilder/dialog-sx.glade:1064
@@ -9971,7 +9971,7 @@ msgstr ""
 
 #: gnucash/gnucash-core-app.cpp:344
 msgid "Hidden Options"
-msgstr "预算选项"
+msgstr "隐藏选项"
 
 #: gnucash/gnucash-core-app.cpp:347
 msgid "[datafile]"
@@ -13002,7 +13002,7 @@ msgid ""
 "Select language and region specific categories that correspond to the ways "
 "that you foresee you will use GnuCash. Each category you select will cause "
 "several accounts to be created."
-msgstr "选择程序的区域和语言,这将创建一些相应的科目。"
+msgstr "设置程序的区域和语种,还可选择一些内置的科目树模板。"
 
 #: gnucash/gtkbuilder/assistant-hierarchy.glade:169
 msgid "<b>Categories</b>"
@@ -14872,7 +14872,7 @@ msgid ""
 "Currently you have no saved reports.\n"
 msgstr ""
 "\n"
-"现在没有保留的形式。\n"
+"目前尚无保存的模板。\n"
 
 #: gnucash/gtkbuilder/dialog-custom-report.glade:113
 msgid ""
@@ -14882,8 +14882,8 @@ msgid ""
 "Configuration\" from\n"
 "the Reports menu or tool bar."
 msgstr ""
-"保存报表模板:首先打开一个报表,\n"
-"调整报表选项,然后从报表菜单或工具栏中选择\n"
+"保存模板:首先打开一个报表,\n"
+"调整选项,然后从菜单或工具栏中执行\n"
 "\"保存模板\"。"
 
 #: gnucash/gtkbuilder/dialog-date-close.glade:7
@@ -16335,11 +16335,11 @@ msgstr "<b>对账</b>"
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:2584
 msgid "Check cleared _transactions"
-msgstr "检查已核实交易(_T)"
+msgstr "标记已核实交易(_T)"
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:2590
 msgid "Pre-check cleared transactions when creating a reconcile dialog."
-msgstr "创建对账对话框时,预先检查已核实的交易。"
+msgstr "对账时,预先标记已核实的交易。"
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:2602
 msgid "Automatic credit card _payment"
@@ -17268,11 +17268,11 @@ msgstr "模板"
 
 #: gnucash/gtkbuilder/dialog-sx.glade:1454
 msgid "Since Last Run..."
-msgstr "自上次运行后..."
+msgstr "自上次运行..."
 
 #: gnucash/gtkbuilder/dialog-sx.glade:1554
 msgid "_Review created transactions"
-msgstr "核实已创建交易(_R)"
+msgstr "复核已创建交易(_R)"
 
 #: gnucash/gtkbuilder/dialog-tax-info.glade:13
 msgid "Income Tax Information"
@@ -17329,7 +17329,7 @@ msgstr "<b>副本号</b>"
 #: gnucash/gtkbuilder/dialog-tax-table.glade:7
 #: gnucash/gtkbuilder/dialog-tax-table.glade:31
 msgid "Tax Tables"
-msgstr "税率表"
+msgstr "税率"
 
 #: gnucash/gtkbuilder/dialog-tax-table.glade:143
 msgid "<b>Tax Table Entries</b>"
@@ -17946,21 +17946,21 @@ msgstr "在"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:15
 msgid "Edit budget for all periods"
-msgstr "预算期间"
+msgstr "期间"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:116
 msgid "Replace"
-msgstr "代替"
+msgstr "替换"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:120
 msgid ""
 "Replace the budget for all periods with new 'value'. Use empty value to "
 "unset budget for the accounts."
-msgstr "用新的“值”替换整个时期的预算。空值才能取消禁止此帐户的预算。"
+msgstr "新值替换全部期间预算,空值取消此科目的预算。"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:133
 msgid "Add"
-msgstr "添加"
+msgstr "相加"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:137
 msgid "Add 'value' to current budget for each period"
@@ -17968,16 +17968,16 @@ msgstr "为每个时期添加“值”到当前预算"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:151
 msgid "Multiply"
-msgstr "多行"
+msgstr "相乘"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:155
 msgid "Multiply current budget for each period by 'value'"
-msgstr "每个时期的当前预算乘以 \"价值\""
+msgstr "新值和期间预算的每一个值相乘"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:177
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:316
 msgid "The number of leading digits to keep when rounding"
-msgstr "当四舍五入的时候保留前几位"
+msgstr "四舍五入的时候保留的小数位数"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:196
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:334
@@ -17986,21 +17986,21 @@ msgstr "有效数字"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:208
 msgid "Use a fixed value or apply transformation for all periods."
-msgstr "对所有的时期使用一个固定的值,或者进行转换。"
+msgstr "所有期间预算,使用定值替换或转换。"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:240
 msgid "Estimate Budget Values"
-msgstr "估计预算值"
+msgstr "评估"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:303
 msgid "Use the average value over all actual periods for all projected periods"
-msgstr "对所有预测期使用所有实际期的平均值"
+msgstr "所有期间预算使用实际期间的平均值"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:372
 msgid ""
 "GnuCash will estimate budget values for the selected accounts from past "
 "transactions."
-msgstr "GnuCash 将从过去的交易事项中对选中的科目进行评估预算价格。"
+msgstr "GnuCash 将从选中科目、过去的交易,估计预算。"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:389
 msgid "Use Average"
@@ -18009,11 +18009,11 @@ msgstr "均值"
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:422
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:683
 msgid "Budget Options"
-msgstr "预算选项"
+msgstr "选项"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:488
 msgid "Budget Name"
-msgstr "预算名称"
+msgstr "名称"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:552
 msgid "Number of Periods"
@@ -18021,21 +18021,21 @@ msgstr "期数"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:582
 msgid "Budget Period"
-msgstr "预算期间"
+msgstr "期间"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:634
 #: gnucash/report/reports/standard/general-ledger.scm:126
 #: gnucash/report/trep-engine.scm:83 gnucash/report/trep-engine.scm:1074
 msgid "Show Account Code"
-msgstr "显示科目编码"
+msgstr "编码"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:658
 msgid "Show Description"
-msgstr "显示描述"
+msgstr "描述"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:700
 msgid "Note: Use View->'Filter By...' to control visible accounts."
-msgstr "注意:使用“查看”->“筛选依据...”来控制可见帐户。"
+msgstr "注意:使用\"查看 -> 筛选... -> 其他\"显示隐藏科目。"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:721
 msgid "Budget List"
@@ -18244,11 +18244,11 @@ msgstr "天"
 
 #: gnucash/gtkbuilder/gnc-recurrence.glade:15
 msgid "week(s)"
-msgstr "周(次)"
+msgstr "周"
 
 #: gnucash/gtkbuilder/gnc-recurrence.glade:18
 msgid "month(s)"
-msgstr "月( )"
+msgstr "月"
 
 #: gnucash/gtkbuilder/gnc-recurrence.glade:21
 msgid "year(s)"
@@ -18262,11 +18262,11 @@ msgstr "每 "
 msgid ""
 "Number of calendar units in the recurrence: E.g. Biweekly = every 2 weeks; "
 "Quarterly = every 3 months"
-msgstr "重复的日历单位的数量:如,每两周的 = 每 2 周;季度的 = 每 3 月"
+msgstr "日历单位换算:例如,每两周 = 每 2 周;季度 = 每 3 月"
 
 #: gnucash/gtkbuilder/gnc-recurrence.glade:109
 msgid "beginning on"
-msgstr "开始于"
+msgstr "开始"
 
 #: gnucash/gtkbuilder/gnc-recurrence.glade:144
 msgid "last of month"
@@ -18278,13 +18278,13 @@ msgstr "总是使用月内最后一天(或星期的最后一天)?"
 
 #: gnucash/gtkbuilder/gnc-recurrence.glade:160
 msgid "same week & day"
-msgstr "相同的周和日子"
+msgstr "同周同天"
 
 #: gnucash/gtkbuilder/gnc-recurrence.glade:164
 msgid ""
 "Match the \"day of week\" and \"week of month\"? (for example, the \"second "
 "Tuesday\" of every month)"
-msgstr "匹配“星期几”和“月内第几周”?(例如,每月的“星期二”)"
+msgstr "匹配“星期几”和“月内第几周”,(例如,每月的“星期二”)"
 
 #: gnucash/gtkbuilder/gnc-tree-view-owner.glade:62
 msgid "Only show _active owners"
@@ -18296,29 +18296,25 @@ msgstr "显示零余额的所有者(_Z)"
 
 #: gnucash/gtkbuilder/window-autoclear.glade:71
 msgid "About Auto-Clear"
-msgstr "关于自动核实"
+msgstr "介绍"
 
 #: gnucash/gtkbuilder/window-autoclear.glade:86
 msgid ""
 "Use this dialog if you want GnuCash to automatically find which transactions "
 "are cleared, given an ending balance. For example, said ending balance can "
 "be the current balance given by your bank online."
-msgstr ""
-"如果使用此对话框,GNucash会自动查找在本财政年度结束时清除的交易。例如,这里规"
-"定的术语的余额可能是网上银行的当前余额。"
+msgstr "如果希望 GnuCash 在给定余额的情况下自动核实交易,请使用此功能。例如,所述期末余额可以是网银的当前余额。"
 
 #: gnucash/gtkbuilder/window-autoclear.glade:101
 msgid "Caution!"
-msgstr "警告!"
+msgstr "注意!"
 
 #: gnucash/gtkbuilder/window-autoclear.glade:116
 msgid ""
 "This tool might be slow or abort if the number of uncleared splits is more "
 "than approximately 20. In that case please clear at least some of them "
 "manually."
-msgstr ""
-"如果不清楚的分裂约为20或更多,该工具可能会慢或停止。那时,手动拍摄至少一部"
-"分。"
+msgstr "如果科目未核实的交易数量大于 20,此功能可能会变慢或中止,这种情况下,请先手动核实一部分。"
 
 #: gnucash/gtkbuilder/window-autoclear.glade:138
 #: gnucash/gtkbuilder/window-reconcile.glade:117
@@ -18327,11 +18323,11 @@ msgstr "期末余额(_E)"
 
 #: gnucash/gtkbuilder/window-autoclear.glade:177
 msgid "_Review cleared splits"
-msgstr "复查已核实分录(_R)"
+msgstr "复查已核实交易(_R)"
 
 #: gnucash/gtkbuilder/window-autoclear.glade:181
 msgid "Select this option to open a register tab with newly cleared splits."
-msgstr "选择此选项可打开新清除的拆分录制输出选项卡。"
+msgstr "新标签页显示已核实交易。"
 
 #: gnucash/gtkbuilder/window-reconcile.glade:71
 msgid "<b>Reconcile Information</b>"
@@ -21561,7 +21557,7 @@ msgstr "交易的描述"
 #: gnucash/report/trep-engine.scm:1237 gnucash/report/trep-engine.scm:1238
 msgctxt "Column header for 'Document Link'"
 msgid "L"
-msgstr "中继"
+msgstr "L"
 
 #: gnucash/register/ledger-core/split-register-layout.c:711
 #: gnucash/register/ledger-core/split-register-layout.c:751
@@ -21655,7 +21651,7 @@ msgstr "%s 已对账"
 
 #: gnucash/register/ledger-core/split-register-model.c:1017
 msgid "Scheduled"
-msgstr "交易计划"
+msgstr "计划"
 
 #: gnucash/register/ledger-core/split-register-model.c:1066
 msgid ""
@@ -22211,7 +22207,7 @@ msgstr "排序"
 #: gnucash/report/reports/standard/customer-summary.scm:77
 #: gnucash/report/reports/standard/new-aging.scm:41
 msgid "Sort Order"
-msgstr "顺序"
+msgstr "方式"
 
 #: gnucash/report/reports/aging.scm:40
 #: gnucash/report/reports/example/average-balance.scm:43
@@ -22272,14 +22268,14 @@ msgstr "显示多种货币合计"
 #: gnucash/report/reports/aging.scm:43
 #: gnucash/report/reports/standard/new-aging.scm:42
 msgid "Show zero balance items"
-msgstr "显示零余额条目"
+msgstr "显示余额为零的科目"
 
 #: gnucash/report/reports/aging.scm:44
 #: gnucash/report/reports/standard/new-aging.scm:43
 #: gnucash/report/reports/standard/new-owner-report.scm:46
 #: gnucash/report/reports/standard/owner-report.scm:41
 msgid "Due or Post Date"
-msgstr "入账日期"
+msgstr "日期"
 
 #: gnucash/report/reports/aging.scm:47
 #: gnucash/report/reports/standard/new-aging.scm:46
@@ -22326,6 +22322,7 @@ msgstr "欠款总额"
 
 #: gnucash/report/reports/aging.scm:350
 #: gnucash/report/reports/standard/new-aging.scm:97
+#, fuzzy
 msgid "Bracket Total Owed"
 msgstr "把总欠款归为一类"
 
@@ -22623,7 +22620,7 @@ msgstr "显示以星期几区分的支出合计饼图"
 #: gnucash/report/reports/standard/income-statement.scm:64
 #: gnucash/report/reports/standard/trial-balance.scm:79
 msgid "Levels of Subaccounts"
-msgstr "子科目层数"
+msgstr "深度"
 
 #: gnucash/report/reports/example/daily-reports.scm:61
 #: gnucash/report/reports/standard/account-piecharts.scm:74
@@ -23473,7 +23470,7 @@ msgstr "父科目小计"
 #: gnucash/report/reports/standard/income-statement.scm:74
 #: gnucash/report/reports/standard/trial-balance.scm:121
 msgid "Include accounts with zero total balances"
-msgstr "包含零余额科目"
+msgstr "包含余额为零科目"
 
 #: gnucash/report/reports/standard/account-summary.scm:105
 #: gnucash/report/reports/standard/balance-sheet.scm:101
@@ -24472,7 +24469,7 @@ msgstr "费用类型"
 #: gnucash/report/reports/standard/budget-income-statement.scm:66
 #: gnucash/report/reports/standard/budget.scm:70
 msgid "Range start"
-msgstr "范围开始"
+msgstr "开始"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:52
 #: gnucash/report/reports/standard/budget.scm:72
@@ -24482,7 +24479,7 @@ msgstr "悬在报表范围结束时的预算期间。"
 #: gnucash/report/reports/standard/budget-barchart.scm:53
 #: gnucash/report/reports/standard/budget.scm:73
 msgid "Exact start period"
-msgstr "确切的开始时间"
+msgstr "确切的始期"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:55
 #: gnucash/report/reports/standard/budget.scm:75
@@ -24493,7 +24490,7 @@ msgstr "悬在报表范围结束时的预算期间。"
 #: gnucash/report/reports/standard/budget-income-statement.scm:70
 #: gnucash/report/reports/standard/budget.scm:77
 msgid "Range end"
-msgstr "范围结束"
+msgstr "结束"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:59
 #: gnucash/report/reports/standard/budget.scm:79
@@ -24503,7 +24500,7 @@ msgstr "悬在报表范围结束时的预算期间。"
 #: gnucash/report/reports/standard/budget-barchart.scm:60
 #: gnucash/report/reports/standard/budget.scm:80
 msgid "Exact end period"
-msgstr "付款期间"
+msgstr "确切的止期"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:62
 #: gnucash/report/reports/standard/budget.scm:82
@@ -24513,32 +24510,32 @@ msgstr "悬在报表范围结束时的预算期间。"
 #: gnucash/report/reports/standard/budget-barchart.scm:65
 #: gnucash/report/reports/standard/budget.scm:111
 msgid "First budget period"
-msgstr "首个预算周期"
+msgstr "第一个预算期间"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:66
 #: gnucash/report/reports/standard/budget.scm:112
 msgid "Previous budget period"
-msgstr "上个预算周期"
+msgstr "前一个预算期间"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:67
 #: gnucash/report/reports/standard/budget.scm:113
 msgid "Current budget period"
-msgstr "当前预算周期"
+msgstr "当前预算期间"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:68
 #: gnucash/report/reports/standard/budget.scm:114
 msgid "Next budget period"
-msgstr "下个预算周期"
+msgstr "下一个预算期间"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:69
 #: gnucash/report/reports/standard/budget.scm:115
 msgid "Last budget period"
-msgstr "预算期间"
+msgstr "最后一个预算期间"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:70
 #: gnucash/report/reports/standard/budget.scm:116
 msgid "Manual period selection"
-msgstr "手动选择周期"
+msgstr "自定义"
 
 #: gnucash/report/reports/standard/budget-barchart.scm:136
 msgid "Calculate as running sum?"
@@ -24585,7 +24582,7 @@ msgstr "~a:~a - ~a"
 #: gnucash/report/reports/standard/budget-income-statement.scm:62
 #: gnucash/report/reports/standard/budget.scm:66
 msgid "Report for range of budget periods"
-msgstr "一个预算期间的范围的报表"
+msgstr "自定义预算期间"
 
 #: gnucash/report/reports/standard/budget-income-statement.scm:64
 #: gnucash/report/reports/standard/budget.scm:68
@@ -24719,7 +24716,7 @@ msgstr "损益"
 #: gnucash/report/reports/standard/budget.scm:45
 #: gnucash/report/reports/standard/cash-flow.scm:45
 msgid "Account Display Depth"
-msgstr "科目显示深度"
+msgstr "深度"
 
 #: gnucash/report/reports/standard/budget.scm:46
 #: gnucash/report/reports/standard/cash-flow.scm:46
@@ -24728,7 +24725,7 @@ msgstr "始终显示子科目"
 
 #: gnucash/report/reports/standard/budget.scm:49
 msgid "Show Budget"
-msgstr "显示预算"
+msgstr "预算"
 
 #: gnucash/report/reports/standard/budget.scm:50
 msgid "Display a column for the budget values."
@@ -24736,7 +24733,7 @@ msgstr "显示一列预算值。"
 
 #: gnucash/report/reports/standard/budget.scm:51
 msgid "Show Budget Notes"
-msgstr "显示预算"
+msgstr "预算说明"
 
 #: gnucash/report/reports/standard/budget.scm:52
 msgid "Display a column for the budget notes."
@@ -24744,7 +24741,7 @@ msgstr "显示一个预算说明的栏目。"
 
 #: gnucash/report/reports/standard/budget.scm:53
 msgid "Show Actual"
-msgstr "显示实际"
+msgstr "实际"
 
 #: gnucash/report/reports/standard/budget.scm:54
 msgid "Display a column for the actual values."
@@ -24752,7 +24749,7 @@ msgstr "显示一列实际值。"
 
 #: gnucash/report/reports/standard/budget.scm:55
 msgid "Show Difference"
-msgstr "显示差额"
+msgstr "差额"
 
 #: gnucash/report/reports/standard/budget.scm:56
 msgid "Display the difference as budget - actual."
@@ -24760,15 +24757,15 @@ msgstr "将差额显示为预算-实际。"
 
 #: gnucash/report/reports/standard/budget.scm:57
 msgid "Use accumulated amounts"
-msgstr "使用累计金额"
+msgstr "累计数值"
 
 #: gnucash/report/reports/standard/budget.scm:58
 msgid "Values are accumulated across periods."
-msgstr "数值是跨期累积的。"
+msgstr "跨期累计数值。"
 
 #: gnucash/report/reports/standard/budget.scm:59
 msgid "Show Column with Totals"
-msgstr "显示带合计的列"
+msgstr "合计列"
 
 #: gnucash/report/reports/standard/budget.scm:60
 msgid "Display a column with the row totals."
@@ -24776,13 +24773,13 @@ msgstr "显示一列行的总数。"
 
 #: gnucash/report/reports/standard/budget.scm:61
 msgid "Include accounts with zero total balances and budget values"
-msgstr "包括余额合计和预算为零的科目"
+msgstr "余额和预算为零的科目"
 
 #: gnucash/report/reports/standard/budget.scm:62
 msgid ""
 "Include accounts with zero total (recursive) balances and budget values in "
 "this report."
-msgstr "在此报告中包括总余额(递归)为零的账户和预算值。"
+msgstr "此报表包含余额和预算为零的科目。"
 
 #: gnucash/report/reports/standard/budget.scm:84
 msgid "Include collapsed periods before selected."
@@ -24818,7 +24815,7 @@ msgstr "实际"
 #. Translators: Abbreviation for "Difference" amount
 #: gnucash/report/reports/standard/budget.scm:534
 msgid "Diff"
-msgstr "比较"
+msgstr "差额"
 
 #. Translators: using accumulated amounts mean
 #. budget will report on budgeted and actual
@@ -26101,7 +26098,7 @@ msgstr "联络"
 #: gnucash/report/reports/standard/new-aging.scm:405
 #: gnucash/report/reports/standard/receivables.scm:69
 msgid "Shipping address"
-msgstr "送货地址"
+msgstr "仓库"
 
 #: gnucash/report/reports/standard/new-aging.scm:419
 msgid "Payable Aging"
@@ -26109,7 +26106,7 @@ msgstr "应付账龄"
 
 #: gnucash/report/reports/standard/new-aging.scm:428
 msgid "Receivable Aging"
-msgstr "应收账龄"
+msgstr "选项"
 
 #: gnucash/report/reports/standard/new-owner-report.scm:54
 #: gnucash/report/reports/standard/owner-report.scm:55
@@ -28478,7 +28475,7 @@ msgstr "科目已经自动核实余额。"
 
 #: libgnucash/app-utils/gnc-ui-balances.c:455
 msgid "Too many uncleared splits"
-msgstr "太多未清理的分录"
+msgstr "太多未核实的交易"
 
 #: libgnucash/app-utils/gnc-ui-balances.c:471
 msgid "The selected amount cannot be cleared."

commit 5be0795fdabc70bd7c6e2b00411aa19582ef23f0
Author: Avi Markovitz <avi.markovitz at gmail.com>
Date:   Sat Jul 31 21:44:01 2021 +0200

    Translation update  by Avi Markovitz <avi.markovitz at gmail.com> using Weblate
    
    po/he.po: 100.0% (5364 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Hebrew)
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/he/
    
    Co-authored-by: Avi Markovitz <avi.markovitz at gmail.com>

diff --git a/po/he.po b/po/he.po
index cb8cbcbd3..87bdc8a0a 100644
--- a/po/he.po
+++ b/po/he.po
@@ -11,7 +11,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-07-28 15:33+0000\n"
+"PO-Revision-Date: 2021-07-31 19:43+0000\n"
 "Last-Translator: Avi Markovitz <avi.markovitz at gmail.com>\n"
 "Language-Team: Hebrew <https://hosted.weblate.org/projects/gnucash/gnucash/"
 "he/>\n"
@@ -20,7 +20,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Weblate 4.7.2-dev\n"
+"X-Generator: Weblate 4.8-dev\n"
 "X-Poedit-Basepath: .\n"
 
 #: bindings/guile/commodity-table.scm:44
@@ -6354,8 +6354,8 @@ msgstr ""
 "\n"
 "%s\n"
 "\n"
-"נא להקיש על אוקיי לניקוי זמני של המסנן ולהמשיך.\n"
-"אחרת התא פעיל האחרון יבחר."
+"נא להקיש על 'בסדר' לניקוי זמני של המסנן ולהמשיך.\n"
+"אחרת התא הפעיל האחרון יבחר."
 
 #: gnucash/gnome/gnc-split-reg.c:2371
 msgid "Sort By:"
@@ -10275,7 +10275,7 @@ msgid ""
 "closed. The numbers are the X and Y coordinates of the top left corner of "
 "the window followed by the width and height of the window."
 msgstr ""
-"הגדרה זו קובעת את מיקום החלון שנסגר לאחרונה. המספרים הם ערכי צירי ה X ו Y של "
+"הגדרה זו קובעת את מיקום החלון שנסגר לאחרונה. המספרים הם ערכי צירי ה X ו־Y של "
 "הפינה השמאלית של החלון ובהמשך רוחב וגובה החלון."
 
 #: gnucash/gschemas/org.gnucash.dialogs.business.gschema.xml.in:24
@@ -16283,7 +16283,7 @@ msgstr "_מקומי"
 #: gnucash/gtkbuilder/dialog-preferences.glade:1018
 #: libgnucash/app-utils/business-options.scm:76
 msgid "Fancy Date Format"
-msgstr "מבנה תאריך מהודרת"
+msgstr "מבנה תאריך מהודר"
 
 #: gnucash/gtkbuilder/dialog-preferences.glade:1058
 msgid "<b>Time Format</b>"
@@ -17434,7 +17434,7 @@ msgstr "חיפוש חדש"
 
 #: gnucash/gtkbuilder/dialog-search.glade:348
 msgid "Refine current search"
-msgstr "סנן חיפוש נוכחי"
+msgstr "עידון חיפוש נוכחי"
 
 #: gnucash/gtkbuilder/dialog-search.glade:365
 msgid "Add results to current search"
@@ -17442,7 +17442,7 @@ msgstr "הוספת תוצאות לחיפוש הנוכחי"
 
 #: gnucash/gtkbuilder/dialog-search.glade:382
 msgid "Delete results from current search"
-msgstr "מחק תוצאות מהחיפוש"
+msgstr "מחיקת תוצאות מהחיפוש"
 
 #: gnucash/gtkbuilder/dialog-search.glade:410
 msgid "Search only active data"
@@ -17467,7 +17467,7 @@ msgid ""
 "now be corrected. Press OK to edit them."
 msgstr ""
 "התנועות המחזוריות הבאות מפנות לחשבונות שנמחקו ונדרש תיקון. לעריכה נא להקיש "
-"על אוקיי."
+"על 'בסדר'."
 
 #: gnucash/gtkbuilder/dialog-sx.glade:126
 #: gnucash/gtkbuilder/gnc-frequency.glade:171
@@ -17808,7 +17808,7 @@ msgstr "UTC - זמן בינלאומי מתואם"
 
 #: gnucash/gtkbuilder/gnc-date-format.glade:33
 msgid "No Fancy Date Format"
-msgstr "אין מבנה תאריך מהודרת"
+msgstr "אין מבנה תאריך מהודר"
 
 #: gnucash/gtkbuilder/gnc-date-format.glade:65
 msgid "%Y-%m-%d"
@@ -18419,7 +18419,7 @@ msgstr "פתיחת התקציב שנבחר"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:833
 msgid "Delete the Selected Budget"
-msgstr "מחק את התקציב המסומן"
+msgstr "מחיקת התקציב המסומן"
 
 #: gnucash/gtkbuilder/gnc-plugin-page-budget.glade:868
 msgid "Budget Notes"
@@ -26256,27 +26256,27 @@ msgstr "מודים לך על החסות!"
 
 #: gnucash/report/reports/standard/invoice.scm:335
 msgid "Row 1 Left"
-msgstr "שורה 1 שמאל"
+msgstr "שורה 1, ימין"
 
 #: gnucash/report/reports/standard/invoice.scm:342
 msgid "Row 1 Right"
-msgstr "שורה 1 ימין"
+msgstr "שורה 1, שמאל"
 
 #: gnucash/report/reports/standard/invoice.scm:349
 msgid "Row 2 Left"
-msgstr "שורה 2 שמאל"
+msgstr "שורה 2, ימין"
 
 #: gnucash/report/reports/standard/invoice.scm:356
 msgid "Row 2 Right"
-msgstr "שורה 2 ימין"
+msgstr "שורה 2, שמאל"
 
 #: gnucash/report/reports/standard/invoice.scm:363
 msgid "Row 3 Left"
-msgstr "שורה 3 שמאל"
+msgstr "שורה 3, ימין"
 
 #: gnucash/report/reports/standard/invoice.scm:370
 msgid "Row 3 Right"
-msgstr "שורה 3 ימין"
+msgstr "שורה 3, שמאל"
 
 #: gnucash/report/reports/standard/invoice.scm:423
 #: gnucash/report/reports/standard/job-report.scm:239
@@ -28031,7 +28031,7 @@ msgstr "טבלה ליצוא"
 
 #: gnucash/report/trep-engine.scm:109
 msgid "Account Name Filter"
-msgstr "מסנן שם החשבון"
+msgstr "מסנן שם חשבון"
 
 #: gnucash/report/trep-engine.scm:111
 msgid "Use regular expressions for account name filter"
@@ -28043,7 +28043,7 @@ msgstr "מסנן תנועות"
 
 #: gnucash/report/trep-engine.scm:114
 msgid "Use regular expressions for transaction filter"
-msgstr "שימוש בביטוי רגיל עבור מסנן תנועות"
+msgstr "שימוש בביטוי רגיל למסנן תנועות"
 
 #: gnucash/report/trep-engine.scm:116
 msgid "Transaction Filter excludes matched strings"
@@ -28162,9 +28162,9 @@ msgid ""
 "match Expenses:Travel:Holiday and Expenses:Business:Travel. It can be left "
 "blank, which will disable the filter."
 msgstr ""
-"הצגת חשבונות ששמם המלא תואם למסנן זה בלבד, לדוגמה ':נסיעות' יתאים ל 'הוצאות:"
-"נסיעות:נופש' וגם ל 'הוצאות:עסקים:נסיעות'.ניתן להשאיר את השדה ריק, דבר שישבית "
-"את המסנן."
+"הצגת חשבונות ששמם המלא תואם למסנן זה בלבד, לדוגמה ':נסיעות' יתאים ל "
+"'הוצאות:נסיעות:נופש' וגם ל 'הוצאות:עסקים:נסיעות'. ניתן להשאיר את השדה ריק, "
+"דבר שישבית את המסנן."
 
 #: gnucash/report/trep-engine.scm:569
 msgid ""
@@ -28174,9 +28174,9 @@ msgid ""
 "single character e.g. '20../.' will match 'Travel 2017/1 London'. "
 msgstr ""
 "כברירת מחדל, מסנן החשבון יחפש מחרוזת משנה בלבד. הגדרה כ־true תאפשר יכולות "
-"מלאות לביטוי רגיל של POSIX. 'מכונית|טיסות' יאחזרו תוצאות גם ל 'ההוצאות: רכב' "
-"ו 'הוצאות: טיסות'. להתאמה לתו בודד יש להשתמש בנקודה (.) לדוגמה ' 20.../. ' "
-"יאחזר רשומה 'נסיעות לונדון2017/1 '. "
+"ביטוי רגיל POSIX מלאות. 'מכונית|טיסות' יאחזרו תוצאות גם ל 'ההוצאות: רכב' ו "
+"'הוצאות: טיסות'. להתאמה לתו בודד יש להשתמש בנקודה (.) לדוגמה ' 20.../. ' "
+"יאחזר רשומה 'נסיעות לונדון 2017/1 '. "
 
 #: gnucash/report/trep-engine.scm:578
 msgid ""
@@ -28186,8 +28186,8 @@ msgid ""
 "memo. It can be left blank, which will disable the filter."
 msgstr ""
 "הצגת תנועות שבהן התיאור, ההערות או המיזכר תואמים למסנן זה.\n"
-"לדוגמה ' #מתנה ' תמצא את כל התנועות עם #מתנה בתיאור, בהערות או במיזכר. ניתן "
-"להשאיר את השדה ריק, דבר שיהפוך את המסנן ללא זמין."
+"לדוגמה ' #מתנה ' תאחזר את כל התנועות הכוללות #מתנה בתיאור, בהערות או במיזכר. "
+"ניתן להשאיר את השדה ריק, דבר שישבית את המסנן."
 
 #: gnucash/report/trep-engine.scm:587
 msgid ""
@@ -28196,8 +28196,8 @@ msgid ""
 "will match both tags within description, notes or memo. "
 msgstr ""
 "כברירת מחדל, מסנן התנועות יחפש מחרוזת משנה בלבד. הגדרה כ־true תאפשר יכולות "
-"מלאות לביטוי רגיל של POSIX. '#עבודה|'#משפחה' יאחזרו תוצאות לשני התגים מתוך "
-"שדה התיאור, ההערות או המזכר. "
+"ביטוי רגיל POSIX מלאות. '#עבודה|'#משפחה' יאחזרו תוצאות לשני התגים מתוך שדה "
+"התיאור, ההערות או המזכר. "
 
 #: gnucash/report/trep-engine.scm:596
 msgid "If this option is selected, transactions matching filter are excluded."
@@ -28238,7 +28238,7 @@ msgstr "סינון חשבון."
 
 #: gnucash/report/trep-engine.scm:750
 msgid "Sort by this criterion first."
-msgstr "מיון לפי קריטריון זה תחילה."
+msgstr "מיון לפי תבחין זה תחילה."
 
 #: gnucash/report/trep-engine.scm:761
 msgid "Show the full account name for subtotals and subheadings?"
@@ -28278,7 +28278,7 @@ msgstr "סדר מיון ראשי."
 
 #: gnucash/report/trep-engine.scm:831
 msgid "Sort by this criterion second."
-msgstr "מיון משני לפי קריטריון זה."
+msgstr "מיון משני לפי תבחין זה."
 
 #: gnucash/report/trep-engine.scm:842
 msgid "Subtotal according to the secondary key?"

commit 613f639afa0fbe1a8a7f7de8075fe94ac6c28fa0
Author: TianXing_Yi <ytx.cash at gmail.com>
Date:   Sat Jul 31 21:44:01 2021 +0200

    Translation update  by TianXing_Yi <ytx.cash at gmail.com> using Weblate
    
    po/zh_CN.po: 99.7% (5351 of 5364 strings; 0 fuzzy)
    0 failing checks (0.0%)
    Translation: GnuCash/Program (Chinese (Simplified))
    Translate-URL: https://hosted.weblate.org/projects/gnucash/gnucash/zh_Hans/
    
    Co-authored-by: TianXing_Yi <ytx.cash at gmail.com>

diff --git a/po/zh_CN.po b/po/zh_CN.po
index efcfc2c94..995d78a68 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -23,7 +23,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
 "cgi?product=GnuCash&component=Translations\n"
 "POT-Creation-Date: 2021-06-30 07:34+0200\n"
-"PO-Revision-Date: 2021-07-26 13:34+0000\n"
+"PO-Revision-Date: 2021-07-29 10:33+0000\n"
 "Last-Translator: TianXing_Yi <ytx.cash at gmail.com>\n"
 "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
 "gnucash/gnucash/zh_Hans/>\n"
@@ -4288,7 +4288,7 @@ msgstr "说明"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:226
 msgid "Run Report"
-msgstr "科目报表"
+msgstr "运行报表"
 
 #: gnucash/gnome/gnc-plugin-page-budget.c:310
 #: gnucash/gnome/gnc-plugin-page-budget.c:351
@@ -5257,7 +5257,7 @@ msgstr "本次交易(_T)"
 #: gnucash/gnome/gnc-plugin-page-register2.c:408
 #: gnucash/gnome/gnc-plugin-page-register.c:536
 msgid "Account Report"
-msgstr "科目报表"
+msgstr "标签页报表"
 
 #: gnucash/gnome/gnc-plugin-page-register2.c:409
 #: gnucash/gnome/gnc-plugin-page-register.c:537
@@ -5267,7 +5267,7 @@ msgstr "为本科目打开一个账簿报表"
 #: gnucash/gnome/gnc-plugin-page-register2.c:413
 #: gnucash/gnome/gnc-plugin-page-register.c:541
 msgid "Account Report - Single Transaction"
-msgstr "科目报表 - 单独交易事项"
+msgstr "标签页报表 - 当前交易"
 
 #: gnucash/gnome/gnc-plugin-page-register2.c:414
 #: gnucash/gnome/gnc-plugin-page-register.c:542
@@ -7530,11 +7530,11 @@ msgstr "选择默认的选择。"
 
 #: gnucash/gnome-utils/dialog-options.c:1846
 msgid "Reset defaults"
-msgstr "重置为默认值"
+msgstr "默认值"
 
 #: gnucash/gnome-utils/dialog-options.c:1848
 msgid "Reset all values to their defaults."
-msgstr "将所有数值重置为默认值。"
+msgstr "所有设置恢复初始状态。"
 
 #: gnucash/gnome-utils/dialog-options.c:2249
 msgid "Page"

commit b9d6fc9f4f0e7557efe27259c37b992ecbcf3664
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Jul 31 21:11:56 2021 +0800

    [gnc-report] Handle default_font_family being NULL
    
    There was invalid assumption in afea6fd68. According to the following
    documentation, pango_font_description_get_family can return NULL, and
    g_strdup (NULL) also returns NULL.
    
    https://docs.gtk.org/Pango/method.FontDescription.get_family.html

diff --git a/gnucash/report/gnc-report.c b/gnucash/report/gnc-report.c
index 970133867..96727e96f 100644
--- a/gnucash/report/gnc-report.c
+++ b/gnucash/report/gnc-report.c
@@ -336,7 +336,9 @@ gnc_get_default_report_font_family(void)
 
     pango_font_description_free (font_desc);
 
-    if (g_str_has_prefix (default_font_family, ".AppleSystemUIFont"))
+    if (!default_font_family)
+        return g_strdup ("Arial");
+    else if (g_str_has_prefix (default_font_family, ".AppleSystemUIFont"))
     {
         g_free (default_font_family);
         return g_strdup ("Arial");

commit 3dceb0868e77f931bbf31e413a1c1bfe98f8b0ff
Author: goodvibes2 <goodchris96 at gmail.com>
Date:   Tue Jul 27 13:05:58 2021 +1000

    Delete functions no longer used after mods for bug 798205

diff --git a/gnucash/import-export/import-backend.c b/gnucash/import-export/import-backend.c
index 8e409e6fb..60b01459b 100644
--- a/gnucash/import-export/import-backend.c
+++ b/gnucash/import-export/import-backend.c
@@ -1048,106 +1048,6 @@ gnc_import_process_trans_item (GncImportMatchMap *matchmap,
     return FALSE;
 }
 
-/********************************************************************\
- * check_trans_online_id() Callback function used by
- * gnc_import_exists_online_id.  Takes pointers to transaction and split,
- * returns 0 if their online_ids  do NOT match, or if the split
- * belongs to the transaction
-\********************************************************************/
-static gint check_trans_online_id(Transaction *trans1, void *user_data)
-{
-    Account *account;
-    Split *split1;
-    Split *split2 = user_data;
-    const gchar *online_id1;
-    const gchar *online_id2;
-
-    account = xaccSplitGetAccount(split2);
-    split1 = xaccTransFindSplitByAccount(trans1, account);
-    if (split1 == split2)
-        return 0;
-
-    /* hack - we really want to iterate over the _splits_ of the account
-       instead of the transactions */
-    g_assert(split1 != NULL);
-
-    if (gnc_import_split_has_online_id(split1))
-        online_id1 = gnc_import_get_split_online_id(split1);
-    else
-        online_id1 = gnc_import_get_trans_online_id(trans1);
-
-    online_id2 = gnc_import_get_split_online_id(split2);
-
-    if ((online_id1 == NULL) ||
-            (online_id2 == NULL) ||
-            (strcmp(online_id1, online_id2) != 0))
-    {
-        return 0;
-    }
-    else
-    {
-        /*printf("test_trans_online_id(): Duplicate found\n");*/
-        return 1;
-    }
-}
-
-static gint collect_trans_online_id(Transaction *trans, void *user_data)
-{
-    Split *split;
-    GHashTable *id_hash = user_data;
-    int i=0;
-    
-    const gchar* online_id = gnc_import_get_trans_online_id (trans);
-    if (online_id)
-        g_hash_table_add (id_hash, (void*) online_id);
-
-    for (GList *splits = xaccTransGetSplitList (trans); splits; splits = splits->next)
-    {
-        if (gnc_import_split_has_online_id (splits->data))
-            g_hash_table_add(id_hash, (void*) gnc_import_get_split_online_id (splits->data));
-    }
-    return 0;
-}
-
-/** Checks whether the given transaction's online_id already exists in
-  its parent account. */
-gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_hash)
-{
-    gboolean online_id_exists = FALSE;
-    Account *dest_acct;
-    Split *source_split;
-
-    /* Look for an online_id in the first split */
-    source_split = xaccTransGetSplit(trans, 0);
-    g_assert(source_split);
-
-    // No online id, no point in continuing. We'd crash if we tried.
-    if (!gnc_import_get_split_online_id (source_split))
-        return FALSE;
-    // Create a hash per account of a hash of all transactions IDs. Then the test below will be fast if
-    // we have many transactions to import.
-    dest_acct = xaccSplitGetAccount (source_split);
-    if (!g_hash_table_contains (acct_id_hash, dest_acct))
-    {
-        GHashTable* new_hash = g_hash_table_new (g_str_hash, g_str_equal);
-        g_hash_table_insert (acct_id_hash, dest_acct, new_hash);
-        xaccAccountForEachTransaction (dest_acct, collect_trans_online_id, new_hash);
-    }
-    online_id_exists = g_hash_table_contains (g_hash_table_lookup (acct_id_hash, dest_acct),
-                                              gnc_import_get_split_online_id (source_split));
-    
-    /* If it does, abort the process for this transaction, since it is
-       already in the system. */
-    if (online_id_exists == TRUE)
-    {
-        DEBUG("%s", "Transaction with same online ID exists, destroying current transaction");
-        xaccTransDestroy(trans);
-        xaccTransCommitEdit(trans);
-    }
-    return online_id_exists;
-}
-
-
 /* ******************************************************************
  */
 
diff --git a/gnucash/import-export/import-backend.h b/gnucash/import-export/import-backend.h
index b524d1835..69cd2bc99 100644
--- a/gnucash/import-export/import-backend.h
+++ b/gnucash/import-export/import-backend.h
@@ -57,15 +57,6 @@ typedef enum _action
 /** @name Non-GUI Functions */
 /*@{*/
 
-/** Checks whether the given transaction's online_id already exists in
- * its parent account. The given transaction has to be open for
- * editing. If a matching online_id exists, the transaction is
- * destroyed (!) and TRUE is returned, otherwise FALSE is returned.
- *
- * @param trans The transaction for which to check for an existing
- * online_id. */
-gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_hash);
-
 /** Evaluates the match between trans_info and split using the provided parameters.
  *
  * @param trans_info The TransInfo for the imported transaction
diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index 07f5a1296..10c916135 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -76,7 +76,6 @@ struct _main_matcher_info
     gboolean add_toggled;     // flag to indicate that add has been toggled to stop selection
     gint id;
     GSList* temp_trans_list;  // Temporary list of imported transactions
-    GHashTable* acct_id_hash; // Hash table, per account, of list of transaction IDs.
     GSList* edited_accounts;  // List of accounts currently edited.
 };
 
@@ -144,14 +143,6 @@ static gboolean query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
                                             gpointer user_data);
 /* end local prototypes */
 
-static
-gboolean delete_hash (gpointer key, gpointer value, gpointer user_data)
-{
-    // Value is a hash table that needs to be destroyed.
-    g_hash_table_destroy (value);
-    return TRUE;
-}
-
 static void
 update_all_balances (GNCImportMainMatcher *info)
 {
@@ -218,8 +209,6 @@ gnc_gen_trans_list_delete (GNCImportMainMatcher *info)
     // We've deferred balance computations on many accounts. Let's do it now that we're done.
     update_all_balances (info);
 
-    g_hash_table_foreach_remove (info->acct_id_hash, delete_hash, NULL);
-    info->acct_id_hash = NULL;
     g_free (info);
 }
 
@@ -1133,8 +1122,6 @@ gnc_gen_trans_init_view (GNCImportMainMatcher *info,
                       G_CALLBACK(gnc_gen_trans_onButtonPressed_cb), info);
     g_signal_connect (view, "popup-menu",
                       G_CALLBACK(gnc_gen_trans_onPopupMenu_cb), info);
-
-    info->acct_id_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
 }
 
 static void
diff --git a/gnucash/import-export/import-utilities.c b/gnucash/import-export/import-utilities.c
index 8d672d4e0..4be49b323 100644
--- a/gnucash/import-export/import-utilities.c
+++ b/gnucash/import-export/import-utilities.c
@@ -57,29 +57,6 @@ void gnc_import_set_acc_online_id (Account *account, const gchar *id)
     xaccAccountCommitEdit (account);
 }
 
-const gchar * gnc_import_get_trans_online_id (Transaction * transaction)
-{
-    gchar *id = NULL;
-    qof_instance_get (QOF_INSTANCE (transaction), "online-id", &id, NULL);
-    return id;
-}
-/* Not actually used */
-void gnc_import_set_trans_online_id (Transaction *transaction,
-				     const gchar *id)
-{
-    g_return_if_fail (transaction != NULL);
-    xaccTransBeginEdit (transaction);
-    qof_instance_set (QOF_INSTANCE (transaction), "online-id", id, NULL);
-    xaccTransCommitEdit (transaction);
-}
-
-gboolean gnc_import_trans_has_online_id(Transaction * transaction)
-{
-    const gchar * online_id;
-    online_id = gnc_import_get_trans_online_id(transaction);
-    return (online_id != NULL && strlen(online_id) > 0);
-}
-
 const gchar * gnc_import_get_split_online_id (Split * split)
 {
     gchar *id = NULL;
diff --git a/gnucash/import-export/import-utilities.h b/gnucash/import-export/import-utilities.h
index 1ef733d8b..a39d64157 100644
--- a/gnucash/import-export/import-utilities.h
+++ b/gnucash/import-export/import-utilities.h
@@ -49,17 +49,6 @@ const gchar * gnc_import_get_acc_online_id(Account * account);
 void gnc_import_set_acc_online_id(Account * account,
                                   const gchar * string_value);
 /** @} */
-/** @name Setter-getters
-    Setter and getter functions for the online_id field for
-    Transactions.
-	@{
-*/
-const gchar * gnc_import_get_trans_online_id(Transaction * transaction);
-void gnc_import_set_trans_online_id(Transaction * transaction,
-                                    const gchar * string_value);
-/** @} */
-
-gboolean gnc_import_trans_has_online_id(Transaction * transaction);
 
 /** @name Setter-getters
     Setter and getter functions for the online_id field for

commit 2ee89f6693c031c280432751c4dc5c01b0499877
Author: goodvibes2 <goodchris96 at gmail.com>
Date:   Tue Jul 27 12:15:25 2021 +1000

    Do not drop a potential match just because it has an online_id.
    
    Now that we don't exclude from import a transaction with an FITID that
    matches an already existing transaction, if one accidentally re-imports
    a transaction, this allows it to be automatically matched against the
    previously imported transaction.

diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index 584c41f03..07f5a1296 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -1783,8 +1783,6 @@ create_hash_of_potential_matches (GList *candidate_txns,
     {
         Account* split_account;
         GSList* split_list;
-        if (gnc_import_split_has_online_id (candidate->data))
-            continue;
         split_account = xaccSplitGetAccount (candidate->data);
         /* g_hash_table_steal_extended would do the two calls in one shot but is
          * not available until GLib 2.58.

commit 3f1e24991f7e78bed7a96be6929e5b6c0bda86e0
Author: goodvibes2 <goodchris96 at gmail.com>
Date:   Tue Jul 27 11:57:45 2021 +1000

    Bug 798205 Do not exclude from import a transaction that has an FITID
    
    which matches an already existing split. This is because it
    (1) may be a coincidence and therefore the transaction needs to be added
    or
    (2) could be on a transfer from the account being imported to another
    bank account which has already been imported, and so needs to be
    matched, not added.

diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index 0c31c5a52..584c41f03 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -1715,16 +1715,11 @@ gnc_gen_trans_list_add_trans_with_ref_id (GNCImportMainMatcher *gui, Transaction
     g_assert (gui);
     g_assert (trans);
 
-    if (gnc_import_exists_online_id (trans, gui->acct_id_hash))
-        return;
-    else
-    {
-        transaction_info = gnc_import_TransInfo_new (trans, NULL);
-        gnc_import_TransInfo_set_ref_id (transaction_info, ref_id);
-        // It's much faster to gather the imported transactions into a GSList than directly into the
-        // treeview.
-        gui->temp_trans_list = g_slist_prepend (gui->temp_trans_list, transaction_info);
-    }
+    transaction_info = gnc_import_TransInfo_new (trans, NULL);
+    gnc_import_TransInfo_set_ref_id (transaction_info, ref_id);
+    // It's much faster to gather the imported transactions into a GSList than directly into the
+    // treeview.
+    gui->temp_trans_list = g_slist_prepend (gui->temp_trans_list, transaction_info);
     return;
 }
 

commit 621704ebeb2d182be6784ea6602c6fbd3f3b67ce
Author: Simon Arlott <sa.me.uk>
Date:   Mon Jul 12 19:23:56 2021 +0100

    Bug 798238 - "New security" dialog doesn't save the "Display symbol"
    
    When creating a new commodity the display symbol isn't saved so it defaults
    to one of the other values as appropriate.
    
    After creating the new commodity (without providing a user symbol), set
    the user symbol.

diff --git a/gnucash/gnome-utils/dialog-commodity.c b/gnucash/gnome-utils/dialog-commodity.c
index b1a50e6a5..7e9f8a86b 100644
--- a/gnucash/gnome-utils/dialog-commodity.c
+++ b/gnucash/gnome-utils/dialog-commodity.c
@@ -1301,6 +1301,8 @@ gnc_ui_commodity_dialog_to_object(CommodityWindow * w)
             c = gnc_commodity_new(book, fullname, name_space, mnemonic, code, fraction);
             w->edit_commodity = c;
             gnc_commodity_begin_edit(c);
+
+            gnc_commodity_set_user_symbol(c, user_symbol);
         }
         else
         {

commit 4a5b5f3bf2e7616c2da600ecf25bb470e5710c0c
Author: Simon Arlott <sa.me.uk>
Date:   Thu Jul 8 20:43:02 2021 +0100

    Don't cache the empty string
    
    Avoid unnecessary reference counting for uses of the empty string.

diff --git a/libgnucash/engine/qof-string-cache.cpp b/libgnucash/engine/qof-string-cache.cpp
index 68e4fe479..eb236ebd0 100644
--- a/libgnucash/engine/qof-string-cache.cpp
+++ b/libgnucash/engine/qof-string-cache.cpp
@@ -84,7 +84,7 @@ qof_string_cache_destroy (void)
 void
 qof_string_cache_remove(const char * key)
 {
-    if (key)
+    if (key && key[0] != 0)
     {
         GHashTable* cache = qof_get_string_cache();
         gpointer value;
@@ -111,6 +111,11 @@ qof_string_cache_insert(const char * key)
 {
     if (key)
     {
+        if (key[0] == 0)
+        {
+            return "";
+        }
+
         GHashTable* cache = qof_get_string_cache();
         gpointer value;
         gpointer cache_key;

commit 320df7e4096e504ca002b794064aace27007d06d
Author: Simon Arlott <sa.me.uk>
Date:   Thu Jul 8 20:42:03 2021 +0100

    Use const return values for string cache
    
    This is a prerequisite for being able to return "" (which is const) and
    none of the returned values should ever be modified.

diff --git a/gnucash/gnome-utils/gnc-component-manager.c b/gnucash/gnome-utils/gnc-component-manager.c
index 2d909dc37..b98bcc878 100644
--- a/gnucash/gnome-utils/gnc-component-manager.c
+++ b/gnucash/gnome-utils/gnc-component-manager.c
@@ -241,9 +241,9 @@ add_event_type (ComponentEventInfo *cei, QofIdTypeConst entity_type,
     mask = g_hash_table_lookup (cei->event_masks, entity_type);
     if (!mask)
     {
-        char * key = qof_string_cache_insert ((gpointer) entity_type);
+        const char * key = qof_string_cache_insert ((gpointer) entity_type);
         mask = g_new0 (QofEventId, 1);
-        g_hash_table_insert (cei->event_masks, key, mask);
+        g_hash_table_insert (cei->event_masks, (gpointer)key, mask);
     }
 
     if (or_in)
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 154ff1936..8f12f0c64 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -317,9 +317,9 @@ gnc_account_init(Account* acc)
     priv->parent   = NULL;
     priv->children = NULL;
 
-    priv->accountName = static_cast<char*>(qof_string_cache_insert(""));
-    priv->accountCode = static_cast<char*>(qof_string_cache_insert(""));
-    priv->description = static_cast<char*>(qof_string_cache_insert(""));
+    priv->accountName = qof_string_cache_insert("");
+    priv->accountCode = qof_string_cache_insert("");
+    priv->description = qof_string_cache_insert("");
 
     priv->type = ACCT_TYPE_NONE;
 
@@ -1265,9 +1265,9 @@ xaccCloneAccount(const Account *from, QofBook *book)
      * Also let caller issue the generate_event (EVENT_CREATE) */
     priv->type = from_priv->type;
 
-    priv->accountName = static_cast<char*>(qof_string_cache_insert(from_priv->accountName));
-    priv->accountCode = static_cast<char*>(qof_string_cache_insert(from_priv->accountCode));
-    priv->description = static_cast<char*>(qof_string_cache_insert(from_priv->description));
+    priv->accountName = qof_string_cache_replace(priv->accountName, from_priv->accountName);
+    priv->accountCode = qof_string_cache_replace(priv->accountCode, from_priv->accountCode);
+    priv->description = qof_string_cache_replace(priv->description, from_priv->description);
 
     qof_instance_copy_kvp (QOF_INSTANCE (ret), QOF_INSTANCE (from));
 
@@ -2327,7 +2327,7 @@ int
 xaccAccountOrder (const Account *aa, const Account *ab)
 {
     AccountPrivate *priv_aa, *priv_ab;
-    char *da, *db;
+    const char *da, *db;
     char *endptr = NULL;
     int ta, tb, result;
     long la, lb;
@@ -3264,7 +3264,7 @@ gnc_account_get_full_name(const Account *account)
     AccountPrivate *priv;
     const Account *a;
     char *fullname;
-    gchar **names;
+    const gchar **names;
     int level;
 
     /* So much for hardening the API. Too many callers to this function don't
@@ -3291,7 +3291,7 @@ gnc_account_get_full_name(const Account *account)
 
     /* Get all the pointers in the right order. The root node "entry"
      * becomes the terminating NULL pointer for the array of strings. */
-    names = (gchar **)g_malloc(level * sizeof(gchar *));
+    names = (const gchar **)g_malloc(level * sizeof(gchar *));
     names[--level] = NULL;
     for (a = account; level > 0; a = priv->parent)
     {
@@ -3300,7 +3300,7 @@ gnc_account_get_full_name(const Account *account)
     }
 
     /* Build the full name */
-    fullname =  g_strjoinv(account_separator, names);
+    fullname = g_strjoinv(account_separator, (gchar **)names);
     g_free(names);
 
     return fullname;
diff --git a/libgnucash/engine/AccountP.h b/libgnucash/engine/AccountP.h
index ea147aa83..746a1c504 100644
--- a/libgnucash/engine/AccountP.h
+++ b/libgnucash/engine/AccountP.h
@@ -62,7 +62,7 @@ typedef struct AccountPrivate
      * It is intended to a short, 5 to 30 character long string that
      * is displayed by the GUI as the account mnemonic.
      */
-    char *accountName;
+    const char *accountName;
 
     /* The accountCode is an arbitrary string assigned by the user.
      * It is intended to be reporting code that is a synonym for the
@@ -71,13 +71,13 @@ typedef struct AccountPrivate
      * as 100, 200 or 600 for top-level accounts, and 101, 102..  etc.
      * for detail accounts.
      */
-    char *accountCode;
+    const char *accountCode;
 
     /* The description is an arbitrary string assigned by the user.
      * It is intended to be a longer, 1-5 sentence description of what
      * this account is all about.
      */
-    char *description;
+    const char *description;
 
     /* The type field is the account type, picked from the enumerated
      * list that includes ACCT_TYPE_BANK, ACCT_TYPE_STOCK,
diff --git a/libgnucash/engine/Split.c b/libgnucash/engine/Split.c
index 8fb6091fa..1c9cf710d 100644
--- a/libgnucash/engine/Split.c
+++ b/libgnucash/engine/Split.c
@@ -1495,7 +1495,7 @@ xaccSplitOrder (const Split *sa, const Split *sb)
 {
     int retval;
     int comp;
-    char *da, *db;
+    const char *da, *db;
     gboolean action_for_num;
 
     if (sa == sb) return 0;
diff --git a/libgnucash/engine/SplitP.h b/libgnucash/engine/SplitP.h
index 8e6f41bb6..335db9174 100644
--- a/libgnucash/engine/SplitP.h
+++ b/libgnucash/engine/SplitP.h
@@ -83,7 +83,7 @@ struct split_s
      * It is intended to hold a short (zero to forty character) string
      * that is displayed by the GUI along with this split.
      */
-    char  * memo;
+    const char  *memo;
 
     /* The action field is an arbitrary user-assigned value.
      * It is meant to be a very short (one to ten character) string that
@@ -91,10 +91,10 @@ struct split_s
      * Withdraw, Deposit, ATM, Check, etc. The idea is that this field
      * can be used to create custom reports or graphs of data.
      */
-    char  * action;            /* Buy, Sell, Div, etc.                      */
+    const char  *action;       /* Buy, Sell, Div, etc.                      */
 
-    time64 date_reconciled;  /* date split was reconciled                 */
-    char   reconciled;        /* The reconciled field                      */
+    time64 date_reconciled;    /* date split was reconciled                 */
+    char   reconciled;         /* The reconciled field                      */
 
     /* gains is a flag used to track the relationship between
      * capital-gains splits. Depending on its value, this flag indicates
diff --git a/libgnucash/engine/Transaction.c b/libgnucash/engine/Transaction.c
index e7c3cba0a..986eb8fc3 100644
--- a/libgnucash/engine/Transaction.c
+++ b/libgnucash/engine/Transaction.c
@@ -1699,7 +1699,8 @@ xaccTransCommitEdit (Transaction *trans)
     LEAVE ("(trans=%p)", trans);
 }
 
-#define SWAP(a, b) do { gpointer tmp = (a); (a) = (b); (b) = tmp; } while (0);
+#define SWAP_STR(a, b) do { const char *tmp = (a); (a) = (b); (b) = tmp; } while (0);
+#define SWAP(a, b)     do { gpointer tmp = (a); (a) = (b); (b) = tmp; } while (0);
 
 /* Ughhh. The Rollback function is terribly complex, and, what's worse,
  * it only rolls back the basics.  The TransCommit functions did a bunch
@@ -1738,8 +1739,8 @@ xaccTransRollbackEdit (Transaction *trans)
     /* copy the original values back in. */
 
     orig = trans->orig;
-    SWAP(trans->num, orig->num);
-    SWAP(trans->description, orig->description);
+    SWAP_STR(trans->num, orig->num);
+    SWAP_STR(trans->description, orig->description);
     trans->date_entered = orig->date_entered;
     trans->date_posted = orig->date_posted;
     SWAP(trans->common_currency, orig->common_currency);
@@ -1766,8 +1767,8 @@ xaccTransRollbackEdit (Transaction *trans)
             Split *so = onode->data;
 
             xaccSplitRollbackEdit(s);
-            SWAP(s->action, so->action);
-            SWAP(s->memo, so->memo);
+            SWAP_STR(s->action, so->action);
+            SWAP_STR(s->memo, so->memo);
 	    qof_instance_copy_kvp (QOF_INSTANCE (s), QOF_INSTANCE (so));
             s->reconciled = so->reconciled;
             s->amount = so->amount;
@@ -1915,7 +1916,7 @@ int
 xaccTransOrder_num_action (const Transaction *ta, const char *actna,
                             const Transaction *tb, const char *actnb)
 {
-    char *da, *db;
+    const char *da, *db;
     int retval;
     int64_t na, nb;
 
diff --git a/libgnucash/engine/TransactionP.h b/libgnucash/engine/TransactionP.h
index bbeef7cb0..c42f988c1 100644
--- a/libgnucash/engine/TransactionP.h
+++ b/libgnucash/engine/TransactionP.h
@@ -82,12 +82,12 @@ struct transaction_s
      * It is intended to store a short id number, typically the check number,
      * deposit number, invoice number or other tracking number.
      */
-    char * num;
+    const char *num;
 
     /* The description field is an arbitrary user-assigned value.
      * It is meant to be a short descriptive phrase.
      */
-    char * description;
+    const char *description;
 
     /* The common_currency field is the balancing common currency for
      * all the splits in the transaction.  Alternate, better(?) name:
diff --git a/libgnucash/engine/gnc-budget.c b/libgnucash/engine/gnc-budget.c
index 7865e0bfc..dc67c389a 100644
--- a/libgnucash/engine/gnc-budget.c
+++ b/libgnucash/engine/gnc-budget.c
@@ -61,10 +61,10 @@ typedef struct
 typedef struct GncBudgetPrivate
 {
     /* The name is an arbitrary string assigned by the user. */
-    gchar* name;
+    const gchar *name;
 
     /* The description is an arbitrary string assigned by the user. */
-    gchar* description;
+    const gchar *description;
 
     /* Recurrence (period info) for the budget */
     Recurrence recurrence;
diff --git a/libgnucash/engine/gnc-commodity.c b/libgnucash/engine/gnc-commodity.c
index 23d5c7f3f..2d6998def 100644
--- a/libgnucash/engine/gnc-commodity.c
+++ b/libgnucash/engine/gnc-commodity.c
@@ -70,23 +70,23 @@ typedef struct gnc_commodityPrivate
 {
     gnc_commodity_namespace *name_space;
 
-    char    * fullname;
-    char    * mnemonic;
-    char    * printname;
-    char    * cusip;          /* CUSIP or other identifying code */
-    int       fraction;
-    char    * unique_name;
+    const char *fullname;
+    const char *mnemonic;
+    char       *printname;
+    const char *cusip;                /* CUSIP or other identifying code */
+    int         fraction;
+    char       *unique_name;
 
-    gboolean  quote_flag;	    /* user wants price quotes */
-    gnc_quote_source * quote_source;   /* current/old source of quotes */
-    char    * quote_tz;
+    gboolean    quote_flag;	      /* user wants price quotes */
+    gnc_quote_source *quote_source;   /* current/old source of quotes */
+    const char *quote_tz;
 
     /* the number of accounts using this commodity - this field is not
      * persisted */
-    int       usage_count;
+    int         usage_count;
 
     /* the default display_symbol, set in iso-4217-currencies at start-up */
-    const char * default_symbol;
+    const char *default_symbol;
 } gnc_commodityPrivate;
 
 #define GET_PRIVATE(o) \
@@ -104,7 +104,7 @@ struct gnc_commodity_namespace_s
 {
     QofInstance inst;
 
-    gchar      * name;
+    const gchar *name;
     gboolean     iso4217;
     GHashTable * cm_table;
     GList      * cm_list;
@@ -1997,7 +1997,7 @@ gnc_commodity_table_insert(gnc_commodity_table * table,
     PINFO ("insert %p %s into nsp=%p %s", priv->mnemonic, priv->mnemonic,
            nsp->cm_table, nsp->name);
     g_hash_table_insert(nsp->cm_table,
-                        CACHE_INSERT(priv->mnemonic),
+                        (gpointer)CACHE_INSERT(priv->mnemonic),
                         (gpointer)comm);
     nsp->cm_list = g_list_append(nsp->cm_list, comm);
 
diff --git a/libgnucash/engine/gnc-pricedb-p.h b/libgnucash/engine/gnc-pricedb-p.h
index 84ea6df73..49eaefc92 100644
--- a/libgnucash/engine/gnc-pricedb-p.h
+++ b/libgnucash/engine/gnc-pricedb-p.h
@@ -40,7 +40,7 @@ struct gnc_price_s
     gnc_commodity *currency;
     time64 tmspec;
     PriceSource source;
-    char *type;
+    const char *type;
     gnc_numeric value;
 
     /* 'private' object management fields */
diff --git a/libgnucash/engine/gnc-pricedb.c b/libgnucash/engine/gnc-pricedb.c
index 3dd48eb4f..1b15a5e08 100644
--- a/libgnucash/engine/gnc-pricedb.c
+++ b/libgnucash/engine/gnc-pricedb.c
@@ -558,12 +558,8 @@ gnc_price_set_typestr(GNCPrice *p, const char* type)
     if (!p) return;
     if (g_strcmp0(p->type, type) != 0)
     {
-        gchar *tmp;
-
         gnc_price_begin_edit (p);
-        tmp = CACHE_INSERT((gpointer) type);
-        if (p->type) CACHE_REMOVE(p->type);
-        p->type = tmp;
+        CACHE_REPLACE(p->type, type);
         gnc_price_set_dirty(p);
         gnc_price_commit_edit (p);
     }
diff --git a/libgnucash/engine/gncAddress.c b/libgnucash/engine/gncAddress.c
index 2b4e5222c..6bd871e28 100644
--- a/libgnucash/engine/gncAddress.c
+++ b/libgnucash/engine/gncAddress.c
@@ -39,17 +39,17 @@ struct _gncAddress
 {
     QofInstance inst;
 
-    QofBook *	book;
+    QofBook *     book;
     QofInstance * parent;
-    gboolean	dirty;
-    char *	name;
-    char *	addr1;
-    char *	addr2;
-    char *	addr3;
-    char *	addr4;
-    char *	phone;
-    char *	fax;
-    char *	email;
+    gboolean      dirty;
+    const char *  name;
+    const char *  addr1;
+    const char *  addr2;
+    const char *  addr3;
+    const char *  addr4;
+    const char *  phone;
+    const char *  fax;
+    const char *  email;
 };
 
 struct _gncAddressClass
@@ -393,14 +393,10 @@ gncAddressFree (GncAddress *addr)
 /* Set functions */
 
 #define SET_STR(obj, member, str) { \
-	char * tmp; \
-	\
 	if (member == str) return; \
 	if (!g_strcmp0 (member, str)) return; \
 	gncAddressBeginEdit (obj); \
-	tmp = CACHE_INSERT (str); \
-	CACHE_REMOVE (member); \
-	member = tmp; \
+	CACHE_REPLACE(member, str); \
 	}
 
 void gncAddressSetName (GncAddress *addr, const char *name)
diff --git a/libgnucash/engine/gncBillTerm.c b/libgnucash/engine/gncBillTerm.c
index 93c03f6a7..fb6f2bb15 100644
--- a/libgnucash/engine/gncBillTerm.c
+++ b/libgnucash/engine/gncBillTerm.c
@@ -39,8 +39,8 @@ struct _gncBillTerm
     QofInstance     inst;
 
     /* 'visible' data fields directly manipulated by user */
-    char *          name;
-    char *          desc;
+    const char *    name;
+    const char *    desc;
     GncBillTermType type;
     gint            due_days;
     gint            disc_days;
@@ -72,13 +72,9 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
 #define _GNC_MOD_NAME        GNC_ID_BILLTERM
 
 #define SET_STR(obj, member, str) { \
-        char * tmp; \
-        \
         if (!g_strcmp0 (member, str)) return; \
         gncBillTermBeginEdit (obj); \
-        tmp = CACHE_INSERT (str); \
-        CACHE_REMOVE (member); \
-        member = tmp; \
+        CACHE_REPLACE(member, str); \
         }
 
 AS_STRING_DEC(GncBillTermType, ENUM_TERMS_TYPE)
diff --git a/libgnucash/engine/gncCustomer.c b/libgnucash/engine/gncCustomer.c
index 7d0c47939..ddb03aee0 100644
--- a/libgnucash/engine/gncCustomer.c
+++ b/libgnucash/engine/gncCustomer.c
@@ -53,9 +53,9 @@ struct _gncCustomer
     QofInstance     inst;
 
     /* The following fields are identical to 'vendor' */
-    char *          id;
-    char *          name;
-    char *          notes;
+    const char *    id;
+    const char *    name;
+    const char *    notes;
     GncBillTerm *   terms;
     GncAddress *    addr;
     gnc_commodity * currency;
@@ -371,13 +371,9 @@ static void gncCustomerFree (GncCustomer *cust)
 /* Set Functions */
 
 #define SET_STR(obj, member, str) { \
-        char * tmp; \
-        \
         if (!g_strcmp0 (member, str)) return; \
         gncCustomerBeginEdit (obj); \
-        tmp = CACHE_INSERT (str); \
-        CACHE_REMOVE (member); \
-        member = tmp; \
+        CACHE_REPLACE(member, str); \
         }
 
 void gncCustomerSetID (GncCustomer *cust, const char *id)
diff --git a/libgnucash/engine/gncEmployee.c b/libgnucash/engine/gncEmployee.c
index 7515d12e2..293b52dcb 100644
--- a/libgnucash/engine/gncEmployee.c
+++ b/libgnucash/engine/gncEmployee.c
@@ -47,15 +47,15 @@ static void empl_handle_qof_events (QofInstance *entity, QofEventId event_type,
 struct _gncEmployee
 {
     QofInstance     inst;
-    char *          id;
-    char *          username;
+    const char *    id;
+    const char *    username;
     GncAddress *    addr;
     gnc_commodity * currency;
     gboolean        active;
     gnc_numeric *   balance;
 
-    char *          language;
-    char *          acl;
+    const char *    language;
+    const char *    acl;
     gnc_numeric     workday;
     gnc_numeric     rate;
 
@@ -481,13 +481,9 @@ static void gncEmployeeFree (GncEmployee *employee)
 /* Set Functions */
 
 #define SET_STR(obj, member, str) { \
-        char * tmp; \
-        \
         if (!g_strcmp0 (member, str)) return; \
         gncEmployeeBeginEdit (obj); \
-        tmp = CACHE_INSERT (str); \
-        CACHE_REMOVE (member); \
-        member = tmp; \
+        CACHE_REPLACE (member, str); \
         }
 
 void gncEmployeeSetID (GncEmployee *employee, const char *id)
diff --git a/libgnucash/engine/gncEntry.c b/libgnucash/engine/gncEntry.c
index d48c65845..b96754463 100644
--- a/libgnucash/engine/gncEntry.c
+++ b/libgnucash/engine/gncEntry.c
@@ -44,9 +44,9 @@ struct _gncEntry
 
     time64	date;
     time64	date_entered;
-    char *	desc;
-    char *	action;
-    char *	notes;
+    const char *	desc;
+    const char *	action;
+    const char *	notes;
     gnc_numeric 	quantity;
 
     /* customer invoice data */
@@ -191,13 +191,9 @@ gboolean gncEntryPaymentStringToType (const char *str, GncEntryPaymentType *type
 #define _GNC_MOD_NAME GNC_ID_ENTRY
 
 #define SET_STR(obj, member, str) { \
-	char * tmp; \
-	\
 	if (!g_strcmp0 (member, str)) return; \
 	gncEntryBeginEdit (obj); \
-	tmp = CACHE_INSERT (str); \
-	CACHE_REMOVE (member); \
-	member = tmp; \
+	CACHE_REPLACE (member, str); \
 	}
 
 static inline void mark_entry (GncEntry *entry);
diff --git a/libgnucash/engine/gncInvoice.c b/libgnucash/engine/gncInvoice.c
index 5d489cb13..6ab155f81 100644
--- a/libgnucash/engine/gncInvoice.c
+++ b/libgnucash/engine/gncInvoice.c
@@ -50,11 +50,11 @@ struct _gncInvoice
 {
     QofInstance   inst;
 
-    char          *id;
-    char          *notes;
+    const char    *id;
+    const char    *notes;
     gboolean      active;
 
-    char          *billing_id;
+    const char    *billing_id;
     char          *printname;
     GncBillTerm   *terms;
     GList         *entries;
@@ -87,13 +87,9 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
 #define GNC_INVOICE_DOCLINK "assoc_uri" // this is the old name for the document link, kept for compatibility
 
 #define SET_STR(obj, member, str) { \
-    char * tmp; \
-    \
     if (!g_strcmp0 (member, str)) return; \
     gncInvoiceBeginEdit (obj); \
-    tmp = CACHE_INSERT (str); \
-    CACHE_REMOVE (member); \
-    member = tmp; \
+    CACHE_REPLACE (member, str); \
     }
 
 static void mark_invoice (GncInvoice *invoice);
diff --git a/libgnucash/engine/gncJob.c b/libgnucash/engine/gncJob.c
index bb9635a01..46fb843d6 100644
--- a/libgnucash/engine/gncJob.c
+++ b/libgnucash/engine/gncJob.c
@@ -41,9 +41,9 @@
 struct _gncJob
 {
     QofInstance inst;
-    char *        id;
-    char *        name;
-    char *        desc;
+    const char *  id;
+    const char *  name;
+    const char *  desc;
     GncOwner      owner;
     gboolean      active;
 };
@@ -269,13 +269,9 @@ static void gncJobFree (GncJob *job)
 /* Set Functions */
 
 #define SET_STR(obj, member, str) { \
-        char * tmp; \
-        \
         if (!g_strcmp0 (member, str)) return; \
         gncJobBeginEdit (obj); \
-        tmp = CACHE_INSERT (str); \
-        CACHE_REMOVE (member); \
-        member = tmp; \
+        CACHE_REPLACE (member, str); \
         }
 
 void gncJobSetID (GncJob *job, const char *id)
diff --git a/libgnucash/engine/gncOrder.c b/libgnucash/engine/gncOrder.c
index fbf1b3bd9..24b3901f5 100644
--- a/libgnucash/engine/gncOrder.c
+++ b/libgnucash/engine/gncOrder.c
@@ -43,16 +43,16 @@ struct _gncOrder
 {
     QofInstance inst;
 
-    char *	id;
-    char *	notes;
-    gboolean 	active;
-
-    char *	reference;
-    char *	printname;
-    GncOwner	owner;
-    GList *	entries;
-    time64 	opened;
-    time64 	closed;
+    const char * id;
+    const char * notes;
+    gboolean     active;
+
+    const char * reference;
+    char *       printname;
+    GncOwner     owner;
+    GList *      entries;
+    time64       opened;
+    time64       closed;
 };
 
 struct _gncOrderClass
@@ -65,13 +65,9 @@ static QofLogModule log_module = GNC_MOD_BUSINESS;
 #define _GNC_MOD_NAME	GNC_ID_ORDER
 
 #define SET_STR(obj, member, str) { \
-	char * tmp; \
-	\
 	if (!g_strcmp0 (member, str)) return; \
 	gncOrderBeginEdit (obj); \
-	tmp = CACHE_INSERT (str); \
-	CACHE_REMOVE (member); \
-	member = tmp; \
+	CACHE_REPLACE (member, str); \
 	}
 
 static inline void mark_order (GncOrder *order);
diff --git a/libgnucash/engine/gncTaxTable.c b/libgnucash/engine/gncTaxTable.c
index 182bd0552..3cd689db5 100644
--- a/libgnucash/engine/gncTaxTable.c
+++ b/libgnucash/engine/gncTaxTable.c
@@ -37,7 +37,7 @@
 struct _gncTaxTable
 {
     QofInstance     inst;
-    char *          name;
+    const char *    name;
     GncTaxTableEntryList*  entries;
     time64          modtime;      /* internal date of last modtime */
 
@@ -136,13 +136,9 @@ gncTaxIncludedStringToType (const char *str, GncTaxIncluded *type)
 #define _GNC_MOD_NAME        GNC_ID_TAXTABLE
 
 #define SET_STR(obj, member, str) { \
-        char * tmp; \
-        \
         if (!g_strcmp0 (member, str)) return; \
         gncTaxTableBeginEdit (obj); \
-        tmp = CACHE_INSERT (str); \
-        CACHE_REMOVE (member); \
-        member = tmp; \
+        CACHE_REPLACE (member, str); \
         }
 
 static inline void
diff --git a/libgnucash/engine/gncVendor.c b/libgnucash/engine/gncVendor.c
index 709664314..67af18c61 100644
--- a/libgnucash/engine/gncVendor.c
+++ b/libgnucash/engine/gncVendor.c
@@ -52,9 +52,9 @@ struct _gncVendor
 {
     QofInstance     inst;
 
-    char *          id;
-    char *          name;
-    char *          notes;
+    const char *    id;
+    const char *    name;
+    const char *    notes;
     GncBillTerm *   terms;
     GncAddress *    addr;
     gnc_commodity * currency;
@@ -512,13 +512,9 @@ static void gncVendorFree (GncVendor *vendor)
 /* Set Functions */
 
 #define SET_STR(obj, member, str) { \
-        char * tmp; \
-        \
         if (!g_strcmp0 (member, str)) return; \
         gncVendorBeginEdit (obj); \
-        tmp = CACHE_INSERT (str); \
-        CACHE_REMOVE (member); \
-        member = tmp; \
+        CACHE_REPLACE (member, str); \
         }
 
 void gncVendorSetID (GncVendor *vendor, const char *id)
diff --git a/libgnucash/engine/kvp-frame.cpp b/libgnucash/engine/kvp-frame.cpp
index 60a46edf2..6ab5bc5a6 100644
--- a/libgnucash/engine/kvp-frame.cpp
+++ b/libgnucash/engine/kvp-frame.cpp
@@ -50,7 +50,7 @@ KvpFrameImpl::KvpFrameImpl(const KvpFrameImpl & rhs) noexcept
     std::for_each(rhs.m_valuemap.begin(), rhs.m_valuemap.end(),
         [this](const map_type::value_type & a)
         {
-            auto key = static_cast<char *>(qof_string_cache_insert(a.first));
+            auto key = qof_string_cache_insert(a.first);
             auto val = new KvpValueImpl(*a.second);
             this->m_valuemap.insert({key,val});
         }
diff --git a/libgnucash/engine/qof-string-cache.cpp b/libgnucash/engine/qof-string-cache.cpp
index aa1b89702..68e4fe479 100644
--- a/libgnucash/engine/qof-string-cache.cpp
+++ b/libgnucash/engine/qof-string-cache.cpp
@@ -106,7 +106,7 @@ qof_string_cache_remove(const char * key)
 
 /* If the key exists in the cache, increment the refcount.  Otherwise,
  * add it with a refcount of 1. */
-char *
+const char *
 qof_string_cache_insert(const char * key)
 {
     if (key)
@@ -132,10 +132,10 @@ qof_string_cache_insert(const char * key)
     return NULL;
 }
 
-char *
+const char *
 qof_string_cache_replace(char const * dst, char const * src)
 {
-    char * tmp {qof_string_cache_insert (src)};
+    const char * tmp {qof_string_cache_insert (src)};
     qof_string_cache_remove (dst);
     return tmp;
 }
diff --git a/libgnucash/engine/qof-string-cache.h b/libgnucash/engine/qof-string-cache.h
index f45ff1b19..f8be51c5d 100644
--- a/libgnucash/engine/qof-string-cache.h
+++ b/libgnucash/engine/qof-string-cache.h
@@ -84,11 +84,11 @@ void qof_string_cache_remove(const char * key);
 /** You can use this function with g_hash_table_insert(), for the key
    (or value), as long as you use the destroy notifier above.
 */
-char * qof_string_cache_insert(const char * key);
+const char * qof_string_cache_insert(const char * key);
 
 /** Same as CACHE_REPLACE below, but safe to call from C++.
  */
-char * qof_string_cache_replace(const char * dst, const char * src);
+const char * qof_string_cache_replace(const char * dst, const char * src);
 
 #define CACHE_INSERT(str) qof_string_cache_insert((str))
 #define CACHE_REMOVE(str) qof_string_cache_remove((str))
@@ -101,7 +101,7 @@ char * qof_string_cache_replace(const char * dst, const char * src);
  * It avoids unnecessary ejection by doing INSERT before REMOVE.
 */
 #define CACHE_REPLACE(dst, src) do {          \
-        gpointer tmp = CACHE_INSERT((src));   \
+        const char *tmp = CACHE_INSERT((src));   \
         CACHE_REMOVE((dst));                  \
         (dst) = tmp;                          \
     } while (0)
diff --git a/libgnucash/engine/qofbook.cpp b/libgnucash/engine/qofbook.cpp
index c768296ea..adb1ff790 100644
--- a/libgnucash/engine/qofbook.cpp
+++ b/libgnucash/engine/qofbook.cpp
@@ -613,7 +613,7 @@ qof_book_get_collection (const QofBook *book, QofIdType entity_type)
         col = qof_collection_new (entity_type);
         g_hash_table_insert(
             book->hash_of_collections,
-            qof_string_cache_insert(entity_type), col);
+            (gpointer)qof_string_cache_insert(entity_type), col);
     }
     return col;
 }
diff --git a/libgnucash/engine/test/test-qof-string-cache.c b/libgnucash/engine/test/test-qof-string-cache.c
index f03c01032..f43a1081b 100644
--- a/libgnucash/engine/test/test-qof-string-cache.c
+++ b/libgnucash/engine/test/test-qof-string-cache.c
@@ -55,10 +55,10 @@ test_qof_string_cache( void )
     /* Strings added to the cache should always return the same string address
      * as long as the refcount > 0. */
     gchar str[100];
-    gchar* str1_1;
-    gchar* str1_2;
-    gchar* str1_3;
-    gchar* str1_4;
+    const gchar* str1_1;
+    const gchar* str1_2;
+    const gchar* str1_3;
+    const gchar* str1_4;
 
     strncpy(str, "str1", sizeof(str));
     str1_1 = qof_string_cache_insert(str);      /* Refcount = 1 */
diff --git a/libgnucash/engine/test/utest-Account.cpp b/libgnucash/engine/test/utest-Account.cpp
index 35f411322..b54163cd0 100644
--- a/libgnucash/engine/test/utest-Account.cpp
+++ b/libgnucash/engine/test/utest-Account.cpp
@@ -305,8 +305,8 @@ setup (Fixture *fixture, gconstpointer pData)
     auto accts = g_hash_table_new (g_str_hash, g_str_equal);
     guint ind;
 
-    auto root_str = static_cast<char*>(CACHE_INSERT("root"));
-    g_hash_table_insert (accts, root_str, root);
+    auto root_str = CACHE_INSERT("root");
+    g_hash_table_insert (accts, (gpointer)root_str, root);
     fixture->func = _utest_account_fill_functions ();
     if (parms == NULL)
     {
diff --git a/libgnucash/engine/test/utest-Split.cpp b/libgnucash/engine/test/utest-Split.cpp
index 660210b16..93637627c 100644
--- a/libgnucash/engine/test/utest-Split.cpp
+++ b/libgnucash/engine/test/utest-Split.cpp
@@ -79,8 +79,8 @@ setup (Fixture *fixture, gconstpointer pData)
     xaccSplitSetParent (fixture->split, txn);
     xaccTransCommitEdit (txn);
     gnc_lot_set_account (lot, acc);
-    fixture->split->action = static_cast<char*>(CACHE_INSERT ("foo"));
-    fixture->split->memo = static_cast<char*>(CACHE_INSERT ("bar"));
+    fixture->split->action = CACHE_INSERT ("foo");
+    fixture->split->memo = CACHE_INSERT ("bar");
     fixture->split->acc = acc;
     fixture->split->lot = lot;
     fixture->split->parent = txn;
diff --git a/libgnucash/engine/test/utest-Transaction.cpp b/libgnucash/engine/test/utest-Transaction.cpp
index 3cf10ebb8..beba27bab 100644
--- a/libgnucash/engine/test/utest-Transaction.cpp
+++ b/libgnucash/engine/test/utest-Transaction.cpp
@@ -137,16 +137,16 @@ setup (Fixture *fixture, gconstpointer pData)
     xaccAccountSetCommodity (fixture->acc2, fixture->curr);
     txn->date_posted = posted;
     txn->date_entered = entered;
-    split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split1->memo = CACHE_INSERT ("foo");
+    split1->action = CACHE_INSERT ("bar");
     split1->amount = gnc_numeric_create (100000, 1000);
     split1->value = gnc_numeric_create (3200, 240);
     split2->amount = gnc_numeric_create (-3200, 240);
     split2->value = gnc_numeric_create (-3200, 240);
     split1->acc = fixture->acc1;
     split2->acc = fixture->acc2;
-    txn->num = static_cast<char*>(CACHE_INSERT ("123"));
-    txn->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+    txn->num = CACHE_INSERT ("123");
+    txn->description = CACHE_INSERT ("Waldo Pepper");
     xaccTransBeginEdit (txn);
     {
         xaccTransSetCurrency (txn, fixture->curr);
@@ -722,7 +722,7 @@ test_xaccFreeTransaction (Fixture *fixture, gconstpointer pData)
     /* so the "free" doesn't, leaving the structure for us to test */
     g_object_ref (txn);
     g_object_ref (orig);
-    orig->num = static_cast<char*>(CACHE_INSERT (txn_num));
+    orig->num = CACHE_INSERT (txn_num);
     txn->orig = orig;
 
     fixture->func->xaccFreeTransaction (txn);
@@ -849,17 +849,17 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
     g_assert (xaccTransEqual (txn1, clone, TRUE, FALSE, TRUE, TRUE));
     g_assert_cmpint (check->hits, ==, 5);
 
-    txn1->num = g_strdup("321");
+    txn1->num = CACHE_INSERT("321");
     g_free (check->msg);
     check->msg = g_strdup ("[xaccTransEqual] num differs: 321 vs 123");
     g_assert (!xaccTransEqual (txn1, txn0, TRUE, FALSE, TRUE, TRUE));
     g_assert_cmpint (check->hits, ==, 6);
 
-    g_free(clone->num);
-    clone->num = static_cast<char*>(CACHE_INSERT("123"));
-    g_free(txn1->num);
+    g_free ((char*)clone->num);
+    clone->num = CACHE_INSERT("123");
+    CACHE_REMOVE(txn1->num);
     txn1->num = g_strdup("123");
-    clone->description = g_strdup("salt pork");
+    clone->description = CACHE_INSERT("salt pork");
     g_free (check->msg);
     check->msg = g_strdup ("[xaccTransEqual] descriptions differ: salt pork vs Waldo Pepper");
     g_assert (!xaccTransEqual (clone, txn0, TRUE, FALSE, TRUE, TRUE));
@@ -871,8 +871,8 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
 
     xaccTransBeginEdit (clone);
     cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig);
-    g_free(clone->description);
-    clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+    CACHE_REMOVE(clone->description);
+    clone->description = CACHE_INSERT ("Waldo Pepper");
     auto frame = qof_instance_get_slots (QOF_INSTANCE (clone));
     frame->set({"qux", "quux", "corge"}, new KvpValue(654.321));
     xaccTransCommitEdit (clone);
@@ -885,7 +885,7 @@ test_xaccTransEqual (Fixture *fixture, gconstpointer pData)
     g_assert_cmpint (check->hits, ==, 9);
     xaccTransBeginEdit (clone);
     cleanup->msg = g_strdup_printf (cleanup_fmt, clone->orig);
-    clone->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+    clone->description = CACHE_INSERT ("Waldo Pepper");
     frame->set({"qux", "quux", "corge"}, new KvpValue(123.456));
     xaccTransCommitEdit (clone);
     g_free (cleanup->msg);
@@ -975,8 +975,8 @@ test_xaccTransGetImbalanceValue (Fixture *fixture, gconstpointer pData)
     g_assert (gnc_numeric_equal (xaccTransGetImbalanceValue (fixture->txn),
                                  gnc_numeric_zero ()));
     split1->acc = fixture->acc1;
-    split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split1->memo = CACHE_INSERT ("foo");
+    split1->action = CACHE_INSERT ("bar");
     split1->amount = gnc_numeric_create (100000, 1000);
     split1->value = gnc_numeric_create (3200, 240);
     xaccTransBeginEdit (fixture->txn);
@@ -1001,8 +1001,8 @@ test_xaccTransGetImbalance (Fixture *fixture, gconstpointer pData)
     g_assert_cmpint (g_list_length (mlist), ==, 0);
 
     split1->acc = fixture->acc1;
-    split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split1->memo = CACHE_INSERT ("foo");
+    split1->action = CACHE_INSERT ("bar");
     split1->amount = gnc_numeric_create (100000, 1000);
     split1->value = gnc_numeric_create (3200, 240);
     xaccTransBeginEdit (fixture->txn);
@@ -1043,13 +1043,13 @@ test_xaccTransGetImbalance_trading (Fixture *fixture,
     g_assert (!xaccTransIsBalanced (fixture->txn));
     /* Make it look like a proper trading accounts transactionm */
     split1->acc = acc1;
-    split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split1->memo = CACHE_INSERT ("foo");
+    split1->action = CACHE_INSERT ("bar");
     split1->amount = gnc_numeric_create (-10000, 100);
     split1->value = gnc_numeric_create (-3200, 240);
     split2->acc = acc2;
-    split2->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split2->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split2->memo = CACHE_INSERT ("foo");
+    split2->action = CACHE_INSERT ("bar");
     split2->amount = gnc_numeric_create (3000, 240);
     split2->value = gnc_numeric_create (3200, 240);
     xaccTransBeginEdit (fixture->txn);
@@ -1091,8 +1091,8 @@ test_xaccTransIsBalanced (Fixture *fixture, gconstpointer pData)
     g_assert (xaccTransIsBalanced (fixture->txn));
 
     split1->acc = fixture->acc1;
-    split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split1->memo = CACHE_INSERT ("foo");
+    split1->action = CACHE_INSERT ("bar");
     split1->amount = gnc_numeric_create (100000, 1000);
     split1->value = gnc_numeric_create (3200, 240);
     xaccTransBeginEdit (fixture->txn);
@@ -1124,13 +1124,13 @@ test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData)
     /* The setup transaction is unbalanced in a trading-accounts environment. */
     g_assert (!xaccTransIsBalanced (fixture->txn));
     split1->acc = acc1;
-    split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split1->memo = CACHE_INSERT ("foo");
+    split1->action = CACHE_INSERT ("bar");
     split1->amount = gnc_numeric_create (3200, 240);
     split1->value = gnc_numeric_create (3200, 240);
     split2->acc = acc2;
-    split2->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split2->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split2->memo = CACHE_INSERT ("foo");
+    split2->action = CACHE_INSERT ("bar");
     split2->amount = gnc_numeric_create (-10000, 100);
     split2->value = gnc_numeric_create (-3000, 240);
     xaccTransBeginEdit (fixture->txn);
@@ -1592,8 +1592,8 @@ test_xaccTransCommitEdit (void)
     xaccAccountSetCommodity (acc1, comm);
     xaccAccountSetCommodity (acc2, curr);
     txn->date_posted = posted;
-    split1->memo = static_cast<char*>(CACHE_INSERT ("foo"));
-    split1->action = static_cast<char*>(CACHE_INSERT ("bar"));
+    split1->memo = CACHE_INSERT ("foo");
+    split1->action = CACHE_INSERT ("bar");
     split1->amount = gnc_numeric_create (100000, 1000);
     split1->value = gnc_numeric_create (3200, 240);
     /* Note, deliberately imblanced to force xaccTransScrubImbalance
@@ -1603,8 +1603,8 @@ test_xaccTransCommitEdit (void)
     split2->value = gnc_numeric_create (-3000, 240);
     split1->acc = acc1;
     split2->acc = acc2;
-    txn->num = static_cast<char*>(CACHE_INSERT ("123"));
-    txn->description = static_cast<char*>(CACHE_INSERT ("Waldo Pepper"));
+    txn->num = CACHE_INSERT ("123");
+    txn->description = CACHE_INSERT ("Waldo Pepper");
     xaccTransBeginEdit (txn);
     {
         xaccTransSetCurrency (txn, curr);
@@ -1664,8 +1664,8 @@ test_xaccTransRollbackEdit (Fixture *fixture, gconstpointer pData)
     orig = txn->orig;
     base_frame = orig->inst.kvp_data; /* DupeTransaction copies the kvp_frame */
     g_object_ref (orig); /* Keep rollback from actually freeing it */
-    txn->num = static_cast<char*>(CACHE_INSERT("321"));
-    txn->description = static_cast<char*>(CACHE_INSERT("salt peanuts"));
+    txn->num = CACHE_INSERT("321");
+    txn->description = CACHE_INSERT("salt peanuts");
     txn->common_currency = NULL;
     txn->inst.kvp_data = NULL;
     txn->date_entered = new_entered;
@@ -1757,19 +1757,19 @@ test_xaccTransOrder_num_action (Fixture *fixture, gconstpointer pData)
     g_assert_cmpint (xaccTransOrder_num_action (NULL, NULL, NULL, NULL), ==, 0);
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==,
                      qof_instance_guid_compare (txnA, txnB));
-    txnB->description = static_cast<char*>(CACHE_INSERT ("Salt Peanuts"));
+    txnB->description = CACHE_INSERT ("Salt Peanuts");
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), >=, 1);
     txnB->date_entered += 1;
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
-    txnB->num = static_cast<char*>(CACHE_INSERT ("101"));
+    txnB->num = CACHE_INSERT ("101");
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, 1);
-    txnA->num = static_cast<char*>(CACHE_INSERT ("12a"));
+    txnA->num = CACHE_INSERT ("12a");
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
-    txnB->num = static_cast<char*>(CACHE_INSERT ("12c"));
+    txnB->num = CACHE_INSERT ("12c");
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
-    txnB->num = static_cast<char*>(CACHE_INSERT ("12"));
+    txnB->num = CACHE_INSERT ("12");
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, 1);
-    txnB->num = static_cast<char*>(CACHE_INSERT ("one-oh-one"));
+    txnB->num = CACHE_INSERT ("one-oh-one");
     g_assert_cmpint (xaccTransOrder_num_action (txnA, NULL, txnB, NULL), ==, -1);
     g_assert_cmpint (xaccTransOrder_num_action (txnA, "24", txnB, "42"), ==, -1);
     txnB->date_posted -= 1;

commit 4132939612aff073f3d2afab77171b9c9d59881d
Author: Simon Arlott <sa.me.uk>
Date:   Sun Jul 11 18:51:41 2021 +0100

    Avoid leaking string cache entries for "" in Transaction and Split
    
    When g_object_new() is used, the strings that default to "" are added to
    the string cache. These are then not correctly removed when updating them
    with new values when cloning a Transaction/Split.
    
    Use CACHE_REPLACE instead of CACHE_INSERT.

diff --git a/libgnucash/engine/Split.c b/libgnucash/engine/Split.c
index 8fb6091fa..5ca91507b 100644
--- a/libgnucash/engine/Split.c
+++ b/libgnucash/engine/Split.c
@@ -564,8 +564,8 @@ xaccDupeSplit (const Split *s)
     split->orig_acc = s->orig_acc;
     split->lot = s->lot;
 
-    split->memo = CACHE_INSERT(s->memo);
-    split->action = CACHE_INSERT(s->action);
+    CACHE_REPLACE(split->memo, s->memo);
+    CACHE_REPLACE(split->action, s->action);
 
     qof_instance_copy_kvp (QOF_INSTANCE (split), QOF_INSTANCE (s));
 
diff --git a/libgnucash/engine/Transaction.c b/libgnucash/engine/Transaction.c
index e7c3cba0a..9db75799a 100644
--- a/libgnucash/engine/Transaction.c
+++ b/libgnucash/engine/Transaction.c
@@ -602,8 +602,8 @@ dupe_trans (const Transaction *from)
 
     to = g_object_new (GNC_TYPE_TRANSACTION, NULL);
 
-    to->num         = CACHE_INSERT (from->num);
-    to->description = CACHE_INSERT (from->description);
+    CACHE_REPLACE (to->num, from->num);
+    CACHE_REPLACE (to->description, from->description);
 
     to->splits = g_list_copy (from->splits);
     for (node = to->splits; node; node = node->next)
@@ -647,8 +647,8 @@ xaccTransCloneNoKvp (const Transaction *from)
 
     to->date_entered    = from->date_entered;
     to->date_posted     = from->date_posted;
-    to->num             = CACHE_INSERT (from->num);
-    to->description     = CACHE_INSERT (from->description);
+    CACHE_REPLACE (to->num, from->num);
+    CACHE_REPLACE (to->description, from->description);
     to->common_currency = from->common_currency;
     qof_instance_copy_version(to, from);
     qof_instance_copy_version_check(to, from);

commit bf8fe1123c6acad373514ba8160727cdd0501e52
Author: Simon Arlott <sa.me.uk>
Date:   Sun Jul 11 15:04:43 2021 +0100

    Commit root accounts after loading from XML
    
    The root accounts start with a non-zero editlevel because BeginEdit is
    called for them during loading but not committed after loading.
    
    If the book is then closed without performing any further edits that would
    require a commit, the Account book_end process does nothing because the
    root account is still being edited and so none of the accounts are freed.

diff --git a/libgnucash/backend/xml/io-gncxml-v2.cpp b/libgnucash/backend/xml/io-gncxml-v2.cpp
index c956c8db5..d5b438be7 100644
--- a/libgnucash/backend/xml/io-gncxml-v2.cpp
+++ b/libgnucash/backend/xml/io-gncxml-v2.cpp
@@ -699,6 +699,7 @@ qof_session_load_from_xml_file_v2_full (
     QofBookFileType type)
 {
     Account* root;
+    Account* template_root;
     sixtp_gdv2* gd;
     sixtp* top_parser;
     sixtp* main_parser;
@@ -851,12 +852,18 @@ qof_session_load_from_xml_file_v2_full (
     /* commit all groups, this completes the BeginEdit started when the
      * account_end_handler finished reading the account.
      */
+    template_root = gnc_book_get_template_root (book);
     gnc_account_foreach_descendant (root,
                                     (AccountCb) xaccAccountCommitEdit,
                                     NULL);
-    gnc_account_foreach_descendant (gnc_book_get_template_root (book),
+    gnc_account_foreach_descendant (template_root,
                                     (AccountCb) xaccAccountCommitEdit,
                                     NULL);
+    /* if these exist in the XML file then they will be uncommitted */
+    if (qof_instance_get_editlevel(root) != 0)
+        xaccAccountCommitEdit(root);
+    if (qof_instance_get_editlevel(template_root) != 0)
+        xaccAccountCommitEdit(template_root);
 
     /* start logging again */
     xaccLogEnable ();
diff --git a/libgnucash/backend/xml/test/test-load-xml2.cpp b/libgnucash/backend/xml/test/test-load-xml2.cpp
index 945470078..455d20216 100644
--- a/libgnucash/backend/xml/test/test-load-xml2.cpp
+++ b/libgnucash/backend/xml/test/test-load-xml2.cpp
@@ -108,6 +108,9 @@ test_load_file (const char* filename)
     do_test (gnc_account_get_book (root) == book,
              "book and root account don't match");
 
+    do_test (qof_instance_get_editlevel(root) == 0,
+             "root account editlevel is not 0");
+
     do_test_args (qof_session_get_error (session) == ERR_BACKEND_NO_ERR,
                   "session load xml2", __FILE__, __LINE__,
                   "qof error=%d for file [%s]",

commit f15402a9a603f0cb8e70f8ff89a5235e8be494f5
Author: Simon Arlott <sa.me.uk>
Date:   Sun Jul 11 14:53:57 2021 +0100

    Load test data from XML properly
    
    If qof_session_new() is called without a book then qof_session_load()
    won't do anything.
    
    Set up a book for it to use.

diff --git a/libgnucash/backend/xml/test/test-load-xml2.cpp b/libgnucash/backend/xml/test/test-load-xml2.cpp
index 945470078..8eaf19749 100644
--- a/libgnucash/backend/xml/test/test-load-xml2.cpp
+++ b/libgnucash/backend/xml/test/test-load-xml2.cpp
@@ -92,7 +92,8 @@ test_load_file (const char* filename)
     g_log_set_handler (logdomain, loglevel,
                        (GLogFunc)test_checked_handler, &check);
 
-    auto session = qof_session_new (nullptr);
+    auto book = qof_book_new();
+    auto session = qof_session_new (book);
 
     remove_locks (filename);
 
@@ -102,7 +103,6 @@ test_load_file (const char* filename)
                        ignore_lock ? SESSION_READ_ONLY : SESSION_NORMAL_OPEN);
 
     qof_session_load (session, NULL);
-    auto book = qof_session_get_book (session);
 
     auto root = gnc_book_get_root_account (book);
     do_test (gnc_account_get_book (root) == book,
@@ -115,6 +115,7 @@ test_load_file (const char* filename)
     /* Uncomment the line below to generate corrected files */
     /*    qof_session_save( session, NULL ); */
     qof_session_end (session);
+    qof_book_destroy (book);
 }
 
 int



Summary of changes:
 bindings/core-utils.i                              |   7 +
 bindings/engine-common.i                           |   8 +
 bindings/engine.i                                  |   3 +
 bindings/python/example_scripts/Invoice.tex.tmpl   |  12 +-
 bindings/python/example_scripts/Invoice_2.tex.tmpl |  12 +-
 bindings/python/example_scripts/latex_invoices.py  |  19 +-
 gnucash/gnome-utils/dialog-account.c               |  16 +-
 gnucash/gnome-utils/dialog-commodity.c             |   2 +
 gnucash/gnome-utils/dialog-preferences.c           |   2 +-
 gnucash/gnome-utils/gnc-account-sel.c              |   4 +-
 .../gnome-utils/gnc-cell-renderer-popup-entry.c    |   6 +-
 gnucash/gnome-utils/gnc-component-manager.c        |   4 +-
 gnucash/gnome-utils/gnc-file.c                     |   1 +
 gnucash/gnome/assistant-acct-period.c              |  11 +-
 gnucash/gnome/assistant-hierarchy.c                |   4 +-
 gnucash/gnome/reconcile-view.c                     |   1 +
 gnucash/gnome/window-reconcile.c                   |  15 +-
 gnucash/import-export/import-account-matcher.c     |   9 +-
 gnucash/import-export/import-backend.c             | 100 -------
 gnucash/import-export/import-backend.h             |   9 -
 gnucash/import-export/import-main-matcher.c        |  52 ++--
 gnucash/import-export/import-utilities.c           |  23 --
 gnucash/import-export/import-utilities.h           |  11 -
 gnucash/report/gnc-report.c                        |   4 +-
 gnucash/report/reports/reports.scm                 |   2 -
 .../report/reports/standard/new-owner-report.scm   |   5 -
 libgnucash/app-utils/options.scm                   |   2 +
 libgnucash/backend/dbi/gnc-backend-dbi.cpp         |   4 +-
 libgnucash/backend/sql/gnc-transaction-sql.cpp     |   7 +-
 libgnucash/backend/xml/io-gncxml-v2.cpp            |   9 +-
 libgnucash/backend/xml/test/test-load-xml2.cpp     |   8 +-
 libgnucash/core-utils/gnc-filepath-utils.cpp       |  26 +-
 libgnucash/core-utils/gnc-glib-utils.c             |  32 +++
 libgnucash/core-utils/gnc-glib-utils.h             |  16 ++
 libgnucash/core-utils/test/test-gnc-glib-utils.c   |  57 ++++
 libgnucash/engine/Account.cpp                      | 294 ++++++++-------------
 libgnucash/engine/Account.h                        |   4 +-
 libgnucash/engine/AccountP.h                       |   6 +-
 libgnucash/engine/ScrubBusiness.c                  |   1 +
 libgnucash/engine/Split.c                          |   6 +-
 libgnucash/engine/SplitP.h                         |   8 +-
 libgnucash/engine/Transaction.c                    |  21 +-
 libgnucash/engine/TransactionP.h                   |   4 +-
 libgnucash/engine/gnc-budget.c                     |   4 +-
 libgnucash/engine/gnc-commodity.c                  |  26 +-
 libgnucash/engine/gnc-pricedb-p.h                  |   2 +-
 libgnucash/engine/gnc-pricedb.c                    |   6 +-
 libgnucash/engine/gncAddress.c                     |  26 +-
 libgnucash/engine/gncBillTerm.c                    |  10 +-
 libgnucash/engine/gncCustomer.c                    |  12 +-
 libgnucash/engine/gncEmployee.c                    |  14 +-
 libgnucash/engine/gncEntry.c                       |  12 +-
 libgnucash/engine/gncInvoice.c                     |  12 +-
 libgnucash/engine/gncJob.c                         |  12 +-
 libgnucash/engine/gncOrder.c                       |  26 +-
 libgnucash/engine/gncTaxTable.c                    |   8 +-
 libgnucash/engine/gncVendor.c                      |  12 +-
 libgnucash/engine/kvp-frame.cpp                    |   2 +-
 libgnucash/engine/qof-string-cache.cpp             |  13 +-
 libgnucash/engine/qof-string-cache.h               |   6 +-
 libgnucash/engine/qofbook.cpp                      |   2 +-
 libgnucash/engine/qofinstance.cpp                  |   5 +-
 libgnucash/engine/test/test-qof-string-cache.c     |   8 +-
 libgnucash/engine/test/utest-Account.cpp           |  20 +-
 libgnucash/engine/test/utest-Split.cpp             |   4 +-
 libgnucash/engine/test/utest-Transaction.cpp       |  78 +++---
 po/de.po                                           |  22 +-
 po/he.po                                           |  77 +++---
 po/sv.po                                           | 193 ++++++--------
 po/zh_CN.po                                        | 253 +++++++++---------
 70 files changed, 780 insertions(+), 932 deletions(-)



More information about the gnucash-changes mailing list