From 235b34006d734d55333a182ffd8bbe7fbf8f54bc Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 8 Mar 2016 22:44:52 +0100
Subject: Loaded a dynamic list of dockable panels in the View menu.

---
 ChangeLog                           |  51 ++
 plugins/pychrysa/gui/panels/panel.c |  43 +-
 plugins/python/welcome/panel.py     |   2 +-
 src/analysis/project.c              |   2 +-
 src/gtkext/gtkdockable.c            |  35 +-
 src/gtkext/gtkdockable.h            |   5 +-
 src/gtkext/gtkdockstation.c         | 183 +++----
 src/gtkext/gtkdockstation.h         |   9 +-
 src/gtkext/gtkviewpanel.c           |   4 +-
 src/gui/editem.c                    |  21 +-
 src/gui/editem.h                    |   3 +
 src/gui/menus/menubar.c             |   2 +
 src/gui/menus/project.c             |   2 +-
 src/gui/menus/view.c                | 168 ++++++-
 src/gui/panels/bookmarks.c          |   5 +
 src/gui/panels/glance.c             |  10 +-
 src/gui/panels/history.c            |   7 +-
 src/gui/panels/log.c                |  22 +-
 src/gui/panels/panel-int.h          |  38 +-
 src/gui/panels/panel.c              | 929 +++++++++++++++++++++---------------
 src/gui/panels/panel.h              |  46 +-
 src/gui/panels/regedit.c            |   7 +-
 src/gui/panels/strings.c            |  11 +
 src/gui/panels/symbols.c            |  13 +-
 24 files changed, 1111 insertions(+), 507 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 09dc5d8..ca1655f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+16-03-08  Cyrille Bagard <nocbos@gmail.com>
+
+	* plugins/pychrysa/gui/panels/panel.c:
+	Register new constants for panels.
+
+	* plugins/python/welcome/panel.py:
+	* src/analysis/project.c:
+	Update code.
+
+	* src/gtkext/gtkdockable.c:
+	* src/gtkext/gtkdockable.h:
+	Provide references of dockable items for UI.
+
+	* src/gtkext/gtkdockstation.c:
+	* src/gtkext/gtkdockstation.h:
+	Inherit from GtkNotebook directly for dock stations. Dock and undock
+	widgets.
+
+	* src/gtkext/gtkviewpanel.c:
+	Disable some code.
+
+	* src/gui/editem.c:
+	* src/gui/editem.h:
+	Provide editor item name for external usage.
+
+	* src/gui/menus/menubar.c:
+	Store the global accelerator group.
+
+	* src/gui/menus/project.c:
+	Typo.
+
+	* src/gui/menus/view.c:
+	Load a dynamic list of dockable panels in the View menu. Dock and undock
+	panels on demand.
+
+	* src/gui/panels/bookmarks.c:
+	* src/gui/panels/glance.c:
+	* src/gui/panels/history.c:
+	* src/gui/panels/log.c:
+	Update code.
+
+	* src/gui/panels/panel-int.h:
+	* src/gui/panels/panel.c:
+	* src/gui/panels/panel.h:
+	Give a personality to each panel. Rewrite the tree of docked widgets.
+
+	* src/gui/panels/regedit.c:
+	* src/gui/panels/strings.c:
+	* src/gui/panels/symbols.c:
+	Update code.
+
 16-03-05  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/arm/v7/helpers.h:
diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c
index 3170a66..8046c0e 100644
--- a/plugins/pychrysa/gui/panels/panel.c
+++ b/plugins/pychrysa/gui/panels/panel.c
@@ -32,6 +32,7 @@
 
 
 #include "../editem.h"
+#include "../../helpers.h"
 #include "../../quirks.h"
 
 
@@ -42,6 +43,9 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds);
 /* Place un panneau dans l'ensemble affiché. */
 static PyObject *py_panel_item_dock(PyObject *, PyObject *);
 
+/* Définit les constantes pour les panneaux. */
+static bool py_panel_item_define_constants(PyTypeObject *);
+
 
 
 /******************************************************************************
@@ -60,6 +64,7 @@ static PyObject *py_panel_item_dock(PyObject *, PyObject *);
 
 static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
+    unsigned long personality;              /* Nature du panneau           */
     const char *name;                       /* Désignation humaine         */
     const char *lname;                      /* Nom version longue          */
     PyGObject *widget;                      /* Composant visuel du panneau */
@@ -67,10 +72,10 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)
     int ret;                                /* Bilan de lecture des args.  */
     GEditorItem *item;                      /* Elément de l'éditeur        */
 
-    ret = PyArg_ParseTuple(args, "ssOs", &name, &lname, &widget, &path);
+    ret = PyArg_ParseTuple(args, "kssOs", &personality, &name, &lname, &widget, &path);
     if (!ret) return -1;
 
-    item = g_panel_item_new(get_internal_ref(), name, lname,
+    item = g_panel_item_new(personality, get_internal_ref(), name, lname,
                             GTK_WIDGET(pygobject_get(widget)), path);
 
     /* Enregistrement auprès de PyGObject */
@@ -161,6 +166,37 @@ PyTypeObject *get_python_panel_item_type(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : obj_type = type dont le dictionnaire est à compléter.        *
+*                                                                             *
+*  Description : Définit les constantes pour les panneaux.                    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_panel_item_define_constants(PyTypeObject *obj_type)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    result &= PyDict_AddIntMacro(obj_type, PIP_INVALID);
+
+    result &= PyDict_AddIntMacro(obj_type, PIP_SINGLETON);
+    result &= PyDict_AddIntMacro(obj_type, PIP_BINARY_VIEW);
+    result &= PyDict_AddIntMacro(obj_type, PIP_OTHER);
+
+    result &= PyDict_AddIntMacro(obj_type, PIP_COUNT);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : module = module dont la définition est à compléter.          *
 *                                                                             *
 *  Description : Prend en charge l'objet 'pychrysalide.gui.panels.PanelItem'. *
@@ -185,6 +221,9 @@ bool register_python_panel_item(PyObject *module)
     if (PyType_Ready(py_panel_item_type) != 0)
         return false;
 
+    if (!py_panel_item_define_constants(py_panel_item_type))
+        return false;
+
     Py_INCREF(py_panel_item_type);
     ret = PyModule_AddObject(module, "PanelItem", (PyObject *)py_panel_item_type);
     if (ret != 0) return false;
diff --git a/plugins/python/welcome/panel.py b/plugins/python/welcome/panel.py
index 811f008..7b46c57 100644
--- a/plugins/python/welcome/panel.py
+++ b/plugins/python/welcome/panel.py
@@ -19,7 +19,7 @@ class WelcomePanel(PanelItem):
 
         content = self._build_panel_content()
 
-        super(WelcomePanel, self).__init__('Welcome', 'First commands', content, 'M')
+        super(WelcomePanel, self).__init__(PanelItem.PIP_SINGLETON, 'Welcome', 'First commands', content, 'N')
 
 
     def _build_panel_content(self):
diff --git a/src/analysis/project.c b/src/analysis/project.c
index b787262..623779b 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -666,7 +666,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina
     name = g_loaded_binary_get_name(binary, false);
     lname = g_loaded_binary_get_name(binary, true);
 
-    loaded->item = g_panel_item_new(project->ref, name, lname, scroll, "M");
+    loaded->item = g_panel_item_new(PIP_BINARY_VIEW, project->ref, name, lname, scroll, "N");
 
     /* Enregistrement dans le projet */
 
diff --git a/src/gtkext/gtkdockable.c b/src/gtkext/gtkdockable.c
index 954b651..98b1a04 100644
--- a/src/gtkext/gtkdockable.c
+++ b/src/gtkext/gtkdockable.c
@@ -241,7 +241,7 @@ bool gtk_dockable_can_be_closed(const GtkDockable *dockable)
 *                                                                             *
 ******************************************************************************/
 
-GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable)
+GtkWidget *gtk_dockable_build_widget(GtkDockable *dockable)
 {
     GtkWidget *result;                      /* Composant à retourner       */
     GtkDockableIface *iface;                /* Interface utilisée          */
@@ -286,6 +286,39 @@ GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : dockable = instance GTK dont l'interface est à consulter.    *
+*                support  = composant à partir duquel décrocher ou NULL. [OUT]*
+*                                                                             *
+*  Description : Fournit tous les éléments pour un retrait graphique.         *
+*                                                                             *
+*  Retour      : Composant graphique à décrocher.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *gtk_dockable_decompose(GtkDockable *dockable, GtkWidget **support)
+{
+    GtkWidget *result;                      /* Composant à retourner       */
+    GtkDockableIface *iface;                /* Interface utilisée          */
+
+    iface = GTK_DOCKABLE_GET_IFACE(dockable);
+
+    result = iface->get_widget(dockable);
+
+    if (iface->can_search)
+        result = gtk_widget_get_parent(result);     /* GtkBox */
+
+    if (support != NULL)
+        *support = gtk_widget_get_parent(result);
+
+    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.                       *
 *                                                                             *
diff --git a/src/gtkext/gtkdockable.h b/src/gtkext/gtkdockable.h
index e939fad..31a3310 100644
--- a/src/gtkext/gtkdockable.h
+++ b/src/gtkext/gtkdockable.h
@@ -62,7 +62,10 @@ const char *gtk_dockable_get_name(const GtkDockable *);
 const char *gtk_dockable_get_desc(const GtkDockable *);
 
 /* Fournit le composant graphique intégrable dans un ensemble. */
-GtkWidget *gtk_dockable_get_widget(GtkDockable *);
+GtkWidget *gtk_dockable_build_widget(GtkDockable *);
+
+/* Fournit tous les éléments pour un retrait graphique. */
+GtkWidget *gtk_dockable_decompose(GtkDockable *, GtkWidget **);
 
 /* Révèle ou cache la zone de recherches. */
 void gtk_dockable_toggle_revealer(GtkDockable *, GtkWidget *, gboolean);
diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c
index e10e55f..35006ef 100644
--- a/src/gtkext/gtkdockstation.c
+++ b/src/gtkext/gtkdockstation.c
@@ -57,7 +57,7 @@ static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *);
 
 
 /* Détermine le type du composant d'affichage concentré. */
-G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_BOX)
+G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_NOTEBOOK)
 
 
 /******************************************************************************
@@ -115,53 +115,14 @@ static void gtk_dock_station_class_init(GtkDockStationClass *class)
 
 static void gtk_dock_station_init(GtkDockStation *station)
 {
-    GtkWidget *eventbox;                    /* Réceptacle actif            */
+    GtkNotebook *notebook;                  /* Autre version du composant  */
     GtkWidget *hbox;                        /* Division supérieure         */
     GtkWidget *button;                      /* Bouton de contrôle          */
-    GtkWidget *image;                       /* Image associée              */
 
-    gtk_orientable_set_orientation(GTK_ORIENTABLE(station), GTK_ORIENTATION_VERTICAL);
+    notebook = GTK_NOTEBOOK(station);
 
-    eventbox = gtk_event_box_new();
-    gtk_widget_show(eventbox);
-    //gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0);
-
-    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-    gtk_widget_show(hbox);
-    gtk_container_add(GTK_CONTAINER(eventbox), hbox);
-
-    station->title = GTK_LABEL(qck_create_label(NULL, NULL, "<b>titre</b>"));
-    gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(station->title), TRUE, TRUE, 0);
-    gtk_label_set_use_markup(station->title, TRUE);
-
-    button = gtk_button_new();
-    gtk_widget_show(button);
-    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
-    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
-
-    image = gtk_image_new_from_icon_name("gtk-media-play", GTK_ICON_SIZE_MENU);
-    gtk_widget_show(image);
-    gtk_container_add(GTK_CONTAINER(button), image);
-    gtk_widget_set_size_request(image, 10, 10);
-
-    button = gtk_button_new();
-    gtk_widget_show(button);
-    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
-    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
-
-    image = gtk_image_new_from_icon_name("gtk-close", GTK_ICON_SIZE_MENU);
-    gtk_widget_show(image);
-    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_scrollable(station->notebook, TRUE);
+    gtk_notebook_set_show_border(notebook, FALSE);
+    gtk_notebook_set_scrollable(notebook, TRUE);
 
     /* Définition de la zone de contrôle */
 
@@ -188,9 +149,9 @@ static void gtk_dock_station_init(GtkDockStation *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);
+    gtk_notebook_set_action_widget(notebook, hbox, GTK_PACK_END);
 
-    g_signal_connect(station->notebook, "switch-page",
+    g_signal_connect(notebook, "switch-page",
                      G_CALLBACK(gtk_dock_station_switch_panel), station);
 
 }
@@ -267,10 +228,8 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : station = plateforme GTK à compléter.                        *
-*                widget  = nouvel élément à intégrer.                         *
-*                caption = intitulé court à afficher sur les onglets.         *
-*                desc    = intitulé long pour le titre et la description.     *
+*  Paramètres  : station  = plateforme GTK à compléter.                       *
+*                dockable = nouvel élément à intégrer.                        *
 *                                                                             *
 *  Description : Ajoute un paquet d'informations à l'affichage centralisé.    *
 *                                                                             *
@@ -279,7 +238,8 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
-
+#include "gtkviewpanel.h"
+#include "../gui/panels/history.h"
 void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable)
 {
     GtkWidget *widget;                      /* Composant GTK à intégrer    */
@@ -288,10 +248,34 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
     size_t max;                             /* Taille maximale des titres  */
     char *str;                              /* Titre des prochaines fois   */
     GtkWidget *label;                       /* Etiquette d'onglet          */
+    GtkNotebook *notebook;                  /* Autre version du composant  */
 
     /* Récupération des éléments utiles */
 
-    widget = gtk_dockable_get_widget(dockable);
+    widget = gtk_dockable_build_widget(dockable);
+
+
+    if (strcmp(gtk_dockable_get_name(dockable), "History") == 0)
+    {
+        GtkRequisition req;
+
+        gtk_widget_get_preferred_size(widget, &req, NULL);
+        fprintf(stderr, "Histo req :: %d x %d\n", req.width, req.height);
+
+    }
+
+    /*
+    if (!GTK_IS_SCROLLED_WINDOW(widget)
+        && (
+            strcmp(gtk_dockable_get_name(dockable), "History2") != 0
+            )
+        )
+        widget = gtk_button_new_with_label("123");
+    */
+
+    //widget = gtk_button_new_with_label("123");
+    gtk_widget_show(widget);
+
 
     g_object_set_data(G_OBJECT(widget), "dockable", dockable);
 
@@ -307,24 +291,52 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
     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,
+    notebook = GTK_NOTEBOOK(station);
+
+    if (gtk_notebook_get_n_pages(notebook) > 0)
+    g_signal_handlers_disconnect_by_func(notebook,
                                          G_CALLBACK(gtk_dock_station_switch_panel), station);
 
-    gtk_notebook_insert_page(station->notebook, widget, label, -1);
+    gtk_notebook_insert_page(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",
+    if (gtk_notebook_get_n_pages(notebook) > 1)
+    g_signal_connect(notebook, "switch-page",
                      G_CALLBACK(gtk_dock_station_switch_panel), station);
 
     /* Lancement des mises à jour */
 
-    if (gtk_notebook_get_n_pages(station->notebook) > 1)
-        gtk_notebook_set_current_page(station->notebook, -1);
+    if (gtk_notebook_get_n_pages(notebook) > 1)
+        gtk_notebook_set_current_page(notebook, -1);
+
+
+    // Renéociation des tailles
+    //gtk_widget_queue_resize(GTK_WIDGET(notebook));
+
+
+    if (false)
+    {
+        GtkRequisition req;
+
+        gtk_widget_get_preferred_size(GTK_WIDGET(notebook), &req, NULL);
+        fprintf(stderr, "=== SUPPORT req :: %d x %d\n", req.width, req.height);
+
+
+        gtk_widget_set_size_request(GTK_WIDGET(notebook), req.width, req.height);
+
+
+
+    }
+
+
 
 
-    g_signal_emit_by_name(station, "dock-widget", widget);
+
+
+
+
+
+    //g_signal_emit_by_name(station, "dock-widget", widget);
 
 }
 
@@ -344,32 +356,35 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl
 
 void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *widget)
 {
+    GtkNotebook *notebook;                  /* Autre version du composant  */
     gint index;                             /* Indice de l'onglet actif    */
     GtkWidget *old;                         /* Ancien composant            */
     GtkWidget *label;                       /* Etiquette d'onglet          */
     char *str;                              /* Titre des prochaines fois   */
 
-    index = gtk_notebook_get_current_page(station->notebook);
+    notebook = GTK_NOTEBOOK(station);
+
+    index = gtk_notebook_get_current_page(notebook);
 
-    g_signal_handlers_disconnect_by_func(station->notebook,
+    g_signal_handlers_disconnect_by_func(notebook,
                                          G_CALLBACK(gtk_dock_station_switch_panel), station);
 
-    old = gtk_notebook_get_nth_page(station->notebook, index);
-    label = gtk_notebook_get_tab_label(station->notebook, old);
+    old = gtk_notebook_get_nth_page(notebook, index);
+    label = gtk_notebook_get_tab_label(notebook, old);
 
     g_object_ref(G_OBJECT(old));
     g_object_ref(G_OBJECT(label));
     str = g_object_get_data(G_OBJECT(old), "title");
 
-    gtk_notebook_remove_page(station->notebook, index);
-    gtk_notebook_insert_page(station->notebook, widget, label, index);
+    gtk_notebook_remove_page(notebook, index);
+    gtk_notebook_insert_page(notebook, widget, label, index);
 
     g_object_unref(G_OBJECT(label));
     g_object_set_data(G_OBJECT(widget), "title", str);
 
-    gtk_notebook_set_current_page(station->notebook, index);
+    gtk_notebook_set_current_page(notebook, index);
 
-    g_signal_connect(station->notebook, "switch-page",
+    g_signal_connect(notebook, "switch-page",
                      G_CALLBACK(gtk_dock_station_switch_panel), station);
 
 }
@@ -378,7 +393,7 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *wid
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : station = plateforme GTK à compléter.                        *
-*                widget  = nouvel élément à intégrer.                         *
+*                dockable = élément existant à retirer.                       *
 *                                                                             *
 *  Description : Retire un paquet d'informations de l'affichage centralisé.   *
 *                                                                             *
@@ -388,26 +403,19 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *wid
 *                                                                             *
 ******************************************************************************/
 
-void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget)
+void gtk_dock_station_remove_dockable(GtkDockStation *station, GtkDockable *dockable)
 {
+    GtkNotebook *notebook;                  /* Autre version du composant  */
+    GtkWidget *widget;                      /* Composant GTK à retirer     */
     gint index;                             /* Indice de l'onglet visé     */
-    gint count;                             /* Nombre d'onglets en place   */
 
+    notebook = GTK_NOTEBOOK(station);
 
-    return;
+    widget = gtk_dockable_decompose(dockable, NULL);
 
+    index = gtk_notebook_page_num(notebook, widget);
 
-    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);
-
-    if (count == 0)
-        gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(station))),
-                             GTK_WIDGET(station));
+    gtk_notebook_remove_page(notebook, index);
 
 }
 
@@ -427,7 +435,7 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget)
 
 GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)
 {
-    return gtk_notebook_get_nth_page(station->notebook, index);
+    return gtk_notebook_get_nth_page(GTK_NOTEBOOK(station), index);
 
 }
 
@@ -447,12 +455,15 @@ GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index)
 
 static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station)
 {
+    GtkNotebook *notebook;                  /* Autre version du composant  */
     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);
+    notebook = GTK_NOTEBOOK(station);
+
+    index = gtk_notebook_get_current_page(notebook);
+    widget = gtk_notebook_get_nth_page(notebook, index);
 
     dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable"));
 
diff --git a/src/gtkext/gtkdockstation.h b/src/gtkext/gtkdockstation.h
index d64a0b8..953ceb8 100644
--- a/src/gtkext/gtkdockstation.h
+++ b/src/gtkext/gtkdockstation.h
@@ -51,17 +51,14 @@ typedef struct _GtkDockStationClass GtkDockStationClass;
 /* Station de réception pour concentration d'éléments (instance) */
 struct _GtkDockStation
 {
-    GtkBox vbox;                            /* Présence obligatoire en 1er */
-
-    GtkLabel *title;                        /* Title du support principal  */
-    GtkNotebook *notebook;                  /* Support à onglets           */
+    GtkNotebook parent;                     /* A laisser en premier        */
 
 };
 
 /* Station de réception pour concentration d'éléments (classe) */
 struct _GtkDockStationClass
 {
-    GtkBoxClass parent_class;               /* Présence obligatoire en 1er */
+    GtkNotebookClass parent_class;          /* A laisser en premier        */
 
     /* Signaux */
 
@@ -86,7 +83,7 @@ void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *);
 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 *);
+void gtk_dock_station_remove_dockable(GtkDockStation *, GtkDockable *);
 
 /* Renvoie un composant intégré dans l'affichage centralisé. */
 GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *, gint);
diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c
index a347ad8..b7829c2 100644
--- a/src/gtkext/gtkviewpanel.c
+++ b/src/gtkext/gtkviewpanel.c
@@ -121,8 +121,8 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class)
     widget_class->realize = gtk_view_panel_realize;
     widget_class->size_allocate = gtk_view_panel_size_allocate;
     widget_class->draw = gtk_view_panel_draw;
-    widget_class->get_preferred_height = gtk_view_panel_get_preferred_height;
-    widget_class->get_preferred_width = gtk_view_panel_get_preferred_width;
+    //widget_class->get_preferred_height = gtk_view_panel_get_preferred_height;
+    //widget_class->get_preferred_width = gtk_view_panel_get_preferred_width;
 
     panel_class->compute_inc = gtk_view_panel_compute_scroll_inc;
 
diff --git a/src/gui/editem.c b/src/gui/editem.c
index 1dc77c9..f4d9d71 100644
--- a/src/gui/editem.c
+++ b/src/gui/editem.c
@@ -131,9 +131,28 @@ GObject *g_editor_item_get_global_ref(const GEditorItem *item)
 *                                                                             *
 *  Paramètres  : item = instance à consulter.                                 *
 *                                                                             *
+*  Description : Fournit le nom humain attribué à l'élément réactif.          *
+*                                                                             *
+*  Retour      : Désignation (courte) de l'élément de l'éditeur.              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_editor_item_get_name(const GEditorItem *item)
+{
+    return item->name;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance à consulter.                                 *
+*                                                                             *
 *  Description : Fournit le composant GTK associé à l'élément réactif.        *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Instance de composant graphique chargé.                      *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
diff --git a/src/gui/editem.h b/src/gui/editem.h
index 90b1919..08f76fa 100644
--- a/src/gui/editem.h
+++ b/src/gui/editem.h
@@ -59,6 +59,9 @@ GType g_editor_item_get_type(void);
 /* Fournit l'adresse de l'espace de référencement global. */
 GObject *g_editor_item_get_global_ref(const GEditorItem *);
 
+/* Fournit le nom humain attribué à l'élément réactif. */
+const char *g_editor_item_get_name(const GEditorItem *);
+
 /* Fournit le composant GTK associé à l'élément réactif. */
 GtkWidget *g_editor_item_get_widget(const GEditorItem *);
 
diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c
index db1905c..e2ad155 100644
--- a/src/gui/menus/menubar.c
+++ b/src/gui/menus/menubar.c
@@ -208,6 +208,8 @@ GEditorItem *g_menu_bar_new(GObject *ref, GtkAccelGroup *accgroup)
 
     result = g_object_new(G_TYPE_MENU_BAR, NULL);
 
+    g_object_set_data(G_OBJECT(result), "accgroup", accgroup);
+
     /* Initialisation générique */
 
     item = G_EDITOR_ITEM(result);
diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c
index f4f6233..9e43616 100644
--- a/src/gui/menus/project.c
+++ b/src/gui/menus/project.c
@@ -66,7 +66,7 @@ static void mcb_project_remove_binary(GtkMenuItem *, GStudyProject *);
 GtkWidget *build_menu_project(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
 {
     GtkWidget *result;                      /* Support à retourner         */
-    GtkWidget *menubar;                     /* Support pour éléments       */
+    GtkWidget *menubar;                     /* Support pour éléments #1    */
     GtkWidget *submenuitem;                 /* Sous-élément de menu #1     */
     GtkWidget *deepmenubar;                 /* Support pour éléments #2    */
     GtkWidget *deepmenuitem;                /* Sous-élément de menu #2     */
diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c
index cbfa9bf..e80077a 100644
--- a/src/gui/menus/view.c
+++ b/src/gui/menus/view.c
@@ -29,12 +29,19 @@
 
 
 #include "../editem-int.h"
+#include "../panels/panel.h"
 #include "../../analysis/project.h"
 #include "../../gtkext/easygtk.h"
 #include "../../gtkext/gtkdockstation.h"
 
 
 
+/* Réagit avec le menu "Affichage -> Panneaux latéraux". */
+static void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *);
+
+/* Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". */
+static void mcb_view_change_panel_docking(GtkCheckMenuItem *, GPanelItem *);
+
 /* Réagit avec le menu "Affichage -> Vue xxx". */
 static void mcb_view_change_support(GtkRadioMenuItem *, GMenuBar *);
 
@@ -63,8 +70,9 @@ static void mcb_view_show_full_screen(GtkCheckMenuItem *, GMenuBar *);
 GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
 {
     GtkWidget *result;                      /* Support à retourner         */
-    GtkWidget *menubar;                     /* Support pour éléments       */
+    GtkWidget *menubar;                     /* Support pour éléments #1    */
     GtkWidget *submenuitem;                 /* Sous-élément de menu        */
+    GtkWidget *deepmenubar;                 /* Support pour éléments #2    */
     GSList *rgroup;                         /* Groupe des boutons radio    */
 
     result = gtk_menu_item_new_with_mnemonic(_("_View"));
@@ -73,6 +81,20 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
     menubar = gtk_menu_new();
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(result), menubar);
 
+    /* Affichage -> Panneaux latéraux */
+
+    submenuitem = qck_create_menu_item(NULL, NULL, _("Side panels"), NULL, NULL);
+    g_signal_connect(submenuitem, "select", G_CALLBACK(mcb_view_update_side_panels_list), bar);
+    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+    deepmenubar = gtk_menu_new();
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), deepmenubar);
+
+    /* - */
+
+    submenuitem = qck_create_menu_separator();
+    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
     submenuitem = qck_create_radio_menu_item(ref, "textview", NULL, _("Text view"),
                                              G_CALLBACK(mcb_view_change_support), bar);
     add_accelerator_to_menu_item(submenuitem, "F2", accgroup);
@@ -113,6 +135,8 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
     g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_BINARY));
     gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
+    /* - */
+
     submenuitem = qck_create_menu_separator();
     gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
@@ -194,6 +218,148 @@ void update_menu_view_for_view(GtkWidget *widget, GtkViewPanel *view, GMenuBar *
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : menuitem = élément de menu sélectionné.                      *
+*                bar      = barre de menu parente.                            *
+*                                                                             *
+*  Description : Réagit avec le menu "Affichage -> Panneaux latéraux".        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar)
+{
+    GtkWidget *menubar;                     /* Support pour éléments       */
+    GtkAccelGroup *accgroup;                /* Groupe de raccourcis        */
+
+    typedef struct _panels_loading_filter
+    {
+        GtkContainer *support;              /* Support pour éléments       */
+        GtkAccelGroup *accel;               /* Groupe de raccourcis        */
+
+        PanelItemPersonality personality;   /* Nature des éléments attendus*/
+        bool first;                         /* Premier ajout ?             */
+
+    } panels_loading_filter;
+
+    panels_loading_filter pfilter;
+
+
+    menubar = gtk_menu_item_get_submenu(menuitem);
+
+    /* Réinitialisation */
+
+    void remove_panel_menu_item(GtkWidget *widget, GtkContainer *container)
+    {
+        gtk_container_remove(container, widget);
+
+    }
+
+    gtk_container_foreach(GTK_CONTAINER(menubar), (GtkCallback)remove_panel_menu_item, menubar);
+
+    /* Ajout des panneaux uniques */
+
+    bool add_side_panel_to_list(GPanelItem *panel, panels_loading_filter *filter)
+    {
+        const char *name;                   /* Désignation de l'entrée     */
+        GtkWidget *submenuitem;             /* Sous-élément de menu        */
+        const char *bindings;               /* Raccourcis clavier bruts    */
+
+        if (gtk_panel_item_get_personality(panel) != filter->personality)
+            goto aptl_exit;
+
+        /* Séparation */
+
+        if (filter->first)
+        {
+            filter->first = false;
+
+            submenuitem = qck_create_menu_separator();
+            gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
+
+        }
+
+        /* Elément de menu */
+
+        name = g_editor_item_get_name(G_EDITOR_ITEM(panel));
+
+        submenuitem = qck_create_check_menu_item(NULL, NULL, name,
+                                                 G_CALLBACK(mcb_view_change_panel_docking), panel);
+
+        bindings = gtk_panel_item_get_key_bindings(panel);
+
+        if (bindings != NULL)
+            add_accelerator_to_menu_item(submenuitem, bindings, filter->accel);
+
+        gtk_container_add(filter->support, submenuitem);
+
+        /* Statut de la coche */
+
+        if (g_panel_item_is_docked(panel))
+        {
+            g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_change_panel_docking), panel);
+
+            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), TRUE);
+
+            g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_change_panel_docking), panel);
+
+        }
+
+     aptl_exit:
+
+        return true;
+
+    }
+
+    accgroup = GTK_ACCEL_GROUP(g_object_get_data(G_OBJECT(bar), "accgroup"));
+
+    pfilter.support = GTK_CONTAINER(menubar);
+    pfilter.accel = accgroup;
+
+    pfilter.personality = PIP_SINGLETON;
+    pfilter.first = false;
+
+    browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter);
+
+    pfilter.personality = PIP_OTHER;
+    pfilter.first = true;
+
+    browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : menuitem = élément de menu ayant basculé.                    *
+*                bar      = barre de menu parente.                            *
+*                                                                             *
+*  Description : Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_view_change_panel_docking(GtkCheckMenuItem *menuitem, GPanelItem *item)
+{
+    gboolean active;                        /* Etat de sélection du menu   */
+
+    active = gtk_check_menu_item_get_active(menuitem);
+
+    if (active)
+        g_panel_item_dock(item);
+    else
+        g_panel_item_undock(item);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : menuitem = élément de menu ayant basculé.                    *
 *                bar      = barre de menu parente.                            *
 *                                                                             *
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index e06b891..9eaa1df 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -236,6 +236,7 @@ static void g_bookmarks_panel_class_init(GBookmarksPanelClass *klass)
 static void g_bookmarks_panel_init(GBookmarksPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
+    GPanelItem *pitem;                      /* Version parente du panneau  */
     GObject *ref;                           /* Espace de référencement     */
     GtkTreeStore *store;                    /* Modèle de gestion           */
     GtkWidget *treeview;                    /* Affichage de la liste       */
@@ -255,6 +256,10 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
     ref = G_OBJECT(base->widget);
     g_object_set_data(ref, "panel", panel);
 
+    pitem = G_PANEL_ITEM(panel);
+
+    pitem->personality = PIP_SINGLETON;
+
     /* Partie signets */
 
     store = gtk_tree_store_new(BMC_COUNT, G_TYPE_OBJECT,
diff --git a/src/gui/panels/glance.c b/src/gui/panels/glance.c
index 306281a..6373edd 100644
--- a/src/gui/panels/glance.c
+++ b/src/gui/panels/glance.c
@@ -173,16 +173,24 @@ static void g_glance_panel_class_init(GGlancePanelClass *klass)
 static void g_glance_panel_init(GGlancePanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
+    GPanelItem *pitem;                      /* Version parente du panneau  */
     GtkWidget *area;                        /* Surface de dessin réelle    */
 
     base = G_EDITOR_ITEM(panel);
 
     base->name = _("Glance");
 
+    base->widget = gtk_event_box_new();
+
+    pitem = G_PANEL_ITEM(panel);
+
+    pitem->personality = PIP_SINGLETON;
+
+    /* Support de dessin */
+
     area = gtk_drawing_area_new();
     gtk_widget_show(area);
 
-    base->widget = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(base->widget), area);
     gtk_widget_show(base->widget);
 
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index 74945c7..4d4be0c 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -156,6 +156,7 @@ static void g_history_panel_class_init(GHistoryPanelClass *klass)
 static void g_history_panel_init(GHistoryPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
+    GPanelItem *pitem;                      /* Version parente du panneau  */
     GObject *ref;                           /* Espace de référencement     */
     GtkWidget *scrollwnd;                   /* Support défilant            */
     GtkWidget *treeview;                    /* Affichage de la liste       */
@@ -173,6 +174,10 @@ static void g_history_panel_init(GHistoryPanel *panel)
 
     ref = G_OBJECT(panel);
 
+    pitem = G_PANEL_ITEM(panel);
+
+    pitem->personality = PIP_SINGLETON;
+
     /* Liste des éléments d'évolution */
 
     scrollwnd = gtk_scrolled_window_new(NULL, NULL);
@@ -305,7 +310,7 @@ GEditorItem *g_history_panel_new(GObject *ref)
     result = g_object_new(G_TYPE_HISTORY_PANEL, NULL);
 
     g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_HISTORY_ID,
-                          _("Change history"), G_EDITOR_ITEM(result)->widget, "eM");
+                          _("Change history"), G_EDITOR_ITEM(result)->widget, "eN");
 
     return result;
 
diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c
index ab815e4..7893666 100644
--- a/src/gui/panels/log.c
+++ b/src/gui/panels/log.c
@@ -120,12 +120,18 @@ G_DEFINE_TYPE(GLogPanel, g_log_panel, G_TYPE_PANEL_ITEM);
 static void g_log_panel_class_init(GLogPanelClass *klass)
 {
     GObjectClass *object;                   /* Autre version de la classe  */
+    GPanelItemClass *panel;                 /* Version parente de la classe*/
 
     object = G_OBJECT_CLASS(klass);
 
     object->dispose = (GObjectFinalizeFunc/* ! */)g_log_panel_dispose;
     object->finalize = (GObjectFinalizeFunc)g_log_panel_finalize;
 
+    panel = G_PANEL_ITEM_CLASS(klass);
+
+    panel->unique = true;
+    panel->bindings = "<Shift>F1";
+
 }
 
 
@@ -143,16 +149,27 @@ static void g_log_panel_class_init(GLogPanelClass *klass)
 
 static void g_log_panel_init(GLogPanel *panel)
 {
+    GEditorItem *base;                      /* Version basique d'instance  */
+    GPanelItem *pitem;                      /* Version parente du panneau  */
     GtkWidget *scrolled;                    /* Fenêtre avec défilements    */
     GtkTreeStore *store;                    /* Modèle de gestion           */
     GtkWidget *treeview;                    /* Affichage de la liste       */
     GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
     GtkTreeViewColumn *column;              /* Colonne de la liste         */
-    GEditorItem *base;                      /* Version basique d'instance  */
+
+    base = G_EDITOR_ITEM(panel);
 
     scrolled = gtk_scrolled_window_new(NULL, NULL);
     gtk_widget_show(scrolled);
 
+    base->widget = scrolled;
+
+    pitem = G_PANEL_ITEM(panel);
+
+    pitem->personality = PIP_SINGLETON;
+
+    /* Construction graphique */
+
     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);
 
@@ -184,9 +201,6 @@ static void g_log_panel_init(GLogPanel *panel)
 
     gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
 
-    base = G_EDITOR_ITEM(panel);
-    base->widget = scrolled;
-
 }
 
 
diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h
index b3a9f10..e902722 100644
--- a/src/gui/panels/panel-int.h
+++ b/src/gui/panels/panel-int.h
@@ -29,8 +29,7 @@
 #include "panel.h"
 
 
-#include <gtk/gtkbin.h>
-#include <gtk/gtkwidget.h>
+#include <gtk/gtk.h>
 
 
 #include "../editem-int.h"
@@ -45,10 +44,14 @@ struct _GPanelItem
 
     DL_LIST_ITEM(link);                     /* Maillon de liste chaînée    */
 
+    PanelItemPersonality personality;       /* Nature de l'élément         */
+
     const char *lname;                      /* Description longue          */
 
     const char *path;                       /* Chemin vers la place idéale */
 
+    bool docked;                            /* Panneau inscrusté ?         */
+
 };
 
 
@@ -57,18 +60,25 @@ typedef struct _panel_node
 {
     struct _panel_node *parent;             /* Noeud parent                */
 
-    char *path;                             /* Chemin du nom courant       */
-    size_t depth;                           /* Profondeur utilisée         */
+    union
+    {
+        GtkWidget *widget;                  /* Accès généraliste           */
+        GtkWidget *station;                 /* Station d'accueil simple    */
+        GtkWidget *paned;                   /* Station d'accueil composée  */
 
-    bool simple;                            /* Noeud sans division         */
+    };
 
     union
     {
-        GtkWidget *station;                 /* Station d'accueil simple    */
+        /* Version simple */
+        struct
+        {
+            char *path;                     /* Chemin du nom courant       */
+        };
 
+        /* Version composée */
         struct
         {
-            GtkWidget *paned;               /* Station d'accueil composée  */
             struct _panel_node *first;      /* Premier sous élément        */
             struct _panel_node *second;     /* Second sous élément         */
         };
@@ -78,7 +88,16 @@ typedef struct _panel_node
 } panel_node;
 
 
-#define GET_PANEL_NODE_WIDGET(node) (node->simple ? node->station : node->paned)
+
+#define IS_SIMPLE_NODE(nd)                              \
+    ({                                                  \
+        bool __result;                                  \
+        __result = GTK_IS_DOCK_STATION(nd->station);    \
+        assert(__result || GTK_IS_PANED(nd->paned));    \
+        __result;                                       \
+    })
+
+
 
 
 /* Elément réactif pour panneaux de l'éditeur (classe) */
@@ -86,6 +105,9 @@ struct _GPanelItemClass
 {
     GEditorItemClass parent;                /* A laisser en premier        */
 
+    bool unique;                            /* Panneau instanciable ?      */
+    const char *bindings;                   /* Raccourci clavier éventuel  */
+
     GtkBin *first;                          /* Elément racine              */
 
 };
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 01307cb..8af8672 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -25,6 +25,7 @@
 #include "panel.h"
 
 
+#include <assert.h>
 #include <ctype.h>
 #include <string.h>
 #include <sys/param.h>
@@ -38,6 +39,7 @@
 #include "regedit.h"
 #include "strings.h"
 #include "symbols.h"
+#include "../../common/extstr.h"
 #include "../../gtkext/easygtk.h"
 #include "../../gtkext/gtkdockable-int.h"
 #include "../../gtkext/gtkdockstation.h"
@@ -80,7 +82,7 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *);
 
 
 /* Crée un nouveau noeud pour un panneau particulier. */
-static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t);
+//static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t);
 
 /* Prépare une nouvelle sous-division pour deux panneaux. */
 static void switch_panel_node_into_paned(panel_node *, bool, bool);
@@ -88,41 +90,34 @@ static void switch_panel_node_into_paned(panel_node *, bool, bool);
 /* Met en place un nouveau noeud dans une division. */
 static void attach_panel_node_to_paned(panel_node *, panel_node *, bool);
 
-/* Valorise la correspondance entre un noeud et un chemin. */
-static int compute_panel_node_matching_score(const panel_node *, const char *);
 
-/* Calcule la longueur du plus court chemin vers un 'M'. */
-static size_t _compute_panel_node_main_level(const panel_node *);
 
-/* Recherche le noeud constituant la branche principale. */
-static panel_node *find_main_panel_node_branch(panel_node *, panel_node *);
 
-/* Place au bon endroit un panneau donné. */
-static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t);
+/* Crée un nouveau noeud pour un panneau particulier. */
+static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *);
 
-/* Met à jour l'affichage suite à un changement hiérarchique. */
-static void rebuild_panels_interface(const panel_node *);
 
 
 
-/* ---------------------- REAJUSTEMENT AUTOMATIQUE DE L'ESPACE ---------------------- */
+/* Obtient la désignation d'un élément hiérarchie des noeuds. */
+static char *get_panel_node_path(const panel_node *);
 
+/* Détermine la plus grande longueur commune entre éléments. */
+static size_t compute_path_common_length(const panel_node *, const char *);
 
-/* Part réservée aux parties principales (en %) */
-#define MAIN_PART_PERCENT 70
+/* Détermine la plus grande profondeur d'un noeud de panneaux. */
+static unsigned int compute_deepest_depth(const panel_node *);
 
-/* Part minimale des petits composants (en %) */
-#define MIN_PART_PERCENT 20
+/* Place au bon endroit un panneau donné. */
+static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t);
 
+/* Tente de mettre la main sur une station d'accueil. */
+static panel_node *find_node_for_station(panel_node *, GtkWidget *);
 
-/* Met à jour l'affichage suite à un changement hiérarchique. */
-static void auto_resize_panels(GtkWidget *, GdkRectangle *, gpointer);
+/* Efface de l'organisation un noeud donné en place. */
+static void delete_panel_node(panel_node *);
 
-/* S'enquiert de la taille idéale pour un noeud. */
-static void get_panel_node_size_request(const panel_node *, GtkRequisition *);
 
-/* Impose une taille accordée à un noeud. */
-static void set_panel_node_size_request(const panel_node *, const GtkRequisition *);
 
 
 
@@ -167,6 +162,8 @@ static void g_panel_item_init(GPanelItem *item)
 {
     DL_LIST_ITEM_INIT(&item->link);
 
+    item->personality = PIP_INVALID;
+
 }
 
 
@@ -239,7 +236,8 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : ref    = espace de référencement global.                     *
+*  Paramètres  : personality = nature du panneau à mettre en place.           *
+*                ref    = espace de référencement global.                     *
 *                name   = nom associé à l'élément.                            *
 *                lname  = description longue du panneau.                      *
 *                widget = composant à présenter à l'affichage.                *
@@ -253,12 +251,15 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con
 *                                                                             *
 ******************************************************************************/
 
-GEditorItem *g_panel_item_new(GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)
+GEditorItem *g_panel_item_new(PanelItemPersonality personality, GObject *ref, const char *name, const char *lname, GtkWidget *widget, const char *path)
 {
     GPanelItem *result;                     /* Structure à retourner       */
 
     result = g_object_new(G_TYPE_PANEL_ITEM, NULL);
 
+    assert(personality > PIP_INVALID && personality < PIP_COUNT);
+    result->personality = personality;
+
     g_panel_item_init_ext(result, ref, name, lname, widget, path);
 
     return G_EDITOR_ITEM(result);
@@ -325,6 +326,44 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : item = instance GTK à consulter.                             *
+*                                                                             *
+*  Description : Fournit une indication sur la personnalité du panneau.       *
+*                                                                             *
+*  Retour      : Identifiant lié à la nature du panneau.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *item)
+{
+    return item->personality;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance GTK dont l'interface est à consulter.        *
+*                                                                             *
+*  Description : Indique la définition d'un éventuel raccourci clavier.       *
+*                                                                             *
+*  Retour      : Description d'un raccourci ou NULL si aucun de défini.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *gtk_panel_item_get_key_bindings(const GPanelItem *item)
+{
+    return G_PANEL_ITEM_GET_CLASS(item)->bindings;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : name = désignation courte servant de clef.                   *
 *                                                                             *
 *  Description : Recherche un panneau à partir de son nom court.              *
@@ -364,16 +403,95 @@ GPanelItem *g_panel_item_get(const char *name)
 *                                                                             *
 ******************************************************************************/
 
+static void dump_tree(GtkWidget *root, unsigned int level)
+{
+    unsigned int i;
+    GList *list;
+    GList *iter;
+
+    if (strcmp(G_OBJECT_TYPE_NAME(G_OBJECT(root)), "GtkButton") == 0)
+        return;
+
+    for (i = 0; i < level; i++)
+        fprintf(stderr, "  ");
+
+    fprintf(stderr, "%s (%p)\n", G_OBJECT_TYPE_NAME(G_OBJECT(root)), root);
+
+    if (GTK_IS_CONTAINER(root))
+    {
+        list = gtk_container_get_children(GTK_CONTAINER(root));
+
+        for (iter = list; iter != NULL; iter = g_list_next(iter))
+            dump_tree(GTK_WIDGET(iter->data), level + 1);
+
+    }
+
+}
+
+
+void dump_node(panel_node *node, unsigned int level)
+{
+    unsigned i;
+
+    for (i = 0; i < level; i++)
+        fprintf(stderr, "  ");
+
+    fprintf(stderr, "%p %p -- widget %p -- '%s'\n", node->parent, node, node->station,
+            IS_SIMPLE_NODE(node) ? node->path : "-");
+
+    if (!IS_SIMPLE_NODE(node))
+    {
+        dump_node(node->first, level + 1);
+        dump_node(node->second, level + 1);
+    }
+
+
+}
+
+
+
 void g_panel_item_dock(GPanelItem *item)
 {
+    assert(!item->docked);
+
+    fprintf(stderr, "\n---------\n\n");
+
     /* Tout est à faire... */
     if (_nodes == NULL)
     {
-        _nodes = create_simple_panel_node_for_item(item, item->path, 0);
-        gtk_container_add(GTK_CONTAINER(_support), _nodes->station);
+        _nodes = create_simple_panel_node_for_item(item, item->path);
+        gtk_container_add(GTK_CONTAINER(_support), _nodes->widget);
     }
     else insert_item_as_panel_node(item, _nodes, item->path, 0);
 
+    item->docked = true;
+
+
+
+    dump_tree(_support, 0);
+    fprintf(stderr, "\n");
+    dump_node(_nodes, 0);
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = composant d'affichage à consulter.                    *
+*                                                                             *
+*  Description : Indique si le composant repose sur un support de l'éditeur.  *
+*                                                                             *
+*  Retour      : true si le composant est bien incrusté quelque part.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_panel_item_is_docked(const GPanelItem *item)
+{
+    return item->docked;
+
 }
 
 
@@ -391,12 +509,25 @@ void g_panel_item_dock(GPanelItem *item)
 
 void g_panel_item_undock(GPanelItem *item)
 {
-    GtkWidget *station;                     /* Base du remplacement        */
+    GtkWidget *station;                     /* Support courant             */
+    panel_node *node;                       /* Noeud à supprimer           */
 
-    station = gtk_widget_get_parent(G_EDITOR_ITEM(item)->widget);   /* NoteBook */
-    station = gtk_widget_get_parent(station);   /* DockStation */
+    assert(item->docked);
 
-    gtk_dock_panel_remove_widget(GTK_DOCK_STATION(station), G_EDITOR_ITEM(item)->widget);
+    gtk_dockable_decompose(GTK_DOCKABLE(item), &station);
+
+    gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
+
+    if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0)
+    {
+        node = find_node_for_station(_nodes, station);
+        assert(node != NULL);
+
+        delete_panel_node(node);
+
+    }
+
+    item->docked = false;
 
 }
 
@@ -427,7 +558,7 @@ GtkWidget *init_panels2(GCallback handler, gpointer data)
     result = gtk_event_box_new();
     gtk_widget_show(result);
 
-    g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
+    //g_signal_connect(result, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
 
     _support = result;
     _handler = handler;
@@ -454,10 +585,10 @@ void load_main_panels(GObject *ref)
 {
     GPanelItem *item;                       /* Panneau de base à charger   */
 
-    item = create_regedit_panel(ref);
+    item = create_log_panel(ref);
     g_panel_item_dock(item);
 
-    item = create_log_panel(ref);
+    item = create_regedit_panel(ref);
     g_panel_item_dock(item);
 
     item = create_symbols_panel(ref);
@@ -478,54 +609,49 @@ void load_main_panels(GObject *ref)
 }
 
 
-
-/* ---------------------------------------------------------------------------------- */
-/*                        MECANISMES DE PLACEMENT DES PANNEAUX                        */
-/* ---------------------------------------------------------------------------------- */
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : item  = composant à présenter à l'affichage.                 *
-*                path  = partie du chemin représentée ici.                    *
-*                depth = profondeur du chemin utilisé.                        *
+*  Paramètres  : handle = routine à appeler pour chaque panneau.              *
+*                data   = données fournies pour accompagner cet appel.        *
 *                                                                             *
-*  Description : Crée un nouveau noeud pour un panneau particulier.           *
+*  Description : Effectue le parcours de tous les panneaux chargés.           *
 *                                                                             *
-*  Retour      : Structure d'accueil mise en place.                           *
+*  Retour      : true si le parcours a été total, false sinon.                *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path, size_t depth)
+bool browse_all_item_panels(handle_panel_item_fc handle, void *data)
 {
-    panel_node *result;                     /* Structure à retourner       */
-    GtkWidget *station;                     /* Premier support concentré   */
-
-    result = (panel_node *)calloc(1, sizeof(panel_node));
-
-    result->path = strdup(path);
-    result->depth = depth;
+    bool result;                            /* Résultat à renvoyer         */
+    GPanelItem *iter;                       /* Boucle de parcours          */
 
-    result->simple = true;
+    result = true;
 
-    station = gtk_dock_station_new();
-    g_signal_connect(station, "switch-widget", _handler, _data);
-    gtk_widget_show(station);
+    panels_list_for_each(iter, _panels_list)
+    {
+        result = handle(iter, data);
 
-    result->station = station;
+        if (!result) break;
 
-    gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
+    }
 
     return result;
 
 }
 
 
+
+/* ---------------------------------------------------------------------------------- */
+/*                        MECANISMES DE PLACEMENT DES PANNEAUX                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : item  = composant à présenter à l'affichage.                 *
+*  Paramètres  : node  = noeud à diviser.                                     *
 *                horiz = indique le type d'orientation désiré.                *
 *                first = indication sur l'emplacement à utiliser.             *
 *                                                                             *
@@ -537,51 +663,98 @@ static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const cha
 *                                                                             *
 ******************************************************************************/
 
-static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool first)
+static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool first)
 {
-    panel_node *moved;                      /* Noeud descendu d'un étage   */
     GtkWidget *widget;                      /* Composant à traiter         */
+    panel_node *parent;                     /* Lien de parenté à conserver */
+    panel_node *moved;                      /* Noeud descendu d'un étage   */
+
+    /* Décroche graphiquement le support */
+
+    widget = node->widget;
+
+    g_object_ref(G_OBJECT(widget));
+    gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
 
     /* Descend l'élément actuel */
 
+    parent = node->parent;
+
     moved = (panel_node *)calloc(1, sizeof(panel_node));
 
-    memcpy(moved, current, sizeof(panel_node));
-    moved->parent = current;
+    memcpy(moved, node, sizeof(panel_node));
 
-    widget = GET_PANEL_NODE_WIDGET(current);
+    if (!IS_SIMPLE_NODE(moved))
+    {
+        moved->first->parent = moved;
+        moved->second->parent = moved;
+    }
 
-    g_object_ref(G_OBJECT(widget));
-    gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
+    /* Création du nouveau niveau intermédiaire */
 
-    if (first)
-        current->first = moved;
+    if (horiz)
+        node->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
     else
-        current->second = moved;
+        node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
 
-    /* Achève la transformation */
+    gtk_widget_show(node->paned);
 
-    current->path = NULL;
+    if (parent == NULL)
+        attach_panel_node_to_paned(parent, node, true);
+    else
+        attach_panel_node_to_paned(parent, node, parent->first == node);
 
-    current->simple = false;
 
-    current->station = NULL;
 
-    if (horiz)
-        current->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
-    else
-        current->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
 
-    gtk_widget_show(current->paned);
+    /* Premier ajustement */
 
-    /* Replace le composant d'origine */
+    void split_paned_support(GtkWidget *support, GdkRectangle *alloc, gpointer data)
+    {
+        GtkOrientation orientation;
+        gint position;
 
-    if (first)
-        gtk_paned_add1(GTK_PANED(current->paned), widget);
-    else
-        gtk_paned_add2(GTK_PANED(current->paned), widget);
+        orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(support));
+
+        if (orientation == GTK_ORIENTATION_HORIZONTAL)
+            position = alloc->width / 2;
+        else
+            position = alloc->height / 2;
+
+        /*
+        if (position < 50)
+        position *= 2;
+        */
+
+        gtk_paned_set_position(GTK_PANED(support), position);
+
+        fprintf(stderr, "widget size is currently %dx%d\n", alloc->width, alloc->height);
+
+
+        fprintf(stderr, "position = %d\n", position);
+
+        fprintf(stderr, "---\n");
+
+
+        g_signal_handlers_disconnect_by_func(support, G_CALLBACK(split_paned_support), NULL);
+
+    }
+
+    //g_signal_connect(current->paned, "size-allocate", G_CALLBACK(split_paned_support), NULL);
+
+    static int __counter = 0;
+
+
+
+    if (++__counter == 4)
+        gtk_paned_set_position(GTK_PANED(node->paned), 100);
+
+
+
+
+    /* Replace le composant d'origine */
 
-    g_object_unref(G_OBJECT(widget));
+    attach_panel_node_to_paned(node, moved, first);
 
 }
 
@@ -602,67 +775,143 @@ static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool f
 
 static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first)
 {
-    GtkWidget *widget;                      /* Composant à traiter         */
+    node->parent = parent;
+
+    /* On se trouve à la racine... */
 
-    /* Raccordement hiérarchique */
+    if (parent == NULL)
+        gtk_container_add(GTK_CONTAINER(_support), node->widget);
 
-    if (first)
-        parent->first = node;
     else
-        parent->second = node;
+    {
+        /* Raccordement hiérarchique */
 
-    node->parent = parent;
+        if (first)
+            parent->first = node;
+        else
+            parent->second = node;
 
-    /* Raccordement graphique */
+        /* Raccordement graphique */
 
-    widget = GET_PANEL_NODE_WIDGET(node);
+        assert(!IS_SIMPLE_NODE(parent));
 
-    if (first)
-        gtk_paned_add1(GTK_PANED(parent->paned), widget);
-    else
-        gtk_paned_add2(GTK_PANED(parent->paned), widget);
+        if (first)
+            gtk_paned_pack1(GTK_PANED(parent->paned), node->widget, TRUE, FALSE);
+        else
+            gtk_paned_pack2(GTK_PANED(parent->paned), node->widget, TRUE, FALSE);
+
+    }
 
 }
 
 
+
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : node   = noeud d'où lancer les recherches.                   *
-*                target = identifiant de la position visée.                   *
+*  Paramètres  : item = composant à présenter à l'affichage.                  *
+*                path = partie du chemin représentée ici.                     *
 *                                                                             *
-*  Description : Valorise la correspondance entre un noeud et un chemin.      *
+*  Description : Crée un nouveau noeud pour un panneau particulier.           *
 *                                                                             *
-*  Retour      : Bilan de l'évaluation.                                       *
+*  Retour      : Structure d'accueil mise en place.                           *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static int compute_panel_node_matching_score(const panel_node *node, const char *target)
+static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path)
 {
-    int result;                             /* Bilan à retourner           */
-    size_t len;                             /* Longueur de comparaison     */
-    size_t i;                               /* Boucle de parcours          */
+    panel_node *result;                     /* Structure à retourner       */
+    GtkWidget *station;                     /* Premier support concentré   */
 
-    if (node->simple)
-    {
-        result = 0;
+    /* Partie graphique */
 
-        len = strlen(node->path);
-        len = MIN(len, strlen(target));
+    station = gtk_dock_station_new();
+    g_signal_connect(station, "switch-widget", _handler, _data);
+    gtk_widget_show(station);
 
-        for (i = 0; i < len; i++)
-        {
-            if (node->path[i] != target[i]) break;
-            else result++;
-        }
+    gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item));
 
-    }
+    /* Partie invisible */
+
+    result = (panel_node *)calloc(1, sizeof(panel_node));
+
+    result->station = station;
+
+    result->path = strdup(path);
+
+    return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = noeud dont la désignation est à obtenir.              *
+*                                                                             *
+*  Description : Obtient la désignation d'un élément hiérarchie des noeuds.   *
+*                                                                             *
+*  Retour      : Chaîne construite à libérer de la mémoire après usage.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *get_panel_node_path(const panel_node *node)
+{
+    char *result;                           /* Valeur à retourner          */
+    char *extra;                            /* Complément à ajouter        */
+
+    if (IS_SIMPLE_NODE(node))
+        result = strdup(node->path);
 
     else
     {
-        result = compute_panel_node_matching_score(node->first, target);
-        result = MAX(result, compute_panel_node_matching_score(node->second, target));
+        result = get_panel_node_path(node->first);
+
+        extra = get_panel_node_path(node->second);
+        result = stradd(result, "-");
+        result = stradd(result, extra);
+        free(extra);
+
+        result = strprep(result, "(");
+        result = stradd(result, ")");
+
+
     }
 
     return result;
@@ -673,8 +922,9 @@ static int compute_panel_node_matching_score(const panel_node *node, const char
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : node   = noeud d'où lancer les recherches.                   *
+*                target = identifiant de la position visée.                   *
 *                                                                             *
-*  Description : Calcule la longueur du plus court chemin vers un 'M'.        *
+*  Description : Détermine la plus grande longueur commune entre éléments.    *
 *                                                                             *
 *  Retour      : Bilan de l'évaluation.                                       *
 *                                                                             *
@@ -682,23 +932,34 @@ static int compute_panel_node_matching_score(const panel_node *node, const char
 *                                                                             *
 ******************************************************************************/
 
-static size_t _compute_panel_node_main_level(const panel_node *node)
+static size_t compute_path_common_length(const panel_node *node, const char *target)
 {
-    size_t result;                          /* Plus petit chemin à renvoyer*/
+    size_t result;                          /* Taille à retourner          */
+    size_t len;                             /* Longueur de comparaison     */
+    size_t common1;                         /* Tron common avec le côté #1 */
+    size_t common2;                         /* Tron common avec le côté #2 */
 
-    if (node->simple)
+    if (IS_SIMPLE_NODE(node))
     {
-        result = strcspn(&node->path[node->depth], "M");
+        len = MIN(strlen(node->path), strlen(target));
 
-        if (node->path[node->depth + result] == '\0')
-            result = SIZE_MAX;
+        /**
+         * Il n'y a pas forcément de base commune entre deux branches,
+         * donc on parcourt les chemins depuis leur base respective.
+         */
+        for (result = 0; result < len; result++)
+            if (node->path[result] != target[result])
+                break;
 
     }
 
     else
     {
-        result = _compute_panel_node_main_level(node->first);
-        result = MIN(result, _compute_panel_node_main_level(node->second));
+        common1 = compute_path_common_length(node->first, target);
+        common2 = compute_path_common_length(node->second, target);
+
+        result = MAX(common1, common2);
+
     }
 
     return result;
@@ -708,31 +969,33 @@ static size_t _compute_panel_node_main_level(const panel_node *node)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : a = première branche à analyser.                             *
-*                b = seconde branche à analyser.                              *
+*  Paramètres  : node = noeud d'où lancer les mesures.                        *
 *                                                                             *
-*  Description : Recherche le noeud constituant la branche principale.        *
+*  Description : Détermine la plus grande profondeur d'un noeud de panneaux.  *
 *                                                                             *
-*  Retour      : Branche principale ou NULL si aucune n'est idéale.           *
+*  Retour      : Valeur strictement positive.                                 *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
+static unsigned int compute_deepest_depth(const panel_node *node)
 {
-    panel_node *result;                     /* Trouvaille à remonter       */
-    size_t main_a;                          /* Proximité du 'M' côté a     */
-    size_t main_b;                          /* Proximité du 'M' côté b     */
-
-    main_a = _compute_panel_node_main_level(a);
-    main_b = _compute_panel_node_main_level(b);
+    unsigned int result;                    /* Profondeur à renvoyer       */
+    unsigned int depth1;                    /* Profondeur du côté #1       */
+    unsigned int depth2;                    /* Profondeur du côté #2       */
 
-    if (main_a == SIZE_MAX && main_b == SIZE_MAX)
-        result = NULL;
+    if (IS_SIMPLE_NODE(node))
+        result = 1;
 
     else
-        result = (main_a < main_b ? a : b);
+    {
+        depth1 = compute_deepest_depth(node->first);
+        depth2 = compute_deepest_depth(node->second);
+
+        result = MAX(depth1, depth2);
+
+    }
 
     return result;
 
@@ -741,10 +1004,10 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : item  = composant à présenter à l'affichage.                 *
-*                node  = point d'insertion courant.                           *
-*                path  = partie du chemin représentée ici.                    *
-*                depth = profondeur du chemin utilisé.                        *
+*  Paramètres  : item     = composant à présenter à l'affichage.              *
+*                node     = point d'insertion courant.                        *
+*                path     = partie du chemin représentée ici.                 *
+*                consumed = profondeur du chemin utilisé.                     *
 *                                                                             *
 *  Description : Place au bon endroit un panneau donné.                       *
 *                                                                             *
@@ -754,58 +1017,47 @@ static panel_node *find_main_panel_node_branch(panel_node *a, panel_node *b)
 *                                                                             *
 ******************************************************************************/
 
-static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t depth)
+static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t consumed)
 {
     char div;                               /* Division demandée           */
     bool horiz;                             /* Traduction en composant     */
     bool first;                             /* Point d'insertion           */
     panel_node *new;                        /* Nouveau noeud créé          */
-    int score1;                             /* Score de la 1ère branche    */
-    int score2;                             /* Score de la 2nde branche    */
-    panel_node *support;                    /* Noeud d'accueil désigné     */
+    size_t common1;                         /* Tron common avec le côté #1 */
+    size_t common2;                         /* Tron common avec le côté #2 */
 
-    if (node->simple)
-    {
-        /* Si on est sur la bonne voie... */
-        if (compute_panel_node_matching_score(node, path) > 0)
-        {
-            /* Le parcours s'arrête ici ! */
-            if (strcmp(node->path, path) == 0)
-                gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item));
 
-            /* On ne peut aller plus loin, on doit diviser... */
-            else
-            {
-                div = toupper(path[depth]);
-                first = (div == 'E' || div == 'S');
-                horiz = (div == 'W' || div == 'E');
-
-                switch_panel_node_into_paned(node, horiz, first);
-
-                new = create_simple_panel_node_for_item(item, path, depth);
+    fprintf(stderr, "=== INSERTING '%s' (%zu)... -> '%s'\n", path, consumed,
+            IS_SIMPLE_NODE(node) ? node->path : "-");
 
-                attach_panel_node_to_paned(node, new, !first);
 
-                rebuild_panels_interface(node);
 
-            }
-
-        }
+    if (IS_SIMPLE_NODE(node))
+    {
+        /* Le parcours s'arrête ici ! */
+        if (strcmp(node->path, path) == 0)
+            gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item));
 
         /* On ne peut aller plus loin, on doit diviser... */
         else
         {
-            div = toupper(path[depth]);
-            first = (div == 'E' || div == 'S');
+            div = toupper(path[consumed]);
+            first = (div == 'W' || div == 'N');
             horiz = (div == 'W' || div == 'E');
 
-            switch_panel_node_into_paned(node, horiz, first);
+            fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz);
 
-            new = create_simple_panel_node_for_item(item, path, depth);
+            fprintf(stderr, "--- cutting %p\n", node->station);
 
-            attach_panel_node_to_paned(node, new, !first);
+            switch_panel_node_into_paned(node, horiz, !first);
 
-            rebuild_panels_interface(node);
+            new = create_simple_panel_node_for_item(item, path);
+
+            attach_panel_node_to_paned(node, new, first);
+
+
+            fprintf(stderr, "1# [%p] widget = %p --- split :: %p // %p\n",
+                    node, node->station, node->first, node->second);
 
         }
 
@@ -815,62 +1067,44 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
 
     else
     {
-        score1 = compute_panel_node_matching_score(node->first, path);
-        score2 = compute_panel_node_matching_score(node->second, path);
+        common1 = compute_path_common_length(node->first, path);
+        common2 = compute_path_common_length(node->second, path);
+
+
+        fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, get_panel_node_path(node->first));
+        fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, get_panel_node_path(node->second));
+
 
         /* Si une descente est possible... */
-        if (score1 > 0 || score2 > 0)
+        if (common1 > 0 || common2 > 0)
         {
-            if (node->first->simple || node->second->simple)
-                depth++;
-
-            if (score1 > score2)
-                insert_item_as_panel_node(item, node->first, path, depth);
+            if (common1 > common2)
+                insert_item_as_panel_node(item, node->first, path, common1);
 
             else
-                insert_item_as_panel_node(item, node->second, path, depth);
+                insert_item_as_panel_node(item, node->second, path, common2);
 
         }
 
         /* Sinon, on doit diviser qqch... */
         else
         {
-            /* Si l'élément doit passer en force */
-            if (isupper(path[depth]))
-            {
-                div = path[depth];
-                first = (div == 'E' || div == 'S');
-                horiz = (div == 'W' || div == 'E');
-
-                switch_panel_node_into_paned(node, horiz, first);
-
-                new = create_simple_panel_node_for_item(item, path, depth);
-
-                attach_panel_node_to_paned(node, new, !first);
-
-                rebuild_panels_interface(node);
-
-            }
-
-            else
-            {
-                support = find_main_panel_node_branch(node->first, node->second);
-                if (support == NULL)
-                    support = node->first;
+            div = toupper(path[consumed]);
+            first = (div == 'W' || div == 'N');
+            horiz = (div == 'W' || div == 'E');
 
-                div = toupper(path[depth]);
-                first = (div == 'E' || div == 'S');
-                horiz = (div == 'W' || div == 'E');
+            fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz);
 
-                switch_panel_node_into_paned(support, horiz, first);
+            switch_panel_node_into_paned(node, horiz, !first);
 
-                new = create_simple_panel_node_for_item(item, path, depth);
+            new = create_simple_panel_node_for_item(item, path);
 
-                attach_panel_node_to_paned(support, new, !first);
+            attach_panel_node_to_paned(node, new, first);
 
-                rebuild_panels_interface(support);
 
-            }
+                fprintf(stderr, "2# [%p] split :: %p-%p // %p-%p\n", node,
+                        node->first, node->first->widget,
+                        node->second, node->second->widget);
 
         }
 
@@ -881,55 +1115,42 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : current = point de départ de la réorganisation graphique.    *
+*  Paramètres  : node = point de départ des recherches locales.               *
 *                                                                             *
-*  Description : Met à jour l'affichage suite à un changement hiérarchique.   *
+*  Description : Tente de mettre la main sur une station d'accueil.           *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Eventuel noeud trouvé ou NULL.                               *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void rebuild_panels_interface(const panel_node *current)
+static panel_node *find_node_for_station(panel_node *node, GtkWidget *station)
 {
-    GtkWidget *widget;                      /* Composant à traiter         */
-    panel_node *parent;                     /* Raccourci confortable       */
-
-    widget = GET_PANEL_NODE_WIDGET(current);
+    panel_node *result;                     /* Bilan à remonter            */
 
-    /* On se trouve à la racine... */
-    if (current->parent == NULL)
-            gtk_container_add(GTK_CONTAINER(_support), widget);
+    if (IS_SIMPLE_NODE(node))
+        result = (node->station == station ? node : NULL);
 
-    /* Sinon, une sous-division ne peut venir que d'une division... */
     else
     {
-        /* BUG_ON(parent->simple) */
-
-        parent = current->parent;
+        result = find_node_for_station(node->first, station);
 
-        if (current == parent->first)
-            gtk_paned_add1(GTK_PANED(parent->paned), widget);
-        else
-            gtk_paned_add2(GTK_PANED(parent->paned), widget);
+        if (result == NULL)
+            result = find_node_for_station(node->second, station);
 
     }
 
-}
-
-
+    return result;
 
-/* ---------------------------------------------------------------------------------- */
-/*                        REAJUSTEMENT AUTOMATIQUE DE L'ESPACE                        */
-/* ---------------------------------------------------------------------------------- */
+}
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : current = point de départ de la réorganisation graphique.    *
+*  Paramètres  : node = noeud à supprimer de l'arbre des noeuds.              *
 *                                                                             *
-*  Description : Met à jour l'affichage suite à un changement hiérarchique.   *
+*  Description : Efface de l'organisation un noeud donné en place.            *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -937,77 +1158,91 @@ static void rebuild_panels_interface(const panel_node *current)
 *                                                                             *
 ******************************************************************************/
 
-static void auto_resize_panels(GtkWidget *support, GdkRectangle *alloc, gpointer data)
+static void delete_panel_node(panel_node *node)
 {
-    GtkRequisition available;               /* Taille disponible           */
+    panel_node *parent;                     /* Noeud parent à transformer  */
+    GtkWidget *widget;                      /* Composant à traiter         */
+    panel_node *grandparent;                /* Noeud supérieur au parent   */
+    panel_node *remaining;                  /* Noeud restant               */
 
-    //g_signal_handlers_disconnect_by_func(support, G_CALLBACK(auto_resize_panels), NULL);
+    assert(IS_SIMPLE_NODE(node));
 
-    available.width = alloc->width;
-    available.height = alloc->height;
+    parent = node->parent;
 
-    set_panel_node_size_request(_nodes, &available);
+    /* Destruction du noeud */
 
-    //g_signal_connect(support, "size-allocate", G_CALLBACK(auto_resize_panels), NULL);
+    widget = node->station;
+    gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
 
-}
+    free(node->path);
 
+    free(node);
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : node = noeud à consulter.                                    *
-*                req  = taille demandée par le noeud. [OUT]                   *
-*                                                                             *
-*  Description : S'enquiert de la taille idéale pour un noeud.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+    /* Suppression du niveau intermédiaire */
 
-static void get_panel_node_size_request(const panel_node *node, GtkRequisition *req)
-{
-    gint handle_size;                       /* Taille de la séparation     */
-    GtkRequisition tmp;                     /* Stockage temporaire         */
+    if (parent != NULL)
+    {
+        remaining = (node == parent->first ? parent->second : parent->first);
 
-    if (node->simple)
-        gtk_widget_get_preferred_size(node->station, NULL, req);
+        /* Décroche graphiquement le support */
 
-    else
-    {
-        gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL);
+        widget = remaining->widget;
 
-        if (HAS_H_ORIENTATION(node->paned))
-        {
-            req->width = handle_size;
-            req->height = 0;
-        }
-        else
+        g_object_ref(G_OBJECT(widget));
+        gtk_container_remove(GTK_CONTAINER(parent->paned), widget);
+
+        /* Supprime le composant graphique intermédiaire */
+
+        gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(parent->paned)), parent->paned);
+
+        /* Réinsère la partie restante */
+
+        grandparent = parent->parent;
+
+        memcpy(parent, remaining, sizeof(panel_node));
+
+        if (!IS_SIMPLE_NODE(parent))
         {
-            req->width = 0;
-            req->height = handle_size;
+            parent->first->parent = parent;
+            parent->second->parent = parent;
         }
 
-        get_panel_node_size_request(node->first, &tmp);
-        req->width += tmp.width;
-        req->height += tmp.height;
+        free(remaining);
 
-        get_panel_node_size_request(node->second, &tmp);
-        req->width += tmp.width;
-        req->height += tmp.height;
+        if (grandparent == NULL)
+            attach_panel_node_to_paned(grandparent, parent, true);
+        else
+            attach_panel_node_to_paned(grandparent, parent, grandparent->first == parent);
 
     }
 
 }
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+#if 1
+
+
+#include "../../core/params.h"
+
+
+
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : node  = noeud à consulter.                                   *
-*                space = taille disponible pour le noeud.                     *
+*  Paramètres  : current = point de départ de la réorganisation graphique.    *
 *                                                                             *
-*  Description : Impose une taille accordée à un noeud.                       *
+*  Description : Met à jour l'affichage suite à un changement hiérarchique.   *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1015,125 +1250,45 @@ static void get_panel_node_size_request(const panel_node *node, GtkRequisition *
 *                                                                             *
 ******************************************************************************/
 
-static void set_panel_node_size_request(const panel_node *node, const GtkRequisition *space)
+void save_panel_nodes(void)
 {
-    GtkRequisition first_req;               /* Taille demandée par n°1     */
-    GtkRequisition second_req;              /* Taille demandée par n°2     */
-    gint handle_size;                       /* Taille de la séparation     */
-    panel_node *main_node;                  /* Branche principale          */
-    gint position;                          /* Position de la séparation   */
-    bool can_lower;                         /* Diminution possible ?       */
-    bool can_upper;                         /* Augmentation possible ?     */
-    GtkAllocation allocation;               /* Taille allouée              */
-
-    /* Pour les cas simple, GTK gère très bien... */
-    if (node->simple) return;
-
-    get_panel_node_size_request(node->first, &first_req);
-    get_panel_node_size_request(node->second, &second_req);
 
-    gtk_widget_style_get(node->paned, "handle-size", &handle_size, NULL);
 
-    /**
-     * Définitions des bornes dans chacun des cas.
-     */
+    fprintf(stderr, "Passage avec %p\n", _nodes);
 
-    main_node = find_main_panel_node_branch(node->first, node->second);
-
-    /* Le premier noeud est le principal... */
-    if (node->first == main_node)
+    return;
+    void store_handle_position(panel_node *node, GGenConfig *config)
     {
-        if (HAS_H_ORIENTATION(node->paned))
-            position = (space->width * MAIN_PART_PERCENT) / 100;
-        else
-            position = (space->height * MAIN_PART_PERCENT) / 100;
 
-        can_lower = false;
-        can_upper = true;
+        size_t i;
 
-    }
+        for (i = 0; i < 0/*node->depth*/; i++)
+            fprintf(stderr, "  ");
 
-    /* Le second noeud est le principal... */
-    else if (node->second == main_node)
-    {
-        if (HAS_H_ORIENTATION(node->paned))
-            position = space->width - (space->width * MAIN_PART_PERCENT) / 100;
-        else
-            position = space->height - (space->height * MAIN_PART_PERCENT) / 100;
 
-        can_lower = true;
-        can_upper = false;
+        ///fprintf(stderr, "[%s] %s\n", node->path, node->simple ? "[+]" : ">>");
 
-    }
 
-    /* Les éléments sont quelconques... */
-    else
-    {
-        if (HAS_H_ORIENTATION(node->paned))
-            position = space->width / 2;
-        else
-            position = space->height / 2;
-
-        can_lower = true;
-        can_upper = true;
-
-    }
-
-    /**
-     * Calcul des valeurs applicables et mise en application.
-     */
-
-    /* Correctifs éventuels pour les petits composants */
-    if (node->first == main_node)
-    {
-        if (HAS_H_ORIENTATION(node->paned))
-            second_req.width = MAX(second_req.width, (space->width * MIN_PART_PERCENT) / 100);
-        else
-            second_req.height = MAX(second_req.height, (space->height * MIN_PART_PERCENT) / 100);
-    }
-    else if (node->second == main_node)
-    {
-        if (HAS_H_ORIENTATION(node->paned))
-            first_req.width = MAX(first_req.width, (space->width * MIN_PART_PERCENT) / 100);
-        else
-            first_req.height = MAX(first_req.height, (space->height * MIN_PART_PERCENT) / 100);
-    }
+        if (0/*!node->simple*/)
+        {
+            store_handle_position(node->first, config);
+            store_handle_position(node->second, config);
+        }
 
-    /* Une partie principale arrive en premier */
-    if (!can_lower && can_upper)
-    {
-        if (HAS_H_ORIENTATION(node->paned))
-            position = MAX(position, space->width - second_req.width - handle_size);
-        else
-            position = MAX(position, space->height - second_req.height - handle_size);
-    }
 
-    /* Une partie principale arrive en second */
-    else if (can_lower && !can_upper)
-    {
-        if (HAS_H_ORIENTATION(node->paned))
-            position = MIN(position, second_req.width + handle_size);
-        else
-            position = MIN(position, second_req.height + handle_size);
     }
 
-    /* Chacun pour soit ! */
-    else
-    {
 
+    //get_main_configuration()
 
-        /* TODO */;
 
+    store_handle_position(_nodes, NULL);
 
+    fflush(NULL);
 
-    }
 
-    gtk_paned_set_position(GTK_PANED(node->paned), position);
+}
 
-    gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->first), &allocation);
-    set_panel_node_size_request(node->first, ALLOC_2_REQ(&allocation));
+#endif
 
-    gtk_widget_get_allocation(GET_PANEL_NODE_WIDGET(node->second), &allocation);
-    set_panel_node_size_request(node->second, ALLOC_2_REQ(&allocation));
 
-}
diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h
index 0bf5cb5..baf5fe7 100644
--- a/src/gui/panels/panel.h
+++ b/src/gui/panels/panel.h
@@ -26,6 +26,9 @@
 #define _GUI_PANELS_PANEL_H
 
 
+#include <stdbool.h>
+
+
 #include "../editem.h"
 
 
@@ -45,11 +48,31 @@ typedef struct _GPanelItem GPanelItem;
 typedef struct _GPanelItemClass GPanelItemClass;
 
 
+/* Types de panneaux pour éditeur */
+typedef enum _PanelItemPersonality
+{
+    PIP_INVALID,                            /* Information non initialisée */
+
+    PIP_SINGLETON,                          /* Instance unique             */
+    PIP_BINARY_VIEW,                        /* Affichage d'un binaire      */
+    PIP_OTHER,                              /* Reste du monde              */
+
+    PIP_COUNT
+
+} PanelItemPersonality;
+
+
 /* Indique le type défini pour un élément destiné à un panneau. */
 GType g_panel_item_get_type(void);
 
 /* Crée un élément de panneau réactif. */
-GEditorItem *g_panel_item_new(GObject *, const char *, const char *, GtkWidget *, const char *);
+GEditorItem *g_panel_item_new(PanelItemPersonality, GObject *, const char *, const char *, GtkWidget *, const char *);
+
+/* Fournit une indication sur la personnalité du panneau. */
+PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *);
+
+/* Indique la définition d'un éventuel raccourci clavier. */
+const char *gtk_panel_item_get_key_bindings(const GPanelItem *);
 
 /* Recherche un panneau à partir de son nom court. */
 GPanelItem *g_panel_item_get(const char *);
@@ -57,11 +80,25 @@ GPanelItem *g_panel_item_get(const char *);
 /* Place un panneau dans l'ensemble affiché. */
 void g_panel_item_dock(GPanelItem *);
 
+/* Indique si le composant repose sur un support de l'éditeur. */
+bool g_panel_item_is_docked(const GPanelItem *);
+
 /* Supprime un panneau de l'ensemble affiché. */
 void g_panel_item_undock(GPanelItem *);
 
 
 
+
+
+
+
+void save_panel_nodes(void);
+
+
+
+
+
+
 /* ----------------------- PLACEMENTS DES DIFFERENTS PANNEAUX ----------------------- */
 
 
@@ -72,5 +109,12 @@ GtkWidget *init_panels2(GCallback, gpointer);
 void load_main_panels(GObject *);
 
 
+/* Réalise un traitement sur un panneau de l'éditeur. */
+typedef bool (* handle_panel_item_fc) (GPanelItem *, void *);
+
+/* Effectue le parcours de tous les panneaux chargés. */
+bool browse_all_item_panels(handle_panel_item_fc, void *);
+
+
 
 #endif  /* _GUI_PANELS_PANEL_H */
diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c
index a187a2d..cb4fe85 100644
--- a/src/gui/panels/regedit.c
+++ b/src/gui/panels/regedit.c
@@ -204,6 +204,7 @@ static void g_regedit_panel_class_init(GRegeditPanelClass *klass)
 static void g_regedit_panel_init(GRegeditPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
+    GPanelItem *pitem;                      /* Version parente du panneau  */
     GObject *ref;                           /* Espace de référencement     */
     GtkWidget *label;                       /* Etiquette à utiliser        */
     GtkWidget *search;                      /* Zone de recherche           */
@@ -224,6 +225,10 @@ static void g_regedit_panel_init(GRegeditPanel *panel)
     ref = G_OBJECT(base->widget);
     g_object_set_data(ref, "panel", panel);
 
+    pitem = G_PANEL_ITEM(panel);
+
+    pitem->personality = PIP_SINGLETON;
+
     /* Partie recherche */
 
     label = qck_create_label(NULL, NULL, _("Look for:"));
@@ -386,7 +391,7 @@ GEditorItem *g_regedit_panel_new(GObject *ref)
     result = g_object_new(G_TYPE_REGEDIT_PANEL, NULL);
 
     g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_REGEDIT_ID,
-                          _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "M");
+                          _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "N");
 
     reload_config_into_treeview(G_REGEDIT_PANEL(result), get_main_configuration());
 
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index abbf7ed..9759e71 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -179,6 +179,7 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)
 {
     GObjectClass *object;                   /* Autre version de la classe  */
     GEditorItemClass *editem;               /* Encore une autre vision...  */
+    GPanelItemClass *panel;                 /* Version parente de la classe*/
 
     object = G_OBJECT_CLASS(klass);
 
@@ -189,6 +190,11 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)
 
     editem->update_binary = (update_item_binary_fc)change_strings_panel_current_binary;
 
+    panel = G_PANEL_ITEM_CLASS(klass);
+
+    panel->unique = true;
+    panel->bindings = "<Shift>F12";
+
 }
 
 
@@ -207,6 +213,7 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)
 static void g_strings_panel_init(GStringsPanel *panel)
 {
     GEditorItem *base;                      /* Version basique d'instance  */
+    GPanelItem *pitem;                      /* Version parente du panneau  */
     GObject *ref;                           /* Espace de référencement     */
     GtkTreeStore *store;                    /* Modèle de gestion           */
     GtkWidget *treeview;                    /* Affichage de la liste       */
@@ -227,6 +234,10 @@ static void g_strings_panel_init(GStringsPanel *panel)
     ref = G_OBJECT(base->widget);
     g_object_set_data(ref, "panel", panel);
 
+    pitem = G_PANEL_ITEM(panel);
+
+    pitem->personality = PIP_SINGLETON;
+
     /* Partie chaînes */
 
     store = gtk_tree_store_new(STC_COUNT, G_TYPE_OBJECT,
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index 2a9d612..eebfc4c 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -181,6 +181,7 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)
     GObjectClass *object;                   /* Autre version de la classe  */
     GEditorItemClass *editem;               /* Encore une autre vision...  */
     gchar *filename;                        /* Chemin d'accès à utiliser   */
+    GPanelItemClass *panel;                 /* Version parente de la classe*/
 
     object = G_OBJECT_CLASS(klass);
 
@@ -212,6 +213,11 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)
 
     g_free(filename);
 
+    panel = G_PANEL_ITEM_CLASS(klass);
+
+    panel->unique = true;
+    panel->bindings = "<Shift>F3";
+
 }
 
 
@@ -230,6 +236,7 @@ static void g_symbols_panel_class_init(GSymbolsPanelClass *klass)
 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              */
@@ -250,6 +257,10 @@ static void g_symbols_panel_init(GSymbolsPanel *panel)
     ref = G_OBJECT(base->widget);
     g_object_set_data(ref, "panel", panel);
 
+    pitem = G_PANEL_ITEM(panel);
+
+    pitem->personality = PIP_SINGLETON;
+
     /* Barre d'outils supérieure */
 
     box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
@@ -435,7 +446,7 @@ GEditorItem *g_symbols_panel_new(GObject *ref)
     result = g_object_new(G_TYPE_SYMBOLS_PANEL, NULL);
 
     g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_SYMBOLS_ID,
-                          _("Binary symbols"), G_EDITOR_ITEM(result)->widget, "eM");
+                          _("Binary symbols"), G_EDITOR_ITEM(result)->widget, "eN");
 
     return result;
 
-- 
cgit v0.11.2-87-g4458