From 0769fafb253b846b58cd97c4a1df98ca7417ae1c Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 21 Feb 2018 00:02:44 +0100
Subject: Replaced the old symbol panel by a new improved one.

---
 ChangeLog                         |   28 +
 pixmaps/symbol_object_classic.png |  Bin 0 -> 569 bytes
 src/gtkext/tmgt.c                 |    2 +-
 src/gui/panels/Makefile.am        |    1 +
 src/gui/panels/errors.c           |    2 +-
 src/gui/panels/gresource.xml      |    4 +
 src/gui/panels/symbols.c          | 1088 +++++++++++++++++++++++++++++--------
 src/gui/panels/symbols.ui         |  244 +++++++++
 src/gui/panels/updating-int.h     |    4 +
 src/gui/panels/updating.c         |   28 +
 src/gui/panels/updating.h         |    3 +
 11 files changed, 1170 insertions(+), 234 deletions(-)
 create mode 100644 pixmaps/symbol_object_classic.png
 create mode 100644 src/gui/panels/symbols.ui

diff --git a/ChangeLog b/ChangeLog
index 616debb..90898d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+18-02-21  Cyrille Bagard <nocbos@gmail.com>
+
+	* pixmaps/symbol_object_classic.png:
+	New entry: create an icon for object symbols.
+
+	* src/gtkext/tmgt.c:
+	Typo.
+
+	* src/gui/panels/Makefile.am:
+	Add the 'symbols.ui' file to UI_FILES.
+
+	* src/gui/panels/errors.c:
+	Typo.
+
+	* src/gui/panels/gresource.xml:
+	Update code.
+
+	* src/gui/panels/symbols.c:
+	Replace the old symbol panel by a new improved one.
+
+	* src/gui/panels/symbols.ui:
+	New entry: create a GUI for the symbol panel using Glade.
+
+	* src/gui/panels/updating-int.h:
+	* src/gui/panels/updating.c:
+	* src/gui/panels/updating.h:
+	Clean the data used for updates when needed.
+
 18-02-18  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/gui/panels/errors.c:
diff --git a/pixmaps/symbol_object_classic.png b/pixmaps/symbol_object_classic.png
new file mode 100644
index 0000000..eb028ba
Binary files /dev/null and b/pixmaps/symbol_object_classic.png differ
diff --git a/src/gtkext/tmgt.c b/src/gtkext/tmgt.c
index fa1e2b8..3b06d4c 100644
--- a/src/gtkext/tmgt.c
+++ b/src/gtkext/tmgt.c
@@ -103,7 +103,7 @@ bool is_content_matching(const regex_t *filter, const char *content, regmatch_t
     bool result;                            /* Bilan à retourner           */
     int ret;                                /* Bilan du filtrage           */
 
-    memset( match, 0, sizeof(regmatch_t));
+    memset(match, 0, sizeof(regmatch_t));
 
     if (filter == NULL)
         result = true;
diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am
index a943380..0c7210f 100644
--- a/src/gui/panels/Makefile.am
+++ b/src/gui/panels/Makefile.am
@@ -6,6 +6,7 @@ noinst_LTLIBRARIES  = libguipanels.la
 UI_FILES =								\
 	bintree.ui							\
 	errors.ui							\
+	symbols.ui							\
 	welcome.ui
 
 libguipanels_la_SOURCES =				\
diff --git a/src/gui/panels/errors.c b/src/gui/panels/errors.c
index 2bfe250..afe0283 100644
--- a/src/gui/panels/errors.c
+++ b/src/gui/panels/errors.c
@@ -190,7 +190,7 @@ static void g_error_panel_conclude(GErrorPanel *, unsigned int, error_update_dat
 
 /* Indique le type défini pour un panneau d'affichage des erreurs. */
 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))
+                        G_IMPLEMENT_INTERFACE(G_TYPE_UPDATABLE_PANEL, g_error_panel_interface_init));
 
 
 /******************************************************************************
diff --git a/src/gui/panels/gresource.xml b/src/gui/panels/gresource.xml
index 64a6036..214e546 100644
--- a/src/gui/panels/gresource.xml
+++ b/src/gui/panels/gresource.xml
@@ -1,10 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <gresources>
     <gresource prefix="/org/chrysalide/gui/panels">
+        <file compressed="true">../../../pixmaps/tbutton_list_view.png</file>
+        <file compressed="true">../../../pixmaps/tbutton_tree_view.png</file>
         <file compressed="true">../../../pixmaps/tbutton_collapse.png</file>
         <file compressed="true">../../../pixmaps/tbutton_expand.png</file>
+        <file compressed="true">../../../pixmaps/symbol_class_classic.png</file>
         <file compressed="true">bintree.ui</file>
         <file compressed="true">errors.ui</file>
+        <file compressed="true">symbols.ui</file>
         <file compressed="true">welcome.ui</file>
     </gresource>
 </gresources>
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index dee03b5..6b0b999 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -37,6 +37,7 @@
 
 
 #include "panel-int.h"
+#include "updating-int.h"
 #include "../core/global.h"
 #include "../../format/format.h"
 #include "../../format/symiter.h"
@@ -54,11 +55,10 @@ struct _GSymbolsPanel
 {
     GPanelItem parent;                      /* A laisser en premier        */
 
-    GtkTreeView *treeview;                  /* Composant d'affichage       */
-    GtkTreeStore *store;                    /* Modèle de gestion           */
-
     GLoadedBinary *binary;                  /* Binaire à prendre en compte */
 
+    size_t count;                           /* Quantité de symboles utiles */
+
     regex_t *filter;                        /* Filtre appliqué ou NULL     */
 
 };
@@ -69,6 +69,7 @@ struct _GSymbolsPanelClass
     GPanelItemClass parent;                 /* A laisser en premier        */
 
     cairo_surface_t *routine_img;           /* Image pour les routines     */
+    cairo_surface_t *object_img;            /* Image pour les objets       */
     cairo_surface_t *package_img;           /* Image pour les paquets      */
     cairo_surface_t *class_img;             /* Image pour les classes      */
 
@@ -87,26 +88,37 @@ typedef enum _SymbolsColumn
     SBC_SECTION,                            /* Section d'appartenance      */
 
     SBC_EXPAND,                             /* Affichage des classes       */
-
-    SBC_COUNT                               /* Nombre de colonnes          */
+    SBC_MATCHED,                            /* Correspondance établie ?    */
+    SBC_MATCH_POINTS                        /* Nombre de demandeurs        */
 
 } SymbolsColumn;
 
 
+
+/* Données utiles à la mise à jour */
+typedef struct _symbols_update_data symbols_update_data;
+
+
 /* Initialise la classe des panneaux d'affichage des symboles. */
 static void g_symbols_panel_class_init(GSymbolsPanelClass *);
 
 /* Initialise une instance de panneau d'affichage des symboles. */
 static void g_symbols_panel_init(GSymbolsPanel *);
 
+/* Procède à l'initialisation de l'interface de mise à jour. */
+static void g_symbols_panel_interface_init(GUpdatablePanelInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_symbols_panel_dispose(GSymbolsPanel *);
 
 /* Procède à la libération totale de la mémoire. */
 static void g_symbols_panel_finalize(GSymbolsPanel *);
 
-/* Réagit au changement d'affichage des symboles. */
-static void on_symbols_display_change(GtkToggleToolButton *, GSymbolsPanel *);
+/* Bascule d'affichage des symboles en liste. */
+static void on_symbols_list_display_toggle(GtkToggleToolButton *, GSymbolsPanel *);
+
+/* Bascule l'affichage des symboles en arborescence. */
+static void on_symbols_tree_display_toggle(GtkToggleToolButton *, GSymbolsPanel *);
 
 /* Réagit au changement de sélection des symboles. */
 static void on_symbols_selection_change(GtkTreeSelection *, gpointer);
@@ -114,13 +126,19 @@ static void on_symbols_selection_change(GtkTreeSelection *, gpointer);
 /* Réagit à un changement d'affichage principal de contenu. */
 static void change_symbols_panel_current_binary(GSymbolsPanel *, GLoadedBinary *);
 
+/* Réagit à un changement d'affichage principal de contenu. */
+static void reload_symbols_panel_content(const GSymbolsPanel *, GtkStatusStack *, activity_id_t, symbols_update_data *);
+
 
 
 /* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */
 
 
 /* Réagit à un changement d'affichage principal de contenu. */
-static void reload_symbols_for_new_list_view(GSymbolsPanel *);
+static void reload_symbols_for_new_list_view(const GSymbolsPanel *, GtkStatusStack *, activity_id_t, symbols_update_data *);
+
+/* Met en surbrillance les éléments recherchés dans les noms. */
+static void update_symbol_name_in_list_view(GtkTreeStore *, GtkTreeIter *, const regmatch_t *);
 
 
 
@@ -128,21 +146,26 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *);
 
 
 /* S'assure qu'un noeud donné existe bien. */
-
-static GtkTreeIter ensure_symbol_node_exist(GSymbolsPanel *, GtkTreeIter *, const char *, const regmatch_t *, size_t);
+static GtkTreeIter ensure_symbol_node_exist(const GSymbolsPanel *, GtkTreeIter *, const char *, const regmatch_t *, size_t);
 
 /* Détermine le point d'insertion parent d'une routine. */
-static bool find_parent_for_symbol(GSymbolsPanel *, const GBinSymbol *, GtkTreeIter *, const regmatch_t *, size_t *);
+static bool find_parent_for_symbol(const GSymbolsPanel *, const GBinSymbol *, GtkTreeIter *, const regmatch_t *, size_t *);
 
 /* Réagit à un changement d'affichage principal de contenu. */
-static void reload_symbols_for_new_tree_view(GSymbolsPanel *);
+static void reload_symbols_for_new_tree_view(const GSymbolsPanel *, GtkStatusStack *, activity_id_t, symbols_update_data *);
 
 /* Réagit à une nouvelle demande de réorganisation. */
-static void reorganize_symbols_tree_view(GtkToolButton *, GObject *);
+static void reorganize_symbols_tree_view(GtkToolButton *, const GSymbolsPanel *);
 
 /* Fait en sorte que toutes les classes soient affichées. */
 static gboolean show_all_classes_in_tree_view(GtkTreeModel *, GtkTreePath *, GtkTreeIter *, GtkTreeView *);
 
+/* Actualise une partie d'un nom de symbole éclaté en noeuds. */
+static GtkTreeIter update_symbol_partial_name_in_tree_view(GtkTreeStore *, GtkTreeIter *, const char *, const regmatch_t *, size_t);
+
+/* Met en surbrillance les éléments recherchés dans les noms. */
+static void update_symbol_name_in_tree_view(GtkTreeStore *, const GBinSymbol *, const regmatch_t *);
+
 
 
 /* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */
@@ -151,11 +174,50 @@ static gboolean show_all_classes_in_tree_view(GtkTreeModel *, GtkTreePath *, Gtk
 /* Démarre l'actualisation du filtrage des symboles. */
 static void on_symbols_filter_changed(GtkSearchEntry *, GSymbolsPanel *);
 
+/* Met à jour l'affichage des noeuds en fonction des besoin. */
+static void update_symbol_visibility(GtkTreeStore *, GtkTreeIter *, bool);
+
 /* Exécute un nouveau filtrage des symboles affichés. */
-static void do_filtering_on_symbols(GSymbolsPanel *);
+static void do_filtering_on_symbols(const GSymbolsPanel *, GtkStatusStack *, activity_id_t, symbols_update_data *);
 
 /* Détermine si un nom de symbole doit être filtré ou non. */
-static bool is_symbol_matching(GSymbolsPanel *, const GBinSymbol *, regmatch_t *);
+static bool is_symbol_matching(const GSymbolsPanel *, const GBinSymbol *, regmatch_t *);
+
+
+/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */
+
+
+/* Données utiles à la mise à jour */
+struct _symbols_update_data
+{
+    GtkTreeModel *model;                    /* Source de données associée  */
+
+    size_t count;                           /* Qté d'inscriptions réalisées*/
+
+    char **expanded;                        /* Chemins des noeuds ouverts  */
+    size_t ecount;                          /* Nombre de ces chemins       */
+    size_t eallocated;                      /* Espace alloué effectivement */
+
+};
+
+
+#define EXPAND_ALLOC_RANGE 10
+
+
+/* Prépare une opération de mise à jour de panneau. */
+static const char *g_symbols_panel_setup(const GSymbolsPanel *, unsigned int, size_t *, symbols_update_data **);
+
+/* Bascule l'affichage d'un panneau avant mise à jour. */
+static void g_symbols_panel_introduce(const GSymbolsPanel *, unsigned int, symbols_update_data *);
+
+/* Réalise une opération de mise à jour de panneau. */
+static void g_symbols_panel_process(const GSymbolsPanel *, unsigned int, GtkStatusStack *, activity_id_t, symbols_update_data *);
+
+/* Bascule l'affichage d'un panneau après mise à jour. */
+static void g_symbols_panel_conclude(GSymbolsPanel *, unsigned int, symbols_update_data *);
+
+/* Supprime les données dynamiques utilisées à la mise à jour. */
+static void g_symbols_panel_clean_data(GUpdatablePanel *, unsigned int, symbols_update_data *);
 
 
 
@@ -165,7 +227,8 @@ static bool is_symbol_matching(GSymbolsPanel *, const GBinSymbol *, regmatch_t *
 
 
 /* Indique le type définit pour un panneau d'affichage des symboles. */
-G_DEFINE_TYPE(GSymbolsPanel, g_symbols_panel, G_TYPE_PANEL_ITEM);
+G_DEFINE_TYPE_WITH_CODE(GSymbolsPanel, g_symbols_panel, G_TYPE_PANEL_ITEM,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_UPDATABLE_PANEL, g_symbols_panel_interface_init));
 
 
 /******************************************************************************
@@ -203,6 +266,13 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)
 
     g_free(filename);
 
+    filename = find_pixmap_file("symbol_object_classic.png");
+    assert(filename != NULL);
+
+    klass->object_img = cairo_image_surface_create_from_png(filename);
+
+    g_free(filename);
+
     filename = find_pixmap_file("symbol_package.png");
     assert(filename != NULL);
 
@@ -241,17 +311,11 @@ static void g_symbols_panel_init(GSymbolsPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
     GPanelItem *pitem;                      /* Version parente du panneau  */
-    GObject *ref;                           /* Espace de référencement     */
-    GtkWidget *box;                         /* Séparation horizontale      */
-    GtkWidget *toolbar;                     /* Barre d'outils              */
-    GtkWidget *button;                      /* Bouton de cette même barre  */
-    GtkWidget *separator;                   /* Barre de séparation vert.   */
-    GtkWidget *search;                      /* Zone de recherche           */
-    GtkWidget *scrollwnd;                   /* Support défilant            */
-    GtkWidget *treeview;                    /* Affichage de la liste       */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeView *treeview;                  /* Affichage de la liste       */
+    GtkTreeModelFilter *filter;             /* Filtre pour l'arborescence  */
     GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
     GtkTreeViewColumn *column;              /* Colonne de la liste         */
-    GtkTreeSelection *select;               /* Sélection dans la liste     */
 
     /* Eléments de base */
 
@@ -268,95 +332,15 @@ static void g_symbols_panel_init(GSymbolsPanel *panel)
 
     /* Représentation graphique */
 
-    base->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
-    gtk_widget_show(base->widget);
-
-    ref = G_OBJECT(base->widget);
-    g_object_set_data(ref, "panel", panel);
-
-    /* Barre d'outils supérieure */
-
-    box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
-    gtk_widget_show(box);
-    gtk_box_pack_start(GTK_BOX(base->widget), box, FALSE, FALSE, 0);
-
-    toolbar = gtk_toolbar_new();
-    gtk_widget_show(toolbar);
-    gtk_box_pack_start(GTK_BOX(box), toolbar, TRUE, TRUE, 0);
-
-    button = qck_create_toggle_tool_button(ref, "list", _("List"), "tbutton_list_view.png",
-                                           G_CALLBACK(on_symbols_display_change), panel);
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button),
-                                   _("Show symbols using a list view"));
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(button), -1);
-
-    button = qck_create_toggle_tool_button(ref, "tree", _("Tree"),  "tbutton_tree_view.png", 
-                                           G_CALLBACK(on_symbols_display_change), panel);
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button),
-                                   _("Show symbols using a tree view"));
-    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), TRUE);
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(button), -1);
-
-    separator = qck_create_tool_separator(NULL, NULL);
-    gtk_container_add(GTK_CONTAINER(toolbar), separator);
-
-    button = qck_create_tool_button(ref, "collapse", _("Collapse"),  "tbutton_collapse.png",
-                                    G_CALLBACK(reorganize_symbols_tree_view), ref);
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button),
-                                   _("Collapse all symbol nodes in the tree view"));
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(button), -1);
-
-    button = qck_create_tool_button(ref, "expand", _("Expand"),  "tbutton_expand.png",
-                                    G_CALLBACK(reorganize_symbols_tree_view), ref);
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button),
-                                   _("Expand all symbol nodes in the tree view"));
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(button), -1);
+    builder = g_panel_item_build(pitem, "symbols");
 
-    button = qck_create_tool_button(ref, "classes", _("Classes"),  "symbol_class_classic.png",
-                                    G_CALLBACK(reorganize_symbols_tree_view), ref);
-    gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(button),
-                                   _("Show all classes in the tree view"));
-    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(button), -1);
-
-    separator = qck_create_tool_separator(NULL, NULL);
-    gtk_container_add(GTK_CONTAINER(toolbar), separator);
-
-    /* Espace de recherche */
-
-    search = gtk_search_entry_new();
-    gtk_widget_set_tooltip_text(search, _("Filter symbols using POSIX extended regular expressions"));
-
-    g_signal_connect(search, "search-changed", G_CALLBACK(on_symbols_filter_changed), panel);
-    gtk_widget_show(search);
-    gtk_widget_set_hexpand(search, TRUE);
-
-    gtk_box_pack_start(GTK_BOX(box), search, TRUE, TRUE, 0);
-
-    /* Liste arborescente ou linéaire */
-
-    scrollwnd = gtk_scrolled_window_new(NULL, NULL);
-    gtk_widget_show(scrollwnd);
-    gtk_box_pack_start(GTK_BOX(base->widget), scrollwnd, TRUE, TRUE, 0);
-
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwnd), GTK_SHADOW_IN);
-
-    panel->store = gtk_tree_store_new(SBC_COUNT, G_TYPE_OBJECT, CAIRO_GOBJECT_TYPE_SURFACE, G_TYPE_STRING,
-                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
-
-    treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(panel->store));
-    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
-    gtk_tree_view_set_enable_tree_lines(GTK_TREE_VIEW(treeview), TRUE);
-
-    panel->treeview = GTK_TREE_VIEW(treeview);
-
-    gtk_widget_show(treeview);
-    gtk_container_add(GTK_CONTAINER(scrollwnd), treeview);
-
-    g_object_unref(G_OBJECT(panel->store));
+    filter = GTK_TREE_MODEL_FILTER(gtk_builder_get_object(builder, "filter"));
+    gtk_tree_model_filter_set_visible_column(filter, SBC_MATCHED);
 
     /* Cellules d'affichage */
 
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
     column = gtk_tree_view_column_new();
 
     renderer = gtk_cell_renderer_pixbuf_new();
@@ -385,11 +369,40 @@ static void g_symbols_panel_init(GSymbolsPanel *panel)
     gtk_tree_view_column_set_sort_column_id(column, SBC_SECTION);
     gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
 
-    /* Prise en compte de la sélection */
+    /* Connexion des signaux */
+
+    gtk_builder_add_callback_symbols(builder,
+                                     "on_symbols_list_display_toggle", G_CALLBACK(on_symbols_list_display_toggle),
+                                     "on_symbols_tree_display_toggle", G_CALLBACK(on_symbols_tree_display_toggle),
+                                     "reorganize_symbols_tree_view", G_CALLBACK(reorganize_symbols_tree_view),
+                                     "on_symbols_filter_changed", G_CALLBACK(on_symbols_filter_changed),
+                                     "on_symbols_selection_change", G_CALLBACK(on_symbols_selection_change),
+                                     NULL);
 
-    select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
-    gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
-    g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(on_symbols_selection_change), NULL);
+    gtk_builder_connect_signals(builder, panel);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de mise à jour.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_symbols_panel_interface_init(GUpdatablePanelInterface *iface)
+{
+    iface->setup = (setup_updatable_cb)g_symbols_panel_setup;
+    iface->introduce = (introduce_updatable_cb)g_symbols_panel_introduce;
+    iface->process = (process_updatable_cb)g_symbols_panel_process;
+    iface->conclude = (conclude_updatable_cb)g_symbols_panel_conclude;
+    iface->clean = (clean_updatable_data_cb)g_symbols_panel_clean_data;
 
 }
 
@@ -469,7 +482,7 @@ GPanelItem *g_symbols_panel_new(void)
 *  Paramètres  : button = bouton de la barre activé.                          *
 *                panel  = structure contenant les informations maîtresses.    *
 *                                                                             *
-*  Description : Réagit au changement d'affichage des symboles.               *
+*  Description : Bascule d'affichage des symboles en liste.                   *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -477,54 +490,82 @@ GPanelItem *g_symbols_panel_new(void)
 *                                                                             *
 ******************************************************************************/
 
-static void on_symbols_display_change(GtkToggleToolButton *button, GSymbolsPanel *panel)
+static void on_symbols_list_display_toggle(GtkToggleToolButton *button, GSymbolsPanel *panel)
 {
-    GObject *ref;                           /* Espace de référencement     */
-    GtkToggleToolButton *list;              /* Bouton pour les listes      */
-    GtkToggleToolButton *tree;              /* Bouton pour l'arborescence  */
-    gboolean state;                         /* Etat du bouton courant      */
-    GtkToggleToolButton *other;             /* Bouton à traiter            */
-    GtkWidget *option;                      /* Bouton dont l'accès change  */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkWidget *other;                       /* Autre bouton de la barre    */
 
-    ref = G_OBJECT(G_EDITOR_ITEM(panel)->widget);
+    if (gtk_toggle_tool_button_get_active(button))
+    {
+        /* Accès aux boutons complémentaires */
 
-    list = GTK_TOGGLE_TOOL_BUTTON(g_object_get_data(ref, "list"));
-    tree = GTK_TOGGLE_TOOL_BUTTON(g_object_get_data(ref, "tree"));
+        builder = G_PANEL_ITEM(panel)->builder;
 
-    /* Désactivation de l'autre bouton */
+        other = GTK_WIDGET(gtk_builder_get_object(builder, "collapse"));
+        gtk_widget_set_sensitive(other, FALSE);
 
-    state = gtk_toggle_tool_button_get_active(button);
+        other = GTK_WIDGET(gtk_builder_get_object(builder, "expand"));
+        gtk_widget_set_sensitive(other, FALSE);
 
-    if (button == list) other = tree;
-    else other = list;
+        other = GTK_WIDGET(gtk_builder_get_object(builder, "classes"));
+        gtk_widget_set_sensitive(other, FALSE);
 
-    g_signal_handlers_disconnect_by_func(other, G_CALLBACK(on_symbols_display_change), panel);
-    gtk_toggle_tool_button_set_active(other, !state);
-    g_signal_connect(other, "toggled", G_CALLBACK(on_symbols_display_change), panel);
+        /* Actualisation de l'affichage */
 
-    /* Définition des accès sur le reste de la barre */
+        if (panel->binary != NULL)
+        {
+            g_object_ref(G_OBJECT(panel->binary));
+            change_symbols_panel_current_binary(panel, panel->binary);
+            g_object_unref(G_OBJECT(panel->binary));
+        }
 
-    state = gtk_toggle_tool_button_get_active(tree);
+    }
 
-    option = GTK_WIDGET(g_object_get_data(ref, "collapse"));
-    if (option != NULL)
-        gtk_widget_set_sensitive(option, state);
+}
 
-    option = GTK_WIDGET(g_object_get_data(ref, "expand"));
-    if (option != NULL)
-        gtk_widget_set_sensitive(option, state);
 
-    option = GTK_WIDGET(g_object_get_data(ref, "classes"));
-    if (option != NULL)
-        gtk_widget_set_sensitive(option, state);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : button = bouton de la barre activé.                          *
+*                panel  = structure contenant les informations maîtresses.    *
+*                                                                             *
+*  Description : Bascule l'affichage des symboles en arborescence.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-    /* Actualisation */
+static void on_symbols_tree_display_toggle(GtkToggleToolButton *button, GSymbolsPanel *panel)
+{
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkWidget *other;                       /* Autre bouton de la barre    */
 
-    if (panel->binary != NULL)
+    if (gtk_toggle_tool_button_get_active(button))
     {
-        g_object_ref(G_OBJECT(panel->binary));
-        change_symbols_panel_current_binary(panel, panel->binary);
-        g_object_unref(G_OBJECT(panel->binary));
+        /* Accès aux boutons complémentaires */
+
+        builder = G_PANEL_ITEM(panel)->builder;
+
+        other = GTK_WIDGET(gtk_builder_get_object(builder, "collapse"));
+        gtk_widget_set_sensitive(other, TRUE);
+
+        other = GTK_WIDGET(gtk_builder_get_object(builder, "expand"));
+        gtk_widget_set_sensitive(other, TRUE);
+
+        other = GTK_WIDGET(gtk_builder_get_object(builder, "classes"));
+        gtk_widget_set_sensitive(other, TRUE);
+
+        /* Actualisation de l'affichage */
+
+        if (panel->binary != NULL)
+        {
+            g_object_ref(G_OBJECT(panel->binary));
+            change_symbols_panel_current_binary(panel, panel->binary);
+            g_object_unref(G_OBJECT(panel->binary));
+        }
+
     }
 
 }
@@ -590,8 +631,8 @@ static void on_symbols_selection_change(GtkTreeSelection *selection, gpointer un
 
 static void change_symbols_panel_current_binary(GSymbolsPanel *panel, GLoadedBinary *binary)
 {
-    GtkToggleToolButton *button;            /* Mode de représentation      */
-    GtkRequisition req;                     /* Nouvelle taille idéale      */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeStore *store;                    /* Modèle de gestion           */
 
     /* Basculement du binaire utilisé */
 
@@ -603,29 +644,55 @@ static void change_symbols_panel_current_binary(GSymbolsPanel *panel, GLoadedBin
     if (panel->binary != NULL)
         g_object_ref(G_OBJECT(panel->binary));
 
-    gtk_tree_store_clear(panel->store);
+    /* Réinitialisation */
+
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
+
+    gtk_tree_store_clear(store);
 
-    /* Si le panneau actif ne représente pas un binaire... */
+    /* Si le panneau actif représente un binaire, actualisation de l'affichage */
 
-    if (binary == NULL) return;
+    if (binary != NULL)
+        run_panel_update(G_UPDATABLE_PANEL(panel), PUI_0);
 
-    /* Actualisation de l'affichage */
+}
 
-    button = g_object_get_data(G_OBJECT(G_EDITOR_ITEM(panel)->widget), "list");
+
+/******************************************************************************
+*                                                                             *
+*  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 : Réagit à un changement d'affichage principal de contenu.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void reload_symbols_panel_content(const GSymbolsPanel *panel, GtkStatusStack *status, activity_id_t id, symbols_update_data *data)
+{
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkToggleToolButton *button;            /* Mode de représentation      */
+
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    button = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "list_display"));
 
     if (gtk_toggle_tool_button_get_active(button))
-        reload_symbols_for_new_list_view(panel);
+        reload_symbols_for_new_list_view(panel, status, id, data);
+
     else
     {
-        reload_symbols_for_new_tree_view(panel);
-        reorganize_symbols_tree_view(NULL, G_OBJECT(G_EDITOR_ITEM(panel)->widget));
+        reload_symbols_for_new_tree_view(panel, status, id, data);
+        reorganize_symbols_tree_view(NULL, panel);
     }
 
-    return; /* FIXME */
-
-    gtk_widget_get_preferred_size(GTK_WIDGET(panel->treeview), NULL, &req);
-    gtk_widget_set_size_request(GTK_WIDGET(panel->treeview), req.width, req.height);
-
 }
 
 
@@ -638,6 +705,9 @@ static void change_symbols_panel_current_binary(GSymbolsPanel *panel, GLoadedBin
 /******************************************************************************
 *                                                                             *
 *  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 : Réagit à un changement d'affichage principal de contenu.     *
 *                                                                             *
@@ -647,21 +717,28 @@ static void change_symbols_panel_current_binary(GSymbolsPanel *panel, GLoadedBin
 *                                                                             *
 ******************************************************************************/
 
-static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
+static void reload_symbols_for_new_list_view(const GSymbolsPanel *panel, GtkStatusStack *status, activity_id_t id, symbols_update_data *data)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeStore *store;                    /* Modèle de gestion           */
     GExeFormat *format;                     /* Format associé au binaire   */
     GArchProcessor *proc;                   /* Architecture utilisée       */
     MemoryDataSize size;                    /* Taille des localisations    */
     sym_iter_t *siter;                      /* Parcours des symboles       */
     GBinSymbol *symbol;                     /* Symbole manipulé            */
-    regmatch_t match;                       /* Récupération des trouvailles*/
     cairo_surface_t *icon;                  /* Image associée au symbole   */
+    regmatch_t match;                       /* Récupération des trouvailles*/
+    bool matched;                           /* Correspondance de sélection */
     const char *original;                   /* Etiquette brute d'origine   */
     char *name;                             /* Etiquette mise en relief    */
     const vmpa2t *addr;                     /* Localisation d'un symbole   */
     char virt[VMPA_MAX_LEN];                /* Version humainement lisible */
     GtkTreeIter iter;                       /* Point d'insertion           */
 
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
+
     format = g_loaded_binary_get_format(panel->binary);
 
     proc = g_loaded_binary_get_processor(panel->binary);
@@ -674,9 +751,6 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
          symbol != NULL;
          symbol = get_symbol_iterator_next(siter))
     {
-        if (!is_symbol_matching(panel, symbol, &match))
-            goto rsfnlv_next;
-
         switch (g_binary_symbol_get_target_type(symbol))
         {
             case STP_ROUTINE:
@@ -684,29 +758,46 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
                 icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img;
                 break;
             case STP_OBJECT:
-                icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img; /* FIXME */
+                icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->object_img;
                 break;
             default:
-                assert(false);
+                icon = NULL;
                 break;
         }
 
+        if (icon == NULL)
+            goto rsfnlv_next;
+
+        matched = is_symbol_matching(panel, symbol, &match);
+
         original = g_binary_symbol_get_label(symbol);
-        name = build_highlighted_name(original, &match, 0);
+
+        if (matched)
+            name = build_highlighted_name(original, &match, 0);
+        else
+            name = NULL;
 
         addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
         vmpa2_virt_to_string(addr, size, virt, NULL);
 
-        gtk_tree_store_append(panel->store, &iter, NULL);
-        gtk_tree_store_set(panel->store, &iter,
+        gtk_tree_store_append(store, &iter, NULL);
+        gtk_tree_store_set(store, &iter,
                            SBC_SYMBOL, symbol,
                            SBC_PICTURE, icon,
                            SBC_NAME, name,
                            SBC_ORIGINAL, original,
                            SBC_ADDRESS, virt,
+                           SBC_MATCHED, false,
+                           SBC_MATCH_POINTS, 0,
                            -1);
 
-        free(name);
+        if (matched)
+            update_symbol_visibility(store, &iter, true);
+
+        data->count++;
+
+        if (name != NULL)
+            free(name);
 
  rsfnlv_next:
 
@@ -721,6 +812,40 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : store = gestionnaire de données pour une arborescence.       *
+*                iter  = position des données traitées.                       *
+*                match = correspondance avec un objet recherché.              *
+*                                                                             *
+*  Description : Met en surbrillance les éléments recherchés dans les noms.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void update_symbol_name_in_list_view(GtkTreeStore *store, GtkTreeIter *iter, const regmatch_t *match)
+{
+    GtkTreeModel *model;                    /* Autre vision du gestionnaire*/
+    char *original;                         /* Etiquette brute d'origine   */
+    char *name;                             /* Etiquette mise en relief    */
+
+    model = GTK_TREE_MODEL(store);
+
+    gtk_tree_model_get(model, iter, SBC_ORIGINAL, &original, -1);
+
+    name = build_highlighted_name(original, match, 0);
+
+    gtk_tree_store_set(store, iter, SBC_NAME, name, -1);
+
+    free(original);
+    free(name);
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                            AFFICHAGE SOUS FORME D'ARBRE                            */
@@ -743,29 +868,35 @@ static void reload_symbols_for_new_list_view(GSymbolsPanel *panel)
 *                                                                             *
 ******************************************************************************/
 
-static GtkTreeIter ensure_symbol_node_exist(GSymbolsPanel *panel, GtkTreeIter *parent, const char *raw, const regmatch_t *match, size_t start)
+static GtkTreeIter ensure_symbol_node_exist(const GSymbolsPanel *panel, GtkTreeIter *parent, const char *raw, const regmatch_t *match, size_t start)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
     GtkTreeStore *store;                    /* Gestionnaire de données     */
+    GtkTreeModel *model;                    /* Autre vision du gestionnaire*/
     bool found;                             /* Bilan des recherches        */
     GtkTreeIter iter;                       /* Boucle de parcours          */
     gchar *string;                          /* Chaîne sélectionnée         */
     char *name;                             /* Etiquette mise en relief    */
 
-    store = panel->store;
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
+
+    model = GTK_TREE_MODEL(store);
 
     found = false;
 
-    if (gtk_tree_model_iter_children(GTK_TREE_MODEL(store), &iter, parent))
+    if (gtk_tree_model_iter_children(model, &iter, parent))
         do
         {
-            gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, SBC_ORIGINAL, &string, -1);
+            gtk_tree_model_get(model, &iter, SBC_ORIGINAL, &string, -1);
             found = (strcmp(string, raw) == 0);
             g_free(string);
 
             if (found) break;
 
         }
-        while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
+        while (gtk_tree_model_iter_next(model, &iter));
 
     if (!found) 
     {
@@ -776,6 +907,8 @@ static GtkTreeIter ensure_symbol_node_exist(GSymbolsPanel *panel, GtkTreeIter *p
                            SBC_PICTURE, G_SYMBOLS_PANEL_GET_CLASS(panel)->package_img,
                            SBC_NAME, name,
                            SBC_ORIGINAL, raw,
+                           SBC_MATCHED, false,
+                           SBC_MATCH_POINTS, 0,
                            -1);
 
         free(name);
@@ -803,8 +936,9 @@ static GtkTreeIter ensure_symbol_node_exist(GSymbolsPanel *panel, GtkTreeIter *p
 *                                                                             *
 ******************************************************************************/
 
-static bool find_parent_for_symbol(GSymbolsPanel *panel, const GBinSymbol *symbol, GtkTreeIter *parent, const regmatch_t *match, size_t *last)
+static bool find_parent_for_symbol(const GSymbolsPanel *panel, const GBinSymbol *symbol, GtkTreeIter *parent, const regmatch_t *match, size_t *last)
 {
+    bool result;                            /* Bilan à retourner           */
     const char *label;                      /* Etiquette immuable          */
     char *string;                           /* Etiquette modifiable        */
     const char *sep;                        /* Délimitateur à utiliser     */
@@ -813,6 +947,8 @@ static bool find_parent_for_symbol(GSymbolsPanel *panel, const GBinSymbol *symbo
     char *saveptr;                          /* Ctx. interne de découpage   */
     char *next;                             /* Prochaine partie à traiter  */
 
+    result = false;
+
     *last = 0;
 
     label = g_binary_symbol_get_label(symbol);
@@ -833,18 +969,23 @@ static bool find_parent_for_symbol(GSymbolsPanel *panel, const GBinSymbol *symbo
 
         *parent = ensure_symbol_node_exist(panel, (start == string ? NULL : parent), token, match, token - string);
 
+        result = true;
+
     }
 
     free(string);
 
-    return true;
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel = panneau à mettre à jour.                             *
+*  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 : Réagit à un changement d'affichage principal de contenu.     *
 *                                                                             *
@@ -854,23 +995,30 @@ static bool find_parent_for_symbol(GSymbolsPanel *panel, const GBinSymbol *symbo
 *                                                                             *
 ******************************************************************************/
 
-static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
+static void reload_symbols_for_new_tree_view(const GSymbolsPanel *panel, GtkStatusStack *status, activity_id_t id, symbols_update_data *data)
 {
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeStore *store;                    /* Modèle de gestion           */
     GExeFormat *format;                     /* Format associé au binaire   */
     GArchProcessor *proc;                   /* Architecture utilisée       */
     MemoryDataSize size;                    /* Taille des localisations    */
     sym_iter_t *siter;                      /* Parcours des symboles       */
     GBinSymbol *symbol;                     /* Symbole manipulé            */
+    cairo_surface_t *icon;                  /* Image associée au symbole   */
     regmatch_t match;                       /* Récupération des trouvailles*/
+    bool matched;                           /* Correspondance de sélection */
     GtkTreeIter parent;                     /* Point d'insertion parent    */
     size_t last;                            /* Position du dernier élément */
-    cairo_surface_t *icon;                  /* Image associée au symbole   */
     const char *original;                   /* Etiquette brute d'origine   */
     char *name;                             /* Etiquette mise en relief    */
     const vmpa2t *addr;                     /* Localisation d'un symbole   */
     char virt[VMPA_MAX_LEN];                /* Version humainement lisible */
     GtkTreeIter iter;                       /* Point d'insertion           */
 
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
+
     format = g_loaded_binary_get_format(panel->binary);
 
     proc = g_loaded_binary_get_processor(panel->binary);
@@ -883,22 +1031,6 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
          symbol != NULL;
          symbol = get_symbol_iterator_next(siter))
     {
-        if (!is_symbol_matching(panel, symbol, &match))
-            goto rsfntv_next;
-
-        if (find_parent_for_symbol(panel, symbol, &parent, &match, &last))
-        {
-            gtk_tree_store_set(panel->store, &parent,
-                               SBC_PICTURE, G_SYMBOLS_PANEL_GET_CLASS(panel)->class_img,
-                               SBC_EXPAND, TRUE,
-                               -1);
-
-            gtk_tree_store_append(panel->store, &iter, &parent);
-
-        }
-        else
-            gtk_tree_store_append(panel->store, &iter, NULL);
-
         switch (g_binary_symbol_get_target_type(symbol))
         {
             case STP_ROUTINE:
@@ -906,28 +1038,58 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
                 icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img;
                 break;
             case STP_OBJECT:
-                icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->routine_img; /* FIXME */
+                icon = G_SYMBOLS_PANEL_GET_CLASS(panel)->object_img;
                 break;
             default:
-                assert(false);
+                icon = NULL;
                 break;
         }
 
+        if (icon == NULL)
+            goto rsfntv_next;
+
+        matched = is_symbol_matching(panel, symbol, &match);
+
+        if (find_parent_for_symbol(panel, symbol, &parent, &match, &last))
+        {
+            gtk_tree_store_set(store, &parent,
+                               SBC_PICTURE, G_SYMBOLS_PANEL_GET_CLASS(panel)->class_img,
+                               SBC_EXPAND, TRUE,
+                               -1);
+
+            gtk_tree_store_append(store, &iter, &parent);
+
+        }
+        else
+            gtk_tree_store_append(store, &iter, NULL);
+
         original = g_binary_symbol_get_label(symbol);
-        name = build_highlighted_name(original + last, &match, last);
+
+        if (matched)
+            name = build_highlighted_name(original + last, &match, last);
+        else
+            name = NULL;
 
         addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
         vmpa2_virt_to_string(addr, size, virt, NULL);
 
-        gtk_tree_store_set(panel->store, &iter,
+        gtk_tree_store_set(store, &iter,
                            SBC_SYMBOL, symbol,
                            SBC_PICTURE, icon,
                            SBC_NAME, name,
                            SBC_ORIGINAL, original + last,
                            SBC_ADDRESS, virt,
+                           SBC_MATCHED, false,
+                           SBC_MATCH_POINTS, 0,
                            -1);
 
-        free(name);
+        if (matched)
+            update_symbol_visibility(store, &iter, true);
+
+        data->count++;
+
+        if (name != NULL)
+            free(name);
 
  rsfntv_next:
 
@@ -945,7 +1107,7 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : button = bouton concerné par l'action.                       *
-*                ref    = espace de référencement des composants.             *
+*                panel  = panneau à mettre à jour.                            *
 *                                                                             *
 *  Description : Réagit à une nouvelle demande de réorganisation.             *
 *                                                                             *
@@ -955,22 +1117,36 @@ static void reload_symbols_for_new_tree_view(GSymbolsPanel *panel)
 *                                                                             *
 ******************************************************************************/
 
-static void reorganize_symbols_tree_view(GtkToolButton *button, GObject *ref)
+static void reorganize_symbols_tree_view(GtkToolButton *button, const GSymbolsPanel *panel)
 {
-    GSymbolsPanel *panel;                   /* Données du panneau          */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeView *treeview;                  /* Arborescence graphique      */
+    GtkToolButton *ref_collapse;            /* Bouton de référence #1      */
+    GtkToolButton *ref_expand;              /* Bouton de référence #2      */
+    GtkTreeStore *store;                    /* Modèle de gestion           */
+
+    builder = G_PANEL_ITEM(panel)->builder;
 
-    panel = (GSymbolsPanel *)g_object_get_data(ref, "panel");
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
 
-    if (g_object_get_data(ref, "collapse") == button)
-        gtk_tree_view_collapse_all(panel->treeview);
+    ref_collapse = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "collapse"));
+    ref_expand = GTK_TOOL_BUTTON(gtk_builder_get_object(builder, "expand"));
 
-    else if (g_object_get_data(ref, "expand") == button)
-        gtk_tree_view_expand_all(panel->treeview);
+    if (button == ref_collapse)
+        gtk_tree_view_collapse_all(treeview);
+
+    else if (button == ref_expand)
+        gtk_tree_view_expand_all(treeview);
 
     else
-        gtk_tree_model_foreach(GTK_TREE_MODEL(panel->store),
+    {
+        store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
+
+        gtk_tree_model_foreach(GTK_TREE_MODEL(store),
                                (GtkTreeModelForeachFunc)show_all_classes_in_tree_view,
-                               panel->treeview);
+                               treeview);
+
+    }
 
 }
 
@@ -1013,6 +1189,107 @@ static gboolean show_all_classes_in_tree_view(GtkTreeModel *model, GtkTreePath *
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : store  = gestionnaire de données en arborescence.            *
+*                parent = point d'insertion parent à retrouver. [OUT]         *
+*                raw    = nom du noeud ciblé.                                 *
+*                match  = portion de texte à mettre en évidence.              *
+*                start  = position du texte brute dans l'étiquette complète.  *
+*                                                                             *
+*  Description : Actualise une partie d'un nom de symbole éclaté en noeuds.   *
+*                                                                             *
+*  Retour      : Point de mise à jour prochain.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GtkTreeIter update_symbol_partial_name_in_tree_view(GtkTreeStore *store, GtkTreeIter *parent, const char *raw, const regmatch_t *match, size_t start)
+{
+    GtkTreeModel *model;                    /* Autre vision du gestionnaire*/
+    bool found;                             /* Bilan des recherches        */
+    GtkTreeIter iter;                       /* Boucle de parcours          */
+    gchar *string;                          /* Chaîne sélectionnée         */
+    char *name;                             /* Etiquette mise en relief    */
+
+    model = GTK_TREE_MODEL(store);
+
+    found = false;
+
+    if (gtk_tree_model_iter_children(model, &iter, parent))
+        do
+        {
+            gtk_tree_model_get(model, &iter, SBC_ORIGINAL, &string, -1);
+
+            found = (strcmp(string, raw) == 0);
+            g_free(string);
+
+            if (found) break;
+
+        }
+        while (gtk_tree_model_iter_next(model, &iter));
+
+    assert(found);
+
+    name = build_highlighted_name(raw, match, start);
+
+    gtk_tree_store_set(store, &iter, SBC_NAME, name, -1);
+
+    free(name);
+
+    return iter;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : store  = gestionnaire de données en arborescence.            *
+*                symbol = routine ou objet à intégrer.                        *
+*                match = portion de texte à mettre en évidence.               *
+*                                                                             *
+*  Description : Met en surbrillance les éléments recherchés dans les noms.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void update_symbol_name_in_tree_view(GtkTreeStore *store, const GBinSymbol *symbol, const regmatch_t *match)
+{
+    const char *label;                      /* Etiquette immuable          */
+    char *string;                           /* Etiquette modifiable        */
+    const char *sep;                        /* Délimitateur à utiliser     */
+    GtkTreeIter parent;                     /* Point d'analyse courant     */
+    char *start;                            /* Début de boucle de parcours */
+    char *token;                            /* Partie de texte isolée      */
+    char *saveptr;                          /* Ctx. interne de découpage   */
+
+    label = g_binary_symbol_get_label(symbol);
+
+    if (label != NULL)
+    {
+        string = strdup(label);
+
+        sep = "."/*"::"*/;  /* FIXME */
+
+        for (start = string, token = strtok_r(start, sep, &saveptr);
+             token != NULL;
+             start = NULL, token = strtok_r(NULL, sep, &saveptr))
+        {
+            parent = update_symbol_partial_name_in_tree_view(store, (start == string ? NULL : &parent),
+                                                             token, match, token - string);
+        }
+
+        free(string);
+
+    }
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                           FILTRAGE DES SYMBOLES PRESENTS                           */
@@ -1036,14 +1313,79 @@ static void on_symbols_filter_changed(GtkSearchEntry *entry, GSymbolsPanel *pane
 {
     update_regex_on_search_entry_changed(entry, &panel->filter);
 
-    do_filtering_on_symbols(panel);
+    run_panel_update(G_UPDATABLE_PANEL(panel), PUI_1);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : store = organisation des données sous forme arborescente.    *
+*                iter  = position du noeud courant à traiter.                 *
+*                show  = visibilité à obtenir pour le noeud final.            *
+*                                                                             *
+*  Description : Met à jour l'affichage des noeuds en fonction des besoin.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void update_symbol_visibility(GtkTreeStore *store, GtkTreeIter *iter, bool show)
+{
+    GtkTreeModel *model;                    /* Autre vision du gestionnaire*/
+    guint points;                           /* Compteur de besoins         */
+    GtkTreeIter parent;                     /* Position de noeuf parent    */
+    gboolean further;                       /* Poursuite de remontée       */
+
+    model = GTK_TREE_MODEL(store);
+
+    /* Enumération des besoins */
+
+    gtk_tree_model_get(model, iter, SBC_MATCH_POINTS, &points, -1);
+
+    if (show)
+        points++;
+
+    else
+    {
+        assert(points > 0);
+        points--;
+    }
+
+    gtk_tree_store_set(store, iter, SBC_MATCH_POINTS, points, -1);
+
+    /* Adaptation de l'affichage */
+
+    if (show)
+    {
+        if (points == 1)
+            gtk_tree_store_set(store, iter, SBC_MATCHED, true, -1);
+    }
+
+    else
+    {
+        if (points == 0)
+            gtk_tree_store_set(store, iter, SBC_MATCHED, false, -1);
+    }
+
+    /* Eventuel étage supérieur */
+
+    further = gtk_tree_model_iter_parent(model, &parent, iter);
+
+    if (further)
+        update_symbol_visibility(store, &parent, show);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel = panneau assurant l'affichage des symboles.           *
+*  Paramètres  : panel  = panneau assurant l'affichage des symboles.          *
+*                status = barre de statut à tenir informée.                   *
+*                id     = identifiant pour le suivi de la progression.        *
+*                data   = données complémentaire à manipuler.                 *
 *                                                                             *
 *  Description : Exécute un nouveau filtrage des symboles affichés.           *
 *                                                                             *
@@ -1053,11 +1395,64 @@ static void on_symbols_filter_changed(GtkSearchEntry *entry, GSymbolsPanel *pane
 *                                                                             *
 ******************************************************************************/
 
-static void do_filtering_on_symbols(GSymbolsPanel *panel)
+static void do_filtering_on_symbols(const GSymbolsPanel *panel, GtkStatusStack *status, activity_id_t id, symbols_update_data *data)
 {
-    g_object_ref(G_OBJECT(panel->binary));
-    change_symbols_panel_current_binary(panel, panel->binary);
-    g_object_unref(G_OBJECT(panel->binary));
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeStore *store;                    /* Modèle de gestion           */
+    GtkToggleToolButton *button;            /* Mode de représentation      */
+    gboolean as_list;                       /* Choix dudit mode            */
+
+
+    gboolean filter_symbol_panel_iter(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gboolean *as_list)
+    {
+        GBinSymbol *symbol;                 /* Symbole manipulé            */
+        regmatch_t match;                   /* Récupération des trouvailles*/
+        bool matched;                       /* Correspondance de sélection */
+        gboolean shown;                     /* Visibilité actuelle         */
+
+        gtk_tree_model_get(model, iter, SBC_SYMBOL, &symbol, -1);
+
+        if (symbol != NULL)
+        {
+            matched = is_symbol_matching(panel, symbol, &match);
+
+            gtk_tree_model_get(model, iter, SBC_MATCHED, &shown, -1);
+
+            if (!matched)
+            {
+                if (shown)
+                    update_symbol_visibility(store, iter, false);
+            }
+
+            else
+            {
+                if (*as_list)
+                    update_symbol_name_in_list_view(store, iter, &match);
+                else
+                    update_symbol_name_in_tree_view(store, symbol, &match);
+
+                if (!shown)
+                    update_symbol_visibility(store, iter, true);
+
+            }
+
+            g_object_unref(G_OBJECT(symbol));
+
+        }
+
+        return FALSE;
+
+    }
+
+
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    store = GTK_TREE_STORE(gtk_builder_get_object(builder, "store"));
+    button = GTK_TOGGLE_TOOL_BUTTON(gtk_builder_get_object(builder, "list_display"));
+
+    as_list = gtk_toggle_tool_button_get_active(button);
+
+    gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)filter_symbol_panel_iter, &as_list);
 
 }
 
@@ -1076,29 +1471,258 @@ static void do_filtering_on_symbols(GSymbolsPanel *panel)
 *                                                                             *
 ******************************************************************************/
 
-static bool is_symbol_matching(GSymbolsPanel *panel, const GBinSymbol *symbol, regmatch_t *match)
+static bool is_symbol_matching(const GSymbolsPanel *panel, const GBinSymbol *symbol, regmatch_t *match)
 {
     bool result;                            /* Bilan à retourner           */
-    SymbolStatus status;                    /* Visibilité du symbole obtenu*/
+#ifndef NDEBUG
     SymbolType type;                        /* Type associé au symbole     */
+#endif
 
-    status = g_binary_symbol_get_status(symbol);
+#ifndef NDEBUG
 
-    if (status == SSS_IMPORTED)
-        result = false;
+    type = g_binary_symbol_get_target_type(symbol);
 
-    else
+    assert(type == STP_ROUTINE || type == STP_ENTRY_POINT || type == STP_OBJECT);
+
+#endif
+
+    result = is_content_matching(panel->filter, g_binary_symbol_get_label(symbol), match);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        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_symbols_panel_setup(const GSymbolsPanel *panel, unsigned int uid, size_t *count, symbols_update_data **data)
+{
+    const char *result;                     /* Message à retourner         */
+    GBinFormat *format;                     /* Format du binaire           */
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeView *treeview;                  /* Arborescence graphique      */
+
+    *data = malloc(sizeof(symbols_update_data));
+
+    switch (uid)
     {
-        type = g_binary_symbol_get_target_type(symbol);
+        case PUI_0:
 
-        if (type != STP_ROUTINE && type != STP_ENTRY_POINT && type != STP_OBJECT)
-            result = false;
+            format = G_BIN_FORMAT(g_loaded_binary_get_format(panel->binary));
 
-        else
-            result = is_content_matching(panel->filter, g_binary_symbol_get_label(symbol), match);
+            g_binary_format_lock_symbols_rd(format);
+            *count = g_binary_format_count_symbols(format);
+            g_binary_format_unlock_symbols_rd(format);
+
+            g_object_unref(G_OBJECT(format));
+
+            (*data)->count = 0;
+
+            result = _("Loading symbols registered for the binary format...");
+
+            break;
+
+        case PUI_1:
+
+            *count = panel->count;
+            (*data)->count = panel->count;
+
+            result = _("Filtering symbols registered for the binary format...");
+
+            break;
+
+    }
+
+    /* Mémorisation de tous les noeuds ouverts */
+
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
+    void keep_track_of_expanded(GtkTreeView *tv, GtkTreePath *path, symbols_update_data *sud)
+    {
+        if (sud->ecount == sud->eallocated)
+        {
+            sud->eallocated += EXPAND_ALLOC_RANGE;
+            sud->expanded = (char **)realloc(sud->expanded, sud->eallocated * sizeof(char *));
+        }
+
+        sud->expanded[sud->ecount] = gtk_tree_path_to_string(path);
+
+        sud->ecount++;
 
     }
 
+    (*data)->expanded = NULL;
+    (*data)->ecount = 0;
+    (*data)->eallocated = 0;
+
+    gtk_tree_view_map_expanded_rows(treeview, (GtkTreeViewMappingFunc)keep_track_of_expanded, *data);
+
     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_symbols_panel_introduce(const GSymbolsPanel *panel, unsigned int uid, symbols_update_data *data)
+{
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeView *treeview;                  /* Arborescence graphique      */
+
+    /* Basculement de l'affichage hors ligne */
+
+    g_panel_item_switch_to_updating_mask(G_PANEL_ITEM(panel));
+
+    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));
+
+    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_symbols_panel_process(const GSymbolsPanel *panel, unsigned int uid, GtkStatusStack *status, activity_id_t id, symbols_update_data *data)
+{
+    switch (uid)
+    {
+        case PUI_0:
+            reload_symbols_panel_content(panel, status, id, data);
+            break;
+
+        case PUI_1:
+            do_filtering_on_symbols(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_symbols_panel_conclude(GSymbolsPanel *panel, unsigned int uid, symbols_update_data *data)
+{
+    GtkBuilder *builder;                    /* Constructeur utilisé        */
+    GtkTreeView *treeview;                  /* Arborescence graphique      */
+    size_t i;                               /* Boucle de parcours          */
+    GtkTreePath *path;                      /* Chemin d'accès à un noeud   */
+
+    /* Mise à jour des compteurs */
+
+    panel->count = data->count;
+
+    /* Basculement de l'affichage en ligne */
+
+    builder = G_PANEL_ITEM(panel)->builder;
+
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
+    gtk_tree_view_set_model(treeview, data->model);
+
+    g_object_unref(G_OBJECT(data->model));
+
+    for (i = 0; i < data->ecount; i++)
+    {
+        path = gtk_tree_path_new_from_string(data->expanded[i]);
+
+        gtk_tree_view_expand_to_path(treeview, path);
+
+        gtk_tree_path_free(path);
+
+    }
+
+    g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                data  = données en place à nettoyer avant suppression.       *
+*                                                                             *
+*  Description : Supprime les données dynamiques utilisées à la mise à jour.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_symbols_panel_clean_data(GUpdatablePanel *panel, unsigned int uid, symbols_update_data *data)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < data->ecount; i++)
+        g_free(data->expanded[i]);
+
+    if (data->expanded != NULL)
+        free(data->expanded);
+
+}
diff --git a/src/gui/panels/symbols.ui b/src/gui/panels/symbols.ui
new file mode 100644
index 0000000..284e00a
--- /dev/null
+++ b/src/gui/panels/symbols.ui
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.21.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkTreeStore" id="store">
+    <columns>
+      <!-- column-name symbol -->
+      <column type="GObject"/>
+      <!-- column-name icon -->
+      <column type="CairoSurface"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name original -->
+      <column type="gchararray"/>
+      <!-- column-name address -->
+      <column type="gchararray"/>
+      <!-- column-name section -->
+      <column type="gchararray"/>
+      <!-- column-name expand -->
+      <column type="gboolean"/>
+      <!-- column-name matched -->
+      <column type="gboolean"/>
+      <!-- column-name match_points -->
+      <column type="guint"/>
+    </columns>
+  </object>
+  <object class="GtkTreeModelSort" id="sorter">
+    <property name="model">store</property>
+  </object>
+  <object class="GtkTreeModelFilter" id="filter">
+    <property name="child_model">sorter</property>
+  </object>
+  <object class="GtkImage" id="symbol_class_classic.png">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="resource">/org/chrysalide/gui/panels/../../../pixmaps/symbol_class_classic.png</property>
+  </object>
+  <object class="GtkImage" id="tbutton_collapse.png">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="resource">/org/chrysalide/gui/panels/../../../pixmaps/tbutton_collapse.png</property>
+  </object>
+  <object class="GtkImage" id="tbutton_expand.png">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="resource">/org/chrysalide/gui/panels/../../../pixmaps/tbutton_expand.png</property>
+  </object>
+  <object class="GtkImage" id="tbutton_list_view.png">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="resource">/org/chrysalide/gui/panels/../../../pixmaps/tbutton_list_view.png</property>
+  </object>
+  <object class="GtkImage" id="tbutton_tree_view.png">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="resource">/org/chrysalide/gui/panels/../../../pixmaps/tbutton_tree_view.png</property>
+  </object>
+  <object class="GtkOffscreenWindow">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkBox" id="box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkToolbar">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkRadioToolButton" id="list_display">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="tooltip_text" translatable="yes">Show symbols using a list view</property>
+                <property name="use_underline">True</property>
+                <property name="icon_widget">tbutton_list_view.png</property>
+                <property name="active">True</property>
+                <property name="group">tree_display</property>
+                <signal name="toggled" handler="on_symbols_list_display_toggle" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkRadioToolButton" id="tree_display">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="tooltip_text" translatable="yes">Show symbols using a tree view</property>
+                <property name="use_underline">True</property>
+                <property name="icon_widget">tbutton_tree_view.png</property>
+                <signal name="toggled" handler="on_symbols_tree_display_toggle" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSeparatorToolItem">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolButton" id="collapse">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="tooltip_text" translatable="yes">Collapse all symbol nodes in the tree view</property>
+                <property name="use_underline">True</property>
+                <property name="icon_widget">tbutton_collapse.png</property>
+                <signal name="clicked" handler="reorganize_symbols_tree_view" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolButton" id="expand">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="tooltip_text" translatable="yes">Expand all symbol nodes in the tree view</property>
+                <property name="use_underline">True</property>
+                <property name="icon_widget">tbutton_expand.png</property>
+                <signal name="clicked" handler="reorganize_symbols_tree_view" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolButton" id="classes">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="tooltip_text" translatable="yes">Show all classes in the tree view</property>
+                <property name="use_underline">True</property>
+                <property name="icon_widget">symbol_class_classic.png</property>
+                <signal name="clicked" handler="reorganize_symbols_tree_view" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSeparatorToolItem">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolItem">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkSearchEntry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="tooltip_text" translatable="yes">Filter symbols using POSIX extended regular expressions</property>
+                    <property name="primary_icon_name">edit-find-symbolic</property>
+                    <property name="primary_icon_activatable">False</property>
+                    <property name="primary_icon_sensitive">False</property>
+                    <signal name="search-changed" handler="on_symbols_filter_changed" swapped="no"/>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkStack" id="stack">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkScrolledWindow" id="content">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkTreeView" id="treeview">
+                    <property name="name">treeview</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="model">filter</property>
+                    <property name="headers_visible">False</property>
+                    <property name="search_column">2</property>
+                    <child internal-child="selection">
+                      <object class="GtkTreeSelection">
+                        <signal name="changed" handler="on_symbols_selection_change" swapped="no"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="name">page0</property>
+                <property name="title" translatable="yes">page0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSpinner" id="mask">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="active">True</property>
+              </object>
+              <packing>
+                <property name="name">page1</property>
+                <property name="title" translatable="yes">page1</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child type="titlebar">
+      <placeholder/>
+    </child>
+  </object>
+</interface>
diff --git a/src/gui/panels/updating-int.h b/src/gui/panels/updating-int.h
index eea8e3b..0007a5a 100644
--- a/src/gui/panels/updating-int.h
+++ b/src/gui/panels/updating-int.h
@@ -41,6 +41,9 @@ typedef void (* process_updatable_cb) (const GUpdatablePanel *, unsigned int, Gt
 /* Bascule l'affichage d'un panneau après mise à jour. */
 typedef void (* conclude_updatable_cb) (GUpdatablePanel *, unsigned int, void *);
 
+/* Supprime les données dynamiques utilisées à la mise à jour. */
+typedef void (* clean_updatable_data_cb) (GUpdatablePanel *, unsigned int, void *);
+
 
 /* Mécanisme de mise à jour d'un panneau (interface) */
 struct _GUpdatablePanelIface
@@ -53,6 +56,7 @@ struct _GUpdatablePanelIface
     introduce_updatable_cb introduce;       /* Changement d'affichage #0   */
     process_updatable_cb process;           /* Mise à jour d'affichage     */
     conclude_updatable_cb conclude;         /* Changement d'affichage #1   */
+    clean_updatable_data_cb clean;          /* Nettoyage des données       */
 
 };
 
diff --git a/src/gui/panels/updating.c b/src/gui/panels/updating.c
index 15955dc..2dec844 100644
--- a/src/gui/panels/updating.c
+++ b/src/gui/panels/updating.c
@@ -219,6 +219,32 @@ void g_updatable_panel_conclude(GUpdatablePanel *panel, unsigned int uid, void *
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau ciblé par une mise à jour.                   *
+*                uid   = identifiant de la phase de traitement.               *
+*                data  = données en place à nettoyer avant suppression.       *
+*                                                                             *
+*  Description : Supprime les données dynamiques utilisées à la mise à jour.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_updatable_panel_clean_data(GUpdatablePanel *panel, unsigned int uid, void *data)
+{
+    GUpdatablePanelIface *iface;            /* Interface utilisée          */
+
+    iface = G_UPDATABLE_PANEL_GET_IFACE(panel);
+
+    if (iface->clean != NULL && data != NULL)
+        iface->clean(panel, uid, data);
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                              AIDE POUR LA MISE A JOUR                              */
@@ -311,6 +337,8 @@ static void g_panel_update_dispose(GPanelUpdate *update)
 
 static void g_panel_update_finalize(GPanelUpdate *update)
 {
+    g_updatable_panel_clean_data(update->panel, update->uid, update->data);
+
     if (update->data != NULL)
         free(update->data);
 
diff --git a/src/gui/panels/updating.h b/src/gui/panels/updating.h
index 4edf498..b02f1af 100644
--- a/src/gui/panels/updating.h
+++ b/src/gui/panels/updating.h
@@ -67,6 +67,9 @@ void g_updatable_panel_process(const GUpdatablePanel *, unsigned int, GtkStatusS
 /* Bascule l'affichage d'un panneau après mise à jour. */
 void g_updatable_panel_conclude(GUpdatablePanel *, unsigned int, void *);
 
+/* Supprime les données dynamiques utilisées à la mise à jour. */
+void g_updatable_panel_clean_data(GUpdatablePanel *, unsigned int, void *);
+
 
 
 /* ---------------------------- AIDE POUR LA MISE A JOUR ---------------------------- */
-- 
cgit v0.11.2-87-g4458