From 50a657889a32a6df365bf9880a6f56bf3a0e828c Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 13 Aug 2015 00:35:42 +0000
Subject: Improved the look of dock stations and saved screen space.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@571 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                    |  23 +++
 src/gtkext/Makefile.am       |   2 +
 src/gtkext/easygtk.c         | 186 ++++++++++++++++++---
 src/gtkext/easygtk.h         |   8 +-
 src/gtkext/gtkdockable-int.h |  69 ++++++++
 src/gtkext/gtkdockable.c     | 381 +++++++++++++++++++++++++++++++++++++++++++
 src/gtkext/gtkdockable.h     |  72 ++++++++
 src/gtkext/gtkdockstation.c  | 157 +++++++++++++-----
 src/gtkext/gtkdockstation.h  |   9 +-
 src/gui/panels/bookmarks.c   | 163 +++++++++---------
 src/gui/panels/panel.c       | 108 +++++++++++-
 src/gui/panels/strings.c     | 137 +++++++---------
 12 files changed, 1060 insertions(+), 255 deletions(-)
 create mode 100644 src/gtkext/gtkdockable-int.h
 create mode 100644 src/gtkext/gtkdockable.c
 create mode 100644 src/gtkext/gtkdockable.h

diff --git a/ChangeLog b/ChangeLog
index dac9be0..917cfba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+15-08-13  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/gtkext/easygtk.c:
+	* src/gtkext/easygtk.h:
+	Build toggle buttons with images, too.
+
+	* src/gtkext/gtkdockable.c:
+	* src/gtkext/gtkdockable.h:
+	* src/gtkext/gtkdockable-int.h:
+	New entries: define a GObject interface for dockable widgets.
+
+	* src/gtkext/gtkdockstation.c:
+	* src/gtkext/gtkdockstation.h:
+	Improve the look of dock stations and save screen space.
+
+	* src/gtkext/Makefile.am:
+	Add the 'gtkdockable*[ch]' files from libgtkext_la_SOURCES.
+
+	* src/gui/panels/bookmarks.c:
+	* src/gui/panels/panel.c:
+	* src/gui/panels/strings.c:
+	Implement the new interface and update the code.
+
 15-08-12  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/pychrysa/arch/instruction.c:
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 6d713d9..6849585 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -8,6 +8,8 @@ libgtkext_la_SOURCES =					\
 	gtkblockview.h gtkblockview.c		\
 	gtkbufferview-int.h					\
 	gtkbufferview.h gtkbufferview.c		\
+	gtkdockable-int.h					\
+	gtkdockable.h gtkdockable.c			\
 	gtkdockstation.h gtkdockstation.c	\
 	gtkgraphview.h gtkgraphview.c		\
 	gtksourceview.h gtksourceview.c		\
diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c
index fcbaa19..61e8953 100644
--- a/src/gtkext/easygtk.c
+++ b/src/gtkext/easygtk.c
@@ -28,6 +28,10 @@
 
 
 
+/* Termine la construction d'un composant 'GtkButton'. */
+static void _finish_button_with_img(GtkWidget *, GObject *, const char *, GtkWidget *, const char *);
+
+
 
 /******************************************************************************
 *                                                                             *
@@ -399,6 +403,113 @@ GtkWidget *qck_create_button_with_img(GObject *object, const char *name, const c
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : button  = composant graphique dont la définition est à finir.*
+*                object  = espace dédié à l'inscription de références.        *
+*                name    = nom à donner au nouveau composant.                 *
+*                picture = éventuelle image sous forme de composant GTK.      *
+*                label   = contenu de l'étiquette éventuelle associée.        *
+*                                                                             *
+*  Description : Termine la construction d'un composant 'GtkButton'.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void _finish_button_with_img(GtkWidget *button, GObject *object, const char *name, GtkWidget *picture, const char *label)
+{
+    GtkWidget *caption;                     /* Etiquette à coller          */
+    GtkWidget *hbox;                        /* Séparation horizontale      */
+
+    /* Création des éléments internes (2/2) */
+
+    if (label != NULL)
+    {
+        caption = gtk_label_new_with_mnemonic(label);
+        gtk_widget_show(caption);
+    }
+
+    /* Mise en place */
+
+    if (picture != NULL && label != NULL)
+    {
+        hbox = gtk_hbox_new(FALSE, 2);
+        gtk_widget_show(hbox);
+        gtk_container_add(GTK_CONTAINER(button), hbox);
+
+        gtk_box_pack_start(GTK_BOX(hbox), picture, FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox), caption, FALSE, FALSE, 0);
+
+    }
+
+    else if (picture != NULL)
+        gtk_container_add(GTK_CONTAINER(button), picture);
+
+    else /*if (label != NULL)*/
+        gtk_container_add(GTK_CONTAINER(button), caption);
+
+    /* Interactions GTK... */
+
+    if (G_IS_OBJECT(object) && name != NULL)
+    {
+        g_object_ref(G_OBJECT(button));
+        g_object_set_data_full(object, name, button, (GDestroyNotify)g_object_unref);
+    }
+
+    gtk_widget_show(button);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : object  = espace dédié à l'inscription de références.        *
+*                name    = nom à donner au nouveau composant.                 *
+*                image   = nom de l'image stockée dans GTK.                   *
+*                size    = taille de l'image éventuelle à faire figurer.      *
+*                label   = contenu de l'étiquette éventuelle associée.        *
+*                handler = éventuelle fonction de sélection associée.         *
+*                data    = données à transmettre avec l'événement si besoin.  *
+*                                                                             *
+*  Description : Crée et enregistre un composant 'GtkButton'.                 *
+*                                                                             *
+*  Retour      : Simple bouton mis en place.                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *qck_create_button_with_named_img(GObject *object, const char *name, const char *image, GtkIconSize size, const char *label, GCallback handler, gpointer data)
+{
+    GtkWidget *result;                      /* Résultat à renvoyer         */
+    GtkWidget *picture;                     /* Image de représentation     */
+
+    result = gtk_button_new();
+    gtk_widget_set_can_default(result, TRUE);
+
+    /* Création des éléments internes (1/2) */
+
+    if (image != NULL)
+    {
+        picture = gtk_image_new_from_icon_name(image, size);
+        gtk_widget_show(picture);
+    }
+    else
+        picture = NULL;
+
+    _finish_button_with_img(result, object, name, picture, label);
+
+    if (handler != NULL)
+        g_signal_connect(result, "clicked", handler, data);
+
+	return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : object  = espace dédié à l'inscription de références.        *
 *                name    = nom à donner au nouveau composant.                 *
 *                image   = nom de l'image stockée dans GTK.                   *
@@ -418,13 +529,11 @@ GtkWidget *qck_create_button_with_css_img(GObject *object, const char *name, con
 {
     GtkWidget *result;                      /* Résultat à renvoyer         */
     GtkWidget *picture;                     /* Image de représentation     */
-    GtkWidget *caption;                     /* Etiquette à coller          */
-    GtkWidget *hbox;                        /* Séparation horizontale      */
 
     result = gtk_button_new();
     gtk_widget_set_can_default(result, TRUE);
 
-    /* Création des éléments internes */
+    /* Création des éléments internes (1/2) */
 
     if (image != NULL)
     {
@@ -434,44 +543,59 @@ GtkWidget *qck_create_button_with_css_img(GObject *object, const char *name, con
         gtk_widget_set_name(picture, image);
 
     }
+    else
+        picture = NULL;
 
-    if (label != NULL)
-    {
-        caption = gtk_label_new_with_mnemonic(label);
-        gtk_widget_show(caption);
-    }
+    _finish_button_with_img(result, object, name, picture, label);
 
-    /* Mise en place */
+    if (handler != NULL)
+        g_signal_connect(result, "clicked", handler, data);
 
-    if (image != NULL && label != NULL)
-    {
-        hbox = gtk_hbox_new(FALSE, 2);
-        gtk_widget_show(hbox);
-        gtk_container_add(GTK_CONTAINER(result), hbox);
+	return result;
 
-        gtk_box_pack_start(GTK_BOX(hbox), picture, FALSE, FALSE, 0);
-        gtk_box_pack_start(GTK_BOX(hbox), caption, FALSE, FALSE, 0);
+}
 
-    }
 
-    else if (image != NULL)
-        gtk_container_add(GTK_CONTAINER(result), picture);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : object  = espace dédié à l'inscription de références.        *
+*                name    = nom à donner au nouveau composant.                 *
+*                image   = nom de l'image stockée dans GTK.                   *
+*                size    = taille de l'image éventuelle à faire figurer.      *
+*                label   = contenu de l'étiquette éventuelle associée.        *
+*                handler = éventuelle fonction de sélection associée.         *
+*                data    = données à transmettre avec l'événement si besoin.  *
+*                                                                             *
+*  Description : Crée et enregistre un composant 'GtkCheckButton'.            *
+*                                                                             *
+*  Retour      : Simple bouton mis en place.                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *qck_create_toggle_button_with_named_img(GObject *object, const char *name, const char *image, GtkIconSize size, const char *label, GCallback handler, gpointer data)
+{
+    GtkWidget *result;                      /* Résultat à renvoyer         */
+    GtkWidget *picture;                     /* Image de représentation     */
 
-    else /*if (label != NULL)*/
-        gtk_container_add(GTK_CONTAINER(result), caption);
+    result = gtk_toggle_button_new();
+    gtk_widget_set_can_default(result, TRUE);
 
-    /* Interactions GTK... */
+    /* Création des éléments internes (1/2) */
 
-    if (G_IS_OBJECT(object) && name != NULL)
+    if (image != NULL)
     {
-        g_object_ref(G_OBJECT(result));
-        g_object_set_data_full(object, name, result, (GDestroyNotify)g_object_unref);
+        picture = gtk_image_new_from_icon_name(image, size);
+        gtk_widget_show(picture);
     }
+    else
+        picture = NULL;
 
-    gtk_widget_show(result);
+    _finish_button_with_img(result, object, name, picture, label);
 
     if (handler != NULL)
-        g_signal_connect(result, "clicked", handler, data);
+        g_signal_connect(result, "toggled", handler, data);
 
 	return result;
 
@@ -802,6 +926,14 @@ void add_accelerator_to_menu_item(GtkWidget *item, const char *accelerator, GtkA
 
     gtk_accelerator_parse(accelerator, &key, &mods);
 
+
+    gboolean force_accel_activation(GtkWidget *widget, guint signal_id, gpointer data)
+    {
+        return TRUE;
+    }
+
+    g_signal_connect(item, "can-activate-accel", force_accel_activation, NULL);
+
     gtk_widget_add_accelerator(item, "activate", group,
                                key, mods, GTK_ACCEL_VISIBLE);
 
diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h
index 58229af..13cb7fd 100644
--- a/src/gtkext/easygtk.h
+++ b/src/gtkext/easygtk.h
@@ -60,12 +60,18 @@ GtkWidget *qck_create_textview(GObject *, const char *, GCallback, gpointer);
 GtkWidget *qck_create_button(GObject *, const char *, const char *, GCallback, gpointer);
 
 /* Crée et enregistre un composant 'GtkButton'. */
-GtkWidget *qck_create_button_with_img(GObject *, const char *, const char *, GCallback, gpointer);
+GtkWidget *qck_create_button_with_img(GObject *, const char *, const char *, GCallback, gpointer)   __attribute__ ((deprecated));
+
+/* Crée et enregistre un composant 'GtkButton'. */
+GtkWidget *qck_create_button_with_named_img(GObject *, const char *, const char *, GtkIconSize, const char *, GCallback, gpointer);
 
 /* Crée et enregistre un composant 'GtkButton'. */
 GtkWidget *qck_create_button_with_css_img(GObject *, const char *, const char *, const char *, GCallback, gpointer);
 
 /* Crée et enregistre un composant 'GtkCheckButton'. */
+GtkWidget *qck_create_toggle_button_with_named_img(GObject *, const char *, const char *, GtkIconSize, const char *, GCallback, gpointer);
+
+/* Crée et enregistre un composant 'GtkCheckButton'. */
 GtkWidget *qck_create_check_button(GObject *, const char *, const char *, GCallback, gpointer);
 
 /* Crée et enregistre un composant 'GtkRadioButton'. */
diff --git a/src/gtkext/gtkdockable-int.h b/src/gtkext/gtkdockable-int.h
new file mode 100644
index 0000000..95e1d0c
--- /dev/null
+++ b/src/gtkext/gtkdockable-int.h
@@ -0,0 +1,69 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkdockable-int.h - définitions internes propres aux éléments acceptés dans les composants de rassemblement
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA 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.
+ *
+ *  OpenIDA 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 _GTK_DOCKABLE_INT_H
+#define _GTK_DOCKABLE_INT_H
+
+
+#include "gtkdockable.h"
+
+
+#include <regex.h>
+
+
+
+/* Fournit le nom court du composant encapsulable. */
+typedef const char * (* get_dockable_name_fc) (const GtkDockable *);
+
+/* Fournit le nom court du composant encapsulable. */
+typedef const char * (* get_dockable_desc_fc) (const GtkDockable *);
+
+/* Fournit le composant principal à encapsuler au besoin. */
+typedef GtkWidget * (* get_dockable_widget_fc) (const GtkDockable *);
+
+/* Démarre l'actualisation du filtrage des paramètres. */
+typedef void (* update_filtered_data_fc) (GtkDockable *, const regex_t *);
+
+
+/* Elément accepté dans les rassemblements (interface) */
+struct _GtkDockableIface
+{
+    GTypeInterface base_iface;              /* A laisser en premier        */
+
+    bool can_search;                        /* Contenu fouillable ?        */
+    bool can_be_closed;                     /* Fermeture possible ?        */
+
+    get_dockable_name_fc get_name;          /* Nom pour titre              */
+    get_dockable_desc_fc get_desc;          /* Description humaine         */
+    get_dockable_widget_fc get_widget;      /* Composant à représenter     */
+    update_filtered_data_fc update_filtered;/* Mise à jour du filtrage     */
+
+};
+
+
+/* Redéfinition */
+typedef GtkDockableIface GtkDockableInterface;
+
+
+
+#endif  /* _GTK_DOCKABLE_INT_H */
diff --git a/src/gtkext/gtkdockable.c b/src/gtkext/gtkdockable.c
new file mode 100644
index 0000000..8819108
--- /dev/null
+++ b/src/gtkext/gtkdockable.c
@@ -0,0 +1,381 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkdockable.c - éléments acceptés dans les composants de rassemblement
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA 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.
+ *
+ *  OpenIDA 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 "gtkdockable.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+#include <i18n.h>
+
+
+#include "easygtk.h"
+#include "gtkdockable-int.h"
+
+
+
+/* --------------------- DEFINITIONS PRINCIPALES DE L'INTERFACE --------------------- */
+
+
+/* Procède à l'initialisation de l'interface de rassemblement. */
+static void gtk_dockable_default_init(GtkDockableInterface *);
+
+
+
+/* ------------------------ FONCTIONS DE RECHERCHE INTEGREES ------------------------ */
+
+
+/* Construit une zone de recherches vouée à être intégrée. */
+static GtkWidget *build_search_area(GtkDockable *, GtkWidget **);
+
+/* Met à jour l'expression de filtrage de la zone intégrée. */
+static void on_dockable_search_changed(GtkSearchEntry *, GtkDockable *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       DEFINITIONS PRINCIPALES DE L'INTERFACE                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type d'une interface pour rassemblement. */
+G_DEFINE_INTERFACE(GtkDockable, gtk_dockable, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GTK à initialiser.                         *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de rassemblement.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_dockable_default_init(GtkDockableInterface *iface)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Fournit le nom court du composant encapsulable.              *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *gtk_dockable_get_name(const GtkDockable *dockable)
+{
+    GtkDockableIface *iface;                /* Interface utilisée          */
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    return iface->get_name(dockable);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Fournit le nom long du composant encapsulable.               *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *gtk_dockable_get_desc(const GtkDockable *dockable)
+{
+    GtkDockableIface *iface;                /* Interface utilisée          */
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    return iface->get_desc(dockable);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Indique si le composant représenté à du contenu à fouiller.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool gtk_dockable_can_search(const GtkDockable *dockable)
+{
+    GtkDockableIface *iface;                /* Interface utilisée          */
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    return iface->can_search;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Indique si le composant peut être désencapsulé manuellement. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool gtk_dockable_can_be_closed(const GtkDockable *dockable)
+{
+    GtkDockableIface *iface;                /* Interface utilisée          */
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    return iface->can_be_closed;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                                                                             *
+*  Description : Fournit le composant graphique intégrable dans un ensemble.  *
+*                                                                             *
+*  Retour      : Composant graphique prêt à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable)
+{
+    GtkWidget *result;                      /* Composant à retourner       */
+    GtkDockableIface *iface;                /* Interface utilisée          */
+    GtkWidget *widget;                      /* Composant graphique interne */
+    GtkWidget *revealer;                    /* Révélateur à intégrer ?     */
+    GtkWidget *search;                      /* Zone de recherche           */
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    widget = iface->get_widget(dockable);
+    g_object_ref(G_OBJECT(widget));
+
+    /* Encapsulation avec un panneau coulissant ? */
+
+    if (iface->can_search)
+    {
+        revealer = gtk_revealer_new();
+        gtk_widget_show(revealer);
+
+        gtk_container_add(GTK_CONTAINER(revealer), build_search_area(dockable, &search));
+
+        result = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+        gtk_widget_show(result);
+
+        gtk_box_pack_start(GTK_BOX(result), revealer, FALSE, TRUE, 0);
+        gtk_box_pack_start(GTK_BOX(result), widget, TRUE, TRUE, 0);
+
+        g_object_set_data(G_OBJECT(result), "revealer", revealer);
+        g_object_set_data(G_OBJECT(result), "search", search);
+
+    }
+
+    /* Ou bien non ! */
+    else
+        result = widget;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                built    = composant graphique d'encapsulation mis en place. *
+*                reveal   = détermine l'action à mener.                       *
+*                                                                             *
+*  Description : Révèle ou cache la zone de recherches.                       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_dockable_toggle_revealer(GtkDockable *dockable, GtkWidget *built, gboolean reveal)
+{
+    GtkRevealer *revealer;                  /* Révélateur à actionner      */
+    GtkWidget *entry;                       /* Zone de recherche à activer */
+
+    revealer = GTK_REVEALER(g_object_get_data(G_OBJECT(built), "revealer"));
+    assert(revealer != NULL);
+
+    gtk_revealer_set_reveal_child(revealer, reveal);
+
+    if (reveal)
+    {
+        entry = GTK_WIDGET(g_object_get_data(G_OBJECT(built), "search"));
+        gtk_widget_grab_focus(entry);
+    }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          FONCTIONS DE RECHERCHE INTEGREES                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : dockable = élément encapsulable à avertir des changements.   *
+*                search   = zone de saisie pour lancer les recherches.        *
+*                                                                             *
+*  Description : Construit une zone de recherches vouée à être intégrée.      *
+*                                                                             *
+*  Retour      : Composant GTK prêt à être intégré.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GtkWidget *build_search_area(GtkDockable *dockable, GtkWidget **search)
+{
+    GtkWidget *result;                      /* Support à retourner         */
+    GtkWidget *label;                       /* Etiquette à utiliser        */
+
+    result = gtk_grid_new();
+    gtk_grid_set_row_spacing(GTK_GRID(result), 8);
+    gtk_widget_show(result);
+
+    label = qck_create_label(NULL, NULL, _("Look for:"));
+    g_object_set(label, "margin", 8, NULL);
+    gtk_grid_attach(GTK_GRID(result), label, 0, 0, 1, 1);
+
+    *search = gtk_search_entry_new();
+    g_signal_connect(*search, "search-changed", G_CALLBACK(on_dockable_search_changed), dockable);
+    gtk_widget_set_hexpand(*search, TRUE);
+    gtk_widget_show(*search);
+    gtk_grid_attach_next_to(GTK_GRID(result), *search, label, GTK_POS_RIGHT, 1, 1);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : entry    = entrée de texte contenant le filtre brut.         *
+*  Paramètres  : dockable = élément encapsulable à avertir des changements.   *
+*                                                                             *
+*  Description : Met à jour l'expression de filtrage de la zone intégrée.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void on_dockable_search_changed(GtkSearchEntry *entry, GtkDockable *dockable)
+{
+    regex_t *filter;                        /* Expression régulière        */
+    const gchar *text;                      /* Texte de l'utilisateur      */
+    int ret;                                /* Bilan de mise en place      */
+    GdkRGBA error;                          /* Couleur d'erreur            */
+    GtkDockableIface *iface;                /* Interface utilisée          */
+
+    filter = g_object_get_data(G_OBJECT(entry), "preg_filter");
+
+    text = gtk_entry_get_text(GTK_ENTRY(entry));
+
+    /* Mise en place d'une nouvelle règle */
+    if (strlen(text) > 0)
+    {
+        if (filter == NULL)
+        {
+            void destroy_filter(regex_t *preg)
+            {
+                regfree(preg);
+                free(preg);
+            }
+
+            filter = (regex_t *)calloc(1, sizeof(regex_t));
+            g_object_set_data_full(G_OBJECT(entry), "preg_filter", filter, (GDestroyNotify)destroy_filter);
+
+        }
+        else
+            regfree(filter);
+
+        ret = regcomp(filter, text, REG_EXTENDED);
+
+        if (ret != 0)
+        {
+            error.red = 1.0;
+            error.green = 0.0;
+            error.blue = 0.0;
+            error.alpha = 1.0;
+            gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error);
+
+            return;
+
+        }
+
+    }
+
+    /* Suppresion de toute règle existante */
+    else if (filter != NULL)
+    {
+        g_object_set_data(G_OBJECT(entry), "preg_filter", NULL);
+        filter = NULL;
+    }
+
+    /* Mises à jour */
+
+    gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL);
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    iface->update_filtered(dockable, filter);
+
+}
diff --git a/src/gtkext/gtkdockable.h b/src/gtkext/gtkdockable.h
new file mode 100644
index 0000000..91a6bda
--- /dev/null
+++ b/src/gtkext/gtkdockable.h
@@ -0,0 +1,72 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * gtkdockable.h - prototypes pour les éléments acceptés dans les composants de rassemblement
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA 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.
+ *
+ *  OpenIDA 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 _GTKEXT_GTKDOCKABLE_H
+#define _GTKEXT_GTKDOCKABLE_H
+
+
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+
+
+#define GTK_TYPE_DOCKABLE             (gtk_dockable_get_type())
+#define GTK_DOCKABLE(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_DOCKABLE, GtkDockable))
+#define GTK_DOCKABLE_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), GTK_TYPE_DOCKABLE, GtkDockableIface))
+#define GTK_IS_DOCKABLE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_DOCKABLE))
+#define GTK_IS_DOCKABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), GTK_TYPE_DOCKABLE))
+#define GTK_DOCKABLE_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst), GTK_TYPE_DOCKABLE, GtkDockableIface))
+
+
+/* Elément accepté dans les rassemblements (coquille vide) */
+typedef struct _GtkDockable GtkDockable;
+
+/* Elément accepté dans les rassemblements (interface) */
+typedef struct _GtkDockableIface GtkDockableIface;
+
+
+
+/* Détermine le type d'une interface pour rassemblement. */
+GType gtk_dockable_get_type(void) G_GNUC_CONST;
+
+/* Indique si le composant représenté à du contenu à fouiller. */
+bool gtk_dockable_can_search(const GtkDockable *);
+
+/* Indique si le composant peut être désencapsulé manuellement. */
+bool gtk_dockable_can_be_closed(const GtkDockable *);
+
+/* Fournit le nom court du composant encapsulable. */
+const char *gtk_dockable_get_name(const GtkDockable *);
+
+/* Fournit le nom long du composant encapsulable. */
+const char *gtk_dockable_get_desc(const GtkDockable *);
+
+/* Fournit le composant graphique intégrable dans un ensemble. */
+GtkWidget *gtk_dockable_get_widget(GtkDockable *);
+
+/* Révèle ou cache la zone de recherches. */
+void gtk_dockable_toggle_revealer(GtkDockable *, GtkWidget *, gboolean);
+
+
+
+#endif  /* _GTKEXT_GTKDOCKABLE_H */
diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c
index 2737557..e10e55f 100644
--- a/src/gtkext/gtkdockstation.c
+++ b/src/gtkext/gtkdockstation.c
@@ -42,7 +42,17 @@ static void gtk_dock_station_class_init(GtkDockStationClass *);
 static void gtk_dock_station_init(GtkDockStation *);
 
 /* Met à jour le titre du support de panneaux concentrés. */
-static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, gpointer);
+static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, GtkDockStation *);
+
+
+
+
+/* Révèle ou cache la zone de recherches. */
+static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *);
+
+
+
+
 
 
 
@@ -114,7 +124,7 @@ static void gtk_dock_station_init(GtkDockStation *station)
 
     eventbox = gtk_event_box_new();
     gtk_widget_show(eventbox);
-    gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0);
+    //gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0);
 
     hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
     gtk_widget_show(hbox);
@@ -144,13 +154,42 @@ static void gtk_dock_station_init(GtkDockStation *station)
     gtk_container_add(GTK_CONTAINER(button), image);
     gtk_widget_set_size_request(image, 10, 10);
 
+
+
+
     station->notebook = GTK_NOTEBOOK(gtk_notebook_new());
     gtk_widget_show(GTK_WIDGET(station->notebook));
     gtk_box_pack_start(GTK_BOX(station), GTK_WIDGET(station->notebook), TRUE, TRUE, 0);
     gtk_notebook_set_show_border(station->notebook, FALSE);
-    gtk_notebook_set_tab_pos(station->notebook, GTK_POS_BOTTOM);
     gtk_notebook_set_scrollable(station->notebook, TRUE);
 
+    /* Définition de la zone de contrôle */
+
+    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+    gtk_widget_set_valign(hbox, GTK_ALIGN_CENTER);
+    gtk_widget_set_margin_end(hbox, 8);
+    gtk_widget_show(hbox);
+
+    button = qck_create_toggle_button_with_named_img(G_OBJECT(station), "search",
+                                                     "edit-find-symbolic", GTK_ICON_SIZE_MENU, NULL,
+                                                     G_CALLBACK(on_toggle_revealer), station);
+    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+    button = qck_create_button_with_named_img(G_OBJECT(station), "menu",
+                                              "go-down-symbolic", GTK_ICON_SIZE_MENU, NULL,
+                                              G_CALLBACK(NULL), station);
+    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+    button = qck_create_button_with_named_img(G_OBJECT(station), "close",
+                                              "window-close-symbolic", GTK_ICON_SIZE_MENU, NULL,
+                                              G_CALLBACK(NULL), station);
+    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+
+    gtk_notebook_set_action_widget(station->notebook, hbox, GTK_PACK_END);
+
     g_signal_connect(station->notebook, "switch-page",
                      G_CALLBACK(gtk_dock_station_switch_panel), station);
 
@@ -181,7 +220,7 @@ GtkWidget *gtk_dock_station_new(void)
 *  Paramètres  : notebook = support à l'origine de la mise à jour.            *
 *                page     = onglet mis en avant.                              *
 *                index    = indice de l'onglet actuellement actif.            *
-*                data     = adresse du conteneur supérieur.                   *
+*                station  = conteneur de gestion supérieur.                   *
 *                                                                             *
 *  Description : Met à jour le titre du support de panneaux concentrés.       *
 *                                                                             *
@@ -191,17 +230,35 @@ GtkWidget *gtk_dock_station_new(void)
 *                                                                             *
 ******************************************************************************/
 
-static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, gpointer data)
+static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, GtkDockStation *station)
 {
     GtkWidget *widget;                      /* Panneau concerné            */
-    char *str;                              /* Texte à redonner            */
+    GtkDockable *dockable;                  /* Elément encapsulé           */
+    GtkWidget *button;                      /* Bouton de contrôle          */
 
     widget = gtk_notebook_get_nth_page(notebook, index);
-    str = g_object_get_data(G_OBJECT(widget), "title");
 
-    gtk_dock_panel_update_title(GTK_DOCK_STATION(data), widget, str);
+    dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable"));
+
+    /* Mise à jour des boutons utilisables */
 
-    g_signal_emit_by_name(GTK_DOCK_STATION(data), "switch-widget", widget);
+    button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "search"));
+
+    if (gtk_dockable_can_search(dockable))
+        gtk_widget_show(button);
+    else
+        gtk_widget_hide(button);
+
+    button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "close"));
+
+    if (gtk_dockable_can_be_closed(dockable))
+        gtk_widget_show(button);
+    else
+        gtk_widget_hide(button);
+
+    /* Remontée du changement d'onglet */
+
+    g_signal_emit_by_name(station, "switch-widget", widget);
 
     return TRUE;
 
@@ -223,12 +280,26 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p
 *                                                                             *
 ******************************************************************************/
 
-void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const char *caption, const char *desc)
+void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable)
 {
+    GtkWidget *widget;                      /* Composant GTK à intégrer    */
+    const char *caption;                    /* Nom à donner à l'onglet     */
+    const char *desc;                       /* Description à y associer    */
     size_t max;                             /* Taille maximale des titres  */
     char *str;                              /* Titre des prochaines fois   */
     GtkWidget *label;                       /* Etiquette d'onglet          */
 
+    /* Récupération des éléments utiles */
+
+    widget = gtk_dockable_get_widget(dockable);
+
+    g_object_set_data(G_OBJECT(widget), "dockable", dockable);
+
+    caption = gtk_dockable_get_name(dockable);
+    desc = gtk_dockable_get_desc(dockable);
+
+    /* Mise en place de la page */
+
     if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max))
         max = -1;
 
@@ -236,28 +307,22 @@ void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const
     label = qck_create_label(NULL, NULL, str);
     free(str);
 
+    if (gtk_notebook_get_n_pages(station->notebook) > 0)
     g_signal_handlers_disconnect_by_func(station->notebook,
                                          G_CALLBACK(gtk_dock_station_switch_panel), station);
 
     gtk_notebook_insert_page(station->notebook, widget, label, -1);
     gtk_widget_set_tooltip_text(label, desc);
 
+    if (gtk_notebook_get_n_pages(station->notebook) > 1)
     g_signal_connect(station->notebook, "switch-page",
                      G_CALLBACK(gtk_dock_station_switch_panel), station);
 
-    gtk_notebook_set_show_tabs(station->notebook, gtk_notebook_get_n_pages(station->notebook) > 1);
-
-    str = g_object_get_data(G_OBJECT(widget), "title");
-    if (str != NULL) free(str);
-
-    if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_HEADER, &max))
-        max = -1;
-
-    g_object_set_data(G_OBJECT(widget), "title", ellipsis(strdup(desc), max));
+    /* Lancement des mises à jour */
 
-    gtk_dock_panel_update_title(station, widget, desc);
+    if (gtk_notebook_get_n_pages(station->notebook) > 1)
+        gtk_notebook_set_current_page(station->notebook, -1);
 
-    gtk_notebook_set_current_page(station->notebook, -1);
 
     g_signal_emit_by_name(station, "dock-widget", widget);
 
@@ -328,13 +393,17 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget)
     gint index;                             /* Indice de l'onglet visé     */
     gint count;                             /* Nombre d'onglets en place   */
 
+
+    return;
+
+
     index = gtk_notebook_page_num(station->notebook, widget);
 
     gtk_notebook_remove_page(station->notebook, index);
 
     count = gtk_notebook_get_n_pages(station->notebook);
 
-    gtk_notebook_set_show_tabs(station->notebook, count > 1);
+    //gtk_notebook_set_show_tabs(station->notebook, count > 1);
 
     if (count == 0)
         gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(station))),
@@ -345,50 +414,48 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : station = plateforme GTK à compléter.                        *
-*                widget  = nouvel élément à intégrer.                         *
-*                caption = intitulé court à afficher sur les onglets.         *
+*  Paramètres  : station = plateforme GTK à consulter.                        *
+*                index   = indice de l'onglet visé.                           *
 *                                                                             *
-*  Description : Met à jour, si besoin est, le titre de l'affichage concentré.*
+*  Description : Renvoie un composant intégré dans l'affichage centralisé.    *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Composant associé à l'indice donné.                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void gtk_dock_panel_update_title(GtkDockStation *station, GtkWidget *widget, const char *caption)
+GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)
 {
-    char *str;                              /* Valeur finale reconstituée  */
-
-    str = calloc(strlen("<b>") + strlen(caption) + strlen("</b>") + 1, sizeof(char));
-
-    strcpy(str, "<b>");
-    strcat(str, caption);
-    strcat(str, "</b>");
-
-    gtk_label_set_markup(station->title, str);
-
-    free(str);
+    return gtk_notebook_get_nth_page(station->notebook, index);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : station = plateforme GTK à consulter.                        *
-*                index   = indice de l'onglet visé.                           *
+*  Paramètres  : button  = bouton à l'origine de la procédure.                *
+*                station = station d'accueil pour différents composants.      *
 *                                                                             *
-*  Description : Renvoie un composant intégré dans l'affichage centralisé.    *
+*  Description : Révèle ou cache la zone de recherches.                       *
 *                                                                             *
-*  Retour      : Composant associé à l'indice donné.                          *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)
+static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station)
 {
-    return gtk_notebook_get_nth_page(station->notebook, index);
+    gint index;                             /* Indice de l'onglet courant  */
+    GtkWidget *widget;                      /* Panneau concerné            */
+    GtkDockable *dockable;                  /* Elément encapsulé           */
+
+    index = gtk_notebook_get_current_page(station->notebook);
+    widget = gtk_notebook_get_nth_page(station->notebook, index);
+
+    dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable"));
+
+    gtk_dockable_toggle_revealer(dockable, widget, gtk_toggle_button_get_active(button));
 
 }
diff --git a/src/gtkext/gtkdockstation.h b/src/gtkext/gtkdockstation.h
index 7cc2263..d64a0b8 100644
--- a/src/gtkext/gtkdockstation.h
+++ b/src/gtkext/gtkdockstation.h
@@ -28,6 +28,10 @@
 #include <gtk/gtk.h>
 
 
+#include "gtkdockable.h"
+
+
+
 //G_BEGIN_DECLS
 
 
@@ -76,7 +80,7 @@ GType gtk_dock_station_get_type(void);
 GtkWidget *gtk_dock_station_new(void);
 
 /* Ajoute un paquet d'informations à l'affichage centralisé. */
-void gtk_dock_panel_add_widget(GtkDockStation *, GtkWidget *, const char *, const char *);
+void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *);
 
 /* Change le contenu de l'onglet courant uniquement. */
 void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *);
@@ -84,9 +88,6 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *);
 /* Retire un paquet d'informations de l'affichage centralisé. */
 void gtk_dock_panel_remove_widget(GtkDockStation *, GtkWidget *);
 
-/* Met à jour, si besoin est, le titre de l'affichage concentré. */
-void gtk_dock_panel_update_title(GtkDockStation *, GtkWidget *, const char *);
-
 /* Renvoie un composant intégré dans l'affichage centralisé. */
 GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *, gint);
 
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index 977cbc9..e06b891 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -28,7 +28,6 @@
 #include <assert.h>
 #include <cairo-gobject.h>
 #include <malloc.h>
-#include <regex.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -44,6 +43,7 @@
 #include "../../glibext/chrysamarshal.h"
 #include "../../glibext/signal.h"
 #include "../../gtkext/easygtk.h"
+#include "../../gtkext/gtkdockable-int.h"
 #include "../../gtkext/support.h"
 
 
@@ -57,7 +57,7 @@ struct _GBookmarksPanel
     GPanelItem parent;                      /* A laisser en premier        */
 
     GtkTreeView *treeview;                  /* Composant d'affichage       */
-    regex_t *filter;                        /* Filtre appliqué ou NULL     */
+    const regex_t *filter;                  /* Filtre appliqué ou NULL     */
 
     GtkMenu *menu;                          /* Menu contextuel pour param. */
 
@@ -98,6 +98,9 @@ static void g_bookmarks_panel_class_init(GBookmarksPanelClass *);
 /* Initialise une instance de panneau de paramètres de config. */
 static void g_bookmarks_panel_init(GBookmarksPanel *);
 
+/* Procède à l'initialisation de l'interface de rassemblement. */
+static void g_bookmarks_panel_dockable_interface_init(GtkDockableInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_bookmarks_panel_dispose(GBookmarksPanel *);
 
@@ -141,10 +144,10 @@ static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTr
 
 
 /* Démarre l'actualisation du filtrage des paramètres. */
-static void on_param_search_changed(GtkSearchEntry *, GBookmarksPanel *);
+static void update_filtered_bookmarks(GBookmarksPanel *, const regex_t *);
 
-/* Détermine si un paramètre doit être filtré ou non. */
-static bool is_param_filtered(GBookmarksPanel *, const char *);
+/* Détermine si un signet doit être filtré ou non. */
+static bool is_bookmark_filtered(GBookmarksPanel *, const char *, const char *, const char *);
 
 
 
@@ -177,7 +180,8 @@ static void mcb_bookmarks_panel_filter(GtkMenuItem *, GBookmarksPanel *);
 
 
 /* Indique le type définit pour un panneau d'affichage des signets liés à un binaire. */
-G_DEFINE_TYPE(GBookmarksPanel, g_bookmarks_panel, G_TYPE_PANEL_ITEM);
+G_DEFINE_TYPE_WITH_CODE(GBookmarksPanel, g_bookmarks_panel, G_TYPE_PANEL_ITEM,
+                        G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_bookmarks_panel_dockable_interface_init))
 
 
 /******************************************************************************
@@ -233,9 +237,6 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
     GObject *ref;                           /* Espace de référencement     */
-    GtkWidget *label;                       /* Etiquette à utiliser        */
-    GtkWidget *search;                      /* Zone de recherche           */
-    GtkWidget *scrolled;                    /* Fenêtre défilante           */
     GtkTreeStore *store;                    /* Modèle de gestion           */
     GtkWidget *treeview;                    /* Affichage de la liste       */
     GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
@@ -245,35 +246,16 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
 
     base = G_EDITOR_ITEM(panel);
 
-    base->widget = gtk_grid_new();
+    base->widget = gtk_scrolled_window_new(NULL, NULL);
     gtk_widget_show(base->widget);
 
-    gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(base->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(base->widget), GTK_SHADOW_IN);
 
     ref = G_OBJECT(base->widget);
     g_object_set_data(ref, "panel", panel);
 
-    /* Partie recherche */
-
-    label = qck_create_label(NULL, NULL, _("Look for:"));
-    g_object_set(label, "margin", 8, NULL);
-    gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1);
-
-    search = gtk_search_entry_new();
-    ///g_signal_connect(search, "search-changed", G_CALLBACK(on_param_search_changed), panel);
-    gtk_widget_show(search);
-    gtk_widget_set_hexpand(search, TRUE);
-    gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1);
-
-    /* Partie paramètres */
-
-    scrolled = gtk_scrolled_window_new(NULL, NULL);
-    gtk_widget_show(scrolled);
-    gtk_widget_set_vexpand(scrolled, TRUE);
-    gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1);
-
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+    /* Partie signets */
 
     store = gtk_tree_store_new(BMC_COUNT, G_TYPE_OBJECT,
                                CAIRO_GOBJECT_TYPE_SURFACE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
@@ -287,7 +269,7 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
                      G_CALLBACK(on_key_pressed_over_params), panel);
 
     gtk_widget_show(treeview);
-    gtk_container_add(GTK_CONTAINER(scrolled), treeview);
+    gtk_container_add(GTK_CONTAINER(base->widget), treeview);
 
     g_object_unref(G_OBJECT(store));
 
@@ -352,6 +334,35 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GTK à initialiser.                         *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de rassemblement.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bookmarks_panel_dockable_interface_init(GtkDockableInterface *iface)
+{
+    GtkDockableInterface *parent_iface;     /* Définition précédente       */
+
+    parent_iface = (GtkDockableInterface *)g_type_interface_peek_parent(iface);
+
+    iface->can_search = true;
+    iface->can_be_closed = true;
+
+    iface->get_name = parent_iface->get_name;
+    iface->get_desc = parent_iface->get_desc;
+    iface->get_widget = parent_iface->get_widget;
+    iface->update_filtered = (update_filtered_data_fc)update_filtered_bookmarks;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel = instance d'objet GLib à traiter.                     *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
@@ -385,10 +396,7 @@ static void g_bookmarks_panel_dispose(GBookmarksPanel *panel)
 ******************************************************************************/
 
 static void g_bookmarks_panel_finalize(GBookmarksPanel *panel)
-{   
-    if (panel->filter != NULL)
-        regfree(panel->filter);
-
+{
     G_OBJECT_CLASS(g_bookmarks_panel_parent_class)->finalize(G_OBJECT(panel));
 
 }
@@ -485,6 +493,7 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary
     const vmpa2t *addr;                     /* Adressse associée au signet */
     VMPA_BUFFER(phys);                      /* Position physique           */
     VMPA_BUFFER(virt);                      /* Adresse virtuelle           */
+    const char *comment;                    /* Commentaire associé         */
     GtkTreeIter iter;                       /* Point d'insertion           */
 
     /* Basculement du binaire utilisé */
@@ -537,13 +546,18 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary
         vmpa2_phys_to_string(addr, msize, phys, NULL);
         vmpa2_virt_to_string(addr, msize, virt, NULL);
 
+        comment = g_db_bookmark_get_comment(bookmark);
+
+        if (is_bookmark_filtered(panel, phys, virt, comment))
+            continue;
+
         gtk_tree_store_append(store, &iter, NULL);
         gtk_tree_store_set(store, &iter,
                            BMC_BOOKMARK, bookmark,
                            BMC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img,
                            BMC_PHYSICAL, phys,
                            BMC_VIRTUAL, virt,
-                           BMC_COMMENT, g_db_bookmark_get_comment(bookmark),
+                           BMC_COMMENT, comment,
                            -1);
 
     }
@@ -970,8 +984,8 @@ static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gc
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : entry  = entrée de texte contenant le filtre brut.           *
-*                panel  = panneau assurant l'affichage des paramètres.        *
+*  Paramètres  : panel = panneau assurant l'affichage des paramètres.         *
+*                preg  = expression régulière compilée à utiliser.            *
 *                                                                             *
 *  Description : Démarre l'actualisation du filtrage des paramètres.          *
 *                                                                             *
@@ -981,76 +995,51 @@ static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gc
 *                                                                             *
 ******************************************************************************/
 
-static void on_param_search_changed(GtkSearchEntry *entry, GBookmarksPanel *panel)
+static void update_filtered_bookmarks(GBookmarksPanel *panel, const regex_t *preg)
 {
-    const gchar *text;                      /* Texte de l'utilisateur      */
-    int ret;                                /* Bilan de mise en place      */
-    GdkRGBA error;                          /* Couleur d'erreur            */
-
-    if (panel->filter != NULL)
-    {
-        regfree(panel->filter);
-        free(panel->filter);
-        panel->filter = NULL;
-    }
-
-    text = gtk_entry_get_text(GTK_ENTRY(entry));
-
-    if (strlen(text) > 0)
-    {
-        panel->filter = (regex_t *)calloc(1, sizeof(regex_t));
-        ret = regcomp(panel->filter, text, REG_EXTENDED);
-
-        if (ret != 0)
-        {
-            free(panel->filter);
-            panel->filter = NULL;
+    panel->filter = preg;
 
-            error.red = 1.0;
-            error.green = 0.0;
-            error.blue = 0.0;
-            error.alpha = 1.0;
-            gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error);
-
-            return;
-
-        }
-
-    }
-
-    gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL);
-
-    //reload_config_into_treeview(panel, get_main_configuration());
+    reload_bookmarks_into_treeview(panel, panel->binary);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel = panneau assurant l'affichage des paramètres.         *
-*                name  = chemin d'accès au paramètre à traiter.               *
+*  Paramètres  : panel   = panneau assurant l'affichage des paramètres.       *
+*                phys    = position physique du signet.                       *
+*                virt    = adresse virtuelle du signet.                       *
+*                comment = commentaire lisible associé au signet.             *
 *                                                                             *
-*  Description : Détermine si un paramètre doit être filtré ou non.           *
+*  Description : Détermine si un signet doit être filtré ou non.              *
 *                                                                             *
-*  Retour      : true si le paramètre ne doit pas être affiché, false sinon.  *
+*  Retour      : true si le signet ne doit pas être affiché, false sinon.     *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static bool is_param_filtered(GBookmarksPanel *panel, const char *name)
+static bool is_bookmark_filtered(GBookmarksPanel *panel, const char *phys, const char *virt, const char *comment)
 {
+    bool result;                            /* Bilan à retourner           */
     regmatch_t match;                       /* Récupération des trouvailles*/
     int ret;                                /* Bilan du filtrage           */
 
     if (panel->filter == NULL)
         return false;
 
-    ret = regexec(panel->filter, name, 1, &match, 0);
-    if (ret == REG_NOMATCH)
-        return true;
+    result = true;
+
+    ret = regexec(panel->filter, phys, 1, &match, 0);
+    result &= (ret == REG_NOMATCH);
 
-    return false;
+    ret = regexec(panel->filter, virt, 1, &match, 0);
+    result &= (ret == REG_NOMATCH);
+
+    ret = regexec(panel->filter, comment, 1, &match, 0);
+    result &= (ret == REG_NOMATCH);
+
+    return result;
 
 }
 
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 8a46025..7f18fea 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -40,6 +40,7 @@
 #include "symbols.h"
 #include "welcome.h"
 #include "../../gtkext/easygtk.h"
+#include "../../gtkext/gtkdockable-int.h"
 #include "../../gtkext/gtkdockstation.h"
 
 
@@ -67,6 +68,18 @@ static void g_panel_item_class_init(GPanelItemClass *);
 /* Initialise une instance d'élément réactif pour l'éditeur. */
 static void g_panel_item_init(GPanelItem *);
 
+/* Procède à l'initialisation de l'interface de rassemblement. */
+static void g_panel_item_dockable_interface_init(GtkDockableInterface *);
+
+/* Fournit le nom court du composant encapsulable. */
+static const char *gtk_panel_item_get_name(const GPanelItem *);
+
+/* Fournit le nom long du composant encapsulable. */
+static const char *gtk_panel_item_get_desc(const GPanelItem *);
+
+/* Fournit le composant graphique intégrable dans un ensemble. */
+static GtkWidget *gtk_panel_item_get_widget(GPanelItem *);
+
 
 
 /* ---------------------- MECANISMES DE PLACEMENT DES PANNEAUX ---------------------- */
@@ -129,7 +142,8 @@ static void on_docking_to_main_panel(GtkDockStation *, GtkWidget *, gpointer);
 
 
 /* Indique le type défini pour un élément destiné à un panneau. */
-G_DEFINE_TYPE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM);
+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))
 
 
 /******************************************************************************
@@ -171,6 +185,31 @@ static void g_panel_item_init(GPanelItem *item)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GTK à initialiser.                         *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de rassemblement.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface)
+{
+    iface->can_search = false;
+    iface->can_be_closed = true;
+
+    iface->get_name = (get_dockable_name_fc)gtk_panel_item_get_name;
+    iface->get_desc = (get_dockable_desc_fc)gtk_panel_item_get_desc;
+    iface->get_widget = (get_dockable_widget_fc)gtk_panel_item_get_widget;
+    iface->update_filtered = (update_filtered_data_fc)NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : item   = composant à présenter à l'affichage.                *
 *                ref    = espace de référencement global.                     *
 *                name   = nom associé à l'élément.                            *
@@ -240,6 +279,63 @@ GEditorItem *g_panel_item_new(GObject *ref, const char *name, const char *lname,
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
+*                                                                             *
+*  Description : Fournit le nom court du composant encapsulable.              *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const char *gtk_panel_item_get_name(const GPanelItem *item)
+{
+    return G_EDITOR_ITEM(item)->name;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
+*                                                                             *
+*  Description : Fournit le nom long du composant encapsulable.               *
+*                                                                             *
+*  Retour      : Désignation humaine pour titre d'onglet ou de fenêtre.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const char *gtk_panel_item_get_desc(const GPanelItem *item)
+{
+    return item->lname;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
+*                                                                             *
+*  Description : Fournit le composant graphique intégrable dans un ensemble.  *
+*                                                                             *
+*  Retour      : Composant graphique prêt à emploi.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)
+{
+    return G_EDITOR_ITEM(item)->widget;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : name = désignation courte servant de clef.                   *
 *                                                                             *
 *  Description : Recherche un panneau à partir de son nom court.              *
@@ -423,7 +519,6 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha
 {
     panel_node *result;                     /* Structure à retourner       */
     GtkWidget *station;                     /* Premier support concentré   */
-    GEditorItem *editem;                    /* Autre vision des choses     */
 
     result = (panel_node *)calloc(1, sizeof(panel_node));
 
@@ -438,9 +533,7 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha
 
     result->station = station;
 
-    editem = G_EDITOR_ITEM(item);
-    gtk_dock_panel_add_widget(GTK_DOCK_STATION(station),
-                              editem->widget, editem->name, item->lname);
+    gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
 
     return result;
 
@@ -695,10 +788,7 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
         {
             /* Le parcours s'arrête ici ! */
             if (strcmp(node->path, path) == 0)
-                gtk_dock_panel_add_widget(GTK_DOCK_STATION(node->station),
-                                          G_EDITOR_ITEM(item)->widget,
-                                          G_EDITOR_ITEM(item)->name,
-                                          item->lname);
+                gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item));
 
             /* On ne peut aller plus loin, on doit diviser... */
             else
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 8d41165..4d7d077 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -26,7 +26,6 @@
 
 
 #include <inttypes.h>
-#include <regex.h>
 
 
 #include "panel-int.h"
@@ -34,6 +33,7 @@
 #include "../../core/params.h"
 #include "../../dialogs/gotox.h"
 #include "../../gtkext/easygtk.h"
+#include "../../gtkext/gtkdockable-int.h"
 
 
 
@@ -46,7 +46,7 @@ struct _GStringsPanel
     GPanelItem parent;                      /* A laisser en premier        */
 
     GtkTreeView *treeview;                  /* Composant d'affichage       */
-    regex_t *filter;                        /* Filtre appliqué ou NULL     */
+    const regex_t *filter;                  /* Filtre appliqué ou NULL     */
 
     GtkMenu *menu;                          /* Menu contextuel pour param. */
 
@@ -84,22 +84,23 @@ static void g_strings_panel_class_init(GStringsPanelClass *);
 /* Initialise une instance de panneau d'affichage des chaînes. */
 static void g_strings_panel_init(GStringsPanel *);
 
+/* Procède à l'initialisation de l'interface de rassemblement. */
+static void g_strings_panel_dockable_interface_init(GtkDockableInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_strings_panel_dispose(GStringsPanel *);
 
 /* Procède à la libération totale de la mémoire. */
 static void g_strings_panel_finalize(GStringsPanel *);
 
-/* Réagit à un changement d'affichage principal de contenu. */
-static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *);
-
-
-
 
 
 /* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */
 
 
+/* Réagit à un changement d'affichage principal de contenu. */
+static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *);
+
 /* Réagit au changement de sélection des chaînes textuelles. */
 static void on_strings_selection_change(GtkTreeSelection *, GStringsPanel *);
 
@@ -117,8 +118,8 @@ static void on_string_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkT
 /* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */
 
 
-/* Démarre l'actualisation du filtrage des paramètres. */
-static void on_string_search_changed(GtkSearchEntry *, GStringsPanel *);
+/* Démarre l'actualisation du filtrage des chaînes. */
+static void update_filtered_strings(GStringsPanel *, const regex_t *);
 
 /* Détermine si une chaîne textuelle doit être filtrée ou non. */
 static bool is_string_filtered(GStringsPanel *, const char *, const char *);
@@ -151,14 +152,14 @@ static void mcb_strings_panel_filter(GtkMenuItem *, GStringsPanel *);
 
 
 
-
 /* ---------------------------------------------------------------------------------- */
 /*                            PARTIE PRINCIPALE DU PANNEAU                            */
 /* ---------------------------------------------------------------------------------- */
 
 
 /* Indique le type définit pour un panneau d'affichage des chaînes. */
-G_DEFINE_TYPE(GStringsPanel, g_strings_panel, G_TYPE_PANEL_ITEM);
+G_DEFINE_TYPE_WITH_CODE(GStringsPanel, g_strings_panel, G_TYPE_PANEL_ITEM,
+                        G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_strings_panel_dockable_interface_init))
 
 
 /******************************************************************************
@@ -206,9 +207,6 @@ static void g_strings_panel_init(GStringsPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
     GObject *ref;                           /* Espace de référencement     */
-    GtkWidget *label;                       /* Etiquette à utiliser        */
-    GtkWidget *search;                      /* Zone de recherche           */
-    GtkWidget *scrolled;                    /* Fenêtre défilante           */
     GtkTreeStore *store;                    /* Modèle de gestion           */
     GtkWidget *treeview;                    /* Affichage de la liste       */
     GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
@@ -219,35 +217,16 @@ static void g_strings_panel_init(GStringsPanel *panel)
 
     base = G_EDITOR_ITEM(panel);
 
-    base->widget = gtk_grid_new();
+    base->widget = gtk_scrolled_window_new(NULL, NULL);
     gtk_widget_show(base->widget);
 
-    gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(base->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(base->widget), GTK_SHADOW_IN);
 
     ref = G_OBJECT(base->widget);
     g_object_set_data(ref, "panel", panel);
 
-    /* Partie recherche */
-
-    label = qck_create_label(NULL, NULL, _("Look for:"));
-    g_object_set(label, "margin", 8, NULL);
-    gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1);
-
-    search = gtk_search_entry_new();
-    g_signal_connect(search, "search-changed", G_CALLBACK(on_string_search_changed), panel);
-    gtk_widget_show(search);
-    gtk_widget_set_hexpand(search, TRUE);
-    gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1);
-
-    /* Partie paramètres */
-
-    scrolled = gtk_scrolled_window_new(NULL, NULL);
-    gtk_widget_show(scrolled);
-    gtk_widget_set_vexpand(scrolled, TRUE);
-    gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1);
-
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+    /* Partie chaînes */
 
     store = gtk_tree_store_new(STC_COUNT, G_TYPE_OBJECT,
                                G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
@@ -263,7 +242,7 @@ static void g_strings_panel_init(GStringsPanel *panel)
                      G_CALLBACK(on_key_pressed_over_strings), panel);
 
     gtk_widget_show(treeview);
-    gtk_container_add(GTK_CONTAINER(scrolled), treeview);
+    gtk_container_add(GTK_CONTAINER(base->widget), treeview);
 
     g_object_unref(G_OBJECT(store));
 
@@ -336,6 +315,35 @@ static void g_strings_panel_init(GStringsPanel *panel)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GTK à initialiser.                         *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de rassemblement.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_strings_panel_dockable_interface_init(GtkDockableInterface *iface)
+{
+    GtkDockableInterface *parent_iface;     /* Définition précédente       */
+
+    parent_iface = (GtkDockableInterface *)g_type_interface_peek_parent(iface);
+
+    iface->can_search = true;
+    iface->can_be_closed = true;
+
+    iface->get_name = parent_iface->get_name;
+    iface->get_desc = parent_iface->get_desc;
+    iface->get_widget = parent_iface->get_widget;
+    iface->update_filtered = (update_filtered_data_fc)update_filtered_strings;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel = instance d'objet GLib à traiter.                     *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
@@ -708,10 +716,10 @@ static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, g
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : entry  = entrée de texte contenant le filtre brut.           *
-*                panel  = panneau assurant l'affichage des paramètres.        *
+*  Paramètres  : panel = panneau assurant l'affichage des paramètres.         *
+*                preg  = expression régulière compilée à utiliser.            *
 *                                                                             *
-*  Description : Démarre l'actualisation du filtrage des paramètres.          *
+*  Description : Démarre l'actualisation du filtrage des chaînes.             *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -719,44 +727,9 @@ static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, g
 *                                                                             *
 ******************************************************************************/
 
-static void on_string_search_changed(GtkSearchEntry *entry, GStringsPanel *panel)
+static void update_filtered_strings(GStringsPanel *panel, const regex_t *preg)
 {
-    const gchar *text;                      /* Texte de l'utilisateur      */
-    int ret;                                /* Bilan de mise en place      */
-    GdkRGBA error;                          /* Couleur d'erreur            */
-
-    if (panel->filter != NULL)
-    {
-        regfree(panel->filter);
-        free(panel->filter);
-        panel->filter = NULL;
-    }
-
-    text = gtk_entry_get_text(GTK_ENTRY(entry));
-
-    if (strlen(text) > 0)
-    {
-        panel->filter = (regex_t *)calloc(1, sizeof(regex_t));
-        ret = regcomp(panel->filter, text, REG_EXTENDED);
-
-        if (ret != 0)
-        {
-            free(panel->filter);
-            panel->filter = NULL;
-
-            error.red = 1.0;
-            error.green = 0.0;
-            error.blue = 0.0;
-            error.alpha = 1.0;
-            gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error);
-
-            return;
-
-        }
-
-    }
-
-    gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL);
+    panel->filter = preg;
 
     change_strings_panel_current_binary(panel, panel->binary);
 
@@ -786,18 +759,18 @@ static bool is_string_filtered(GStringsPanel *panel, const char *label, const ch
     if (panel->filter == NULL)
         return false;
 
-    result = false;
+    result = true;
 
     if (label != NULL)
     {
         ret = regexec(panel->filter, label, 1, &match, 0);
-        result |= (ret != REG_NOMATCH);
+        result &= (ret == REG_NOMATCH);
     }
 
     ret = regexec(panel->filter, value, 1, &match, 0);
-    result |= (ret != REG_NOMATCH);
+    result &= (ret == REG_NOMATCH);
 
-    return !result;
+    return result;
 
 }
 
-- 
cgit v0.11.2-87-g4458