gnucash maint: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Sat Oct 16 04:49:14 EDT 2021


Updated	 via  https://github.com/Gnucash/gnucash/commit/d4e4062c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/24fa2899 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/26b2d7ca (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c6103a5c (commit)
	from  https://github.com/Gnucash/gnucash/commit/16184daf (commit)



commit d4e4062c9310f50729c94b73e9f2bd80382fabfb
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sat Oct 16 10:48:55 2021 +0200

    Remove redundant function declaration
    
    gnc_load_scm_configuration is declared and defined in gnucash-core-app.

diff --git a/gnucash/gnucash-commands.hpp b/gnucash/gnucash-commands.hpp
index ae3607147..01511d584 100644
--- a/gnucash/gnucash-commands.hpp
+++ b/gnucash/gnucash-commands.hpp
@@ -40,9 +40,5 @@ namespace Gnucash {
     int report_list (void);
     int report_show (const bo_str& file_to_load,
                      const bo_str& run_report);
-
-    // A helper function to load scm config files (SYSCONFIGDIR/config
-    // and USERCONFIGDIR/config-user.scm) on demand
-    void gnc_load_scm_config(void);
 }
 #endif

commit 24fa289952257cb8a2f2b9d59024be59d05888e3
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Wed Oct 6 18:53:36 2021 +0200

    GSettings - rework internal helper functions to use more C++

diff --git a/libgnucash/app-utils/gnc-gsettings.cpp b/libgnucash/app-utils/gnc-gsettings.cpp
index 8394e4d9f..d78ac8a07 100644
--- a/libgnucash/app-utils/gnc-gsettings.cpp
+++ b/libgnucash/app-utils/gnc-gsettings.cpp
@@ -45,13 +45,10 @@ extern "C" {
 
 namespace bpt = boost::property_tree;
 
-#define GSET_SCHEMA_PREFIX "org.gnucash.GnuCash"
-#define GSET_SCHEMA_OLD_PREFIX "org.gnucash"
-#define CLIENT_TAG  "%s-%s-client"
-#define NOTIFY_TAG  "%s-%s-notify_id"
-
-static GHashTable *schema_hash = NULL;
-static const gchar *gsettings_prefix;
+constexpr auto GSET_SCHEMA_PREFIX = std::string_view("org.gnucash.GnuCash");
+constexpr auto GSET_SCHEMA_OLD_PREFIX = std::string_view("org.gnucash");
+constexpr auto CLIENT_TAG = "%s-%s-client";
+constexpr auto NOTIFY_TAG = "%s-%s-notify_id";
 
 static GHashTable *registered_handlers_hash = NULL;
 
@@ -62,41 +59,23 @@ using pref_id = std::pair<std::string, std::string>;
 
 static std::map<pref_id, pref_id> oldkeys_map;
 
-/* Function declarations */
-
-
-#include <glib.h>
-gchar *gnc_gsettings_normalize_schema_name (const gchar *name);
-
-const gchar *gnc_gsettings_get_prefix (void);
-
+/* API Function declarations */
 void gnc_gsettings_block_all (void);
-
-
 void gnc_gsettings_unblock_all (void);
 
-
 gulong gnc_gsettings_register_cb (const char *schema,
                                   const gchar *key,
                                   gpointer func,
                                   gpointer user_data);
-
-
 void gnc_gsettings_remove_cb_by_func (const gchar *schema,
                                       const gchar *key,
                                       gpointer func,
                                       gpointer user_data);
-
-
 void gnc_gsettings_remove_cb_by_id (const gchar *schema,
                                     guint id);
-
-
 guint gnc_gsettings_register_any_cb (const gchar *schema,
                                      gpointer func,
                                      gpointer user_data);
-
-
 void gnc_gsettings_remove_any_cb_by_func (const gchar *schema,
                                           gpointer func,
                                           gpointer user_data);
@@ -146,66 +125,65 @@ void gnc_gsettings_reset_schema (const gchar *schema);
 void gnc_gsettings_version_upgrade (void);
 
 
-/************************************************************/
-/*               Internal helper functions                  */
-/************************************************************/
-static gboolean gnc_gsettings_is_valid_key(GSettings *settings, const gchar *key)
-{
-    gchar **keys = NULL;
-    gint i = 0;
-    gboolean found = FALSE;
-    GSettingsSchema *schema;
+/* Internal helper functions */
 
+static bool gnc_gsettings_is_valid_key(GSettings *settings, const gchar *key)
+{
     // Check if the key is valid key within settings
-    if (!G_IS_SETTINGS(settings))
-        return FALSE;
+    if (!G_IS_SETTINGS (settings))
+        return false;
 
-    g_object_get (settings, "settings-schema", &schema, NULL);
+    GSettingsSchema *schema;
+    g_object_get (settings, "settings-schema", &schema, nullptr);
     if (!schema)
-        return FALSE;
+        return false;
 
-    keys = g_settings_schema_list_keys (schema);
-    while (keys && keys[i])
-    {
-        if (!g_strcmp0(key, keys[i]))
-        {
-            found = TRUE;
-            break;
-        }
-        i++;
-    }
-    g_strfreev(keys);
+    auto keys = g_settings_schema_list_keys (schema);
+    auto found = g_strv_contains (keys, key);
+    g_strfreev (keys);
 
     return found;
 }
 
+static std::map<std::string, GSettings*> schema_map;
+
+static std::string
+gnc_gsettings_normalize_schema_name (const gchar *name)
+{
+    auto result = std::string_view(name).find (GSET_SCHEMA_PREFIX);
+    if (!name)
+        return std::string (GSET_SCHEMA_PREFIX);
+    if ((std::string_view (name).find (GSET_SCHEMA_PREFIX) == 0) ||
+        (std::string_view (name).find (GSET_SCHEMA_OLD_PREFIX) ==  0))
+        return name;
+
+    return std::string(GSET_SCHEMA_PREFIX) + "." + name;
+}
+
 static GSettings * gnc_gsettings_get_settings_ptr (const gchar *schema_str)
 {
-    GSettings *gset = NULL;
-    gchar *full_name = gnc_gsettings_normalize_schema_name (schema_str);
 
     ENTER("");
-    if (!schema_hash)
-        schema_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-    gset = static_cast<GSettings*> (g_hash_table_lookup (schema_hash, full_name));
-    DEBUG ("Looking for schema %s returned gsettings %p", full_name, gset);
+    auto full_name = gnc_gsettings_normalize_schema_name (schema_str);
+    auto result = schema_map.find (full_name);
 
-    if (!gset)
+    GSettings *gset = nullptr;
+    if (result != schema_map.end())
+    {
+        gset = result->second;
+        DEBUG ("Looking for schema %s returned gsettings %p", full_name.c_str(), gset);
+    }
+    else
     {
         auto schema_source {g_settings_schema_source_get_default()};
-        auto schema {g_settings_schema_source_lookup(schema_source, full_name,
+        auto schema {g_settings_schema_source_lookup(schema_source, full_name.c_str(),
                                                      FALSE)};
         gset = g_settings_new_full (schema, nullptr, nullptr);
-        DEBUG ("Created gsettings object %p for schema %s", gset, full_name);
-        if (G_IS_SETTINGS(gset))
-            g_hash_table_insert (schema_hash, full_name, gset);
+        DEBUG ("Created gsettings object %p for schema %s", gset, full_name.c_str());
+        if (G_IS_SETTINGS (gset))
+            schema_map.insert ({full_name, gset});
         else
-            PWARN ("Ignoring attempt to access unknown gsettings schema %s", full_name);
-    }
-    else
-    {
-        g_free(full_name);
+            PWARN ("Ignoring attempt to access unknown gsettings schema %s", full_name.c_str());
     }
     LEAVE("");
     return gset;
@@ -225,34 +203,6 @@ handlers_hash_unblock_helper (gpointer key, gpointer settings_ptr, gpointer poin
     PINFO("UnBlock handler_id %ld for settings_ptr %p", (gulong)key, settings_ptr);
 }
 
-/************************************************************/
-/*                      GSettings Utilities                 */
-/************************************************************/
-
-const gchar *
-gnc_gsettings_get_prefix (void)
-{
-    return GSET_SCHEMA_PREFIX;
-}
-
-gchar *
-gnc_gsettings_normalize_schema_name (const gchar *name)
-{
-    if (!name)
-    {
-        /* Need to return a newly allocated string */
-        return g_strdup(GSET_SCHEMA_PREFIX);
-    }
-    if (g_str_has_prefix (name, GSET_SCHEMA_PREFIX) ||
-       (g_str_has_prefix (name, GSET_SCHEMA_OLD_PREFIX)))
-    {
-        /* Need to return a newly allocated string */
-        return g_strdup(name);
-    }
-
-    return g_strjoin(".", GSET_SCHEMA_PREFIX, name, NULL);
-}
-
 
 /************************************************************/
 /*                   Change notification                    */
@@ -962,8 +912,9 @@ void gnc_gsettings_version_upgrade (void)
      */
     ENTER("Start of settings transform routine.");
 
+    auto od_maj_min_schema = std::string(GSET_SCHEMA_OLD_PREFIX) + "." + GNC_PREFS_GROUP_GENERAL;
     auto ogG_maj_min = gnc_gsettings_get_user_value (GNC_PREFS_GROUP_GENERAL, GNC_PREF_VERSION);
-    auto og_maj_min = gnc_gsettings_get_user_value (GSET_SCHEMA_OLD_PREFIX "." GNC_PREFS_GROUP_GENERAL, GNC_PREF_VERSION);
+    auto og_maj_min = gnc_gsettings_get_user_value (od_maj_min_schema.c_str(), GNC_PREF_VERSION);
 
     if (!ogG_maj_min && !og_maj_min)
     {
@@ -973,7 +924,7 @@ void gnc_gsettings_version_upgrade (void)
 
     auto old_maj_min = 0;
     if (!ogG_maj_min)
-        old_maj_min = gnc_gsettings_get_int (GSET_SCHEMA_OLD_PREFIX "." GNC_PREFS_GROUP_GENERAL, GNC_PREF_VERSION);
+        old_maj_min = gnc_gsettings_get_int (od_maj_min_schema.c_str(), GNC_PREF_VERSION);
     else
     {
         g_variant_unref (ogG_maj_min);

commit 26b2d7ca7878776a7c6777cd30e1b19185b72983
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Wed Oct 6 17:11:00 2021 +0200

    GSettings - make most of the api private
    
    All preference calls should happen via the gnc_prefs_... apis.
    The gnc_gsettings_... apis are an internal implementation of this.

diff --git a/libgnucash/app-utils/gnc-gsettings.cpp b/libgnucash/app-utils/gnc-gsettings.cpp
index 9e16f07ec..8394e4d9f 100644
--- a/libgnucash/app-utils/gnc-gsettings.cpp
+++ b/libgnucash/app-utils/gnc-gsettings.cpp
@@ -62,6 +62,90 @@ using pref_id = std::pair<std::string, std::string>;
 
 static std::map<pref_id, pref_id> oldkeys_map;
 
+/* Function declarations */
+
+
+#include <glib.h>
+gchar *gnc_gsettings_normalize_schema_name (const gchar *name);
+
+const gchar *gnc_gsettings_get_prefix (void);
+
+void gnc_gsettings_block_all (void);
+
+
+void gnc_gsettings_unblock_all (void);
+
+
+gulong gnc_gsettings_register_cb (const char *schema,
+                                  const gchar *key,
+                                  gpointer func,
+                                  gpointer user_data);
+
+
+void gnc_gsettings_remove_cb_by_func (const gchar *schema,
+                                      const gchar *key,
+                                      gpointer func,
+                                      gpointer user_data);
+
+
+void gnc_gsettings_remove_cb_by_id (const gchar *schema,
+                                    guint id);
+
+
+guint gnc_gsettings_register_any_cb (const gchar *schema,
+                                     gpointer func,
+                                     gpointer user_data);
+
+
+void gnc_gsettings_remove_any_cb_by_func (const gchar *schema,
+                                          gpointer func,
+                                          gpointer user_data);
+
+
+void gnc_gsettings_bind (const gchar *schema,
+                         /*@ null @*/ const gchar *key,
+                         gpointer object,
+                         const gchar *property);
+
+
+gboolean gnc_gsettings_get_bool (const gchar *schema,
+                                 /*@ null @*/ const gchar *key);
+gint gnc_gsettings_get_int (const gchar *schema,
+                            const gchar *key);
+gdouble gnc_gsettings_get_float (const gchar *schema,
+                                 const gchar *key);
+gchar *gnc_gsettings_get_string (const gchar *schema,
+                                 const gchar *key);
+gint gnc_gsettings_get_enum (const gchar *schema,
+                             const gchar *key);
+GVariant *gnc_gsettings_get_value (const gchar *schema,
+                                   const gchar *key);
+
+gboolean gnc_gsettings_set_bool (const gchar *schema,
+                                 const gchar *key,
+                                 gboolean value);
+gboolean gnc_gsettings_set_int (const gchar *schema,
+                                const gchar *key,
+                                gint value);
+gboolean gnc_gsettings_set_float (const gchar *schema,
+                                  const gchar *key,
+                                  gdouble value);
+gboolean gnc_gsettings_set_string (const gchar *schema,
+                                   const gchar *key,
+                                   const gchar *value);
+gboolean gnc_gsettings_set_enum (const gchar *schema,
+                                 const gchar *key,
+                                 gint value);
+gboolean gnc_gsettings_set_value (const gchar *schema,
+                                  const gchar *key,
+                                  GVariant *value);
+void gnc_gsettings_reset (const gchar *schema,
+                          const gchar *key);
+
+void gnc_gsettings_reset_schema (const gchar *schema);
+void gnc_gsettings_version_upgrade (void);
+
+
 /************************************************************/
 /*               Internal helper functions                  */
 /************************************************************/
diff --git a/libgnucash/app-utils/gnc-gsettings.h b/libgnucash/app-utils/gnc-gsettings.h
index 7f2d9f3a0..cf853e737 100644
--- a/libgnucash/app-utils/gnc-gsettings.h
+++ b/libgnucash/app-utils/gnc-gsettings.h
@@ -50,561 +50,11 @@
 #ifndef GNC_GSETTINGS_H
 #define GNC_GSETTINGS_H
 
-#include <glib.h>
-
-/** Convert a partial schema name into a complete gsettings schema name.
- *
- *  This function takes a partial gsettings schema name and converts
- *  it into a fully qualified gsettings schema name.  It does this
- *  by prepending the standard prefix for all gnucash schemas.
- *  If the schema is already fully qualified (i.e. begins with the
- *  default schema prefix, this routine will not change it.
- *
- *  @param name A partial schema name.  The default prefix is
- *  prepended to this name to produce a fully qualified schema
- *  name.
- *
- *  @return This function returns a string pointer to the fully
- *  qualified schema name.  It is the caller's responsibility to
- *  free this string.
- */
-gchar *gnc_gsettings_normalize_schema_name (const gchar *name);
-
-/** Get the default gsettings schema prefix.
- *  If none was set explicitly, this defaults to
- *  "org.gnucash.GnuCash"
- */
-const gchar *gnc_gsettings_get_prefix (void);
-
-
-/** Block all prefs callbacks, used while preference dialog is loaded.
- */
-void gnc_gsettings_block_all (void);
-
-
-/** UnBlock all prefs callbacks, used while preference dialog is loaded.
- */
-void gnc_gsettings_unblock_all (void);
-
-
-/** @name Listening for changes
- @{
-*/
-
-
-/** Register a callback for when a specific key in the settings
- *  schema is changed.  Any time the key's value changes, the routine
- *  will be invoked and will be passed both the changed gsettings entry
- *  and the user data passed to this function.
- *
- *  @param schema This value contains the schema name of the key
- *  to watch.
- *
- *  @param key This value contains the name of the key to watch.
- *
- *  @param func This is a pointer to the function to call when the key
- *  changes.
- *
- *  @param user_data This pointer will be passed to the callback
- *  function.
- *
- *  @return This function returns the handler id for the registered
- *  callback.
- */
-gulong gnc_gsettings_register_cb (const char *schema,
-                                  const gchar *key,
-                                  gpointer func,
-                                  gpointer user_data);
-
-
-/** Remove a function that was registered for a callback when a
- *  specific key in the settings schema changed.  Both the func and
- *  user_data arguments are used to match up the callback to remove.
- *  If no matching func and user_data are found to be registered
- *  for the given key, nothing will happen.
- *
- *  @param schema This value contains the schema name of the key
- *  that is being watched.
- *
- *  @param key This value contains the name of the key being watched.
- *
- *  @param func This is a pointer to the function that was registered
- *  earlier.
- *
- *  @param user_data This pointer was passed to the callback
- *  function when it was registered.
- */
-void gnc_gsettings_remove_cb_by_func (const gchar *schema,
-                                      const gchar *key,
-                                      gpointer func,
-                                      gpointer user_data);
-
-
-/** Remove a function that was registered for a callback when a
- *  specific key in the settings schema changed.  The handler id
- *  that was generated when the callback was registered is
- *  use to find the callback to remove.
- *  If no handler id is found nothing will happen.
- *
- *  @param schema This value contains the schema name of the key
- *  that is being watched.
- *
- *  @param id The handler id of the callback to be removed.
- */
-void gnc_gsettings_remove_cb_by_id (const gchar *schema,
-                                    guint id);
-
-
-/** Register a callback for when any key in the settings schema
- *  is changed.  Any time the value of a key in this schema changes,
- *  the routine will be invoked and will be passed the specified
- *  user data.
- *
- *  @param schema This value contains the name of the schema
- *  that is being watched.
- *
- *  @param func This is a pointer to the function to call when a key
- *  changes.
- *
- *  @param user_data This pointer will be passed to the callback
- *  function.
- */
-guint gnc_gsettings_register_any_cb (const gchar *schema,
-                                     gpointer func,
-                                     gpointer user_data);
-
-
-/** Remove a function that was registered for a callback when any key
- *  in the given settings schema changed.  Both the func and user_data
- *  arguments are used to match up the callback to remove.
- *  If no matching func and user_data are found to be registered
- *  for the given key, nothing will happen.
- *
- *  @param schema This value contains the name of the schema
- *  that is being watched.
- *
- *  @param func This is a pointer to the function that was registered
- *  earlier.
- *
- *  @param user_data This pointer was passed to the callback
- *  function when it was registered.
- *
- *  @note there is no gnc_settings_remove_any_cb_by_id. Use
- *  gnc_settings_remove_cb_by_id instead if you want to
- *  remove a callback set with gnc_settings_register_any_cb
- *  by its handler id.
- */
-void gnc_gsettings_remove_any_cb_by_func (const gchar *schema,
-        gpointer func,
-        gpointer user_data);
-
-
-/** Bind a setting to a g_object property. When this succeeds a change
- *  of the setting will automatically update the bound object property
- *  and vice versa.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @param object The object to be bound.
- *
- *  @param property The property of the object to bind to.
- */
-void gnc_gsettings_bind (const gchar *schema,
-                         /*@ null @*/ const gchar *key,
-                         gpointer object,
-                         const gchar *property);
-
-
-/** @name GSettings Get Functions
- @{
-*/
-
-/** Get a boolean value from GSettings.
- *
- *  Retrieve a TRUE/FALSE value from GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @return This function returns the TRUE or FALSE value stored at
- *  the requested key in the gsettings database.  If the key has never
- *  been set, this function passes on the default value returned by
- *  GSettings as specified in the schema for this key.
- */
-gboolean gnc_gsettings_get_bool (const gchar *schema,
-                                 /*@ null @*/ const gchar *key);
-
-/** Get an integer value from GSettings.
- *
- *  Retrieve an integer value from GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @return This function returns the integer value stored at the
- *  requested key in the gsettings database.  If the key has never been
- *  set, this function passes on the default value returned by GSettings
- *  as specified in the schema for this key.  If there is an error in
- *  processing, this function passed on the value of zero as returned
- *  by GSettings.
- */
-gint gnc_gsettings_get_int (const gchar *schema,
-                            const gchar *key);
-
-/** Get an float value from GSettings.
- *
- *  Retrieve an float value from GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @return This function returns the float value stored at the
- *  requested key in the gsettings database.  If the key has never been
- *  set, this function passes on the default value returned by GSettings
- *  as specified in the schema for this key.  If there is an error in
- *  processing, this function passed on the value of zero as returned
- *  by GSettings.
- */
-gdouble gnc_gsettings_get_float (const gchar *schema,
-                                 const gchar *key);
-
-/** Get a string value from GSettings.
- *
- *  Retrieve an string value from GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @return This function returns the string value stored at the
- *  requested key in the gsettings database.  If the key has never been
- *  set, this function passes on the default value returned by GSettings
- *  as specified in the schema for this key.  If there is an error in
- *  processing, this function passed on the NULL value as returned by
- *  GSettings.  It is the callers responsibility to free any string
- *  returned by this function.
- */
-gchar *gnc_gsettings_get_string (const gchar *schema,
-                                 const gchar *key);
-
-/** Get an enum value from GSettings.
- *
- *  Retrieve an enum value from GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @return This function returns the enum value stored at the
- *  requested key in the gsettings database.  If the key has never been
- *  set, this function passes on the default value returned by GSettings
- *  as specified in the schema for this key.  If there is an error in
- *  processing, this function passed on the value of zero as returned
- *  by GSettings.
- */
-gint gnc_gsettings_get_enum (const gchar *schema,
-                             const gchar *key);
-
-/** Get an arbitrary combination of values from GSettings.
- *
- *  Retrieve an arbitrary combination of values from GSettings.   This
- *  combination of values can be anything that can be encapsulated
- *  in a GVariant structure.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @return This function returns the a GVariant encapsulating the combination
- *  of values stored at the requested key in the gsettings database.
- *  If the key has never been set, this function passes on the default
- *  value returned by GSettings as specified in the schema for this key.
- *  If there is an error in processing, this function passed on the NULL
- *  value as returned by GSettings.
- *  It is the callers responsibility to free any GVariant data returned
- *  by this function.
- */
-GVariant *gnc_gsettings_get_value (const gchar *schema,
-                                   const gchar *key);
-
-/** @} */
-
-/** @name GSettings Set/Unset Functions
- @{
-*/
-
-
-/** Store a boolean value into GSettings.
- *
- *  Store a boolean value into GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @param value The boolean value to be stored.
- *
- *  @return This function returns true if the value was set successfully
- *  on the key or false if not.
- */
-gboolean gnc_gsettings_set_bool (const gchar *schema,
-                                 const gchar *key,
-                                 gboolean value);
-
-/** Store an integer value into GSettings.
- *
- *  Store an integer into GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @param value The integer number to be stored.
- *
- *  @return This function returns true if the value was set successfully
- *  on the key or false if not.
- */
-gboolean gnc_gsettings_set_int (const gchar *schema,
-                                const gchar *key,
-                                gint value);
-
-/** Store a float value into GSettings.
- *
- *  Store a float into GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @param value The floating point number to be stored.
- *
- *  @return This function returns true if the value was set successfully
- *  on the key or false if not.
- */
-gboolean gnc_gsettings_set_float (const gchar *schema,
-                                  const gchar *key,
-                                  gdouble value);
-
-
-/** Store a string into GSettings.
- *
- *  Store a single string into GSettings. The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @param value The string to be stored.  GSettings will make a copy of this
- *  string, so it is the callers responsibility to free the space used
- *  by this string (if necessary).
- *
- *  @return This function returns true if the value was set successfully
- *  on the key or false if not.
- */
-gboolean gnc_gsettings_set_string (const gchar *schema,
-                                   const gchar *key,
-                                   const gchar *value);
-
-/** Store an enum value into GSettings.
- *
- *  Store an enum into GSettings.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @param value The enum number to be stored.
- *
- *  @return This function returns true if the value was set successfully
- *  on the key or false if not.
- */
-gboolean gnc_gsettings_set_enum (const gchar *schema,
-                                 const gchar *key,
-                                 gint value);
-
-/** Store an arbitrary combination of values into GSettings.
- *
- *  Store an arbitrary combination of values into GSettings.  This
- *  combination of values can be anything that can be encapsulated
- *  in a GVariant structure.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- *
- *  @param value The combination of values encapsulated in a GVariant
- *  to be stored.
- *
- *  @return This function returns true if the value was set successfully
- *  on the key or false if not.
- */
-gboolean gnc_gsettings_set_value (const gchar *schema,
-                                  const gchar *key,
-                                  GVariant *value);
-
-/** Reset a key to its default value in GSettings.
- *
- *  Reset a key to its default value in GSettings.  Internally this
- *  is done by removing the value from the database.  The next attempt
- *  to read this value will return the default as specified in the
- *  GSettings schema for this key.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- *
- *  @param key This string is the name of the particular key within
- *  the named schema of gsettings.
- */
-void gnc_gsettings_reset (const gchar *schema,
-                          const gchar *key);
-
-/** Reset all keys in a schema to their default values in GSettings.
- *
- *  Reset a keys in schema to their default values in GSettings.  Internally
- *  this is done by removing the values from the database.  The next attempt
- *  to read a keys will return its default as specified in the
- *  GSettings schema for this key.  The schema name
- *  provided as argument is combined with the default gnucash schema
- *  prefix to produce a fully qualified schema name.
- *
- *  @param schema This string provides a grouping of keys within the
- *  GnuCash schema of the gsettings database.  It can be a simple string
- *  as in "history" for settings that are common to many areas of
- *  gnucash, or it can be a partial path name as in
- *  "dialogs.business.invoice" for setting that only apply to one
- *  specific area of the program.
- */
-void gnc_gsettings_reset_schema (const gchar *schema);
-
-/** @} */
-
 
 /** Configure gsettings as the backend for the gnucash preferences api.
  */
 void gnc_gsettings_load_backend (void);
 
-/** Check whether we need to adjust the user settings
- * to a newer version.
- *
- * New version of GnuCash may come with changes in the
- * settings schema. This function will take the necessary
- * steps to convert old settings to new (when possible).
- */
-void gnc_gsettings_version_upgrade (void);
-
 #endif /* GNC_GSETTINGS_H */
 /** @} */
 /** @} */
diff --git a/libgnucash/app-utils/gnc-prefs-utils.c b/libgnucash/app-utils/gnc-prefs-utils.c
index 90fd918d2..06aaadd22 100644
--- a/libgnucash/app-utils/gnc-prefs-utils.c
+++ b/libgnucash/app-utils/gnc-prefs-utils.c
@@ -22,6 +22,7 @@
 \********************************************************************/
 
 #include <config.h>
+#include <glib.h>
 
 #include "gnc-gsettings.h"
 #include "gnc-prefs-utils.h"

commit c6103a5c171f459b6ca070c61bcde939885ae613
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Wed Oct 6 16:50:57 2021 +0200

    Add structure to map migrated preferences to old ones
    
    This can be used to keep both in sync in the period between
    initial migration and eventual obsolence.
    Note only non-obsoleted, migrated preferences are tracked.
    We don't want to resync preferences that have been
    obsoleted (reset). That would nullify the whole idea
    of making them obsolete for future removal.
    
    This commit only adds the mapping, synching will follow in a future
    commit.

diff --git a/libgnucash/app-utils/gnc-gsettings.cpp b/libgnucash/app-utils/gnc-gsettings.cpp
index 17b25114b..9e16f07ec 100644
--- a/libgnucash/app-utils/gnc-gsettings.cpp
+++ b/libgnucash/app-utils/gnc-gsettings.cpp
@@ -41,6 +41,7 @@ extern "C" {
 #include <boost/property_tree/xml_parser.hpp>
 #include <fstream>
 #include <iostream>
+#include <map>
 
 namespace bpt = boost::property_tree;
 
@@ -57,6 +58,10 @@ static GHashTable *registered_handlers_hash = NULL;
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = "gnc.app-utils.gsettings";
 
+using pref_id = std::pair<std::string, std::string>;
+
+static std::map<pref_id, pref_id> oldkeys_map;
+
 /************************************************************/
 /*               Internal helper functions                  */
 /************************************************************/
@@ -313,7 +318,9 @@ void gnc_gsettings_bind (const gchar *schema,
     g_return_if_fail (G_IS_SETTINGS (settings_ptr));
 
     if (gnc_gsettings_is_valid_key (settings_ptr, key))
+    {
         g_settings_bind (settings_ptr, key, object, property, G_SETTINGS_BIND_DEFAULT);
+    }
     else
     {
         PERR ("Invalid key %s for schema %s", key, schema);
@@ -687,6 +694,10 @@ migrate_one_key (const opt_str_vec &oldpath, const opt_str_vec &oldkey,
     auto user_value = gnc_gsettings_get_user_value (oldpath->c_str(), oldkey->c_str());
     if (user_value)
         gnc_gsettings_set_value (newpath->c_str(), newkey->c_str(), user_value);
+
+    /* Add old preference to oldkeys_map so we can keep it in sync with its replacement */
+    oldkeys_map.emplace (std::make_pair(*oldpath, *oldkey),
+                         std::make_pair(*newpath, *newkey));
 }
 
 static void
@@ -700,6 +711,9 @@ obsolete_one_key (const opt_str_vec &oldpath, const opt_str_vec &oldkey)
 
     PINFO ("Resetting obsolete '%s:%s'", oldpath->c_str(), oldkey->c_str());
     gnc_gsettings_reset (oldpath->c_str(), oldkey->c_str());
+
+    /* Removve old preference to oldkeys_map. It's been reset we don't want to keep it in synch any more */
+    oldkeys_map.erase (std::make_pair(*oldpath, *oldkey));
 }
 
 static void
@@ -723,10 +737,39 @@ parse_one_release_node (bpt::ptree &pt)
                     obsolete_one_key (node.second.get_optional<std::string> ("<xmlattr>.old-path"),
                                       node.second.get_optional<std::string> ("<xmlattr>.old-key"));
                 else
-                {
                     DEBUG ("Skipping unknown node <%s>", node.first.c_str());
+            });
+}
+
+static void
+update_oldkeys_only (bpt::ptree &pt)
+{
+    /* handles oldkey tracking for release nodes that don't require full processing
+     * any more (when the preference db compatibility level is higher than what's in
+     * this release node)
+     * But even for those nodes we need to extract old preference ids to potentially
+     * keep them in sync with their replacements
+     */
+
+    std::for_each (pt.begin(), pt.end(),
+            [] (std::pair<bpt::ptree::key_type, bpt::ptree> node)
+            {
+                auto oldpath = node.second.get_optional<std::string> ("<xmlattr>.old-path");
+                auto oldkey = node.second.get_optional<std::string> ("<xmlattr>.old-key");
+                auto newpath = node.second.get_optional<std::string> ("<xmlattr>.new-path");
+                auto newkey = node.second.get_optional<std::string> ("<xmlattr>.new-key");
+
+                if ((node.first == "<xmlattr>") || (node.first == "deprecate"))
                     return;
-                }
+                else if (node.first == "migrate")
+                    /* Add old preference to oldkeys_map so we can keep it in sync with its replacement */
+                    oldkeys_map.emplace (std::make_pair(*oldpath, *oldkey),
+                                         std::make_pair(*newpath, *newkey));
+                else if (node.first == "obsolete")
+                    /* Removve old preference to oldkeys_map. It's been reset we don't want to keep it in synch any more */
+                    oldkeys_map.erase (std::make_pair(*oldpath, *oldkey));
+                else
+                    DEBUG ("Skipping unknown node <%s>", node.first.c_str());
             });
 }
 
@@ -751,13 +794,13 @@ transform_settings (int old_maj_min)
         bpt::read_xml (transform_stream, pt);
     }
     catch (bpt::xml_parser_error &e) {
-        PWARN ("Failed to parse GnuCash preferences transformation file.\n");
-        PWARN ("Error message:\n");
-        PWARN ("%s\n", e.what());
+        PWARN ("Failed to parse GnuCash preferences transformation file.");
+        PWARN ("Error message:");
+        PWARN ("%s", e.what());
         return;
     }
     catch (...) {
-        PWARN ("Unknown error while parsing GnuCash preferences transformation file.\n");
+        PWARN ("Unknown error while parsing GnuCash preferences transformation file.");
         return;
     }
 
@@ -776,15 +819,36 @@ transform_settings (int old_maj_min)
                     DEBUG ("Skipping <release> node - no version attribute found");
                     return;
                 }
+
                 if (*version <= old_maj_min)
                 {
-                    DEBUG ("Skipping <release> node - version %i is less than current compatibility level %i", *version, old_maj_min);
-                    return;
+                    DEBUG ("Already processed <release> node with version %i (current compatibility level %i). Extracting old preferences only.",
+                           *version, old_maj_min);
+                    update_oldkeys_only (node.second);
+                }
+                else
+                {
+                    DEBUG ("Found <release> node with version %i (current compatibility level %i). Processing child nodes.",
+                           *version, old_maj_min);
+                    parse_one_release_node (node.second);
                 }
-                DEBUG ("Retrieved version value '%i'", *version);
-
-                parse_one_release_node (node.second);
             });
+
+    /* oldkeys_map is generated oldkey->newkey for efficiency reasons but for
+     * subesquent use we need newkey->oldkey. So let's swap keys and values now. */
+    std::map<pref_id, pref_id> tmp_map;
+    std::for_each (oldkeys_map.begin(), oldkeys_map.end(),
+        [&tmp_map] (auto map_it)
+        {
+            tmp_map.emplace (map_it.second, map_it.first);
+            DEBUG ("Added new pref-> old_pref mapping for %s:%s -> %s:%s",
+                   map_it.second.first.c_str(),
+                   map_it.second.second.c_str(),
+                   map_it.first.first.c_str(),
+                   map_it.first.second.c_str());
+        });
+    oldkeys_map = tmp_map;
+
 }
 
 void gnc_gsettings_version_upgrade (void)



Summary of changes:
 gnucash/gnucash-commands.hpp           |   4 -
 libgnucash/app-utils/gnc-gsettings.cpp | 277 +++++++++++------
 libgnucash/app-utils/gnc-gsettings.h   | 550 ---------------------------------
 libgnucash/app-utils/gnc-prefs-utils.c |   1 +
 4 files changed, 189 insertions(+), 643 deletions(-)



More information about the gnucash-changes mailing list