From 1eadace09a51cd93aaf78d91f0d601730728dfd5 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 18 Feb 2018 22:27:51 +0100
Subject: Moved the resource builder as part of panel base.

---
 ChangeLog                  | 13 +++++++++
 src/gui/panels/bintree.c   | 63 +++++++++++++++++++++---------------------
 src/gui/panels/errors.c    | 69 +++++++++++++++++++++++++++-------------------
 src/gui/panels/panel-int.h | 18 ++++++++++++
 src/gui/panels/panel.c     | 43 +++++++++++++++++++++++++++++
 src/gui/panels/welcome.c   | 33 ++++++++++++----------
 6 files changed, 163 insertions(+), 76 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9275256..b1e2410 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 18-02-18  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/gui/panels/bintree.c:
+	* src/gui/panels/errors.c:
+	Update code.
+
+	* src/gui/panels/panel-int.h:
+	* src/gui/panels/panel.c:
+	Move the resource builder as part of panel base.
+
+	* src/gui/panels/welcome.c:
+	Update code.
+
+18-02-18  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/gui/panels/panel.c:
 	Destroy panel resources on exit.
 
diff --git a/src/gui/panels/bintree.c b/src/gui/panels/bintree.c
index 89e2ae1..c2caef7 100644
--- a/src/gui/panels/bintree.c
+++ b/src/gui/panels/bintree.c
@@ -53,8 +53,6 @@ struct _GBintreePanel
 {
     GPanelItem parent;                      /* A laisser en premier        */
 
-    GtkBuilder *builder;                    /* Constructeur utilisé        */
-
     GLoadedBinary *binary;                  /* Binaire représenté          */
     regex_t *filter;                        /* Filtre appliqué ou NULL     */
 
@@ -168,6 +166,7 @@ static void g_bintree_panel_init(GBintreePanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
     GPanelItem *pitem;                      /* Version parente du panneau  */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeView *treeview;                  /* Affichage de la liste       */
     GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
     GtkTreeViewColumn *column;              /* Colonne de la liste         */
@@ -194,15 +193,11 @@ static void g_bintree_panel_init(GBintreePanel *panel)
 
     /* Représentation graphique */
 
-    panel->builder = gtk_builder_new_from_resource("/org/chrysalide/gui/panels/bintree.ui");
-
-    base->widget = GTK_WIDGET(gtk_builder_get_object(panel->builder, "box"));
-    g_object_ref(G_OBJECT(base->widget));
-    gtk_widget_unparent(base->widget);
+    builder = g_panel_item_build(pitem, "bintree");
 
     /* Liste des portions binaires */
 
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
 
     column = gtk_tree_view_column_new();
     gtk_tree_view_append_column(treeview, column);
@@ -241,7 +236,7 @@ static void g_bintree_panel_init(GBintreePanel *panel)
 
     /* Connexion des signaux */
 
-    gtk_builder_add_callback_symbols(panel->builder,
+    gtk_builder_add_callback_symbols(builder,
                                      "gtk_tree_view_collapse_all", G_CALLBACK(gtk_tree_view_collapse_all),
                                      "gtk_tree_view_expand_all", G_CALLBACK(gtk_tree_view_expand_all),
                                      "on_depth_spin_value_changed", G_CALLBACK(on_depth_spin_value_changed),
@@ -249,7 +244,7 @@ static void g_bintree_panel_init(GBintreePanel *panel)
                                      "on_bintree_selection_changed", G_CALLBACK(on_bintree_selection_changed),
                                      NULL);
 
-    gtk_builder_connect_signals(panel->builder, panel);
+    gtk_builder_connect_signals(builder, panel);
 
 }
 
@@ -268,8 +263,6 @@ static void g_bintree_panel_init(GBintreePanel *panel)
 
 static void g_bintree_panel_dispose(GBintreePanel *panel)
 {
-    g_object_unref(G_OBJECT(panel->builder));
-
     if (panel->binary != NULL)
         g_object_unref(G_OBJECT(panel->binary));
 
@@ -343,22 +336,23 @@ GPanelItem *g_bintree_panel_new(void)
 
 static bool populate_tree_with_portion(GBinPortion *portion, GBinPortion *parent, BinaryPortionVisit visit, GBintreePanel *panel)
 {
-    const char *desc;               /* Description d'origine       */
-    bool fmatched;                  /* Correspondance rencontrée ? */
-    regmatch_t match;               /* Position d'un filtre        */
-    char *node_caption;             /* Etiquette de nouveau noeud  */
-    const mrange_t *range;          /* Espace de portion à traiter */
-    VMPA_BUFFER(offset);            /* Décalage physique           */
-    char *node_start;               /* Position pour nouveau noeud */
-    vmpa2t end;                     /* Zone de construction temp.  */
-    char *node_end;                 /* Bordure pour nouveau noeud  */
-    PortionAccessRights rights;     /* Droits d'accès à analyser   */
-    char hrights[4];                /* Version humainement lisible */
-    char *node_rights;              /* Droits pour nouveau noeud   */
-    cairo_surface_t *icon;          /* Miniature de décoration     */
-    GtkTreeStore *store;            /* Modèle de gestion           */
-    GtkTreeIter iter;               /* Point d'insertion           */
-    GtkTreeIter *save;              /* Sauvegarde d'une position   */
+    const char *desc;                       /* Description d'origine       */
+    bool fmatched;                          /* Correspondance rencontrée ? */
+    regmatch_t match;                       /* Position d'un filtre        */
+    char *node_caption;                     /* Etiquette de nouveau noeud  */
+    const mrange_t *range;                  /* Espace de portion à traiter */
+    VMPA_BUFFER(offset);                    /* Décalage physique           */
+    char *node_start;                       /* Position pour nouveau noeud */
+    vmpa2t end;                             /* Zone de construction temp.  */
+    char *node_end;                         /* Bordure pour nouveau noeud  */
+    PortionAccessRights rights;             /* Droits d'accès à analyser   */
+    char hrights[4];                        /* Version humainement lisible */
+    char *node_rights;                      /* Droits pour nouveau noeud   */
+    cairo_surface_t *icon;                  /* Miniature de décoration     */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeStore *store;                    /* Modèle de gestion           */
+    GtkTreeIter iter;                       /* Point d'insertion           */
+    GtkTreeIter *save;                      /* Sauvegarde d'une position   */
 
     if (parent == NULL)
         return true;
@@ -408,7 +402,9 @@ static bool populate_tree_with_portion(GBinPortion *portion, GBinPortion *parent
 
         icon = NULL;
 
-        store = GTK_TREE_STORE(gtk_builder_get_object(panel->builder, "store"));
+        builder = G_PANEL_ITEM(panel)->builder;
+
+        store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
 
         gtk_tree_store_append(store, &iter, panel->top);
 
@@ -474,6 +470,7 @@ static bool populate_tree_with_portion(GBinPortion *portion, GBinPortion *parent
 
 static void update_panel_with_binary_portions(GBintreePanel *panel, GLoadedBinary *binary)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeStore *store;                    /* Modèle de gestion           */
     GExeFormat *format;                     /* Format du binaire           */
     GBinPortion *portions;                  /* Couche première de portions */
@@ -489,7 +486,9 @@ static void update_panel_with_binary_portions(GBintreePanel *panel, GLoadedBinar
 
     panel->binary = binary;
 
-    store = GTK_TREE_STORE(gtk_builder_get_object(panel->builder, "store"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
 
     gtk_tree_store_clear(store);
 
@@ -538,13 +537,13 @@ static void update_panel_with_binary_portions(GBintreePanel *panel, GLoadedBinar
 
     gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)compute_max_depth, &max_depth);
 
-    depth_spin = GTK_SPIN_BUTTON(gtk_builder_get_object(panel->builder, "depth_spin"));
+    depth_spin = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "depth_spin"));
 
     gtk_spin_button_set_range(depth_spin, 0, max_depth);
 
     /* Restauration au mieux de l'affichage */
 
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
 
     switch (panel->last)
     {
diff --git a/src/gui/panels/errors.c b/src/gui/panels/errors.c
index f27d0fc..5b996e5 100644
--- a/src/gui/panels/errors.c
+++ b/src/gui/panels/errors.c
@@ -61,8 +61,6 @@ struct _GErrorPanel
 {
     GPanelItem parent;                      /* A laisser en premier        */
 
-    GtkBuilder *builder;                    /* Constructeur utilisé        */
-
     GLoadedBinary *binary;                  /* Binaire représenté          */
 
     size_t count;                           /* Nombre de soucis présents   */
@@ -263,6 +261,7 @@ static void g_error_panel_init(GErrorPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
     GPanelItem *pitem;                      /* Version parente du panneau  */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeSortable *store;                 /* Gestionnaire des données    */
     GtkTreeModelFilter *filter;             /* Filtre pour l'arborescence  */
     GtkTreeView *treeview;                  /* Affichage de la liste       */
@@ -288,22 +287,18 @@ static void g_error_panel_init(GErrorPanel *panel)
 
     /* Représentation graphique */
 
-    panel->builder = gtk_builder_new_from_resource("/org/chrysalide/gui/panels/errors.ui");
+    builder = g_panel_item_build(pitem, "errors");
 
-    base->widget = GTK_WIDGET(gtk_builder_get_object(panel->builder, "box"));
-    g_object_ref(G_OBJECT(base->widget));
-    gtk_widget_unparent(base->widget);
-
-    store = GTK_TREE_SORTABLE(gtk_builder_get_object(panel->builder, "store"));
+    store = GTK_TREE_SORTABLE(gtk_builder_get_object(builder, "store"));
     gtk_tree_sortable_set_sort_func(store, ETC_ADDR, sort_errors_in_panel, NULL, NULL);
     gtk_tree_sortable_set_sort_column_id(store, ETC_ADDR, GTK_SORT_ASCENDING);
 
-    filter = GTK_TREE_MODEL_FILTER(gtk_builder_get_object(panel->builder, "filter"));
+    filter = GTK_TREE_MODEL_FILTER(gtk_builder_get_object(builder, "filter"));
     gtk_tree_model_filter_set_visible_column(filter, ETC_VISIBLE);
 
     /* Liste des erreurs relevées */
 
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
 
     column = gtk_tree_view_column_new();
     gtk_tree_view_append_column(treeview, column);
@@ -334,14 +329,14 @@ static void g_error_panel_init(GErrorPanel *panel)
 
     /* Connexion des signaux */
 
-    gtk_builder_add_callback_symbols(panel->builder,
+    gtk_builder_add_callback_symbols(builder,
                                      "gtk_tree_view_collapse_all", G_CALLBACK(gtk_tree_view_collapse_all),
                                      "gtk_tree_view_expand_all", G_CALLBACK(gtk_tree_view_expand_all),
                                      "on_error_filter_toggled", G_CALLBACK(on_error_filter_toggled),
                                      "on_error_selection_changed", G_CALLBACK(on_error_selection_changed),
                                      NULL);
 
-    gtk_builder_connect_signals(panel->builder, panel);
+    gtk_builder_connect_signals(builder, panel);
 
 }
 
@@ -382,8 +377,6 @@ static void g_error_panel_interface_init(GUpdatablePanelInterface *iface)
 
 static void g_error_panel_dispose(GErrorPanel *panel)
 {
-    g_object_unref(G_OBJECT(panel->builder));
-
     if (panel->binary != NULL)
         g_object_unref(G_OBJECT(panel->binary));
 
@@ -483,6 +476,7 @@ static gint sort_errors_in_panel(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIte
 
 static void update_panel_with_binary_errors(GErrorPanel *panel, GLoadedBinary *binary)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkListStore *store;                    /* Modèle de gestion           */
 
     /* Réinitialisation */
@@ -495,7 +489,9 @@ static void update_panel_with_binary_errors(GErrorPanel *panel, GLoadedBinary *b
     if (panel->binary != NULL)
         g_object_ref(G_OBJECT(panel->binary));
 
-    store = GTK_LIST_STORE(gtk_builder_get_object(panel->builder, "store"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
 
     gtk_list_store_clear(store);
 
@@ -527,6 +523,7 @@ static void update_panel_with_binary_errors(GErrorPanel *panel, GLoadedBinary *b
 
 static void update_error_panel(const GErrorPanel *panel, GtkStatusStack *status, activity_id_t id, error_update_data *data)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkListStore *store;                    /* Modèle de gestion           */
     GBinFormat *format;                     /* Format du binaire           */
     size_t fcount;                          /* Quantité d'erreurs #1       */
@@ -543,7 +540,9 @@ static void update_error_panel(const GErrorPanel *panel, GtkStatusStack *status,
     bool ret;                               /* Bilan d'une récupération    */
 #endif
 
-    store = GTK_LIST_STORE(gtk_builder_get_object(panel->builder, "store"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
 
     /* Recensement initial */
 
@@ -567,13 +566,13 @@ static void update_error_panel(const GErrorPanel *panel, GtkStatusStack *status,
 
     if (panel->binary == NULL || (fcount + pcount) == 0)
     {
-        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "format"));
+        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "format"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
 
-        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "disass"));
+        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "disass"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
 
-        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "output"));
+        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "output"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
 
         gtk_list_store_append(store, &iter);
@@ -595,15 +594,15 @@ static void update_error_panel(const GErrorPanel *panel, GtkStatusStack *status,
 
     else
     {
-        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "format"));
+        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "format"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), TRUE);
         show_format = gtk_toggle_button_get_active(button);
 
-        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "disass"));
+        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "disass"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), TRUE);
         show_disass = gtk_toggle_button_get_active(button);
 
-        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "output"));
+        button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "output"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), TRUE);
         show_output = gtk_toggle_button_get_active(button);
 
@@ -794,6 +793,7 @@ static void on_error_filter_toggled(GtkToggleButton *button, GErrorPanel *panel)
 
 static void filter_error_panel(const GErrorPanel *panel, GtkStatusStack *status, activity_id_t id, error_update_data *data)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeModel *store;                    /* Modèle de gestion           */
     GtkToggleButton *button;                /* Bouton à manipuler          */
     gboolean show_format;                   /* Affichages liés au format   */
@@ -805,17 +805,19 @@ static void filter_error_panel(const GErrorPanel *panel, GtkStatusStack *status,
     guint errno;                            /* Code d'erreur associé       */
     gboolean state;                         /* Bilan d'un filtrage         */
 
-    store = GTK_TREE_MODEL(gtk_builder_get_object(panel->builder, "store"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store"));
 
     /* Actualisation des données */
 
-    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "format"));
+    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "format"));
     show_format = gtk_toggle_button_get_active(button);
 
-    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "disass"));
+    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "disass"));
     show_disass = gtk_toggle_button_get_active(button);
 
-    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "output"));
+    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "output"));
     show_output = gtk_toggle_button_get_active(button);
 
 
@@ -886,10 +888,13 @@ static void filter_error_panel(const GErrorPanel *panel, GtkStatusStack *status,
 
 static void update_error_panel_summary(const GErrorPanel *panel)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkLabel *summary;                      /* Etiquette à mettre à jour   */
     char *msg;                              /* Bilan à faire afficher      */
 
-    summary = GTK_LABEL(gtk_builder_get_object(panel->builder, "summary"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    summary = GTK_LABEL(gtk_builder_get_object(builder, "summary"));
 
     if (panel->count == 0)
         gtk_label_set_markup(summary, NULL);
@@ -1044,11 +1049,14 @@ static const char *g_error_panel_setup(const GErrorPanel *panel, unsigned int ui
 
 static void g_error_panel_introduce(const GErrorPanel *panel, unsigned int uid, error_update_data *data)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeView *treeview;                  /* Arborescence graphique      */
 
     /* Basculement de l'affichage hors ligne */
 
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
 
     data->model = gtk_tree_view_get_model(treeview);
     g_object_ref(G_OBJECT(data->model));
@@ -1107,6 +1115,7 @@ static void g_error_panel_process(const GErrorPanel *panel, unsigned int uid, Gt
 
 static void g_error_panel_conclude(GErrorPanel *panel, unsigned int uid, error_update_data *data)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeView *treeview;                  /* Arborescence graphique      */
 
     /* Mise à jour des statistiques */
@@ -1118,7 +1127,9 @@ static void g_error_panel_conclude(GErrorPanel *panel, unsigned int uid, error_u
 
     /* Basculement de l'affichage en ligne */
 
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
 
     gtk_tree_view_set_model(treeview, data->model);
 
diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h
index 33b0746..0543829 100644
--- a/src/gui/panels/panel-int.h
+++ b/src/gui/panels/panel-int.h
@@ -60,6 +60,20 @@ struct _GPanelItem
 
     bool docked;                            /* Panneau inscrusté ?         */
 
+    /**
+     * La gestion générique du constructeur repose sur quelques
+     * prérequis quant à l'enregistrement de composants :
+     *
+     *    - "box" doit être le support de panneau à intégrer.
+     *
+     *    - pour les contenus actualisables, une pile de composants
+     *      "stack" doit contenir un support "content" pour le
+     *      contenu principal et un support "mask" qui prend le
+     *      relais pendant les opérations de mise à jour.
+     */
+
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+
 };
 
 /* Elément réactif pour panneaux de l'éditeur (classe) */
@@ -85,5 +99,9 @@ struct _GPanelItemClass
 #define panels_list_for_each(pos, head) dl_list_for_each(pos, head, GPanelItem, link) 
 
 
+/* Charge les éléments graphiques du panneau via les ressources. */
+GtkBuilder *g_panel_item_build(GPanelItem *, const char *);
+
+
 
 #endif  /* _GUI_PANELS_PANEL_INT_H */
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 6536977..80de791 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -170,6 +170,9 @@ static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface)
 
 static void g_panel_item_dispose(GPanelItem *item)
 {
+    if (item->builder != NULL) // REMME
+    g_object_unref(G_OBJECT(item->builder));
+
     G_OBJECT_CLASS(g_panel_item_parent_class)->dispose(G_OBJECT(item));
 
 }
@@ -240,6 +243,46 @@ GPanelItem *g_panel_item_new(PanelItemPersonality personality, const char *name,
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : item = panneau dont la construction est à poursuivre.        *
+*                name = nom associé à l'élément dans les ressources globales. *
+*                                                                             *
+*  Description : Charge les éléments graphiques du panneau via les ressources.*
+*                                                                             *
+*  Retour      : Constructeur mis en place, afin de faciliter son usage.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkBuilder *g_panel_item_build(GPanelItem *item, const char *name)
+{
+    GtkBuilder *result;                     /* Constructeur à retourner    */
+    char *path;                             /* Chemin d'accès à constituer */
+    GEditorItem *base;                      /* Version basique d'instance  */
+
+    asprintf(&path, "/org/chrysalide/gui/panels/%s.ui", name);
+
+    result = gtk_builder_new_from_resource(path);
+
+    free(path);
+
+    item->builder = result;
+
+    base = G_EDITOR_ITEM(item);
+
+    base->widget = GTK_WIDGET(gtk_builder_get_object(result, "box"));
+
+    g_object_ref(G_OBJECT(base->widget));
+
+    gtk_widget_unparent(base->widget);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
 *                                                                             *
 *  Description : Fournit le nom court du composant encapsulable.              *
diff --git a/src/gui/panels/welcome.c b/src/gui/panels/welcome.c
index 0edeb41..eeff152 100644
--- a/src/gui/panels/welcome.c
+++ b/src/gui/panels/welcome.c
@@ -53,7 +53,6 @@ struct _GWelcomePanel
 {
     GPanelItem parent;                      /* A laisser en premier        */
 
-    GtkBuilder *builder;                    /* Constructeur utilisé        */
     cairo_surface_t *background;            /* Fond pour astuces           */
 
     char **tips;                            /* Liste de toutes les astuces */
@@ -181,6 +180,7 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
     GPanelItem *pitem;                      /* Version parente du panneau  */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeView *treeview;                  /* Affichage de la liste       */
     GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
     GtkTreeViewColumn *column;              /* Colonne de la liste         */
@@ -205,15 +205,11 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
 
     /* Représentation graphique */
 
-    panel->builder = gtk_builder_new_from_resource("/org/chrysalide/gui/panels/welcome.ui");
-
-    base->widget = GTK_WIDGET(gtk_builder_get_object(panel->builder, "box"));
-    g_object_ref(G_OBJECT(base->widget));
-    gtk_widget_unparent(base->widget);
+    builder = g_panel_item_build(pitem, "welcome");
 
     /* Liste des projets récents */
 
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
 
     column = gtk_tree_view_column_new();
     gtk_tree_view_append_column(treeview, column);
@@ -225,7 +221,7 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
 
     /* Affichage au démarrage ? */
 
-    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "startup"));
+    button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "startup"));
 
     g_generic_config_get_value(get_main_configuration(), MPK_WELCOME_STARTUP, &state);
 
@@ -241,7 +237,7 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
 
     /* Connexion des signaux */
 
-    gtk_builder_add_callback_symbols(panel->builder,
+    gtk_builder_add_callback_symbols(builder,
                                      "on_tip_background_draw", G_CALLBACK(on_tip_background_draw),
                                      "on_new_binary_clicked", G_CALLBACK(on_new_binary_clicked),
                                      "on_row_activated_for_projects", G_CALLBACK(on_row_activated_for_projects),
@@ -250,7 +246,7 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
                                      "on_tip_next_clicked", G_CALLBACK(on_tip_next_clicked),
                                      NULL);
 
-    gtk_builder_connect_signals(panel->builder, panel);
+    gtk_builder_connect_signals(builder, panel);
 
 }
 
@@ -269,8 +265,6 @@ static void g_welcome_panel_init(GWelcomePanel *panel)
 
 static void g_welcome_panel_dispose(GWelcomePanel *panel)
 {
-    g_object_unref(G_OBJECT(panel->builder));
-
     free(panel->tips);
 
     G_OBJECT_CLASS(g_welcome_panel_parent_class)->dispose(G_OBJECT(panel));
@@ -513,6 +507,7 @@ static void on_recent_list_changed(GtkRecentManager *manager, GWelcomePanel *pan
 
 static void g_welcome_panel_reload_project_list(GWelcomePanel *panel, GtkRecentManager *manager)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkListStore *store;                    /* Modèle de gestion           */
     bool empty;                             /* Liste vide ?                */
     GList *recents;                         /* Liste des fichiers récents  */
@@ -522,7 +517,9 @@ static void g_welcome_panel_reload_project_list(GWelcomePanel *panel, GtkRecentM
 
     /* Réinitialisation */
 
-    store = GTK_LIST_STORE(gtk_builder_get_object(panel->builder, "store"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
 
     gtk_list_store_clear(store);
 
@@ -668,6 +665,7 @@ static void g_welcome_panel_check_version(GWelcomePanel *panel)
     size_t got;                             /* Quantité de données reçues  */
     char *version;                          /* Version récupérée           */
     int available;                          /* Version disponible          */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkLabel *label;                        /* Etiquette à éditer          */
     char *msg;                              /* Message à faire paraître    */
 
@@ -711,7 +709,9 @@ static void g_welcome_panel_check_version(GWelcomePanel *panel)
 
     /* Affichage */
 
-    label = GTK_LABEL(gtk_builder_get_object(panel->builder, "version"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    label = GTK_LABEL(gtk_builder_get_object(builder, "version"));
 
     if (skip)
         asprintf(&msg,
@@ -818,11 +818,14 @@ static void on_tip_next_clicked(GtkButton *button, GWelcomePanel *panel)
 
 static void g_welcome_panel_refresh_tip(GWelcomePanel *panel)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkLabel *label;                        /* Etiquette de présentation   */
 
     assert(panel->current < panel->count);
 
-    label = GTK_LABEL(gtk_builder_get_object(panel->builder, "tip"));
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    label = GTK_LABEL(gtk_builder_get_object(builder, "tip"));
 
     gtk_label_set_markup(label, panel->tips[panel->current]);
 
-- 
cgit v0.11.2-87-g4458