From 70243bca0f6b77c6861a98a014f68f74d7a415fd Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 9 Dec 2020 00:27:45 +0100
Subject: Fixed registered signals for ephemeral panels.

---
 src/glibext/configuration.c | 40 ++++++++++++++++++++++++++++++++++++++++
 src/gui/panels/bookmarks.c  |  2 ++
 src/gui/panels/regedit.c    | 40 +++++++++++++++++++++++++---------------
 src/gui/panels/welcome.c    | 17 +++++++++++++++--
 4 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/src/glibext/configuration.c b/src/glibext/configuration.c
index c19f7ef..7fd9a98 100644
--- a/src/glibext/configuration.c
+++ b/src/glibext/configuration.c
@@ -166,6 +166,10 @@ struct _GGenConfigClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
+    /* Signaux */
+
+    void (* modified) (GGenConfig *, GCfgParam *);
+
 };
 
 
@@ -181,6 +185,9 @@ static void g_generic_config_dispose(GGenConfig *);
 /* Procède à la libération totale de la mémoire. */
 static void g_generic_config_finalize(GGenConfig *);
 
+/* Réagit à un changement de valeur pour un paramètre. */
+static void on_config_param_modified(GCfgParam *, GGenConfig *);
+
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -1183,6 +1190,13 @@ static void g_generic_config_class_init(GGenConfigClass *klass)
     object->dispose = (GObjectFinalizeFunc/* ! */)g_generic_config_dispose;
     object->finalize = (GObjectFinalizeFunc)g_generic_config_finalize;
 
+    g_signal_new("modified",
+                 G_TYPE_GEN_CONFIG,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GGenConfigClass, modified),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__OBJECT,
+                 G_TYPE_NONE, 1, G_TYPE_OBJECT);
 
 }
 
@@ -1546,6 +1560,8 @@ GCfgParam *_g_generic_config_add_param(GGenConfig *config, GCfgParam *param, boo
 
     config->params = g_list_append(config->params, param);
 
+    g_signal_connect(param, "modified", G_CALLBACK(on_config_param_modified), config);
+
  exit:
 
     if (lock)
@@ -1558,6 +1574,26 @@ GCfgParam *_g_generic_config_add_param(GGenConfig *config, GCfgParam *param, boo
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : param  = instance dont le contenu a évolué.                  *
+*                config = configuration globalement mise à jour.              *
+*                                                                             *
+*  Description : Réagit à un changement de valeur pour un paramètre.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void on_config_param_modified(GCfgParam *param, GGenConfig *config)
+{
+    g_signal_emit_by_name(config, "modified", param);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : config = configuration à mettre à jour.                      *
 *                path   = chemin d'accès au paramètre visé.                   *
 *                                                                             *
@@ -1577,9 +1613,13 @@ void g_generic_config_delete_param(GGenConfig *config, const char *path)
 
     old = _g_generic_config_search(config, path, false);
 
+    g_signal_handlers_disconnect_by_func(old, G_CALLBACK(on_config_param_modified), config);
+
     if (old != NULL)
         config->params = g_list_remove(config->params, old);
 
+    g_object_unref(G_OBJECT(old));
+
     g_generic_config_wunlock(config);
 
 }
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index b57e657..75d0a85 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -315,6 +315,8 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
 
 static void g_bookmarks_panel_dispose(GBookmarksPanel *panel)
 {
+    change_bookmarks_panel_current_content(panel, NULL, NULL);
+
     g_clear_object(&panel->binary);
 
     G_OBJECT_CLASS(g_bookmarks_panel_parent_class)->dispose(G_OBJECT(panel));
diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c
index 585cc22..47bbfa9 100644
--- a/src/gui/panels/regedit.c
+++ b/src/gui/panels/regedit.c
@@ -53,6 +53,8 @@ struct _GRegeditPanel
 {
     GPanelItem parent;                      /* A laisser en premier        */
 
+    GGenConfig *config;                     /* Configuration à afficher    */
+
     regex_t *filter;                        /* Filtre appliqué ou NULL     */
 
     GtkMenu *menu;                          /* Menu contextuel pour param. */
@@ -109,10 +111,10 @@ static char *g_regedit_panel_class_get_path(const GRegeditPanelClass *);
 
 
 /* Recharge une configuration donnée à l'affichage. */
-static void reload_config_into_treeview(GRegeditPanel *, GGenConfig *);
+static void reload_config_into_treeview(GRegeditPanel *);
 
 /* Actualise l'affichage des données d'un paramètre modifié. */
-static void on_config_param_modified(GCfgParam *, GRegeditPanel *);
+static void on_configuration_param_modified(GGenConfig *, GCfgParam *, GRegeditPanel *);
 
 /* Actualise la valeur affichée d'un paramètre de configuration. */
 static void update_config_param_value(GtkListStore *, GtkTreeIter *);
@@ -233,6 +235,9 @@ static void g_regedit_panel_init(GRegeditPanel *panel)
                                                                         _("Configuration parameters"),
                                                                         PANEL_REGEDIT_ID));
 
+    panel->config = get_main_configuration();
+    g_object_ref(G_OBJECT(panel->config));
+
     /* Représentation graphique */
 
     builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(pitem->widget));
@@ -279,7 +284,9 @@ static void g_regedit_panel_init(GRegeditPanel *panel)
 
     /* Actualisation du contenu du panneau */
 
-    reload_config_into_treeview(panel, get_main_configuration());
+    reload_config_into_treeview(panel);
+
+    g_signal_connect(panel->config, "modified", G_CALLBACK(on_configuration_param_modified), panel);
 
 }
 
@@ -298,6 +305,11 @@ static void g_regedit_panel_init(GRegeditPanel *panel)
 
 static void g_regedit_panel_dispose(GRegeditPanel *panel)
 {
+    if (panel->config != NULL)
+        g_signal_handlers_disconnect_by_func(panel->config, G_CALLBACK(on_configuration_param_modified), panel);
+
+    g_clear_object(&panel->config);
+
     G_OBJECT_CLASS(g_regedit_panel_parent_class)->dispose(G_OBJECT(panel));
 
 }
@@ -405,8 +417,7 @@ GPanelItem *g_regedit_panel_new(void)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel  = panneau d'affichage de paramètres de configuration. *
-*                config = configuration à présenter à l'écran.                *
+*  Paramètres  : panel = panneau d'affichage de paramètres de configuration.  *
 *                                                                             *
 *  Description : Recharge une configuration donnée à l'affichage.             *
 *                                                                             *
@@ -416,7 +427,7 @@ GPanelItem *g_regedit_panel_new(void)
 *                                                                             *
 ******************************************************************************/
 
-static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config)
+static void reload_config_into_treeview(GRegeditPanel *panel)
 {
     GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkListStore *store;                    /* Modèle de gestion           */
@@ -432,9 +443,9 @@ static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config
 
     gtk_list_store_clear(store);
 
-    g_generic_config_rlock(config);
+    g_generic_config_rlock(panel->config);
 
-    params = g_generic_config_list_params(config);
+    params = g_generic_config_list_params(panel->config);
 
     for (p = g_list_first(params); p != NULL; p = g_list_next(p))
     {
@@ -480,11 +491,9 @@ static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config
 
         update_config_param_value(store, &iter);
 
-        g_signal_connect(param, "modified", G_CALLBACK(on_config_param_modified), panel);
-
     }
 
-    g_generic_config_runlock(config);
+    g_generic_config_runlock(panel->config);
 
     g_object_unref(G_OBJECT(builder));
 
@@ -493,8 +502,9 @@ static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : param = instance dont le contenu a évolué.                   *
-*                panel = panneau d'affichage de paramètres à mettre à jour.   *
+*  Paramètres  : config = configuration changée dans son ensemble.            *
+*                param  = instance dont le contenu a évolué.                  *
+*                panel  = panneau d'affichage de paramètres à mettre à jour.  *
 *                                                                             *
 *  Description : Actualise l'affichage des données d'un paramètre modifié.    *
 *                                                                             *
@@ -504,7 +514,7 @@ static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config
 *                                                                             *
 ******************************************************************************/
 
-static void on_config_param_modified(GCfgParam *param, GRegeditPanel *panel)
+static void on_configuration_param_modified(GGenConfig *config, GCfgParam *param, GRegeditPanel *panel)
 {
     GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeView *treeview;                  /* Affichage de la liste       */
@@ -876,7 +886,7 @@ static void on_param_search_changed(GtkSearchEntry *entry, GRegeditPanel *panel)
 
     gtk_style_context_remove_class(context, "filter-error");
 
-    reload_config_into_treeview(panel, get_main_configuration());
+    reload_config_into_treeview(panel);
 
 }
 
diff --git a/src/gui/panels/welcome.c b/src/gui/panels/welcome.c
index 9192d66..14e88c5 100644
--- a/src/gui/panels/welcome.c
+++ b/src/gui/panels/welcome.c
@@ -63,6 +63,8 @@ struct _GWelcomePanel
 
     bool uorigin;                           /* Origine de l'affichage      */
 
+    gulong sig_id;                          /* Connexion par signal        */
+
 };
 
 /* Panneau d'accueil par défaut (classe) */
@@ -269,7 +271,7 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
 
     manager = get_project_manager();
 
-    g_signal_connect(manager, "changed", G_CALLBACK(on_recent_list_changed), panel);
+    panel->sig_id = g_signal_connect(manager, "changed", G_CALLBACK(on_recent_list_changed), panel);
 
     g_welcome_panel_reload_project_list(panel, manager);
 
@@ -294,7 +296,16 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
 
 static void g_welcome_panel_dispose(GWelcomePanel *panel)
 {
-    free(panel->tips);
+    GtkRecentManager *manager;              /* Gestionnaire global         */
+
+    if (panel->sig_id > 0)
+    {
+        manager = get_project_manager();
+
+        g_signal_handler_disconnect(manager, panel->sig_id);
+        panel->sig_id = 0;
+
+    }
 
     G_OBJECT_CLASS(g_welcome_panel_parent_class)->dispose(G_OBJECT(panel));
 
@@ -317,6 +328,8 @@ static void g_welcome_panel_finalize(GWelcomePanel *panel)
 {
     cairo_surface_destroy(panel->background);
 
+    free(panel->tips);
+
     G_OBJECT_CLASS(g_welcome_panel_parent_class)->finalize(G_OBJECT(panel));
 
 }
-- 
cgit v0.11.2-87-g4458