From a11ef1ad68fdb86d4a7d75b0ddeea126aa1adb09 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 11 Feb 2018 16:33:56 +0100
Subject: Created a dedicated interface fot panel updating.

---
 ChangeLog                     |  21 ++
 src/core/logs.c               |   3 +
 src/gui/panels/Makefile.am    |   2 +
 src/gui/panels/errors.c       | 378 +++++++++++++++++++++++++-----------
 src/gui/panels/panel-int.h    |  29 ---
 src/gui/panels/panel.c        | 182 ------------------
 src/gui/panels/panel.h        |  34 ----
 src/gui/panels/updating-int.h |  65 +++++++
 src/gui/panels/updating.c     | 431 ++++++++++++++++++++++++++++++++++++++++++
 src/gui/panels/updating.h     | 118 ++++++++++++
 10 files changed, 904 insertions(+), 359 deletions(-)
 create mode 100644 src/gui/panels/updating-int.h
 create mode 100644 src/gui/panels/updating.c
 create mode 100644 src/gui/panels/updating.h

diff --git a/ChangeLog b/ChangeLog
index f2e8dc7..c317398 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+18-02-11  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/core/logs.c:
+	Remove compilation warnings.
+
+	* src/gui/panels/Makefile.am:
+	Add the 'updating*[ch]' files to libguipanels_la_SOURCES.
+
+	* src/gui/panels/errors.c:
+	Update code.
+
+	* src/gui/panels/panel-int.h:
+	* src/gui/panels/panel.c:
+	* src/gui/panels/panel.h:
+	Remove old code.
+
+	* src/gui/panels/updating-int.h:
+	* src/gui/panels/updating.c:
+	* src/gui/panels/updating.h:
+	New entries: create a dedicated interface fot panel updating.
+
 18-02-05  Cyrille Bagard <nocbos@gmail.com>
 
 	* configure.ac:
diff --git a/src/core/logs.c b/src/core/logs.c
index f92e581..ceed5a9 100644
--- a/src/core/logs.c
+++ b/src/core/logs.c
@@ -24,6 +24,9 @@
 #include "logs.h"
 
 
+#include <malloc.h>
+
+
 #include "../gui/core/panels.h"
 #include "../gui/panels/log.h"
 
diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am
index 506ae38..a943380 100644
--- a/src/gui/panels/Makefile.am
+++ b/src/gui/panels/Makefile.am
@@ -21,6 +21,8 @@ libguipanels_la_SOURCES =				\
 	resources.h resources.c				\
 	strings.h strings.c					\
 	symbols.h symbols.c					\
+	updating-int.h						\
+	updating.h updating.c				\
 	welcome.h welcome.c
 
 libguipanels_la_LDFLAGS = 
diff --git a/src/gui/panels/errors.c b/src/gui/panels/errors.c
index f62e684..f27d0fc 100644
--- a/src/gui/panels/errors.c
+++ b/src/gui/panels/errors.c
@@ -34,6 +34,7 @@
 
 
 #include "panel-int.h"
+#include "updating-int.h"
 #include "../core/global.h"
 #include "../../core/global.h"
 #include "../../format/format.h"
@@ -42,6 +43,9 @@
 
 
 
+/* ----------------------- PRESENTATION GRAPHIQUE DES ERREURS ----------------------- */
+
+
 /* Origine de la dernière ouverture/fermeture reproductible */
 typedef enum _UserActionType
 {
@@ -111,12 +115,19 @@ typedef struct _error_desc_t
 } error_desc_t;
 
 
+/* Données utiles à la mise à jour */
+typedef struct _error_update_data error_update_data;
+
+
 /* Initialise la classe des panneaux d'affichage des erreurs. */
 static void g_error_panel_class_init(GErrorPanelClass *);
 
 /* Initialise une instance de panneau d'affichage des erreurs. */
 static void g_error_panel_init(GErrorPanel *);
 
+/* Procède à l'initialisation de l'interface de mise à jour. */
+static void g_error_panel_interface_init(GUpdatablePanelInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_error_panel_dispose(GErrorPanel *);
 
@@ -130,24 +141,58 @@ static gint sort_errors_in_panel(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, g
 static void update_panel_with_binary_errors(GErrorPanel *, GLoadedBinary *);
 
 /* Effectue la mise à jour du contenu du panneau d'erreurs. */
-static void update_error_panel(GErrorPanel *, GtkStatusStack *, activity_id_t);
+static void update_error_panel(const GErrorPanel *, GtkStatusStack *, activity_id_t, error_update_data *);
 
 /* Actualise l'affichage des erreurs sur la base des filtres. */
 static void on_error_filter_toggled(GtkToggleButton *, GErrorPanel *);
 
 /* Filtre l'affichage du contenu du panneau d'erreurs. */
-static void filter_error_panel(GErrorPanel *, GtkStatusStack *, activity_id_t);
+static void filter_error_panel(const GErrorPanel *, GtkStatusStack *, activity_id_t, error_update_data *);
 
 /* Affiche un petit résumé concis des soucis remontés. */
-static void update_error_panel_summary(GPanelUpdate *, GErrorPanel *);
+static void update_error_panel_summary(const GErrorPanel *);
 
 /* Réagit au changement de sélection des portions. */
 static void on_error_selection_changed(GtkTreeSelection *, gpointer);
 
 
 
+/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */
+
+
+/* Données utiles à la mise à jour */
+struct _error_update_data
+{
+    GtkTreeModel *model;                    /* Source de données associée  */
+
+    size_t count;                           /* Nombre de soucis présents   */
+    size_t kept;                            /* Nombre d'éléments affichés  */
+
+};
+
+
+/* Prépare une opération de mise à jour de panneau. */
+static const char *g_error_panel_setup(const GErrorPanel *, unsigned int, size_t *, error_update_data **);
+
+/* Bascule l'affichage d'un panneau avant mise à jour. */
+static void g_error_panel_introduce(const GErrorPanel *, unsigned int, error_update_data *);
+
+/* Réalise une opération de mise à jour de panneau. */
+static void g_error_panel_process(const GErrorPanel *, unsigned int, GtkStatusStack *, activity_id_t, error_update_data *);
+
+/* Bascule l'affichage d'un panneau après mise à jour. */
+static void g_error_panel_conclude(GErrorPanel *, unsigned int, error_update_data *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         PRESENTATION GRAPHIQUE DES ERREURS                         */
+/* ---------------------------------------------------------------------------------- */
+
+
 /* Indique le type défini pour un panneau d'affichage des erreurs. */
-G_DEFINE_TYPE(GErrorPanel, g_error_panel, G_TYPE_PANEL_ITEM);
+G_DEFINE_TYPE_WITH_CODE(GErrorPanel, g_error_panel, G_TYPE_PANEL_ITEM,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_UPDATABLE_PANEL, g_error_panel_interface_init))
 
 
 /******************************************************************************
@@ -303,6 +348,28 @@ static void g_error_panel_init(GErrorPanel *panel)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de mise à jour.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_error_panel_interface_init(GUpdatablePanelInterface *iface)
+{
+    iface->setup = (setup_updatable_cb)g_error_panel_setup;
+    iface->introduce = (introduce_updatable_cb)g_error_panel_introduce;
+    iface->process = (process_updatable_cb)g_error_panel_process;
+    iface->conclude = (conclude_updatable_cb)g_error_panel_conclude;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel = instance d'objet GLib à traiter.                     *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
@@ -417,11 +484,6 @@ static gint sort_errors_in_panel(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIte
 static void update_panel_with_binary_errors(GErrorPanel *panel, GLoadedBinary *binary)
 {
     GtkListStore *store;                    /* Modèle de gestion           */
-    GBinFormat *format;                     /* Format du binaire           */
-    size_t fcount;                          /* Quantité d'erreurs #1       */
-    GArchProcessor *proc;                   /* Architecture du binaire     */
-    size_t pcount;                          /* Quantité d'erreurs #2       */
-    GPanelUpdate *update;                   /* Procédure de mise à jour    */
 
     /* Réinitialisation */
 
@@ -439,41 +501,11 @@ static void update_panel_with_binary_errors(GErrorPanel *panel, GLoadedBinary *b
 
     /* Actualisation de l'affichage */
 
-    if (binary != NULL)
-    {
-        format = G_BIN_FORMAT(g_loaded_binary_get_format(binary));
-
-        g_binary_format_lock_errors(format);
-        fcount = g_binary_format_count_errors(format);
-        g_binary_format_unlock_errors(format);
-
-        g_object_unref(G_OBJECT(format));
-
-        proc = g_loaded_binary_get_processor(binary);
-
-        g_arch_processor_lock_errors(proc);
-        pcount = g_arch_processor_count_errors(proc);
-        g_arch_processor_unlock_errors(proc);
-
-        g_object_unref(G_OBJECT(proc));
-
-    }
-
-    else
-    {
-        fcount = 0;
-        pcount = 0;
-    }
-
-    update = g_panel_update_new(G_PANEL_ITEM(panel),
-                                _("Loading errors occurred during the disassembling process..."),
-                                fcount + pcount,
-                                (pu_fallback_cb)update_error_panel);
+    panel->count = 0;
+    panel->kept = 0;
 
-    g_signal_connect_to_main(update, "work-completed", G_CALLBACK(update_error_panel_summary), panel,
-                             g_cclosure_marshal_VOID__VOID);
-
-    g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(update), DEFAULT_WORK_GROUP);
+    if (binary != NULL)
+        run_panel_update(G_UPDATABLE_PANEL(panel), PUI_0);
 
 }
 
@@ -483,6 +515,7 @@ static void update_panel_with_binary_errors(GErrorPanel *panel, GLoadedBinary *b
 *  Paramètres  : panel  = panneau à mettre à jour.                            *
 *                status = barre de statut à tenir informée.                   *
 *                id     = identifiant pour le suivi de la progression.        *
+*                data   = données complémentaire à manipuler.                 *
 *                                                                             *
 *  Description : Effectue la mise à jour du contenu du panneau d'erreurs.     *
 *                                                                             *
@@ -492,10 +525,8 @@ static void update_panel_with_binary_errors(GErrorPanel *panel, GLoadedBinary *b
 *                                                                             *
 ******************************************************************************/
 
-static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activity_id_t id)
+static void update_error_panel(const GErrorPanel *panel, GtkStatusStack *status, activity_id_t id, error_update_data *data)
 {
-    GtkTreeView *treeview;                  /* Arborescence graphique      */
-    GtkTreeModel *model;                    /* Source de données associée  */
     GtkListStore *store;                    /* Modèle de gestion           */
     GBinFormat *format;                     /* Format du binaire           */
     size_t fcount;                          /* Quantité d'erreurs #1       */
@@ -505,8 +536,6 @@ static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
     gboolean show_format;                   /* Affichages liés au format   */
     gboolean show_disass;                   /* Affichages liés à l'arch.   */
     gboolean show_output;                   /* Affichages liés à la sortie */
-    size_t count;                           /* Nombre de soucis présents   */
-    size_t kept;                            /* Nombre d'éléments affichés  */
     GtkTreeIter iter;                       /* Point d'insertion           */
     size_t i;                               /* Boucle de parcours          */
     error_desc_t error;                     /* Description de soucis       */
@@ -514,15 +543,6 @@ static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
     bool ret;                               /* Bilan d'une récupération    */
 #endif
 
-    /* Basculement de l'affichage hors ligne */
-
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
-
-    model = gtk_tree_view_get_model(treeview);
-    g_object_ref(G_OBJECT(model));
-
-    gtk_tree_view_set_model(treeview, NULL);
-
     store = GTK_LIST_STORE(gtk_builder_get_object(panel->builder, "store"));
 
     /* Recensement initial */
@@ -549,15 +569,12 @@ static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
     {
         button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "format"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-        show_format = gtk_toggle_button_get_active(button);
 
         button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "disass"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-        show_disass = gtk_toggle_button_get_active(button);
 
         button = GTK_TOGGLE_BUTTON(gtk_builder_get_object(panel->builder, "output"));
         gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-        show_output = gtk_toggle_button_get_active(button);
 
         gtk_list_store_append(store, &iter);
 
@@ -569,8 +586,8 @@ static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
                            ETC_VISIBLE, TRUE,
                            -1);
 
-        count = 0;
-        kept = 0;
+        data->count = 0;
+        data->kept = 0;
 
     }
 
@@ -675,17 +692,14 @@ static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
                                ETC_ADDR, &e->addr,
                                -1);
 
-            count++;
+            data->count++;
 
             if (state)
-                kept++;
+                data->kept++;
 
         }
 
 
-        count = 0;
-        kept = 0;
-
         for (i = 0; i < fcount; i++)
         {
             /* On remet à zéro tous les octets de l'union ! */
@@ -740,15 +754,6 @@ static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
 
     }
 
-    panel->count = count;
-    panel->kept = kept;
-
-    /* Basculement de l'affichage en ligne */
-
-    gtk_tree_view_set_model(treeview, model);
-
-    g_object_unref(G_OBJECT(model));
-
 }
 
 
@@ -767,17 +772,7 @@ static void update_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
 
 static void on_error_filter_toggled(GtkToggleButton *button, GErrorPanel *panel)
 {
-    GPanelUpdate *update;                   /* Procédure de mise à jour    */
-
-    update = g_panel_update_new(G_PANEL_ITEM(panel),
-                                _("Filtering errors occurred during the disassembling process..."),
-                                panel->count,
-                                (pu_fallback_cb)filter_error_panel);
-
-    g_signal_connect_to_main(update, "work-completed", G_CALLBACK(update_error_panel_summary), panel,
-                             g_cclosure_marshal_VOID__VOID);
-
-    g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(update), DEFAULT_WORK_GROUP);
+    run_panel_update(G_UPDATABLE_PANEL(panel), PUI_1);
 
 }
 
@@ -787,6 +782,7 @@ static void on_error_filter_toggled(GtkToggleButton *button, GErrorPanel *panel)
 *  Paramètres  : panel  = panneau à mettre à jour.                            *
 *                status = barre de statut à tenir informée.                   *
 *                id     = identifiant pour le suivi de la progression.        *
+*                data   = données complémentaire à manipuler.                 *
 *                                                                             *
 *  Description : Filtre l'affichage du contenu du panneau d'erreurs.          *
 *                                                                             *
@@ -796,31 +792,19 @@ static void on_error_filter_toggled(GtkToggleButton *button, GErrorPanel *panel)
 *                                                                             *
 ******************************************************************************/
 
-static void filter_error_panel(GErrorPanel *panel, GtkStatusStack *status, activity_id_t id)
+static void filter_error_panel(const GErrorPanel *panel, GtkStatusStack *status, activity_id_t id, error_update_data *data)
 {
-    GtkTreeView *treeview;                  /* Arborescence graphique      */
-    GtkTreeModel *model;                    /* Source de données associée  */
     GtkTreeModel *store;                    /* Modèle de gestion           */
     GtkToggleButton *button;                /* Bouton à manipuler          */
     gboolean show_format;                   /* Affichages liés au format   */
     gboolean show_disass;                   /* Affichages liés à l'arch.   */
     gboolean show_output;                   /* Affichages liés à la sortie */
-    size_t kept;                            /* Nombre d'éléments affichés  */
     GtkTreeIter iter;                       /* Boucle de parcours          */
     gboolean valid;                         /* Validité du point courant   */
     gboolean format;                        /* Origine du soucis remonté   */
     guint errno;                            /* Code d'erreur associé       */
     gboolean state;                         /* Bilan d'un filtrage         */
 
-    /* Basculement de l'affichage hors ligne */
-
-    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
-
-    model = gtk_tree_view_get_model(treeview);
-    g_object_ref(G_OBJECT(model));
-
-    gtk_tree_view_set_model(treeview, NULL);
-
     store = GTK_TREE_MODEL(gtk_builder_get_object(panel->builder, "store"));
 
     /* Actualisation des données */
@@ -866,8 +850,6 @@ static void filter_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
     }
 
 
-    kept = 0;
-
     for (valid = gtk_tree_model_get_iter_first(store, &iter);
          valid;
          valid = gtk_tree_model_iter_next(store, &iter))
@@ -881,27 +863,18 @@ static void filter_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
                            -1);
 
         if (state)
-            kept++;
+            data->kept++;
 
         gtk_status_stack_update_activity_value(status, id, 1);
 
     }
 
-    panel->kept = kept;
-
-    /* Basculement de l'affichage en ligne */
-
-    gtk_tree_view_set_model(treeview, model);
-
-    g_object_unref(G_OBJECT(model));
-
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : update = tâche venant de se terminer.                        *
-*                panel  = structure contenant les informations maîtresses.    *
+*  Paramètres  : panel = structure contenant les informations maîtresses.     *
 *                                                                             *
 *  Description : Affiche un petit résumé concis des soucis remontés.          *
 *                                                                             *
@@ -911,7 +884,7 @@ static void filter_error_panel(GErrorPanel *panel, GtkStatusStack *status, activ
 *                                                                             *
 ******************************************************************************/
 
-static void update_error_panel_summary(GPanelUpdate *update, GErrorPanel *panel)
+static void update_error_panel_summary(const GErrorPanel *panel)
 {
     GtkLabel *summary;                      /* Etiquette à mettre à jour   */
     char *msg;                              /* Bilan à faire afficher      */
@@ -975,3 +948,180 @@ static void on_error_selection_changed(GtkTreeSelection *selection, gpointer unu
     }
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        MECANISMES DE MISE A JOUR DE PANNEAU                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                count = nombre d'étapes à prévoir dans le traitement. [OUT]  *
+*                data  = données sur lesquelles s'appuyer ensuite. [OUT]      *
+*                                                                             *
+*  Description : Prépare une opération de mise à jour de panneau.             *
+*                                                                             *
+*  Retour      : Description du message d'information.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const char *g_error_panel_setup(const GErrorPanel *panel, unsigned int uid, size_t *count, error_update_data **data)
+{
+    const char *result;                     /* Message à retourner         */
+    GBinFormat *format;                     /* Format du binaire           */
+    size_t fcount;                          /* Quantité d'erreurs #1       */
+    GArchProcessor *proc;                   /* Architecture du binaire     */
+    size_t pcount;                          /* Quantité d'erreurs #2       */
+
+    *data = malloc(sizeof(error_update_data));
+
+    switch (uid)
+    {
+        case PUI_0:
+
+            format = G_BIN_FORMAT(g_loaded_binary_get_format(panel->binary));
+
+            g_binary_format_lock_errors(format);
+            fcount = g_binary_format_count_errors(format);
+            g_binary_format_unlock_errors(format);
+
+            g_object_unref(G_OBJECT(format));
+
+            proc = g_loaded_binary_get_processor(panel->binary);
+
+            g_arch_processor_lock_errors(proc);
+            pcount = g_arch_processor_count_errors(proc);
+            g_arch_processor_unlock_errors(proc);
+
+            g_object_unref(G_OBJECT(proc));
+
+            *count = fcount + pcount;
+
+            result = _("Loading errors occurred during the disassembling process...");
+
+            (*data)->count = *count;
+            (*data)->kept = 0;
+
+            break;
+
+        case PUI_1:
+
+            *count = panel->count;
+
+            result = _("Filtering errors occurred during the disassembling process...");
+
+            (*data)->count = panel->count;
+            (*data)->kept = 0;
+
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                data  = données préparées par l'appelant.                    *
+*                                                                             *
+*  Description : Bascule l'affichage d'un panneau avant mise à jour.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : Cette fonction est appelée depuis le contexte principal.     *
+*                                                                             *
+******************************************************************************/
+
+static void g_error_panel_introduce(const GErrorPanel *panel, unsigned int uid, error_update_data *data)
+{
+    GtkTreeView *treeview;                  /* Arborescence graphique      */
+
+    /* Basculement de l'affichage hors ligne */
+
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+
+    data->model = gtk_tree_view_get_model(treeview);
+    g_object_ref(G_OBJECT(data->model));
+
+    gtk_tree_view_set_model(treeview, NULL);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel  = panneau ciblé par une mise à jour.                  *
+*                uid    = identifiant de la phase de traitement.              *
+*                status = barre de statut à tenir informée.                   *
+*                id     = identifiant pour le suivi de la progression.        *
+*                data   = données préparées par l'appelant.                   *
+*                                                                             *
+*  Description : Réalise une opération de mise à jour de panneau.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_error_panel_process(const GErrorPanel *panel, unsigned int uid, GtkStatusStack *status, activity_id_t id, error_update_data *data)
+{
+    switch (uid)
+    {
+        case PUI_0:
+            update_error_panel(panel, status, id, data);
+            break;
+
+        case PUI_1:
+            filter_error_panel(panel, status, id, data);
+            break;
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                data  = données préparées par l'appelant.                    *
+*                                                                             *
+*  Description : Bascule l'affichage d'un panneau après mise à jour.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : Cette fonction est appelée depuis le contexte principal.     *
+*                                                                             *
+******************************************************************************/
+
+static void g_error_panel_conclude(GErrorPanel *panel, unsigned int uid, error_update_data *data)
+{
+    GtkTreeView *treeview;                  /* Arborescence graphique      */
+
+    /* Mise à jour des statistiques */
+
+    panel->count = data->count;
+    panel->kept = data->kept;
+
+    update_error_panel_summary(panel);
+
+    /* Basculement de l'affichage en ligne */
+
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(panel->builder, "treeview"));
+
+    gtk_tree_view_set_model(treeview, data->model);
+
+    g_object_unref(G_OBJECT(data->model));
+
+}
diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h
index d95485c..33b0746 100644
--- a/src/gui/panels/panel-int.h
+++ b/src/gui/panels/panel-int.h
@@ -34,13 +34,9 @@
 
 #include "../editem-int.h"
 #include "../../common/dllist.h"
-#include "../../glibext/delayed-int.h"
 
 
 
-/* ------------------------- BASE D'UN PANNEAU POUR EDITEUR ------------------------- */
-
-
 /* Place un panneau dans l'ensemble affiché. */
 typedef void (* ack_dock_process_fc) (GPanelItem *item);
 
@@ -90,29 +86,4 @@ struct _GPanelItemClass
 
 
 
-/* ---------------------------- AIDE POUR LA MISE A JOUR ---------------------------- */
-
-
-/* Procédure de mise à jour de panneau graphique (instance) */
-struct _GPanelUpdate
-{
-    GDelayedWork parent;                    /* A laisser en premier        */
-
-    GPanelItem *panel;                      /* Panneau à manipuler         */
-    pu_fallback_cb internal;                /* Traitement sous-traité      */
-
-    const char *msg;                        /* Description de l'opération  */
-    size_t max;                             /* Nombre d'éléments à traiter */
-
-};
-
-/* Procédure de mise à jour de panneau graphique (classe) */
-struct _GPanelUpdateClass
-{
-    GDelayedWorkClass parent;               /* A laisser en premier        */
-
-};
-
-
-
 #endif  /* _GUI_PANELS_PANEL_INT_H */
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index c9d5ecf..e70d57b 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -59,31 +59,6 @@ static char *gtk_panel_item_build_configuration_key(const GPanelItem *, const ch
 
 
 
-/* ---------------------------- AIDE POUR LA MISE A JOUR ---------------------------- */
-
-
-/* Initialise la classe des tâches des mises à jour de panneaux. */
-static void g_panel_update_class_init(GPanelUpdateClass *);
-
-/* Initialise une tâche d'étude de routines. */
-static void g_panel_update_init(GPanelUpdate *);
-
-/* Supprime toutes les références externes. */
-static void g_panel_update_dispose(GPanelUpdate *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_panel_update_finalize(GPanelUpdate *);
-
-/* Assure la mise à jour d'un panneau en différé. */
-static void g_panel_update_process(GPanelUpdate *, GtkStatusStack *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                           BASE D'UN PANNEAU POUR EDITEUR                           */
-/* ---------------------------------------------------------------------------------- */
-
-
 /* Indique le type défini pour un élément destiné à un panneau. */
 G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM,
                         G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_panel_item_dockable_interface_init))
@@ -575,160 +550,3 @@ void g_panel_item_undock(GPanelItem *item)
         G_PANEL_ITEM_GET_CLASS(item)->ack_undock(item);
 
 }
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                              AIDE POUR LA MISE A JOUR                              */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Indique le type défini pour les tâches d'étude de routines. */
-G_DEFINE_TYPE(GPanelUpdate, g_panel_update, G_TYPE_DELAYED_WORK);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des tâches des mises à jour de panneaux.*
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_panel_update_class_init(GPanelUpdateClass *klass)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-    GDelayedWorkClass *work;                /* Version en classe parente   */
-
-    object = G_OBJECT_CLASS(klass);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_panel_update_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_panel_update_finalize;
-
-    work = G_DELAYED_WORK_CLASS(klass);
-
-    work->run = (run_task_fc)g_panel_update_process;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : update = instance à initialiser.                             *
-*                                                                             *
-*  Description : Initialise une tâche d'étude de routines.                    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_panel_update_init(GPanelUpdate *update)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : update = instance d'objet GLib à traiter.                    *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_panel_update_dispose(GPanelUpdate *update)
-{
-    g_object_unref(G_OBJECT(update->panel));
-
-    G_OBJECT_CLASS(g_panel_update_parent_class)->dispose(G_OBJECT(update));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : update = instance d'objet GLib à traiter.                    *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_panel_update_finalize(GPanelUpdate *update)
-{
-    G_OBJECT_CLASS(g_panel_update_parent_class)->finalize(G_OBJECT(update));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : panel    = panneau graphique devant être actualisé.          *
-*                msg      = description de l'activité à présenter.            *
-*                max      = marge de progression à attendre.                  *
-*                internal = procédure de sous-traitance à appeler.            *
-*                                                                             *
-*  Description : Crée une tâche de mise à jour non bloquante.                 *
-*                                                                             *
-*  Retour      : Tâche créée.                                                 *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GPanelUpdate *g_panel_update_new(GPanelItem *panel, const char *msg, size_t max, pu_fallback_cb internal)
-{
-    GPanelUpdate *result;                   /* Tâche à retourner           */
-
-    result = g_object_new(G_TYPE_PANEL_UPDATE, NULL);
-
-    g_object_ref(G_OBJECT(panel));
-    result->panel = panel;
-
-    result->internal = internal;
-
-    result->msg = msg;
-    result->max = max;
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : update = étude de routines à mener.                          *
-*                status = barre de statut à tenir informée.                   *
-*                                                                             *
-*  Description : Assure la mise à jour d'un panneau en différé.               *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_panel_update_process(GPanelUpdate *update, GtkStatusStack *status)
-{
-    activity_id_t id;                       /* Identifiant de progression  */
-
-    id = gtk_status_stack_add_activity(status, update->msg, update->max);
-
-    update->internal(update->panel, status, id);
-
-    gtk_status_stack_remove_activity(status, id);
-
-}
diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h
index b293fd3..bdeffcc 100644
--- a/src/gui/panels/panel.h
+++ b/src/gui/panels/panel.h
@@ -31,13 +31,9 @@
 
 #include "../editem.h"
 #include "../../glibext/configuration.h"
-#include "../../gtkext/gtkstatusstack.h"
 
 
 
-/* ------------------------- BASE D'UN PANNEAU POUR EDITEUR ------------------------- */
-
-
 #define G_TYPE_PANEL_ITEM               g_panel_item_get_type()
 #define G_PANEL_ITEM(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_panel_item_get_type(), GPanelItem))
 #define G_IS_PANEL_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_panel_item_get_type()))
@@ -105,34 +101,4 @@ void g_panel_item_undock(GPanelItem *);
 
 
 
-/* ---------------------------- AIDE POUR LA MISE A JOUR ---------------------------- */
-
-
-#define G_TYPE_PANEL_UPDATE            g_panel_update_get_type()
-#define G_PANEL_UPDATE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PANEL_UPDATE, GRoutinesStudy))
-#define G_IS_PANEL_UPDATE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PANEL_UPDATE))
-#define G_PANEL_UPDATE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PANEL_UPDATE, GRoutinesStudyClass))
-#define G_IS_PANEL_UPDATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PANEL_UPDATE))
-#define G_PANEL_UPDATE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PANEL_UPDATE, GRoutinesStudyClass))
-
-
-/* Procédure de mise à jour de panneau graphique (instance) */
-typedef struct _GPanelUpdate GPanelUpdate;
-
-/* Procédure de mise à jour de panneau graphique (classe) */
-typedef struct _GPanelUpdateClass GPanelUpdateClass;
-
-
-/* Assure l'étude des routines en différé. */
-typedef void (* pu_fallback_cb) (GPanelItem *, GtkStatusStack *, activity_id_t);
-
-
-/* Indique le type défini pour les tâches d'étude de routines. */
-GType g_panel_update_get_type(void);
-
-/* Crée une tâche de mise à jour non bloquante. */
-GPanelUpdate *g_panel_update_new(GPanelItem *, const char *, size_t, pu_fallback_cb);
-
-
-
 #endif  /* _GUI_PANELS_PANEL_H */
diff --git a/src/gui/panels/updating-int.h b/src/gui/panels/updating-int.h
new file mode 100644
index 0000000..eea8e3b
--- /dev/null
+++ b/src/gui/panels/updating-int.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * updating-int.h - définitions internes propres aux mise à jour de panneaux
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GUI_PANELS_UPDATING_INT_H
+#define _GUI_PANELS_UPDATING_INT_H
+
+
+#include "updating.h"
+
+
+
+/* Prépare une opération de mise à jour de panneau. */
+typedef const char * (* setup_updatable_cb) (const GUpdatablePanel *, unsigned int, size_t *, void **);
+
+/* Bascule l'affichage d'un panneau avant mise à jour. */
+typedef void (* introduce_updatable_cb) (const GUpdatablePanel *, unsigned int, void *);
+
+/* Réalise une opération de mise à jour de panneau. */
+typedef void (* process_updatable_cb) (const GUpdatablePanel *, unsigned int, GtkStatusStack *, activity_id_t, void *);
+
+/* Bascule l'affichage d'un panneau après mise à jour. */
+typedef void (* conclude_updatable_cb) (GUpdatablePanel *, unsigned int, void *);
+
+
+/* Mécanisme de mise à jour d'un panneau (interface) */
+struct _GUpdatablePanelIface
+{
+    GTypeInterface base_iface;              /* A laisser en premier        */
+
+    /* Méthodes virtuelles */
+
+    setup_updatable_cb setup;               /* Préparation des traitements */
+    introduce_updatable_cb introduce;       /* Changement d'affichage #0   */
+    process_updatable_cb process;           /* Mise à jour d'affichage     */
+    conclude_updatable_cb conclude;         /* Changement d'affichage #1   */
+
+};
+
+
+/* Redéfinition */
+typedef GUpdatablePanelIface GUpdatablePanelInterface;
+
+
+
+#endif  /* _GUI_PANELS_UPDATING_INT_H */
diff --git a/src/gui/panels/updating.c b/src/gui/panels/updating.c
new file mode 100644
index 0000000..15955dc
--- /dev/null
+++ b/src/gui/panels/updating.c
@@ -0,0 +1,431 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * updating.c - mise à jour des panneaux de l'interface
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "updating.h"
+
+
+#include <malloc.h>
+
+
+#include "updating-int.h"
+#include "../../core/global.h"
+#include "../../glibext/delayed-int.h"
+#include "../../glibext/signal.h"
+
+
+
+/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */
+
+
+/* Procède à l'initialisation de l'interface de mise à jour. */
+static void g_updatable_panel_default_init(GUpdatablePanelInterface *);
+
+
+
+/* ---------------------------- AIDE POUR LA MISE A JOUR ---------------------------- */
+
+
+/* Procédure de mise à jour de panneau graphique (instance) */
+struct _GPanelUpdate
+{
+    GDelayedWork parent;                    /* A laisser en premier        */
+
+    GUpdatablePanel *panel;                 /* Panneau à manipuler         */
+    unsigned int uid;                       /* Identifiant complémentaire  */
+
+    size_t max;                             /* Marge de progression finale */
+    void *data;                             /* Données utiles au traitement*/
+    const char *msg;                        /* Description d'activité      */
+
+};
+
+/* Procédure de mise à jour de panneau graphique (classe) */
+struct _GPanelUpdateClass
+{
+    GDelayedWorkClass parent;               /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des tâches des mises à jour de panneaux. */
+static void g_panel_update_class_init(GPanelUpdateClass *);
+
+/* Initialise une tâche d'étude de mise à jour. */
+static void g_panel_update_init(GPanelUpdate *);
+
+/* Supprime toutes les références externes. */
+static void g_panel_update_dispose(GPanelUpdate *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_panel_update_finalize(GPanelUpdate *);
+
+/* Assure la mise à jour d'un panneau en différé. */
+static void g_panel_update_process(GPanelUpdate *, GtkStatusStack *);
+
+/* Marque l'achèvement d'une mise à jour de panneau. */
+static void conclude_panel_update(GPanelUpdate *, GUpdatablePanel *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        MECANISMES DE MISE A JOUR DE PANNEAU                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type d'une interface pour la mise à jour de panneau. */
+G_DEFINE_INTERFACE(GUpdatablePanel, g_updatable_panel, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de mise à jour.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_updatable_panel_default_init(GUpdatablePanelInterface *iface)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                count = nombre d'étapes à prévoir dans le traitement. [OUT]  *
+*                data  = données sur lesquelles s'appuyer ensuite. [OUT]      *
+*                                                                             *
+*  Description : Prépare une opération de mise à jour de panneau.             *
+*                                                                             *
+*  Retour      : Description du message d'information.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_updatable_panel_setup(const GUpdatablePanel *panel, unsigned int uid, size_t *count, void **data)
+{
+    GUpdatablePanelIface *iface;            /* Interface utilisée          */
+
+    iface = G_UPDATABLE_PANEL_GET_IFACE(panel);
+
+    *data = NULL;
+
+    return iface->setup(panel, uid, count, data);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                data  = données préparées par l'appelant.                    *
+*                                                                             *
+*  Description : Bascule l'affichage d'un panneau avant mise à jour.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : Cette fonction est appelée depuis le contexte principal.     *
+*                                                                             *
+******************************************************************************/
+
+void g_updatable_panel_introduce(const GUpdatablePanel *panel, unsigned int uid, void *data)
+{
+    GUpdatablePanelIface *iface;            /* Interface utilisée          */
+
+    iface = G_UPDATABLE_PANEL_GET_IFACE(panel);
+
+    iface->introduce(panel, uid, data);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel  = panneau ciblé par une mise à jour.                  *
+*                uid    = identifiant de la phase de traitement.              *
+*                status = barre de statut à tenir informée.                   *
+*                id     = identifiant pour le suivi de la progression.        *
+*                data   = données préparées par l'appelant.                   *
+*                                                                             *
+*  Description : Réalise une opération de mise à jour de panneau.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_updatable_panel_process(const GUpdatablePanel *panel, unsigned int uid, GtkStatusStack *status, activity_id_t id, void *data)
+{
+    GUpdatablePanelIface *iface;            /* Interface utilisée          */
+
+    iface = G_UPDATABLE_PANEL_GET_IFACE(panel);
+
+    iface->process(panel, uid, status, id, data);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                data  = données préparées par l'appelant.                    *
+*                                                                             *
+*  Description : Bascule l'affichage d'un panneau après mise à jour.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : Cette fonction est appelée depuis le contexte principal.     *
+*                                                                             *
+******************************************************************************/
+
+void g_updatable_panel_conclude(GUpdatablePanel *panel, unsigned int uid, void *data)
+{
+    GUpdatablePanelIface *iface;            /* Interface utilisée          */
+
+    iface = G_UPDATABLE_PANEL_GET_IFACE(panel);
+
+    iface->conclude(panel, uid, data);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                              AIDE POUR LA MISE A JOUR                              */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour les tâches de mise à jour de panneau. */
+G_DEFINE_TYPE(GPanelUpdate, g_panel_update, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des tâches des mises à jour de panneaux.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_panel_update_class_init(GPanelUpdateClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GDelayedWorkClass *work;                /* Version en classe parente   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_panel_update_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_panel_update_finalize;
+
+    work = G_DELAYED_WORK_CLASS(klass);
+
+    work->run = (run_task_fc)g_panel_update_process;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : update = instance à initialiser.                             *
+*                                                                             *
+*  Description : Initialise une tâche d'étude de mise à jour.                 *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_panel_update_init(GPanelUpdate *update)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : update = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_panel_update_dispose(GPanelUpdate *update)
+{
+    g_object_unref(G_OBJECT(update->panel));
+
+    G_OBJECT_CLASS(g_panel_update_parent_class)->dispose(G_OBJECT(update));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : update = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_panel_update_finalize(GPanelUpdate *update)
+{
+    if (update->data != NULL)
+        free(update->data);
+
+    G_OBJECT_CLASS(g_panel_update_parent_class)->finalize(G_OBJECT(update));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = interface permettant une mise à jour de panneau.     *
+*                uid   = identifiant à associer à la procédure.               *
+*                                                                             *
+*  Description : Crée une tâche de mise à jour non bloquante.                 *
+*                                                                             *
+*  Retour      : Tâche créée.                                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GPanelUpdate *g_panel_update_new(GUpdatablePanel *panel, unsigned int uid)
+{
+    GPanelUpdate *result;                   /* Tâche à retourner           */
+
+    result = g_object_new(G_TYPE_PANEL_UPDATE, NULL);
+
+    g_object_ref(G_OBJECT(panel));
+    result->panel = panel;
+
+    result->uid = uid;
+
+    result->msg = g_updatable_panel_setup(panel, uid, &result->max, &result->data);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : update = opération de mise à jour à mener.                   *
+*                status = barre de statut à tenir informée.                   *
+*                                                                             *
+*  Description : Assure la mise à jour d'un panneau en différé.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_panel_update_process(GPanelUpdate *update, GtkStatusStack *status)
+{
+    activity_id_t id;                       /* Identifiant de progression  */
+
+    id = gtk_status_stack_add_activity(status, update->msg, update->max);
+
+    g_updatable_panel_process(update->panel, update->uid, status, id, update->data);
+
+    gtk_status_stack_remove_activity(status, id);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : update = tâche venant de se terminer.                        *
+*                panel  = interface visée par la procédure.                   *
+*                                                                             *
+*  Description : Marque l'achèvement d'une mise à jour de panneau.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void conclude_panel_update(GPanelUpdate *update, GUpdatablePanel *panel)
+{
+    g_updatable_panel_conclude(panel, update->uid, update->data);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            ENCAPSULATION DE HAUT NIVEAU                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = interface permettant une mise à jour de panneau.     *
+*                uid   = identifiant à associer à la procédure.               *
+*                                                                             *
+*  Description : Prépare et lance l'actualisation d'un panneau.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : Cette fonction est à appeler depuis le contexte principal.   *
+*                                                                             *
+******************************************************************************/
+
+void run_panel_update(GUpdatablePanel *panel, unsigned int uid)
+{
+    GPanelUpdate *update;                   /* Procédure de mise à jour    */
+
+    update = g_panel_update_new(panel, uid);
+
+    g_signal_connect_to_main(update, "work-completed", G_CALLBACK(conclude_panel_update), panel,
+                             g_cclosure_marshal_VOID__VOID);
+
+    g_updatable_panel_introduce(panel, uid, update->data);
+
+    g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(update), DEFAULT_WORK_GROUP);
+
+}
diff --git a/src/gui/panels/updating.h b/src/gui/panels/updating.h
new file mode 100644
index 0000000..4edf498
--- /dev/null
+++ b/src/gui/panels/updating.h
@@ -0,0 +1,118 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * updating.h - prototypes pour la mise à jour des panneaux de l'interface
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GUI_PANELS_UPDATING_H
+#define _GUI_PANELS_UPDATING_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+
+#include "../../gtkext/gtkstatusstack.h"
+
+
+
+/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */
+
+
+#define G_TYPE_UPDATABLE_PANEL             (g_updatable_panel_get_type())
+#define G_UPDATABLE_PANEL(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_UPDATABLE_PANEL, GUpdatablePanel))
+#define G_UPDATABLE_PANEL_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_UPDATABLE_PANEL, GUpdatablePanelIface))
+#define G_IS_UPDATABLE_PANEL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_UPDATABLE_PANEL))
+#define G_IS_UPDATABLE_PANEL_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_UPDATABLE_PANEL))
+#define G_UPDATABLE_PANEL_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_UPDATABLE_PANEL, GUpdatablePanelIface))
+
+
+/* Mécanisme de mise à jour d'un panneau (coquille vide) */
+typedef struct _GUpdatablePanel GUpdatablePanel;
+
+/* Mécanisme de mise à jour d'un panneau (interface) */
+typedef struct _GUpdatablePanelIface GUpdatablePanelIface;
+
+
+/* Détermine le type d'une interface pour la mise à jour de panneau. */
+GType g_updatable_panel_get_type(void) G_GNUC_CONST;
+
+/* Prépare une opération de mise à jour de panneau. */
+const char *g_updatable_panel_setup(const GUpdatablePanel *, unsigned int, size_t *, void **);
+
+/* Bascule l'affichage d'un panneau avant mise à jour. */
+void g_updatable_panel_introduce(const GUpdatablePanel *, unsigned int, void *);
+
+/* Réalise une opération de mise à jour de panneau. */
+void g_updatable_panel_process(const GUpdatablePanel *, unsigned int, GtkStatusStack *, activity_id_t, void *);
+
+/* Bascule l'affichage d'un panneau après mise à jour. */
+void g_updatable_panel_conclude(GUpdatablePanel *, unsigned int, void *);
+
+
+
+/* ---------------------------- AIDE POUR LA MISE A JOUR ---------------------------- */
+
+
+#define G_TYPE_PANEL_UPDATE            g_panel_update_get_type()
+#define G_PANEL_UPDATE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PANEL_UPDATE, GPanelUpdate))
+#define G_IS_PANEL_UPDATE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PANEL_UPDATE))
+#define G_PANEL_UPDATE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PANEL_UPDATE, GPanelUpdateClass))
+#define G_IS_PANEL_UPDATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PANEL_UPDATE))
+#define G_PANEL_UPDATE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PANEL_UPDATE, GPanelUpdateClass))
+
+
+/* Procédure de mise à jour de panneau graphique (instance) */
+typedef struct _GPanelUpdate GPanelUpdate;
+
+/* Procédure de mise à jour de panneau graphique (classe) */
+typedef struct _GPanelUpdateClass GPanelUpdateClass;
+
+
+/* Indique le type défini pour les tâches de mise à jour de panneau. */
+GType g_panel_update_get_type(void);
+
+/* Crée une tâche de mise à jour non bloquante. */
+GPanelUpdate *g_panel_update_new(GUpdatablePanel *, unsigned int);
+
+
+
+/* -------------------------- ENCAPSULATION DE HAUT NIVEAU -------------------------- */
+
+
+/* Identifiants arbitraires pour distinguer les phases */
+typedef enum _PanelUpdateID
+{
+    PUI_0,                                  /* Phase #0                    */
+    PUI_1,                                  /* Phase #1                    */
+    PUI_2,                                  /* Phase #2                    */
+    PUI_3,                                  /* Phase #3                    */
+    PUI_4                                   /* Phase #4                    */
+
+} PanelUpdateID;
+
+
+/* Prépare et lance l'actualisation d'un panneau. */
+void run_panel_update(GUpdatablePanel *, unsigned int);
+
+
+
+#endif  /* _GUI_PANELS_UPDATING_H */
-- 
cgit v0.11.2-87-g4458