gnucash maint: Bug 647805 - Interdependent report options fail to change state after using apply for a limited number of times

Geert Janssens gjanssens at code.gnucash.org
Fri Sep 15 14:59:24 EDT 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/3bc0241e (commit)
	from  https://github.com/Gnucash/gnucash/commit/b9d6e025 (commit)



commit 3bc0241e7428fd26bac16f189a8670cb9e1b2040
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Fri Sep 15 20:13:51 2017 +0200

    Bug 647805 - Interdependent report options fail to change state after using apply for a limited number of times
    
    On the C side an SCM guile_options object is wrapped in a GNCOptionDB. This is
    however a multi-to-one relationship. That is there can be several GNCOptionDBs
    wrapping the same SCM guile_options object. This happens for example when
    a report is open together with its Options dialog. Both manager their own
    GNCOptionDB object while both wrap the same SCM guile_options.
    
    The problem in this bug was caused by a callback function picking the wrong
    GNCOptionDB based on the given SCM guile_options object. Which GNCOptionDB
    got picked was completely dependent on how g_hash_table_foreach would cycle
    through the stored dbs. It appears this is dependent on the in-memory order
    of the hash table's values.
    
    By being more selective of which GNCOptionDB we're looking for, this
    could be circumvented. The GNCOptionDB we want is the one related to the open
    report options dialog. This GNCOptionDB is different from the one managed by
    the report tab in that it has callbacks set. So from now on we search for
    a GNCOptionDB that wraps the give SCM guile_options and has one particular
    callback set.

diff --git a/src/app-utils/option-util.c b/src/app-utils/option-util.c
index 75d65eb..22b24a6 100644
--- a/src/app-utils/option-util.c
+++ b/src/app-utils/option-util.c
@@ -233,35 +233,6 @@ gnc_option_db_new(SCM guile_options)
     return odb;
 }
 
-typedef struct
-{
-    GNCOptionDB *odb;
-    SCM guile_options;
-} ODBFindInfo;
-
-static void
-option_db_finder (gpointer key, gpointer value, gpointer data)
-{
-    ODBFindInfo *find_info = data;
-    GNCOptionDB *odb = value;
-
-    if (odb && (odb->guile_options == find_info->guile_options))
-        find_info->odb = odb;
-}
-
-static GNCOptionDB *
-gnc_option_db_find (SCM guile_options)
-{
-    ODBFindInfo find_info;
-
-    find_info.odb = NULL;
-    find_info.guile_options = guile_options;
-
-    g_hash_table_foreach (option_dbs, option_db_finder, &find_info);
-
-    return find_info.odb;
-}
-
 /* Create an option DB for a particular data type */
 GNCOptionDB *
 gnc_option_db_new_for_type(QofIdType id_type)
@@ -2634,6 +2605,27 @@ gnc_date_option_value_get_relative (SCM option_value)
     return scm_call_1 (getters.date_option_value_relative, option_value);
 }
 
+static int
+find_option_db_with_selectable_pred (gpointer key, gpointer value, gpointer data)
+{
+    SCM guile_options = data;
+    GNCOptionDB *odb = value;
+
+    if (odb && (odb->guile_options == guile_options)
+        && odb->set_selectable    )
+        return TRUE;
+
+    return FALSE;
+
+}
+
+static GNCOptionDB *
+find_option_db_with_selectable (SCM guile_options)
+{
+    return g_hash_table_find (option_dbs, find_option_db_with_selectable_pred,
+                              guile_options);
+}
+
 /*******************************************************************\
  * gnc_option_db_set_option_selectable_by_name                     *
  *   set the sensitivity of the option widget                      *
@@ -2645,7 +2637,7 @@ gnc_date_option_value_get_relative (SCM option_value)
  * Return: SCM value                                               *
 \*******************************************************************/
 void
-gnc_option_db_set_option_selectable_by_name(SCM guile_option,
+gnc_option_db_set_option_selectable_by_name(SCM guile_options,
         const char *section,
         const char *name,
         gboolean selectable)
@@ -2653,7 +2645,7 @@ gnc_option_db_set_option_selectable_by_name(SCM guile_option,
     GNCOptionDB *odb;
     GNCOption *option;
 
-    odb = gnc_option_db_find (guile_option);
+    odb = find_option_db_with_selectable (guile_options);
     if (!odb)
         return;
 



Summary of changes:
 src/app-utils/option-util.c | 54 +++++++++++++++++++--------------------------
 1 file changed, 23 insertions(+), 31 deletions(-)



More information about the gnucash-changes mailing list