diff --git a/gnucash/gnome-utils/dialog-preferences.c b/gnucash/gnome-utils/dialog-preferences.c index 2e4e779233..98c0801b45 100644 --- a/gnucash/gnome-utils/dialog-preferences.c +++ b/gnucash/gnome-utils/dialog-preferences.c @@ -1153,9 +1153,8 @@ gnc_prefs_connect_one (const gchar *name, GList* child = gtk_container_get_children(GTK_CONTAINER(widget)); widget_child = child->data; g_list_free(child); - DEBUG(" %s - hbox", name); - DEBUG("Hbox widget type is %s and name is %s", gtk_widget_get_name(GTK_WIDGET(widget_child)), name); - + DEBUG(" %s - box", name); + DEBUG("Box widget type is %s and name is %s", gtk_widget_get_name(GTK_WIDGET(widget_child)), name); if (GNC_IS_CURRENCY_EDIT(widget_child)) { DEBUG(" %s - currency_edit", name); @@ -1163,7 +1162,7 @@ gnc_prefs_connect_one (const gchar *name, } else if (GNC_IS_PERIOD_SELECT(widget_child)) { - DEBUG(" %s - period_Select", name); + DEBUG(" %s - period_select", name); gnc_prefs_connect_period_select(GNC_PERIOD_SELECT(widget_child), name ); } else if (GNC_IS_DATE_EDIT(widget_child)) @@ -1173,7 +1172,7 @@ gnc_prefs_connect_one (const gchar *name, } else if (GTK_FILE_CHOOSER_BUTTON(widget_child)) { - DEBUG(" %s - file chooser buuton", name); + DEBUG(" %s - file chooser button", name); gnc_prefs_connect_file_chooser_button(GTK_FILE_CHOOSER_BUTTON(widget_child), name ); } } @@ -1344,7 +1343,9 @@ gnc_preferences_dialog_create(GtkWindow *parent) gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0); DEBUG("We have the following interesting widgets:"); + gnc_prefs_block_all(); // Block All Registered callbacks g_hash_table_foreach(prefs_table, (GHFunc)gnc_prefs_connect_one, dialog); + gnc_prefs_unblock_all(); // UnBlock All Registered callbacks DEBUG("Done with interesting widgets."); /* Other stuff */ diff --git a/libgnucash/app-utils/gnc-gsettings.c b/libgnucash/app-utils/gnc-gsettings.c index 6e174eebb1..d2f0fc69d6 100644 --- a/libgnucash/app-utils/gnc-gsettings.c +++ b/libgnucash/app-utils/gnc-gsettings.c @@ -53,6 +53,8 @@ static GHashTable *schema_hash = NULL; static const gchar *gsettings_prefix; static xmlExternalEntityLoader defaultEntityLoader = NULL; +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"; @@ -131,6 +133,19 @@ static GSettings * gnc_gsettings_get_settings_ptr (const gchar *schema_str) return gset; } +static void +handlers_hash_block_helper (gpointer key, gpointer settings_ptr, gpointer pointer) +{ + g_signal_handler_block (settings_ptr, (gulong)key); // block signal_handler + PINFO("Block handler_id %ld for settings_ptr %p", (gulong)key, settings_ptr); +} + +static void +handlers_hash_unblock_helper (gpointer key, gpointer settings_ptr, gpointer pointer) +{ + g_signal_handler_unblock (settings_ptr, (gulong)key); // unblock signal_handler + PINFO("UnBlock handler_id %ld for settings_ptr %p", (gulong)key, settings_ptr); +} /************************************************************/ /* GSettings Utilities */ @@ -203,6 +218,17 @@ gnc_gsettings_register_cb (const gchar *schema, retval = g_signal_connect (settings_ptr, signal, G_CALLBACK (func), user_data); + if (!registered_handlers_hash) + registered_handlers_hash = g_hash_table_new (g_direct_hash, g_direct_equal); + + if (retval != 0) + { + g_hash_table_insert (registered_handlers_hash, + GINT_TO_POINTER(retval), settings_ptr); //key, value + + PINFO("schema: %s, key: %s, settings_ptr: %p, handler_id: %ld", + schema, key, settings_ptr, retval); + } g_free (signal); LEAVE(""); @@ -218,6 +244,7 @@ gnc_gsettings_remove_cb_by_func (const gchar *schema, { gint matched = 0; GQuark quark = 0; + gulong handler_id = 0; GSettings *settings_ptr = gnc_gsettings_get_settings_ptr (schema); g_return_if_fail (G_IS_SETTINGS (settings_ptr)); @@ -228,7 +255,7 @@ gnc_gsettings_remove_cb_by_func (const gchar *schema, if ((key) && (gnc_gsettings_is_valid_key(settings_ptr, key))) quark = g_quark_from_string (key); - matched = g_signal_handlers_disconnect_matched ( + handler_id = g_signal_handler_find ( settings_ptr, G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, g_signal_lookup ("changed", G_TYPE_SETTINGS), /* signal_id */ @@ -236,7 +263,24 @@ gnc_gsettings_remove_cb_by_func (const gchar *schema, NULL, /* closure */ G_CALLBACK (func), /* callback function */ user_data); - LEAVE ("Schema: %s, key: %s - removed %d handlers for 'changed' signal", schema, key, matched); + + while (handler_id) + { + matched ++; + gnc_gsettings_remove_cb_by_id (schema, handler_id); + + handler_id = g_signal_handler_find ( + settings_ptr, + G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, + g_signal_lookup ("changed", G_TYPE_SETTINGS), /* signal_id */ + quark, /* signal_detail */ + NULL, /* closure */ + G_CALLBACK (func), /* callback function */ + user_data); + } + + LEAVE ("Schema: %s, key: %s, hashtable size: %d - removed %d handlers for 'changed' signal", + schema, key, g_hash_table_size (registered_handlers_hash), matched); } @@ -247,7 +291,15 @@ gnc_gsettings_remove_cb_by_id (const gchar *schema, GSettings *settings_ptr = gnc_gsettings_get_settings_ptr (schema); g_return_if_fail (G_IS_SETTINGS (settings_ptr)); + ENTER (); + g_signal_handler_disconnect (settings_ptr, handlerid); + + // remove the handlerid from the registerered_handlers_hash + g_hash_table_remove (registered_handlers_hash, GINT_TO_POINTER(handlerid)); + + LEAVE ("Schema: %s, handlerid: %d, hashtable size: %d - removed for handler", + schema, handlerid, g_hash_table_size (registered_handlers_hash)); } @@ -600,6 +652,8 @@ void gnc_gsettings_load_backend (void) prefsbackend->set_value = gnc_gsettings_set_value; prefsbackend->reset = gnc_gsettings_reset; prefsbackend->reset_group = gnc_gsettings_reset_schema; + prefsbackend->block_all = gnc_gsettings_block_all; + prefsbackend->unblock_all = gnc_gsettings_unblock_all; LEAVE("Prefsbackend bind = %p", prefsbackend->bind); } @@ -850,3 +904,21 @@ void gnc_gsettings_version_upgrade (void) if (cur_maj_min > old_maj_min) gnc_gsettings_set_int (GNC_PREFS_GROUP_GENERAL, GNC_PREF_VERSION, cur_maj_min); } + + +void gnc_gsettings_block_all (void) +{ + PINFO("block registered_handlers_hash list size is %d", + g_hash_table_size (registered_handlers_hash)); + g_hash_table_foreach (registered_handlers_hash, + handlers_hash_block_helper, NULL); +} + + +void gnc_gsettings_unblock_all (void) +{ + PINFO("unblock registered_handlers_hash list size is %d", + g_hash_table_size (registered_handlers_hash)); + g_hash_table_foreach (registered_handlers_hash, + handlers_hash_unblock_helper, NULL); +} diff --git a/libgnucash/app-utils/gnc-gsettings.h b/libgnucash/app-utils/gnc-gsettings.h index 44dcb9910f..7f058684e5 100644 --- a/libgnucash/app-utils/gnc-gsettings.h +++ b/libgnucash/app-utils/gnc-gsettings.h @@ -86,6 +86,16 @@ void gnc_gsettings_set_prefix (const gchar *prefix); 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 @{ */ diff --git a/libgnucash/core-utils/gnc-prefs-p.h b/libgnucash/core-utils/gnc-prefs-p.h index b780fee549..a5ab85580e 100644 --- a/libgnucash/core-utils/gnc-prefs-p.h +++ b/libgnucash/core-utils/gnc-prefs-p.h @@ -104,6 +104,10 @@ typedef struct void (*reset_group) (const gchar *group); + void (*block_all) (void); + + void (*unblock_all) (void); + } PrefsBackend; extern PrefsBackend *prefsbackend; diff --git a/libgnucash/core-utils/gnc-prefs.c b/libgnucash/core-utils/gnc-prefs.c index 73eec923d3..d59e91f636 100644 --- a/libgnucash/core-utils/gnc-prefs.c +++ b/libgnucash/core-utils/gnc-prefs.c @@ -368,3 +368,14 @@ gboolean gnc_prefs_is_set_up (void) return (prefsbackend !=NULL); } +void gnc_prefs_block_all (void) +{ + if (prefsbackend && prefsbackend->block_all) + (prefsbackend->block_all) (); +} + +void gnc_prefs_unblock_all (void) +{ + if (prefsbackend && prefsbackend->unblock_all) + (prefsbackend->unblock_all) (); +} diff --git a/libgnucash/core-utils/gnc-prefs.h b/libgnucash/core-utils/gnc-prefs.h index 41c241d461..c665a26214 100644 --- a/libgnucash/core-utils/gnc-prefs.h +++ b/libgnucash/core-utils/gnc-prefs.h @@ -124,6 +124,14 @@ guint gnc_prefs_get_long_version( void ); */ gboolean gnc_prefs_is_set_up (void); +/** Block all preference callbacks +*/ +void gnc_prefs_block_all (void); + +/** Unblock all preferences callbacks +*/ +void gnc_prefs_unblock_all (void); + /** @name Listening for changes @{ */