From dc8a2b19dbb32bfe49b1ff6640cc609238b392ca Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 9 Mar 2016 19:04:49 +0100
Subject: Stored and loaded panels attributes using the global configuration.

---
 ChangeLog                           |  41 ++++++++++
 plugins/pychrysa/gui/panels/panel.c |  21 ++++--
 plugins/python/welcome/panel.py     |   3 +-
 plugins/python/welcome/plugin.py    |   4 +-
 src/analysis/project.c              |  10 +--
 src/common/extstr.c                 |  27 +++++++
 src/common/extstr.h                 |   7 ++
 src/gui/core/Makefile.am            |   1 +
 src/gui/core/core.c                 |  97 ++++++++++++++++++++++++
 src/gui/core/core.h                 |  47 ++++++++++++
 src/gui/core/panels.c               |  27 ++++---
 src/gui/core/panels.h               |   3 +-
 src/gui/editor.c                    |   5 +-
 src/gui/panels/bookmarks.c          |   3 +-
 src/gui/panels/glance.c             |   4 +-
 src/gui/panels/history.c            |   4 +-
 src/gui/panels/log.c                |   3 +-
 src/gui/panels/panel-int.h          |   3 +-
 src/gui/panels/panel.c              | 147 ++++++++++++++++++++++++++++++++++--
 src/gui/panels/panel.h              |   9 ++-
 src/gui/panels/regedit.c            |   3 +-
 src/gui/panels/strings.c            |   4 +-
 src/gui/panels/symbols.c            |   3 +-
 src/main.c                          |  20 ++++-
 24 files changed, 451 insertions(+), 45 deletions(-)
 create mode 100644 src/gui/core/core.c
 create mode 100644 src/gui/core/core.h

diff --git a/ChangeLog b/ChangeLog
index 84f6ffc..8fed981 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,46 @@
 16-03-09  Cyrille Bagard <nocbos@gmail.com>
 
+	* plugins/pychrysa/gui/panels/panel.c:
+	* plugins/python/welcome/panel.py:
+	* plugins/python/welcome/plugin.py:
+	* src/analysis/project.c:
+	Update code.
+
+	* src/common/extstr.c:
+	* src/common/extstr.h:
+	Convert strings to lower or upper cases.
+
+	* src/gui/core/Makefile.am:
+	Add the new 'core.[ch]' files to libguicore_la_SOURCES.
+
+	* src/gui/core/core.c:
+	* src/gui/core/core.h:
+	New entries: load gui components for the editor at startup.
+
+	* src/gui/core/panels.c:
+	* src/gui/core/panels.h:
+	* src/gui/editor.c:
+	* 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:
+	Store and load panels attributes using the global configuration.
+
+	* src/gui/panels/regedit.c:
+	* src/gui/panels/strings.c:
+	* src/gui/panels/symbols.c:
+	Update code.
+
+	* src/main.c:
+	Complete the loading of panels for the editor.
+
+16-03-09  Cyrille Bagard <nocbos@gmail.com>
+
 	* configure.ac:
 	Add the new Makefile from the 'src/gui/core' directory.
 
diff --git a/plugins/pychrysa/gui/panels/panel.c b/plugins/pychrysa/gui/panels/panel.c
index 1246717..bfdfb5f 100644
--- a/plugins/pychrysa/gui/panels/panel.c
+++ b/plugins/pychrysa/gui/panels/panel.c
@@ -28,6 +28,7 @@
 #include <pygobject.h>
 
 
+#include <core/params.h>
 #include <gui/core/panels.h>
 #include <gui/panels/panel.h>
 
@@ -69,18 +70,29 @@ static int py_panel_item_init(PyObject *self, PyObject *args, PyObject *kwds)
     const char *name;                       /* Désignation humaine         */
     const char *lname;                      /* Nom version longue          */
     PyGObject *widget;                      /* Composant visuel du panneau */
+    int startup;                            /* Recommandation au démarrage */
     const char *path;                       /* Placement à l'affichage     */
     int ret;                                /* Bilan de lecture des args.  */
     GPanelItem *item;                       /* Elément de l'éditeur        */
 
-    ret = PyArg_ParseTuple(args, "kssOs", &personality, &name, &lname, &widget, &path);
+    ret = PyArg_ParseTuple(args, "kssOps", &personality, &name, &lname, &widget, &startup, &path);
     if (!ret) return -1;
 
     item = g_panel_item_new(personality, name, lname,
-                            GTK_WIDGET(pygobject_get(widget)), path);
+                            GTK_WIDGET(pygobject_get(widget)), startup, path);
 
     /* FIXME ? Est-ce à l'utilisateur de s'enregistrer ? */
-    register_panel_item(item, get_internal_ref());
+    register_panel_item(item, get_internal_ref(), get_main_configuration());
+
+    /**
+     * Si Python ne voit plus la variable représentant le panneau utilisée,
+     * il va la supprimer, ce qui va supprimer le composant GTK.
+     *
+     * On sera donc en situation de Use-After-Free, dont les conséquences
+     * arrivent très vite.
+     */
+    g_object_ref(GTK_WIDGET(pygobject_get(widget)));
+    Py_INCREF(self);
 
     /* Enregistrement auprès de PyGObject */
 
@@ -112,8 +124,7 @@ static PyObject *py_panel_item_dock(PyObject *self, PyObject *args)
 
     item = G_PANEL_ITEM(pygobject_get(self));
 
-    /* FIXME : les panneaux sont incrustés d'office ! */
-    //g_panel_item_dock(item);
+    g_panel_item_dock(item);
 
     Py_RETURN_NONE;
 
diff --git a/plugins/python/welcome/panel.py b/plugins/python/welcome/panel.py
index 7b46c57..a577c8c 100644
--- a/plugins/python/welcome/panel.py
+++ b/plugins/python/welcome/panel.py
@@ -19,7 +19,8 @@ class WelcomePanel(PanelItem):
 
         content = self._build_panel_content()
 
-        super(WelcomePanel, self).__init__(PanelItem.PIP_SINGLETON, 'Welcome', 'First commands', content, 'N')
+        super(WelcomePanel, self).__init__(PanelItem.PIP_SINGLETON, 'Welcome', 'First commands', \
+                                           content, False, 'N')
 
 
     def _build_panel_content(self):
diff --git a/plugins/python/welcome/plugin.py b/plugins/python/welcome/plugin.py
index 8a9f9a2..a26c93b 100644
--- a/plugins/python/welcome/plugin.py
+++ b/plugins/python/welcome/plugin.py
@@ -30,7 +30,7 @@ class WelcomePlugin(PluginModule):
 
         self._panel = WelcomePanel()
 
-        self._panel.dock()
-        self._panel.register()
+        #self._panel.dock()
+        #self._panel.register()
 
         return True
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 08df9d8..96d7e40 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -595,8 +595,7 @@ void g_study_project_add_loaded_binary(GLoadedBinary *binary, GStudyProject *pro
     g_signal_connect(project->binaries[index]->views[BVW_BLOCK], "size-allocate",
                      G_CALLBACK(scroll_for_the_first_time), binary);
 
-    /* FIXME : les panneaux sont incrustés d'office ! */
-    //g_panel_item_dock(project->binaries[index]->item);
+    g_panel_item_dock(project->binaries[index]->item);
 
 }
 
@@ -668,8 +667,8 @@ 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(PIP_BINARY_VIEW, name, lname, scroll, "N");
-    register_panel_item(loaded->item, project->ref);
+    loaded->item = g_panel_item_new(PIP_BINARY_VIEW, name, lname, scroll, true, "N");
+    register_panel_item(loaded->item, project->ref, get_main_configuration());
 
     /* Enregistrement dans le projet */
 
@@ -784,8 +783,7 @@ void g_study_project_display(const GStudyProject *project)
     size_t i;                               /* Boucle de parcours          */
 
     for (i = 0; i < project->binaries_count; i++)
-        /* FIXME : les panneaux sont incrustés d'office ! */
-        ;//g_panel_item_dock(project->binaries[i]->item);
+        g_panel_item_dock(project->binaries[i]->item);
 
 }
 
diff --git a/src/common/extstr.c b/src/common/extstr.c
index 9986ec1..ed5b971 100644
--- a/src/common/extstr.c
+++ b/src/common/extstr.c
@@ -220,6 +220,33 @@ char *strrpl(char *haystack, const char *needle1, const char *needle2)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : str = chaîne de caractères à manipuler. [OUT]                *
+*                                                                             *
+*  Description : Bascule toute une chaîne de caractères en (min|maj)uscules.  *
+*                                                                             *
+*  Retour      : Pointeur sur la chaîne fournie.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *_strxxx(char *str, int (* fn) (int))
+{
+    size_t max;                             /* Empleur du parcours         */
+    size_t i;                               /* Boucle de parcours          */
+
+    max = strlen(str);
+
+    for (i = 0; i < max; i++)
+        str[i] = fn(str[i]);
+
+    return str;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : str   = chaîne de caractères à traiter.                      *
 *                delim = séparateur entre les mots.                           *
 *                count = nombre de mots trouvés. [OUT]                        *
diff --git a/src/common/extstr.h b/src/common/extstr.h
index 6542d2f..e1d784d 100644
--- a/src/common/extstr.h
+++ b/src/common/extstr.h
@@ -25,6 +25,7 @@
 #define _COMMON_EXTSTR_H
 
 
+#include <ctype.h>
 #include <sys/types.h>
 
 
@@ -44,6 +45,12 @@ int strrcmp(const char *, const char *);
 /* Remplace des éléments d'une chaîne par d'autres. */
 char *strrpl(char *, const char *, const char *);
 
+/* Bascule toute une chaîne de caractères en (min|maj)uscules. */
+char *_strxxx(char *, int (* fn) (int));
+
+#define strlower(str) _strxxx(str, tolower)
+#define strupper(str) _strxxx(str, toupper)
+
 /* Extrait une liste de mots d'une chaîne. */
 char **strtoka(const char *, const char *, size_t *);
 
diff --git a/src/gui/core/Makefile.am b/src/gui/core/Makefile.am
index 948bd24..2000f58 100755
--- a/src/gui/core/Makefile.am
+++ b/src/gui/core/Makefile.am
@@ -2,6 +2,7 @@
 noinst_LTLIBRARIES = libguicore.la
 
 libguicore_la_SOURCES =					\
+	core.h core.c						\
 	panels.h panels.c
 
 libguicore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS)
diff --git a/src/gui/core/core.c b/src/gui/core/core.c
new file mode 100644
index 0000000..16e5cc8
--- /dev/null
+++ b/src/gui/core/core.c
@@ -0,0 +1,97 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - chargement et le déchargement du tronc commun pour l'éditeur graphique
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "core.h"
+
+
+#include "panels.h"
+
+
+#include "../../core/params.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ref = espace de référencement global.                        *
+*                                                                             *
+*  Description : Charge les éléments graphiques de l'éditeur.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_all_gui_components(GObject *ref)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+    load_main_panels(ref);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : config = configuration globale à utiliser.                   *
+*                                                                             *
+*  Description : Finalise le chargement des éléments graphiques de l'éditeur. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool complete_loading_of_all_gui_components(GGenConfig *config)
+{
+    bool result;                            /* Bilan à faire remonter      */
+
+    result = browse_all_item_panels((handle_panel_item_fc)gtk_panel_item_apply_configuration, config);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Décharge les éléments graphiques de l'éditeur.               *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void unload_all_gui_components(void)
+{
+
+}
diff --git a/src/gui/core/core.h b/src/gui/core/core.h
new file mode 100644
index 0000000..f5ab761
--- /dev/null
+++ b/src/gui/core/core.h
@@ -0,0 +1,47 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour le chargement et le déchargement du tronc commun pour l'éditeur graphique
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  OpenIDA is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  OpenIDA is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GUI_CORE_CORE_H
+#define _GUI_CORE_CORE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "../../glibext/configuration.h"
+
+
+
+/* Charge les éléments graphiques de l'éditeur. */
+bool load_all_gui_components(GObject *);
+
+/* Finalise le chargement des éléments graphiques de l'éditeur. */
+bool complete_loading_of_all_gui_components(GGenConfig *);
+
+/* Décharge les éléments graphiques de l'éditeur. */
+void unload_all_gui_components(void);
+
+
+
+#endif  /* _GUI_CORE_CORE_H */
diff --git a/src/gui/core/panels.c b/src/gui/core/panels.c
index 6b77e92..d8565f4 100644
--- a/src/gui/core/panels.c
+++ b/src/gui/core/panels.c
@@ -33,6 +33,7 @@
 #include "../panels/regedit.h"
 #include "../panels/strings.h"
 #include "../panels/symbols.h"
+#include "../../core/params.h"
 #include "../../gtkext/gtkdockable.h"
 
 
@@ -56,36 +57,40 @@ static GPanelItem *_panels_list = NULL;
 
 void load_main_panels(GObject *ref)
 {
+    GGenConfig *config;                     /* Configuration globale       */
     GPanelItem *item;                       /* Panneau de base à charger   */
 
+    config = get_main_configuration();
+
     item = g_log_panel_new();
-    register_panel_item(item, ref);
+    register_panel_item(item, ref, config);
 
     item = g_regedit_panel_new();
-    register_panel_item(item, ref);
+    register_panel_item(item, ref, config);
 
     item = g_symbols_panel_new();
-    register_panel_item(item, ref);
+    register_panel_item(item, ref, config);
 
     item = g_history_panel_new();
-    register_panel_item(item, ref);
+    register_panel_item(item, ref, config);
 
     item = g_strings_panel_new();
-    register_panel_item(item, ref);
+    register_panel_item(item, ref, config);
 
     item = g_glance_panel_new();
-    register_panel_item(item, ref);
+    register_panel_item(item, ref, config);
 
     item = g_bookmarks_panel_new();
-    register_panel_item(item, ref);
+    register_panel_item(item, ref, config);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : item = composant à présenter à l'affichage.                  *
-*                ref  = espace de référencement global.                       *
+*  Paramètres  : item   = composant à présenter à l'affichage.                *
+*                ref    = espace de référencement global.                     *
+*                config = configuration à compléter.                          *
 *                                                                             *
 *  Description : Enregistre un panneau comme partie intégrante de l'éditeur.  *
 *                                                                             *
@@ -95,7 +100,7 @@ void load_main_panels(GObject *ref)
 *                                                                             *
 ******************************************************************************/
 
-void register_panel_item(GPanelItem *item, GObject *ref)
+void register_panel_item(GPanelItem *item, GObject *ref, GGenConfig *config)
 {
     GEditorItem *parent;                    /* Autre version de l'élément  */
 
@@ -116,7 +121,7 @@ void register_panel_item(GPanelItem *item, GObject *ref)
 
     gtk_dockable_setup_dnd(GTK_DOCKABLE(item));
 
-    g_panel_item_dock(item);
+    gtk_panel_item_setup_configuration(item, config);
 
 }
 
diff --git a/src/gui/core/panels.h b/src/gui/core/panels.h
index 1a8f9d8..07ce133 100644
--- a/src/gui/core/panels.h
+++ b/src/gui/core/panels.h
@@ -30,6 +30,7 @@
 
 
 #include "../panels/panel.h"
+#include "../../glibext/configuration.h"
 
 
 
@@ -37,7 +38,7 @@
 void load_main_panels(GObject *);
 
 /* Enregistre un panneau comme partie intégrante de l'éditeur. */
-void register_panel_item(GPanelItem *, GObject *);
+void register_panel_item(GPanelItem *, GObject *, GGenConfig *);
 
 /* Réalise un traitement sur un panneau de l'éditeur. */
 typedef bool (* handle_panel_item_fc) (GPanelItem *, void *);
diff --git a/src/gui/editor.c b/src/gui/editor.c
index bcbdfe1..fdf253f 100644
--- a/src/gui/editor.c
+++ b/src/gui/editor.c
@@ -34,6 +34,7 @@
 
 #include "status.h"
 #include "menus/menubar.h"
+#include "core/core.h"
 #include "panels/panel.h"
 #include "tb/portions.h"
 #include "tb/source.h"
@@ -305,7 +306,7 @@ GtkWidget *create_editor(void)
         //_support = init_panels2(G_CALLBACK(on_dock_item_switch), ref);
         gtk_box_pack_start(GTK_BOX(vbox1), _support, TRUE, TRUE, 0);
 
-        load_main_panels(ref);
+        /* ... = */load_all_gui_components(ref);
 
 
     } while(0);
@@ -324,7 +325,7 @@ GtkWidget *create_editor(void)
 
     /* Autre */
 
-    prepare_drag_and_drop_window();
+    /* ... = */prepare_drag_and_drop_window();
 
 
 
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index 87789b6..222176a 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -255,7 +255,8 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel)
 
     pitem->personality = PIP_SINGLETON;
     pitem->lname = _("Bookmarks");
-    pitem->path = "SE";
+    pitem->dock_at_startup = false;
+    pitem->path = strdup("SE");
 
     /* Représentation graphique */
 
diff --git a/src/gui/panels/glance.c b/src/gui/panels/glance.c
index 1dab8b4..c473116 100644
--- a/src/gui/panels/glance.c
+++ b/src/gui/panels/glance.c
@@ -25,6 +25,7 @@
 #include "glance.h"
 
 
+#include <string.h>
 #include <gtk/gtk.h>
 
 
@@ -186,7 +187,8 @@ static void g_glance_panel_init(GGlancePanel *panel)
 
     pitem->personality = PIP_SINGLETON;
     pitem->lname = _("Glance");
-    pitem->path = "es";
+    pitem->dock_at_startup = true;
+    pitem->path = strdup("es");
 
     /* Support de dessin */
 
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index 526a775..15574be 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -25,6 +25,7 @@
 #include "history.h"
 
 
+#include <string.h>
 #include <cairo-gobject.h>
 
 
@@ -176,7 +177,8 @@ static void g_history_panel_init(GHistoryPanel *panel)
 
     pitem->personality = PIP_SINGLETON;
     pitem->lname = _("Change history");
-    pitem->path = "eN";
+    pitem->dock_at_startup = true;
+    pitem->path = strdup("eN");
 
     /* Représentation graphique */
 
diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c
index 1b8c6bc..da35c8f 100644
--- a/src/gui/panels/log.c
+++ b/src/gui/panels/log.c
@@ -168,7 +168,8 @@ static void g_log_panel_init(GLogPanel *panel)
 
     pitem->personality = PIP_SINGLETON;
     pitem->lname = _("Misc information");
-    pitem->path = "S";
+    pitem->dock_at_startup = true;
+    pitem->path = strdup("S");
 
     /* Représentation graphique */
 
diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h
index 5e906f0..7e44275 100644
--- a/src/gui/panels/panel-int.h
+++ b/src/gui/panels/panel-int.h
@@ -48,7 +48,8 @@ struct _GPanelItem
 
     const char *lname;                      /* Description longue          */
 
-    const char *path;                       /* Chemin vers la place idéale */
+    bool dock_at_startup;                   /* Recommandation au démarrage */
+    char *path;                             /* Chemin vers la place idéale */
 
     bool docked;                            /* Panneau inscrusté ?         */
 
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 00a4eea..71fa155 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -26,9 +26,11 @@
 
 
 #include <assert.h>
+#include <stdio.h>
 
 
 #include "panel-int.h"
+#include "../../common/extstr.h"
 #include "../../gtkext/gtkdockable-int.h"
 
 
@@ -51,6 +53,9 @@ static const char *gtk_panel_item_get_desc(const GPanelItem *);
 /* Fournit le composant graphique intégrable dans un ensemble. */
 static GtkWidget *gtk_panel_item_get_widget(GPanelItem *);
 
+/* Construit la chaîne d'accès à un élément de configuration. */
+static char *gtk_panel_item_build_configuration_key(const GPanelItem *, const char *);
+
 
 
 /* Indique le type défini pour un élément destiné à un panneau. */
@@ -140,10 +145,11 @@ static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : personality = nature du panneau à mettre en place.           *
-*                name   = nom associé à l'élément.                            *
-*                lname  = description longue du panneau.                      *
-*                widget = composant à présenter à l'affichage.                *
-*                path   = chemin vers la place idéale pour le futur panneau.  *
+*                name    = nom associé à l'élément.                           *
+*                lname   = description longue du panneau.                     *
+*                widget  = composant à présenter à l'affichage.               *
+*                startup = chargement au démarrage ?                          *
+*                path    = chemin vers la place idéale pour le futur panneau. *
 *                                                                             *
 *  Description : Crée un élément de panneau réactif.                          *
 *                                                                             *
@@ -153,7 +159,7 @@ static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface)
 *                                                                             *
 ******************************************************************************/
 
-GPanelItem *g_panel_item_new(PanelItemPersonality personality, const char *name, const char *lname, GtkWidget *widget, const char *path)
+GPanelItem *g_panel_item_new(PanelItemPersonality personality, const char *name, const char *lname, GtkWidget *widget, bool startup, const char *path)
 {
     GPanelItem *result;                     /* Structure à retourner       */
     GEditorItem *parent;                    /* Autre version de l'élément  */
@@ -170,7 +176,8 @@ GPanelItem *g_panel_item_new(PanelItemPersonality personality, const char *name,
 
     result->lname = lname;
 
-    result->path = path;
+    result->dock_at_startup = startup;
+    result->path = strdup(path);
 
     return result;
 
@@ -236,6 +243,134 @@ static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : item   = instance GTK à consulter.                           *
+*                attrib = élément de configuration à inclure dans le résultat.*
+*                                                                             *
+*  Description : Construit la chaîne d'accès à un élément de configuration.   *
+*                                                                             *
+*  Retour      : Chaîne de caractères à libérer après usage.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *gtk_panel_item_build_configuration_key(const GPanelItem *item, const char *attrib)
+{
+    char *result;                           /* Construction à renvoyer     */
+    const char *name;                       /* Nom court du panneau        */
+
+    name = g_editor_item_get_name(G_EDITOR_ITEM(item));
+
+    asprintf(&result, "gui.panels.%s.%s", name, attrib);
+
+    result = strrpl(result, " ", "_");
+
+    result = strlower(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = instance GTK à consulter.                           *
+*                config = configuration à compléter.                          *
+*                                                                             *
+*  Description : Met en place les bases de la configuration du panneau.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool gtk_panel_item_setup_configuration(const GPanelItem *item, GGenConfig *config)
+{
+    bool result;                            /* Bilan à retourner           */
+    char *key;                              /* Clef d'accès à un paramètre */
+    GCfgParam *param;                       /* Paramètre chargé            */
+
+    result = true;
+
+    key = gtk_panel_item_build_configuration_key(item, "dock_at_startup");
+
+    param = g_generic_config_create_param(config, key, CPT_BOOLEAN, item->dock_at_startup);
+
+    if (param == NULL)
+    {
+        result = false;
+        goto gpisc_exit;
+    }
+
+    free(key);
+
+    key = gtk_panel_item_build_configuration_key(item, "path");
+
+    param = g_generic_config_create_param(config, key, CPT_STRING, item->path);
+    if (param == NULL)
+        result = false;
+
+ gpisc_exit:
+
+    free(key);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item   = instance GTK à consulter.                           *
+*                config = configuration à charger.                            *
+*                                                                             *
+*  Description : Charge un panneau sur les bases de la configuration fournie. *
+*                                                                             *
+*  Retour      : true, par conformité avec browse_all_item_panels().          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool gtk_panel_item_apply_configuration(GPanelItem *item, GGenConfig *config)
+{
+    char *key;                              /* Clef d'accès à un paramètre */
+    const char *new_path;                   /* Nouveau chemin de placement */
+    bool status;                            /* Statut de l'encapsulation   */
+
+    key = gtk_panel_item_build_configuration_key(item, "path");
+
+    if (g_generic_config_get_value(config, key, &new_path))
+    {
+        free(item->path);
+
+        item->path = strdup(new_path);
+
+    }
+
+    free(key);
+
+    key = gtk_panel_item_build_configuration_key(item, "dock_at_startup");
+
+    if (g_generic_config_get_value(config, key, &status))
+    {
+        item->dock_at_startup = status;
+
+        if (item->dock_at_startup)
+            g_signal_emit_by_name(item, "dock-request");
+
+    }
+
+    free(key);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : item = instance GTK à consulter.                             *
 *                                                                             *
 *  Description : Fournit une indication sur la personnalité du panneau.       *
diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h
index bb46c5a..cbe9030 100644
--- a/src/gui/panels/panel.h
+++ b/src/gui/panels/panel.h
@@ -30,6 +30,7 @@
 
 
 #include "../editem.h"
+#include "../../glibext/configuration.h"
 
 
 
@@ -66,7 +67,13 @@ typedef enum _PanelItemPersonality
 GType g_panel_item_get_type(void);
 
 /* Crée un élément de panneau réactif. */
-GPanelItem *g_panel_item_new(PanelItemPersonality, const char *, const char *, GtkWidget *, const char *);
+GPanelItem *g_panel_item_new(PanelItemPersonality, const char *, const char *, GtkWidget *, bool, const char *);
+
+/* Met en place les bases de la configuration du panneau. */
+bool gtk_panel_item_setup_configuration(const GPanelItem *, GGenConfig *);
+
+/* Charge un panneau sur les bases de la configuration fournie. */
+bool gtk_panel_item_apply_configuration(GPanelItem *, GGenConfig *);
 
 /* Fournit une indication sur la personnalité du panneau. */
 PanelItemPersonality gtk_panel_item_get_personality(const GPanelItem *);
diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c
index a62f824..5e224ec 100644
--- a/src/gui/panels/regedit.c
+++ b/src/gui/panels/regedit.c
@@ -225,7 +225,8 @@ static void g_regedit_panel_init(GRegeditPanel *panel)
 
     pitem->personality = PIP_SINGLETON;
     pitem->lname = _("Configuration parameters");
-    pitem->path = "N";
+    pitem->dock_at_startup = true;
+    pitem->path = strdup("N");
 
     /* Représentation graphique */
 
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 0c39b4b..ae436cf 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -25,6 +25,7 @@
 #include "strings.h"
 
 
+#include <string.h>
 #include <inttypes.h>
 
 
@@ -233,7 +234,8 @@ static void g_strings_panel_init(GStringsPanel *panel)
 
     pitem->personality = PIP_SINGLETON;
     pitem->lname = _("Strings");
-    pitem->path = "SE";
+    pitem->dock_at_startup = false;
+    pitem->path = strdup("N");
 
     /* Représentation graphique */
 
diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c
index 1b7453b..422c9b4 100644
--- a/src/gui/panels/symbols.c
+++ b/src/gui/panels/symbols.c
@@ -259,7 +259,8 @@ static void g_symbols_panel_init(GSymbolsPanel *panel)
 
     pitem->personality = PIP_SINGLETON;
     pitem->lname = _("Binary symbols");
-    pitem->path = "eN";
+    pitem->dock_at_startup = true;
+    pitem->path = strdup("eN");
 
     /* Représentation graphique */
 
diff --git a/src/main.c b/src/main.c
index 67feabc..74ba72f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -91,11 +91,16 @@ static void show_version(void)
 
 int main(int argc, char **argv)
 {
+    int result;                             /* Bilan de l'exécution        */
     GtkWidget *editor;                      /* Fenêtre graphique           */
     GDbServer *server;                      /* Enregistrements locaux      */
+    GGenConfig *config;                     /* Configuration globale       */
+    bool status;                            /* Bilan d'opérations          */
     const char *filename;                   /* Chemin du dernier projet    */
     GStudyProject *project;                 /* Nouveau projet courant      */
 
+    result = EXIT_FAILURE;
+
     if (argc > 1 && strcmp(argv[1], "--version") == 0)
     {
         show_version();
@@ -165,12 +170,17 @@ int main(int argc, char **argv)
 
     init_all_plugins(G_OBJECT(editor));
 
+    config = get_main_configuration();
+
+    status = complete_loading_of_all_gui_components(config);
+    if (!status) goto exit_complete_gui;
+
     server = g_db_server_new("localhost", 1337);
     g_db_server_start(server);
 
     /* Charge le dernier projet */
 
-    if (!g_generic_config_get_value(get_main_configuration(), MPK_LAST_PROJECT, &filename))
+    if (!g_generic_config_get_value(config, MPK_LAST_PROJECT, &filename))
         filename = NULL;
 
     if (filename == NULL) project = g_study_project_new(G_OBJECT(editor));
@@ -180,14 +190,20 @@ int main(int argc, char **argv)
 
     /* Exécution du programme */
 
+    result = EXIT_SUCCESS;
+
     gtk_main();
 
     g_db_server_stop(server);
 
+ exit_complete_gui:
+
     exit_all_plugins();
 
+    //gtk_widget_destroy(editor);
+
     unload_all_basic_components();
 
-    return EXIT_SUCCESS;
+    return result;
 
 }
-- 
cgit v0.11.2-87-g4458