From 2c28d59fb3671c0fdd1987784076d4968c58b651 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 27 Dec 2017 00:52:44 +0100
Subject: Created the GLoadedContent interface to load all kinds of content.

---
 ChangeLog                             |  53 ++++
 plugins/pychrysa/analysis/Makefile.am |   1 +
 plugins/pychrysa/analysis/content.c   |   4 +-
 plugins/pychrysa/analysis/content.h   |   2 +-
 plugins/pychrysa/analysis/loaded.c    | 146 ++++++++++
 plugins/pychrysa/analysis/loaded.h    |  42 +++
 plugins/pychrysa/analysis/module.c    |   3 +
 src/analysis/Makefile.am              |   2 +
 src/analysis/binary.c                 | 327 +++++++++++++++++-----
 src/analysis/binary.h                 |  35 +--
 src/analysis/loaded-int.h             |  79 ++++++
 src/analysis/loaded.c                 | 362 +++++++++++++++++++++++++
 src/analysis/loaded.h                 |  92 +++++++
 src/analysis/project.c                | 491 +++++++---------------------------
 src/analysis/project.h                |  34 +--
 src/glibext/gloadedpanel-int.h        |   9 +
 src/glibext/gloadedpanel.c            |  52 ++++
 src/glibext/gloadedpanel.h            |  21 +-
 src/gtkext/graph/cluster.c            |   7 +-
 src/gtkext/gtkblockdisplay.c          |  32 ++-
 src/gtkext/gtkblockdisplay.h          |   3 +
 src/gtkext/gtkbufferdisplay.c         |  10 +-
 src/gtkext/gtkdisplaypanel-int.h      |   4 +-
 src/gtkext/gtkdisplaypanel.c          | 175 ++++++------
 src/gtkext/gtkdisplaypanel.h          |   6 -
 src/gui/editor.c                      |  90 ++++++-
 src/gui/menus/project.c               |  41 +--
 src/gui/menus/view.c                  |  66 ++---
 28 files changed, 1518 insertions(+), 671 deletions(-)
 create mode 100644 plugins/pychrysa/analysis/loaded.c
 create mode 100644 plugins/pychrysa/analysis/loaded.h
 create mode 100644 src/analysis/loaded-int.h
 create mode 100644 src/analysis/loaded.c
 create mode 100644 src/analysis/loaded.h

diff --git a/ChangeLog b/ChangeLog
index 7b9a2ad..973d4ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+17-12-27  Cyrille Bagard <nocbos@gmail.com>
+
+	* plugins/pychrysa/analysis/Makefile.am:
+	Add the 'loaded.[ch]' files to libpychrysaanalysis_la_SOURCES.
+
+	* plugins/pychrysa/analysis/content.c:
+	* plugins/pychrysa/analysis/content.h:
+	Typo.
+
+	* plugins/pychrysa/analysis/loaded.c:
+	* plugins/pychrysa/analysis/loaded.h:
+	New entries: provide Python bindings for loaded contents.
+
+	* plugins/pychrysa/analysis/module.c:
+	Update code.
+
+	* src/analysis/Makefile.am:
+	Add the 'loaded*[ch]' files to libanalysis_la_SOURCES.
+
+	* src/analysis/binary.c:
+	* src/analysis/binary.h:
+	Update loaded binaries as loaded contents.
+
+	* src/analysis/loaded-int.h:
+	* src/analysis/loaded.c:
+	* src/analysis/loaded.h:
+	New entries: create the GLoadedContent interface to load all kinds of content.
+
+	* src/analysis/project.c:
+	* src/analysis/project.h:
+	Make projects only store loaded contents. Clean code.
+
+	* src/glibext/gloadedpanel-int.h:
+	* src/glibext/gloadedpanel.c:
+	* src/glibext/gloadedpanel.h:
+	Add setter and getter to deal with linked loaded contents.
+
+	* src/gtkext/graph/cluster.c:
+	* src/gtkext/gtkblockdisplay.c:
+	* src/gtkext/gtkblockdisplay.h:
+	* src/gtkext/gtkbufferdisplay.c:
+	* src/gtkext/gtkdisplaypanel-int.h:
+	* src/gtkext/gtkdisplaypanel.c:
+	* src/gtkext/gtkdisplaypanel.h:
+	Update code.
+
+	* src/gui/editor.c:
+	Track project changes here.
+
+	* src/gui/menus/project.c:
+	* src/gui/menus/view.c:
+	Update code.
+
 17-12-26  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/project.c:
diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am
index 31d37f6..c1639e7 100644
--- a/plugins/pychrysa/analysis/Makefile.am
+++ b/plugins/pychrysa/analysis/Makefile.am
@@ -5,6 +5,7 @@ libpychrysaanalysis_la_SOURCES =		\
 	binary.h binary.c					\
 	block.h block.c						\
 	content.h content.c					\
+	loaded.h loaded.c					\
 	module.h module.c					\
 	routine.h routine.c
 
diff --git a/plugins/pychrysa/analysis/content.c b/plugins/pychrysa/analysis/content.c
index 95f88f6..1f36eb8 100644
--- a/plugins/pychrysa/analysis/content.c
+++ b/plugins/pychrysa/analysis/content.c
@@ -416,7 +416,7 @@ PyTypeObject *get_python_binary_content_type(void)
 
         PyVarObject_HEAD_INIT(NULL, 0)
 
-        .tp_name        = "pychrysalide.analysis.contents.BinContent",
+        .tp_name        = "pychrysalide.analysis.BinContent",
         .tp_basicsize   = sizeof(PyObject),
 
         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
@@ -437,7 +437,7 @@ PyTypeObject *get_python_binary_content_type(void)
 *                                                                             *
 *  Paramètres  : module = module dont la définition est à compléter.          *
 *                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.glibext.BinContent'.   *
+*  Description : Prend en charge l'objet 'pychrysalide.analysis.BinContent'.  *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
diff --git a/plugins/pychrysa/analysis/content.h b/plugins/pychrysa/analysis/content.h
index 691d901..da1b9be 100644
--- a/plugins/pychrysa/analysis/content.h
+++ b/plugins/pychrysa/analysis/content.h
@@ -34,7 +34,7 @@
 /* Fournit un accès à une définition de type à diffuser. */
 PyTypeObject *get_python_binary_content_type(void);
 
-/* Prend en charge l'objet 'pychrysalide.glibext.BinContent'. */
+/* Prend en charge l'objet 'pychrysalide.analysis.BinContent'. */
 bool register_python_binary_content(PyObject *);
 
 
diff --git a/plugins/pychrysa/analysis/loaded.c b/plugins/pychrysa/analysis/loaded.c
new file mode 100644
index 0000000..b38025a
--- /dev/null
+++ b/plugins/pychrysa/analysis/loaded.c
@@ -0,0 +1,146 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loaded.c - prototypes pour l'équivalent Python du fichier "analysis/loaded.c"
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "loaded.h"
+
+
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <i18n.h>
+
+
+#include <analysis/loaded.h>
+
+
+
+/* Détermine le nombre de vues disponibles pour un contenu. */
+static PyObject *py_loaded_content_count_views(PyObject *, PyObject *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = contenu chargé à manipuler.                           *
+*                args = non utilisé ici.                                      *
+*                                                                             *
+*  Description : Détermine le nombre de vues disponibles pour un contenu.     *
+*                                                                             *
+*  Retour      : Quantité strictement positive.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_loaded_content_count_views(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GLoadedContent *content;                /* Version GLib du format      */
+    size_t count;                           /* Quantité à retourner        */
+
+    content = G_LOADED_CONTENT(pygobject_get(self));
+
+    count = g_loaded_content_count_views(content);
+
+    result = PyLong_FromUnsignedLongLong(count);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_loaded_content_type(void)
+{
+    static PyMethodDef py_loaded_content_methods[] = {
+        {
+            "count_views", py_loaded_content_count_views,
+            METH_NOARGS,
+            "count_views($self, /)\n--\n\nCompute the quantity of available views."
+        },
+        { NULL }
+    };
+
+    static PyGetSetDef py_loaded_content_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_loaded_content_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.LoadedContent",
+        .tp_basicsize   = sizeof(PyObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide loaded content",
+
+        .tp_methods     = py_loaded_content_methods,
+        .tp_getset      = py_loaded_content_getseters
+
+    };
+
+    return &py_loaded_content_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.....LoadedContent'.    *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_loaded_content(PyObject *module)
+{
+    PyTypeObject *py_loaded_content_type;   /* Type Python 'LoadedContent' */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_loaded_content_type = get_python_loaded_content_type();
+
+    dict = PyModule_GetDict(module);
+    pyg_register_interface(dict, "LoadedContent", G_TYPE_LOADED_CONTENT, py_loaded_content_type);
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/analysis/loaded.h b/plugins/pychrysa/analysis/loaded.h
new file mode 100644
index 0000000..3238202
--- /dev/null
+++ b/plugins/pychrysa/analysis/loaded.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loaded.h - prototypes pour l'équivalent Python du fichier "analysis/loaded.h"
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_LOADED_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_LOADED_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_loaded_content_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.LoadedContent'. */
+bool register_python_loaded_content(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_CONTENT_H */
diff --git a/plugins/pychrysa/analysis/module.c b/plugins/pychrysa/analysis/module.c
index 253fe76..f4a0f5b 100644
--- a/plugins/pychrysa/analysis/module.c
+++ b/plugins/pychrysa/analysis/module.c
@@ -31,6 +31,7 @@
 #include "binary.h"
 #include "block.h"
 #include "content.h"
+#include "loaded.h"
 #include "routine.h"
 #include "contents/module.h"
 #include "db/module.h"
@@ -84,6 +85,8 @@ bool add_analysis_module_to_python_module(PyObject *super)
 
     result = true;
 
+    result &= register_python_loaded_content(module);
+
     result &= register_python_loaded_binary(module);
     result &= register_python_instr_block(module);
     //result &= register_python_binary_content(module);
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am
index 9e84753..c5f8c82 100755
--- a/src/analysis/Makefile.am
+++ b/src/analysis/Makefile.am
@@ -7,6 +7,8 @@ libanalysis_la_SOURCES =				\
 	block.h block.c						\
 	content-int.h						\
 	content.h content.c					\
+	loaded-int.h						\
+	loaded.h loaded.c					\
 	loading.h loading.c					\
 	project.h project.c					\
 	roptions.h roptions.c				\
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 7b0e528..5b2caf0 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -35,6 +35,7 @@
 #include <i18n.h>
 
 
+#include "loaded-int.h"
 #include "routine.h"
 #include "db/client.h"
 //#include "decomp/decompiler.h"
@@ -47,7 +48,11 @@
 #include "../core/global.h"
 #include "../core/params.h"
 #include "../core/processors.h"
-#include "../glibext/chrysamarshal.h"
+//#include "../glibext/chrysamarshal.h"
+#include "../gtkext/easygtk.h"
+#include "../gtkext/gtkblockdisplay.h"
+#include "../gtkext/gtkdisplaypanel.h"
+#include "../gtkext/gtkgraphdisplay.h"
 #include "../gui/panels/log.h"
 
 
@@ -98,7 +103,6 @@ struct _GLoadedBinaryClass
     /* Signaux */
 
     void (* disassembly_done) (GLoadedBinary *);
-    void (* display_changed) (GLoadedBinary *, BinaryView, BufferLineColumn);
 
 };
 
@@ -109,6 +113,9 @@ static void g_loaded_binary_class_init(GLoadedBinaryClass *);
 /* Initialise une description de fichier binaire. */
 static void g_loaded_binary_init(GLoadedBinary *);
 
+/* Procède à l'initialisation de l'interface de contenu chargé. */
+static void g_loaded_binary_interface_init(GLoadedContentInterface *);
+
 /* Supprime toutes les références externes. */
 static void g_loaded_binary_dispose(GLoadedBinary *);
 
@@ -145,6 +152,28 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *);
 static void _g_loaded_binary_analyse(GLoadedBinary *, disassembly_ack_fc);
 
 
+/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */
+
+
+/* Fournit le désignation associée à l'élément chargé. */
+static const char *g_loaded_binary_describe(const GLoadedBinary *, bool);
+
+/* Détermine le nombre de vues disponibles pour un contenu. */
+static unsigned int g_loaded_binary_count_views(const GLoadedBinary *);
+
+/* Met en place la vue demandée pour un contenu binaire. */
+static GtkWidget *g_loaded_binary_build_view(GLoadedBinary *, unsigned int);
+
+/* Retrouve l'indice correspondant à la vue donnée d'un contenu. */
+static unsigned int g_loaded_binary_get_view_index(GLoadedBinary *, GtkWidget *);
+
+/* Fournit toutes les options d'affichage pour un contenu. */
+bool * const g_loaded_binary_get_all_display_options(const GLoadedBinary *, unsigned int);
+
+/* Définit une option d'affichage pour un contenu chargé. */
+static bool g_loaded_binary_set_display_option(GLoadedBinary *, unsigned int, unsigned int, bool);
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                          ENCADREMENTS D'UN BINAIRE CHARGE                          */
@@ -152,7 +181,8 @@ static void _g_loaded_binary_analyse(GLoadedBinary *, disassembly_ack_fc);
 
 
 /* Indique le type défini pour une description de fichier binaire. */
-G_DEFINE_TYPE(GLoadedBinary, g_loaded_binary, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_CODE(GLoadedBinary, g_loaded_binary, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE(G_TYPE_LOADED_CONTENT, g_loaded_binary_interface_init));
 
 
 /******************************************************************************
@@ -184,14 +214,6 @@ static void g_loaded_binary_class_init(GLoadedBinaryClass *klass)
                  g_cclosure_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
 
-    g_signal_new("display-changed",
-                 G_TYPE_LOADED_BINARY,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GLoadedBinaryClass, display_changed),
-                 NULL, NULL,
-                 g_cclosure_user_marshal_VOID__ENUM_ENUM,
-                 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-
 }
 
 
@@ -237,6 +259,32 @@ static void g_loaded_binary_init(GLoadedBinary *binary)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de contenu chargé. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_loaded_binary_interface_init(GLoadedContentInterface *iface)
+{
+    iface->describe = (describe_loaded_fc)g_loaded_binary_describe;
+
+    iface->count_views = (count_loaded_views_fc)g_loaded_binary_count_views;
+    iface->build_view = (build_loaded_view_fc)g_loaded_binary_build_view;
+    iface->get_view_index = (get_loaded_view_index_fc)g_loaded_binary_get_view_index;
+
+    iface->get_all_options = (get_all_loaded_options_fc)g_loaded_binary_get_all_display_options;
+    iface->set_option = (set_loaded_option_fc)g_loaded_binary_set_display_option;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : binary = instance d'objet GLib à traiter.                    *
 *                                                                             *
 *  Description : Supprime toutes les références externes.                     *
@@ -499,6 +547,7 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch
 *                xdoc    = structure XML en cours d'édition.                  *
 *                context = contexte à utiliser pour les recherches.           *
 *                path    = chemin d'accès réservé au binaire.                 *
+*                base    = référence au lieu d'enregistrement du projet.      *
 *                                                                             *
 *  Description : Ecrit une sauvegarde du binaire dans un fichier XML.         *
 *                                                                             *
@@ -508,13 +557,12 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch
 *                                                                             *
 ******************************************************************************/
 
-bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
+bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *base)
 {
     bool result;                            /* Bilan à faire remonter      */
     char *content_path;                     /* Partie "Contenus"           */
     char *access;                           /* Chemin d'accès à un élément */
     GBinContent *content;                   /* Contenu à référencer        */
-    const gchar *hash;                      /* Empreinte à mémoriser       */
     size_t debugs_count;                    /* Quantité de formats liés    */
     size_t i;                               /* Boucle de parcours          */
     GDbgFormat *debug;                      /* Informations de débogage    */
@@ -524,33 +572,28 @@ bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathC
     content_path = strdup(path);
     content_path = stradd(content_path, "/Contents");
 
-    access = strdup(content_path);
-    access = stradd(access, "/Main");
+    asprintf(&access, "%s/Main", content_path);
 
     content = g_binary_format_get_content(G_BIN_FORMAT(binary->format));
-    hash = g_binary_content_get_checksum(content);
+    result = g_binary_content_save(content, xdoc, context, access, base);
     g_object_unref(G_OBJECT(content));
 
-    result = add_content_to_node(xdoc, context, access, hash);
-
     free(access);
 
     debugs_count = g_exe_format_count_debug_info(binary->format);
 
-    for (i = 0; i < debugs_count; i++)
+    for (i = 0; i < debugs_count && result; i++)
     {
         asprintf(&access, "%s/DebugInfo[position()=%zu]", content_path, i);
 
         debug = g_exe_format_get_debug_info(binary->format, i);
 
         content = g_binary_format_get_content(G_BIN_FORMAT(debug));
-        hash = g_binary_content_get_checksum(content);
+        result = g_binary_content_save(content, xdoc, context, access, base);
         g_object_unref(G_OBJECT(content));
 
         g_object_unref(G_OBJECT(debug));
 
-        result &= add_content_to_node(xdoc, context, access, hash);
-
         free(access);
 
     }
@@ -1625,56 +1668,6 @@ GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *binary,
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary = élément binaire à mettre à jour.                    *
-*                view   = type de représentation visée.                       *
-*                col    = indice de colonne dont l'affichage est à modifier.  *
-*                state  = nouvel état de l'affichage.                         *
-*                                                                             *
-*  Description : Définit si une colonne donnée doit apparaître dans le rendu. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_loaded_binary_set_column_display(GLoadedBinary *binary, BinaryView view, BufferLineColumn col, bool state)
-{
-    bool old;                               /* Ancien état à remplacer     */
-
-    old = binary->col_display[view][col];
-
-    if (state != old)
-    {
-        binary->col_display[view][col] = state;
-        g_signal_emit_by_name(binary, "display-changed", view, col);
-    }
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary = élément binaire à consulter.                        *
-*                view   = type de représentation visée.                       *
-*                                                                             *
-*  Description : Indique quelles colonnes doivent apparaître dans le rendu.   *
-*                                                                             *
-*  Retour      : Consigne d'affichage. [OUT]                                  *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-const bool *g_loaded_binary_get_column_display(GLoadedBinary *binary, BinaryView view)
-{
-    return binary->col_display[view];
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : binary = élément binaire à consulter.                        *
 *                                                                             *
 *  Description : Indique si les lignes doivent apparaître dans le rendu.      *
@@ -1760,3 +1753,193 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binar
     g_signal_emit_by_name(binary, "disassembly-done");
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        GESTION SOUS FORME DE CONTENU CHARGE                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = élément chargé à consulter.                         *
+*                long   = précise s'il s'agit d'une version longue ou non.    *
+*                                                                             *
+*  Description : Fournit le désignation associée à l'élément chargé.          *
+*                                                                             *
+*  Retour      : Description courante.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static const char *g_loaded_binary_describe(const GLoadedBinary *binary, bool full)
+{
+    const char *result;                     /* Description à retourner     */
+    GBinContent *content;                   /* Contenu binaire mannipulé   */
+
+    content = g_binary_format_get_content(G_BIN_FORMAT(binary->format));
+
+    result = g_binary_content_describe(content, full);
+
+    g_object_unref(G_OBJECT(content));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = contenu chargé à consulter.                         *
+*                                                                             *
+*  Description : Détermine le nombre de vues disponibles pour un contenu.     *
+*                                                                             *
+*  Retour      : Quantité strictement positive.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static unsigned int g_loaded_binary_count_views(const GLoadedBinary *binary)
+{
+    return BVW_COUNT;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = contenu chargé à consulter.                         *
+*                index  = indice de la vue ciblée.                            *
+*                                                                             *
+*  Description : Met en place la vue demandée pour un contenu binaire.        *
+*                                                                             *
+*  Retour      : Composant graphique nouveau.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GtkWidget *g_loaded_binary_build_view(GLoadedBinary *binary, unsigned int index)
+{
+    GtkWidget *result;                      /* Support à retourner         */
+    GtkWidget *display;                     /* Composant d'affichage       */
+
+    assert(index < g_loaded_binary_count_views(binary));
+
+    switch (index)
+    {
+        case BVW_BLOCK:
+            display = gtk_block_display_new();
+            break;
+
+        case BVW_GRAPH:
+            display = gtk_graph_display_new();
+            break;
+
+        default:
+            assert(false);
+            break;
+    }
+
+    gtk_widget_show(display);
+
+    g_loaded_panel_set_content(G_LOADED_PANEL(display), G_LOADED_CONTENT(binary));
+
+    result = qck_create_scrolled_window(NULL, NULL);
+    gtk_container_add(GTK_CONTAINER(result), display);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = contenu chargé à consulter.                         *
+*                index  = composant graphique en place.                       *
+*                                                                             *
+*  Description : Retrouve l'indice correspondant à la vue donnée d'un contenu.*
+*                                                                             *
+*  Retour      : Indice de la vue représentée, ou -1 en cas d'erreur.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static unsigned int g_loaded_binary_get_view_index(GLoadedBinary *binary, GtkWidget *view)
+{
+    unsigned int result;                    /* Indice à retourner          */
+
+    if (GTK_IS_BLOCK_DISPLAY(view))
+        result = BVW_BLOCK;
+
+    else if (GTK_IS_GRAPH_DISPLAY(view))
+        result = BVW_GRAPH;
+
+    else
+    {
+        assert(false);
+        result = -1;
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = contenu chargé à consulter.                         *
+*                index  = composant graphique à cibler.                       *
+*                                                                             *
+*  Description : Fournit toutes les options d'affichage pour un contenu.      *
+*                                                                             *
+*  Retour      : Tableau de paramètres en accès libre.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool * const g_loaded_binary_get_all_display_options(const GLoadedBinary *binary, unsigned int index)
+{
+    return binary->col_display[index];
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary = contenu chargé à consulter.                         *
+*                index  = composant graphique à cibler.                       *
+*                option = type de paramètre à manipuler.                      *
+*                state  = valeur dudit paramètre.                             *
+*                                                                             *
+*  Description : Définit une option d'affichage pour un contenu chargé.       *
+*                                                                             *
+*  Retour      : true si un changement a été effectué, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_loaded_binary_set_display_option(GLoadedBinary *binary, unsigned int index, unsigned int option, bool state)
+{
+    bool result;                            /* Variation à faire remonter  */
+    bool old;                               /* Ancien état à remplacer     */
+
+    old = binary->col_display[index][option];
+
+    if (state != old)
+    {
+        binary->col_display[index][option] = state;
+        result = true;
+    }
+
+    else result = false;
+
+    return result;
+
+}
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 2df42aa..73b5a71 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -74,16 +74,6 @@ typedef enum _BinaryPartModel
 
 } BinaryPartModel;
 
-/* Type de représentations */
-typedef enum _BinaryView
-{
-    BVW_BLOCK,                              /* Version basique             */
-    BVW_GRAPH,                              /* Affichage en graphique      */
-
-    BVW_COUNT
-
-} BinaryView;
-
 
 /* Indique le type défini pour une description de fichier binaire. */
 GType g_loaded_binary_get_type(void);
@@ -95,7 +85,7 @@ GLoadedBinary *g_loaded_binary_new(GBinContent *);
 GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr, const char *, GStudyProject *);
 
 /* Ecrit une sauvegarde du binaire dans un fichier XML. */
-bool g_loaded_binary_save(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *);
+bool g_loaded_binary_save(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *);
 
 /* Fournit le nom associé à l'élément binaire. */
 const char *g_loaded_binary_get_name(const GLoadedBinary *, bool);
@@ -191,15 +181,26 @@ GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *);
 /* Fournit le tampon associé au contenu d'un fichier source. */
 //GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t);
 
-/* Définit si une colonne donnée doit apparaître dans le rendu. */
-void g_loaded_binary_set_column_display(GLoadedBinary *, BinaryView, BufferLineColumn, bool);
-
-/* Indique quelles colonnes doivent apparaître dans le rendu. */
-const bool *g_loaded_binary_get_column_display(GLoadedBinary *, BinaryView);
-
 /* Indique si les lignes doivent apparaître dans le rendu. */
 bool *g_loaded_binary_display_decomp_lines(GLoadedBinary *);
 
 
 
+
+
+/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */
+
+
+/* Type de représentations */
+typedef enum _BinaryView
+{
+    BVW_BLOCK,                              /* Version basique             */
+    BVW_GRAPH,                              /* Affichage en graphique      */
+
+    BVW_COUNT
+
+} BinaryView;
+
+
+
 #endif  /* _ANALYSIS_BINARY_H */
diff --git a/src/analysis/loaded-int.h b/src/analysis/loaded-int.h
new file mode 100644
index 0000000..a574d27
--- /dev/null
+++ b/src/analysis/loaded-int.h
@@ -0,0 +1,79 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loaded-int.h - définitions internes propres aux contenus chargés
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_LOADED_INT_H
+#define _ANALYSIS_LOADED_INT_H
+
+
+#include "loaded.h"
+
+
+
+/* Fournit le désignation associée à l'élément chargé. */
+typedef const char * (* describe_loaded_fc) (const GLoadedContent *, bool);
+
+/* Détermine le nombre de vues disponibles pour un contenu. */
+typedef unsigned int (* count_loaded_views_fc) (const GLoadedContent *);
+
+/* Met en place la vue demandée pour un contenu chargé. */
+typedef GtkWidget * (* build_loaded_view_fc) (GLoadedContent *, unsigned int);
+
+/* Retrouve l'indice correspondant à la vue donnée d'un contenu. */
+typedef unsigned int (* get_loaded_view_index_fc) (GLoadedContent *, GtkWidget *);
+
+/* Fournit toutes les options d'affichage pour un contenu. */
+typedef bool * const (* get_all_loaded_options_fc) (const GLoadedContent *, unsigned int);
+
+/* Définit une option d'affichage pour un contenu. */
+typedef bool ( * set_loaded_option_fc) (GLoadedContent *, unsigned int, unsigned int, bool);
+
+
+/* Accès à un contenu binaire quelconque (interface) */
+struct _GLoadedContentIface
+{
+    GTypeInterface base_iface;              /* A laisser en premier        */
+
+    /* Méthodes virtuelles */
+
+    describe_loaded_fc describe;            /* Description de contenu      */
+
+    count_loaded_views_fc count_views;      /* Compteur de vues            */
+    build_loaded_view_fc build_view;        /* Mise en place de vues       */
+    get_loaded_view_index_fc get_view_index;/* Récupération d'indice de vue*/
+
+    get_all_loaded_options_fc get_all_options;  /* Obtention de liste brute*/
+    set_loaded_option_fc set_option;        /* Définition d'affichage      */
+
+    /* Signaux */
+
+    void (* display_changed) (GLoadedContent *, unsigned int, unsigned int);
+
+};
+
+
+/* Redéfinition */
+typedef GLoadedContentIface GLoadedContentInterface;
+
+
+
+#endif  /* _ANALYSIS_LOADED_INT_H */
diff --git a/src/analysis/loaded.c b/src/analysis/loaded.c
new file mode 100644
index 0000000..5ce16c1
--- /dev/null
+++ b/src/analysis/loaded.c
@@ -0,0 +1,362 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loaded.c - intégration des contenus chargés
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "loaded.h"
+
+
+#include <assert.h>
+
+
+#include "loaded-int.h"
+#include "../glibext/chrysamarshal.h"
+#include "../glibext/gloadedpanel.h"
+
+
+
+/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */
+
+
+/* Procède à l'initialisation de l'interface de contenu chargé. */
+static void g_loaded_content_default_init(GLoadedContentInterface *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        GESTION SOUS FORME DE CONTENU CHARGE                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type d'une interface pour l'intégration de contenu chargé. */
+G_DEFINE_INTERFACE(GLoadedContent, g_loaded_content, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de contenu chargé. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_loaded_content_default_init(GLoadedContentInterface *iface)
+{
+    g_signal_new("display-changed",
+                 G_TYPE_LOADED_CONTENT,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GLoadedContentIface, display_changed),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__ENUM_ENUM,
+                 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = élément chargé à consulter.                        *
+*                long    = précise s'il s'agit d'une version longue ou non.   *
+*                                                                             *
+*  Description : Fournit le désignation associée à l'élément chargé.          *
+*                                                                             *
+*  Retour      : Description courante.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_loaded_content_describe(const GLoadedContent *content, bool full)
+{
+    GLoadedContentIface *iface;             /* Interface utilisée          */
+
+    iface = G_LOADED_CONTENT_GET_IFACE(content);
+
+    return iface->describe(content, full);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu chargé à consulter.                        *
+*                                                                             *
+*  Description : Détermine le nombre de vues disponibles pour un contenu.     *
+*                                                                             *
+*  Retour      : Quantité strictement positive.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int g_loaded_content_count_views(const GLoadedContent *content)
+{
+    GLoadedContentIface *iface;             /* Interface utilisée          */
+
+    iface = G_LOADED_CONTENT_GET_IFACE(content);
+
+    return iface->count_views(content);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu chargé à consulter.                        *
+*                index   = indice de la vue ciblée.                           *
+*                                                                             *
+*  Description : Met en place la vue demandée pour un contenu chargé.         *
+*                                                                             *
+*  Retour      : Composant graphique nouveau.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *g_loaded_content_build_view(GLoadedContent *content, unsigned int index)
+{
+    GtkWidget *result;                      /* Support à retourner         */
+    GLoadedContentIface *iface;             /* Interface utilisée          */
+
+    iface = G_LOADED_CONTENT_GET_IFACE(content);
+
+    assert(index <= g_loaded_content_count_views(content));
+
+    result = iface->build_view(content, index);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu chargé à consulter.                        *
+*                index   = composant graphique en place.                      *
+*                                                                             *
+*  Description : Retrouve l'indice correspondant à la vue donnée d'un contenu.*
+*                                                                             *
+*  Retour      : Indice de la vue représentée, ou -1 en cas d'erreur.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+unsigned int g_loaded_content_get_view_index(GLoadedContent *content, GtkWidget *view)
+{
+    unsigned int result;                    /* Indice à retourner          */
+    GLoadedContentIface *iface;             /* Interface utilisée          */
+
+    iface = G_LOADED_CONTENT_GET_IFACE(content);
+
+    result = iface->get_view_index(content, view);
+
+    assert(result == -1 || result <= g_loaded_content_count_views(content));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu chargé à consulter.                        *
+*                index   = composant graphique à cibler.                      *
+*                                                                             *
+*  Description : Fournit toutes les options d'affichage pour un contenu.      *
+*                                                                             *
+*  Retour      : Tableau de paramètres en accès libre.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool * const g_loaded_content_get_all_display_options(const GLoadedContent *content, unsigned int index)
+{
+    bool const *result;                     /* Accès aux options à renvoyer*/
+    GLoadedContentIface *iface;             /* Interface utilisée          */
+
+    assert(index <= g_loaded_content_count_views(content));
+
+    iface = G_LOADED_CONTENT_GET_IFACE(content);
+
+    result = iface->get_all_options(content, index);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : content = contenu chargé à consulter.                        *
+*                index   = composant graphique à cibler.                      *
+*                option  = type de paramètre à manipuler.                     *
+*                state   = valeur dudit paramètre.                            *
+*                                                                             *
+*  Description : Définit une option d'affichage pour un contenu chargé.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_loaded_content_set_display_option(GLoadedContent *content, unsigned int index, unsigned int option, bool state)
+{
+    GLoadedContentIface *iface;             /* Interface utilisée          */
+    bool changed;                           /* Note un changement          */
+
+    assert(index <= g_loaded_content_count_views(content));
+
+    iface = G_LOADED_CONTENT_GET_IFACE(content);
+
+    changed = iface->set_option(content, index, option, state);
+
+    if (changed)
+        g_signal_emit_by_name(content, "display-changed", index, option);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         VUES ET BASCULEMENT ENTRE LES VUES                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau affichant un contenu binaire.                *
+*                                                                             *
+*  Description : Fournit la station d'accueil d'un panneau d'affichage.       *
+*                                                                             *
+*  Retour      : Composant GTK fourni sans transfert de propriété.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkDockStation *get_dock_station_for_view_panel(GtkWidget *panel)
+{
+    GtkWidget *result;                      /* Support trouvé à retourner  */
+
+    /**
+     * La hiérarchie des composants empilés est la suivante :
+     *
+     *  - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré)
+     *  - GtkScrolledWindow
+     *  - GtkDockStation
+     *
+     */
+
+    result = gtk_widget_get_parent(panel);  /* ScrolledWindow */
+    result = gtk_widget_get_parent(result);             /* DockStation */
+
+    return GTK_DOCK_STATION(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau affichant un contenu binaire.                *
+*                                                                             *
+*  Description : Fournit le support défilant d'un panneau d'affichage.        *
+*                                                                             *
+*  Retour      : Composant GTK fourni sans transfert de propriété.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *get_scroll_window_for_view_panel(GtkWidget *panel)
+{
+    GtkWidget *result;                      /* Support trouvé à retourner  */
+
+    /**
+     * La hiérarchie des composants empilés est la suivante :
+     *
+     *  - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré)
+     *  - GtkScrolledWindow
+     *  - GtkDockStation
+     *
+     */
+
+    result = gtk_widget_get_parent(panel);  /* ScrolledWindow */
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : view = composant retourné par un contenu chargé.             *
+*                                                                             *
+*  Description : Fournit le panneau chargé inclus dans un affichage.          *
+*                                                                             *
+*  Retour      : Composant GTK fourni sans transfert de propriété.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkWidget *get_loaded_panel_from_built_view(GtkWidget *view)
+{
+    GtkWidget *result;                      /* Support trouvé à retourner  */
+
+    if (G_IS_LOADED_PANEL(view))
+        result = view;
+
+    else
+    {
+        assert(GTK_IS_CONTAINER(view));
+
+        result = NULL;
+
+        void track_loaded_panel(GtkWidget *widget, GtkWidget **found)
+        {
+            if (*found == NULL)
+            {
+                if (G_IS_LOADED_PANEL(widget))
+                    *found = widget;
+
+                else if (GTK_IS_CONTAINER(widget))
+                    gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)track_loaded_panel, found);
+
+            }
+
+        }
+
+        gtk_container_foreach(GTK_CONTAINER(view), (GtkCallback)track_loaded_panel, &result);
+
+        assert(result != NULL);
+
+    }
+
+    return result;
+
+}
diff --git a/src/analysis/loaded.h b/src/analysis/loaded.h
new file mode 100644
index 0000000..d1d9102
--- /dev/null
+++ b/src/analysis/loaded.h
@@ -0,0 +1,92 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loaded.h - prototypes pour l'intégration des contenus chargés
+ *
+ * Copyright (C) 2017 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_LOADED_H
+#define _ANALYSIS_LOADED_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+
+#include "../gtkext/gtkdockstation.h"
+
+
+
+/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */
+
+
+#define G_TYPE_LOADED_CONTENT             (g_loaded_content_get_type())
+#define G_LOADED_CONTENT(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADED_CONTENT, GLoadedContent))
+#define G_LOADED_CONTENT_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LOADED_CONTENT, GLoadedContentIface))
+#define G_IS_LOADED_CONTENT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADED_CONTENT))
+#define G_IS_LOADED_CONTENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LOADED_CONTENT))
+#define G_LOADED_CONTENT_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LOADED_CONTENT, GLoadedContentIface))
+
+
+/* Accès à un contenu binaire quelconque (coquille vide) */
+typedef struct _GLoadedContent GLoadedContent;
+
+/* Accès à un contenu binaire quelconque (interface) */
+typedef struct _GLoadedContentIface GLoadedContentIface;
+
+
+/* Détermine le type d'une interface pour l'intégration de contenu chargé. */
+GType g_loaded_content_get_type(void) G_GNUC_CONST;
+
+/* Fournit le désignation associée à l'élément chargé. */
+const char *g_loaded_content_describe(const GLoadedContent *, bool);
+
+/* Détermine le nombre de vues disponibles pour un contenu. */
+unsigned int g_loaded_content_count_views(const GLoadedContent *);
+
+/* Met en place la vue demandée pour un contenu chargé. */
+GtkWidget *g_loaded_content_build_view(GLoadedContent *, unsigned int);
+
+/* Retrouve l'indice correspondant à la vue donnée d'un contenu. */
+unsigned int g_loaded_content_get_view_index(GLoadedContent *, GtkWidget *);
+
+/* Fournit toutes les options d'affichage pour un contenu. */
+bool * const g_loaded_content_get_all_display_options(const GLoadedContent *, unsigned int);
+
+/* Définit une option d'affichage pour un contenu chargé. */
+void g_loaded_content_set_display_option(GLoadedContent *, unsigned int, unsigned int, bool);
+
+
+
+/* ----------------------- VUES ET BASCULEMENT ENTRE LES VUES ----------------------- */
+
+
+/* Fournit la station d'accueil d'un panneau d'affichage. */
+GtkDockStation *get_dock_station_for_view_panel(GtkWidget *);
+
+/* Fournit le support défilant d'un panneau d'affichage. */
+GtkWidget *get_scroll_window_for_view_panel(GtkWidget *);
+
+/* Fournit le panneau chargé inclus dans un affichage. */
+GtkWidget *get_loaded_panel_from_built_view(GtkWidget *);
+
+
+
+#endif  /* _ANALYSIS_LOADED_H */
diff --git a/src/analysis/project.c b/src/analysis/project.c
index cb1c70a..a5b59ab 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -33,15 +33,13 @@
 #include <i18n.h>
 
 
+#include "loaded.h"
 #include "loading.h"
 #include "../common/xml.h"
 #include "../core/global.h"
 #include "../core/params.h"
-#include "../glibext/signal.h"
-#include "../gtkext/easygtk.h"
 #include "../glibext/delayed-int.h"
-#include "../gtkext/gtkblockdisplay.h"
-#include "../gtkext/gtkgraphdisplay.h"
+#include "../glibext/signal.h"
 #include "../gui/core/panels.h"
 #include "../gui/panels/log.h"
 #include "../gui/panels/panel.h"
@@ -78,13 +76,9 @@ struct _GStudyProject
 
     char *filename;                         /* Lieu d'enregistrement       */
 
-    loaded_content *contents;               /* Contenus binaires chargés   */
-    size_t contents_count;                  /* Nombre de ces contenus      */
-    GMutex cnt_mutex;                       /* Modification de la liste    */
-
-    loaded_binary **binaries;               /* Fichiers binaires associés  */
-    size_t binaries_count;                  /* Nombre de ces fichiers      */
-    GMutex bin_mutex;                       /* Modification de la liste    */
+    GLoadedContent **contents;              /* Contenus chargés et intégrés*/
+    size_t count;                           /* Quantité de ces contenus    */
+    GMutex mutex;                           /* Encadrement des accès       */
 
 };
 
@@ -94,6 +88,11 @@ struct _GStudyProjectClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
+    /* Signaux */
+
+    void (* content_added) (GStudyProject *, GLoadedContent *);
+    void (* content_removed) (GStudyProject *, GLoadedContent *);
+
 };
 
 
@@ -103,17 +102,6 @@ static void g_study_project_class_init(GStudyProjectClass *);
 /*Initialise une instance de projet d'étude. */
 static void g_study_project_init(GStudyProject *);
 
-/* Assure un positionnement initial idéal. */
-static gboolean scroll_for_the_first_time(GtkWidget *, GdkEvent *, GLoadedBinary *);
-
-
-
-/* ----------------------- VUES ET BASCULEMENT ENTRE LES VUES ----------------------- */
-
-
-/* Met en place un ensemble de vues pour un binaire. */
-GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *, GLoadedBinary *, BinaryView, GtkDisplayPanel **);
-
 
 
 /* ---------------------------------------------------------------------------------- */
@@ -139,6 +127,21 @@ G_DEFINE_TYPE(GStudyProject, g_study_project, G_TYPE_OBJECT);
 
 static void g_study_project_class_init(GStudyProjectClass *klass)
 {
+    g_signal_new("content-added",
+                 G_TYPE_STUDY_PROJECT,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GStudyProjectClass, content_added),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__OBJECT,
+                 G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+    g_signal_new("content-removed",
+                 G_TYPE_STUDY_PROJECT,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GStudyProjectClass, content_removed),
+                 NULL, NULL,
+                 g_cclosure_marshal_VOID__OBJECT,
+                 G_TYPE_NONE, 1, G_TYPE_OBJECT);
 
 }
 
@@ -157,9 +160,7 @@ static void g_study_project_class_init(GStudyProjectClass *klass)
 
 static void g_study_project_init(GStudyProject *project)
 {
-    g_mutex_init(&project->cnt_mutex);
-
-    g_mutex_init(&project->bin_mutex);
+    g_mutex_init(&project->mutex);
 
 }
 
@@ -201,6 +202,10 @@ GStudyProject *g_study_project_new(void)
 
 GStudyProject *g_study_project_open(const char *filename)
 {
+    return NULL;
+
+#if 0
+
     GStudyProject *result;                  /* Adresse à retourner         */
     xmlDocPtr xdoc;                         /* Structure XML chargée       */
     xmlXPathContextPtr context;             /* Contexte pour les XPath     */
@@ -318,6 +323,8 @@ GStudyProject *g_study_project_open(const char *filename)
 
     return result;
 
+#endif
+
 }
 
 
@@ -336,50 +343,31 @@ GStudyProject *g_study_project_open(const char *filename)
 
 bool g_study_project_save(GStudyProject *project, const char *filename)
 {
+    return false;
+
+#if 0
+
     bool result;                            /* Bilan à retourner           */
     xmlDocPtr xdoc;                         /* Document XML à créer        */
     xmlXPathContextPtr context;             /* Contexte pour les recherches*/
     const char *final;                      /* Lieu d'enregistrement final */
     size_t i;                               /* Boucle de parcours          */
-    size_t access_len;                      /* Taille d'un chemin interne  */
     char *access;                           /* Chemin pour une sous-config.*/
 
     result = create_new_xml_file(&xdoc, &context);
 
-    result &= (ensure_node_exist(xdoc, context, "/ChrysalideProject") != NULL);
+    if (result)
+        result = (ensure_node_exist(xdoc, context, "/ChrysalideProject") != NULL);
 
     final = filename != NULL ? filename : project->filename;
 
-    /* Enregistrement des contenus binaires attachés */
-
-    for (i = 0; i < project->contents_count && result; i++)
-    {
-        if (project->contents[i].state == PCS_INTERNAL) continue;
-
-        access_len = strlen("/ChrysalideProject/Contents/Content[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
-
-        access = calloc(access_len, sizeof(char));
-        snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%zu]", i + 1);
-
-        result = g_binary_content_save(project->contents[i].content, xdoc, context, access, final);
-
-        if (result)
-            result = add_long_attribute_to_node(xdoc, context, access, "state", project->contents[i].state);
-
-        free(access);
-
-    }
-
     /* Enregistrement des binaires analysés */
 
     for (i = 0; i < project->binaries_count && result; i++)
     {
-        access_len = strlen("/ChrysalideProject/Binaries/Binary[position()=") + SIZE_T_MAXLEN + strlen("]") + 1;
-
-        access = calloc(access_len, sizeof(char));
-        snprintf(access, access_len, "/ChrysalideProject/Binaries/Binary[position()=%zu]", i + 1);
+        asprintf(&access, "/ChrysalideProject/Binaries/Binary[position()=%zu]", i + 1);
 
-        result = g_loaded_binary_save(project->binaries[i]->binary, xdoc, context, access);
+        result = g_loaded_binary_save(project->binaries[i]->binary, xdoc, context, access, final);
 
         free(access);
 
@@ -400,6 +388,8 @@ bool g_study_project_save(GStudyProject *project, const char *filename)
 
     return result;
 
+#endif
+
 }
 
 
@@ -438,6 +428,8 @@ const char *g_study_project_get_filename(const GStudyProject *project)
 
 void g_study_project_add_binary_content(GStudyProject *project, GBinContent *content, ProjectContentState state)
 {
+#if 0
+
     loaded_content *new;                    /* Nouveau contenu à définir   */
 
     g_mutex_lock(&project->cnt_mutex);
@@ -454,6 +446,7 @@ void g_study_project_add_binary_content(GStudyProject *project, GBinContent *con
 
     g_mutex_unlock(&project->cnt_mutex);
 
+#endif
 
 }
 
@@ -473,6 +466,10 @@ void g_study_project_add_binary_content(GStudyProject *project, GBinContent *con
 
 GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *project, const char *hash)
 {
+    return NULL;
+
+#if 0
+
     GBinContent *result;                    /* Trouvaille à retourner      */
     size_t i;                               /* Boucle de parcours          */
     GBinContent *iter;                      /* Contenu binaire analysé     */
@@ -499,6 +496,8 @@ GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *project,
 
     return result;
 
+#endif
+
 }
 
 
@@ -524,7 +523,7 @@ void ack_loaded_binary(GBinaryLoader *loader, GStudyProject *project)
     if (binary != NULL)
     {
         g_signal_connect_to_main_swapped(binary, "disassembly-done",
-                                         G_CALLBACK(g_study_project_attach_binary), project,
+                                         G_CALLBACK(g_study_project_attach_content), project,
                                          g_cclosure_marshal_VOID__VOID);
 
         g_loaded_binary_analyse(binary);
@@ -536,43 +535,10 @@ void ack_loaded_binary(GBinaryLoader *loader, GStudyProject *project)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : widget = composant d'affichage nouvellement porté à l'écran. *
-*                event  = informations liées à l'événement.                   *
-*                binary = fichier binaire à associer au projet actuel.        *
-*                                                                             *
-*  Description : Assure un positionnement initial idéal.                      *
-*                                                                             *
-*  Retour      : FALSE.                                                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GLoadedBinary *binary)
-{
-    GExeFormat *format;                 /* Format associé au binaire       */
-    vmpa2t target;                      /* Position initiale à viser       */
-
-    g_signal_handlers_disconnect_by_func(widget, G_CALLBACK(scroll_for_the_first_time), binary);
-
-    format = g_loaded_binary_get_format(binary);
-
-    if (g_exe_format_get_main_address(format, &target))
-        gtk_display_panel_request_move(GTK_DISPLAY_PANEL(widget), &target);
-
-    g_object_unref(G_OBJECT(format));
-
-    return FALSE;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : project = project à effacer de la mémoire.                   *
-*                binary  = fichier binaire à associer au projet actuel.       *
+*  Paramètres  : project = project à manipuler.                               *
+*                content = contenu chargé à associer au projet actuel.        *
 *                                                                             *
-*  Description : Attache un fichier donné à un projet donné.                  *
+*  Description : Attache un contenu donné à un projet donné.                  *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -580,48 +546,28 @@ static gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GL
 *                                                                             *
 ******************************************************************************/
 
-void g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *binary)
+void g_study_project_attach_content(GStudyProject *project, GLoadedContent *content)
 {
-    loaded_binary *new;                     /* Nouveau binaire à présenter */
-    GtkDisplayPanel *display;               /* Composant d'affichage       */
-    GPanelItem *panel;                      /* Nouveau panneau associé     */
-
-    /* Mise en place */
-
-    new = (loaded_binary *)calloc(1, sizeof(loaded_binary));
-
-    new->binary = binary;
-
-    /* Enregistrement dans le projet */
+    g_mutex_lock(&project->mutex);
 
-    g_mutex_lock(&project->bin_mutex);
+    project->contents = (GLoadedContent **)realloc(project->contents,
+                                                   ++project->count * sizeof(GLoadedContent *));
 
-    project->binaries = (loaded_binary **)realloc(project->binaries,
-                                                  ++project->binaries_count * sizeof(loaded_binary *));
+    project->contents[project->count - 1] = content;
 
-    project->binaries[project->binaries_count - 1] = new;
+    g_mutex_unlock(&project->mutex);
 
-    /* Premier affichage */
-
-    panel = _setup_new_panel_item_for_binary(project, binary, BVW_BLOCK, &display);
-
-    g_mutex_unlock(&project->bin_mutex);
-
-    g_signal_connect(display, "size-allocate", G_CALLBACK(scroll_for_the_first_time), binary);
-
-    g_panel_item_dock(panel);
-
-    update_project_area(project);
+    g_signal_emit_by_name(project, "content-added", content);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : project = project à effacer de la mémoire.                   *
-*                binary  = fichier binaire à dissocier au projet actuel.      *
+*  Paramètres  : project = project à manipuler.                               *
+*                content = contenu chargé à dissocier du projet actuel.       *
 *                                                                             *
-*  Description : Détache un fichier donné à un projet donné.                  *
+*  Description : Détache un contenu donné d'un projet donné.                  *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -629,29 +575,27 @@ void g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *binary
 *                                                                             *
 ******************************************************************************/
 
-void g_study_project_detach_binary(GStudyProject *project, GLoadedBinary *binary)
+void g_study_project_detach_content(GStudyProject *project, GLoadedContent *content)
 {
-    //GtkDockPanel *dpanel;                   /* Support de panneaux         */
-    //GDockItem *ditem;                       /* Support d'affichage utilisé */
     size_t i;                               /* Boucle de parcours          */
 
-    //dpanel = GTK_DOCK_PANEL(g_object_get_data(project->ref, "binpanel"));
-    //ditem = gtk_dock_panel_get_item_from_binary(project, binary); FIXME !!
-
-    //gtk_dock_panel_remove_item(dpanel, ditem);
+    g_mutex_lock(&project->mutex);
 
+    for (i = 0; i < project->count; i++)
+        if (project->contents[i] == content) break;
 
+    if ((i + 1) < project->count)
+        memmove(&project->contents[i], &project->contents[i + 1],
+                (project->count - i - 1) * sizeof(GLoadedContent *));
 
-    for (i = 0; i < project->binaries_count; i++)
-        if (project->binaries[i]->binary == binary) break;
+    project->contents = (GLoadedContent **)realloc(project->contents,
+                                                   --project->count * sizeof(GLoadedContent *));
 
-    if ((i + 1) < project->binaries_count)
-        memmove(&project->binaries[i], &project->binaries[i + 1], (project->binaries_count - i - 1) * sizeof(loaded_binary *));
+    g_mutex_unlock(&project->mutex);
 
-    project->binaries = (loaded_binary **)realloc(project->binaries,
-                                                   --project->binaries_count * sizeof(loaded_binary *));
+    g_signal_emit_by_name(project, "content-removed", content);
 
-    update_project_area(project);
+    g_object_unref(G_OBJECT(content));
 
 }
 
@@ -670,6 +614,7 @@ void g_study_project_detach_binary(GStudyProject *project, GLoadedBinary *binary
 
 void g_study_project_display(const GStudyProject *project)
 {
+#if 0
     size_t i;                               /* Boucle de parcours #1       */
     loaded_binary *handled;                 /* Binaire prise en compte     */
     size_t j;                               /* Boucle de parcours #2       */
@@ -682,7 +627,7 @@ void g_study_project_display(const GStudyProject *project)
             g_panel_item_dock(handled->items[j]);
 
     }
-
+#endif
 }
 
 
@@ -700,6 +645,7 @@ void g_study_project_display(const GStudyProject *project)
 
 void g_study_project_hide(const GStudyProject *project)
 {
+#if 0
     size_t i;                               /* Boucle de parcours #1       */
     loaded_binary *handled;                 /* Binaire prise en compte     */
     size_t j;                               /* Boucle de parcours #2       */
@@ -712,16 +658,16 @@ void g_study_project_hide(const GStudyProject *project)
             g_panel_item_undock(handled->items[j]);
 
     }
-
+#endif
 }
 
 
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : project = projet dont le contenu est à afficher.             *
-*                count = nombre de binaires pris en compte. [OUT]             *
+*                count = nombre de contenus pris en compte. [OUT]             *
 *                                                                             *
-*  Description : Fournit l'ensemble des binaires associés à un projet.        *
+*  Description : Fournit l'ensemble des contenus associés à un projet.        *
 *                                                                             *
 *  Retour      : Liste à libérer de la mémoire.                               *
 *                                                                             *
@@ -729,278 +675,23 @@ void g_study_project_hide(const GStudyProject *project)
 *                                                                             *
 ******************************************************************************/
 
-GLoadedBinary **g_study_project_get_binaries(const GStudyProject *project, size_t *count)
+GLoadedContent **g_study_project_get_contents(GStudyProject *project, size_t *count)
 {
-    GLoadedBinary **result;                 /* Tableau à retourner         */
+    GLoadedContent **result;                /* Tableau à retourner         */
     size_t i;                               /* Boucle de parcours          */
 
-    *count = project->binaries_count;
-    result = (GLoadedBinary **)calloc(*count, sizeof(GLoadedBinary *));
+    g_mutex_lock(&project->mutex);
+
+    *count = project->count;
+    result = (GLoadedContent **)calloc(*count, sizeof(GLoadedContent *));
 
     for (i = 0; i < *count; i++)
     {
-        result[i] = project->binaries[i]->binary;
+        result[i] = project->contents[i];
         g_object_ref(G_OBJECT(result[i]));
     }
 
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                         VUES ET BASCULEMENT ENTRE LES VUES                         */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : project = zone d'inscription du nouveau panneau.             *
-*                binary  = fichier binaire dont les vues sont à créer.        *
-*                wanted  = interface de visualisation demandée.               *
-*                panel   = interface de visualisation principale. [OUT]       *
-*                                                                             *
-*  Description : Met en place un ensemble de vues pour un binaire.            *
-*                                                                             *
-*  Retour      : Panneau mis en place et prêt à être inséré.                  *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBinary *binary, BinaryView wanted, GtkDisplayPanel **panel)
-{
-    GPanelItem *result;                     /* Nouveau panneau à renvoyer  */
-    size_t k;                               /* Boucle de parcours #3       */
-    loaded_binary *handled;                 /* Dossier de suivi à compléter*/
-    GtkDisplayPanel *displays[BVW_COUNT];   /* Composants pour l'affichage */
-    BinaryView i;                           /* Boucle de parcours #1       */
-    GtkWidget *display;                     /* Affichage du binaire        */
-    GtkWidget *scroll;                      /* Surface d'exposition        */
-    GtkWidget *selected;                    /* Interface de prédilection   */
-    const char *name;                       /* Titre associé au binaire    */
-    const char *lname;                      /* Description du binaire      */
-    BinaryView j;                           /* Boucle de parcours #2       */
-
-    /* Recherche du dossier correspondant */
-
-    for (k = 0; k < project->binaries_count; k++)
-        if (project->binaries[k]->binary == binary)
-            break;
-
-    assert(k < project->binaries_count);
-
-    handled = project->binaries[k];
-
-    /* Créations */
-
-    for (i = 0; i < BVW_COUNT; i++)
-    {
-        /* Préparation du support visuel */
-
-        switch (i)
-        {
-            case BVW_BLOCK:
-                display = gtk_block_display_new();
-                break;
-            case BVW_GRAPH:
-                display = gtk_graph_display_new();
-                break;
-            default: /* GCC ! */
-                break;
-        }
-
-        gtk_widget_show(display);
-
-        displays[i] = GTK_DISPLAY_PANEL(display);
-
-        gtk_display_panel_attach_binary(displays[i], binary, i);
-
-        /* Intégration finale dans un support défilant */
-
-        scroll = qck_create_scrolled_window(NULL, NULL);
-        gtk_container_add(GTK_CONTAINER(scroll), display);
-
-        if (i == wanted)
-        {
-            selected = scroll;
-            *panel = GTK_DISPLAY_PANEL(display);
-        }
-
-    }
-
-    /* Support graphique final */
-
-    name = g_loaded_binary_get_name(binary, false);
-    lname = g_loaded_binary_get_name(binary, true);
-
-    result = g_panel_item_new(PIP_BINARY_VIEW, name, lname, selected, true, "N");
-    register_panel_item(result, get_main_configuration());
-
-    handled->items = (GPanelItem **)realloc(handled->items, ++handled->count * sizeof(GPanelItem *));
-    handled->items[handled->count - 1] = result;
-
-    /* Etablissement des liens */
-
-    for (i = 0; i < BVW_COUNT; i++)
-        for (j = 0; j < BVW_COUNT; j++)
-        {
-            if (j == i)
-                continue;
-
-            switch (j)
-            {
-                case BVW_BLOCK:
-                    g_object_set_data(G_OBJECT(displays[i]), "block_alt_view", displays[j]);
-                    break;
-                case BVW_GRAPH:
-                    g_object_set_data(G_OBJECT(displays[i]), "graph_alt_view", displays[j]);
-                    break;
-                default: /* GCC ! */
-                    break;
-            }
-
-        }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : project = zone d'inscription du nouveau panneau.             *
-*                binary  = fichier binaire dont les vues sont à créer.        *
-*                wanted  = interface de visualisation demandée.               *
-*                panel   = interface de visualisation principale. [OUT]       *
-*                                                                             *
-*  Description : Met en place un ensemble de vues pour un binaire.            *
-*                                                                             *
-*  Retour      : Panneau mis en place et prêt à être inséré.                  *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GPanelItem *setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBinary *binary, BinaryView wanted, GtkDisplayPanel **panel)
-{
-    GPanelItem *result;                     /* Nouveau panneau à renvoyer  */
-
-    /**
-     * La liste des binaires pris en charge ne doit pas évoluer en cours
-     * de traitement. On place donc le verrou adapté...
-     */
-
-    g_mutex_lock(&project->bin_mutex);
-
-    result = _setup_new_panel_item_for_binary(project, binary, wanted, panel);
-
-    g_mutex_unlock(&project->bin_mutex);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : panel = panneau affichant un contenu binaire.                *
-*                                                                             *
-*  Description : Fournit la station d'accueil d'un panneau d'affichage.       *
-*                                                                             *
-*  Retour      : Composant GTK fourni sans transfert de propriété.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GtkDockStation *get_dock_station_for_view_panel(GtkDisplayPanel *panel)
-{
-    GtkWidget *result;                      /* Support trouvé à retourner  */
-
-    /**
-     * La hiérarchie des composants empilés est la suivante :
-     *
-     *  - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré)
-     *  - GtkScrolledWindow
-     *  - GtkDockStation
-     *
-     */
-
-    result = gtk_widget_get_parent(GTK_WIDGET(panel));  /* ScrolledWindow */
-    result = gtk_widget_get_parent(result);             /* DockStation */
-
-    return GTK_DOCK_STATION(result);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : panel = panneau affichant un contenu binaire.                *
-*                                                                             *
-*  Description : Fournit le support défilant d'un panneau d'affichage.        *
-*                                                                             *
-*  Retour      : Composant GTK fourni sans transfert de propriété.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GtkWidget *get_scroll_window_for_view_panel(GtkDisplayPanel *panel)
-{
-    GtkWidget *result;                      /* Support trouvé à retourner  */
-
-    /**
-     * La hiérarchie des composants empilés est la suivante :
-     *
-     *  - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré)
-     *  - GtkScrolledWindow
-     *  - GtkDockStation
-     *
-     */
-
-    result = gtk_widget_get_parent(GTK_WIDGET(panel));  /* ScrolledWindow */
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : panel = panneau affichant un contenu binaire.                *
-*                view  = autre vision recherchée.                             *
-*                                                                             *
-*  Description : Fournit une vision alternative d'un panneau d'affichage.     *
-*                                                                             *
-*  Retour      : Composant GTK fourni sans transfert de propriété.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GtkDisplayPanel *get_alt_view_for_view_panel(GtkDisplayPanel *panel, BinaryView view)
-{
-    GtkDisplayPanel *result;                /* Panneau visé à renvoyer     */
-
-    switch (view)
-    {
-        case BVW_BLOCK:
-            result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "block_alt_view"));
-            break;
-        case BVW_GRAPH:
-            result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "graph_alt_view"));
-            break;
-        default:
-            assert(false);
-            result = NULL;
-            break;
-    }
-
-    if (result != NULL)
-        g_object_ref(G_OBJECT(result));
+    g_mutex_unlock(&project->mutex);
 
     return result;
 
diff --git a/src/analysis/project.h b/src/analysis/project.h
index 8288384..9e777ee 100644
--- a/src/analysis/project.h
+++ b/src/analysis/project.h
@@ -29,15 +29,14 @@
 
 
 #include "binary.h"
-#include "../gtkext/gtkdockstation.h"
-#include "../gtkext/gtkdisplaypanel.h"
+#include "loaded.h"
 
 
 /**
  * Comme "gui/panels/panel.h" inclut "gui/editem.h", qui inclut lui même
  * ce fichier pour la mise à jour de la zone de projet, on redéfinit...
  */
-typedef struct _GPanelItem GPanelItem;
+//typedef struct _GPanelItem GPanelItem;
 
 /**
  * Autre boucle sans fin similaire...
@@ -99,11 +98,11 @@ GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *, const
 /* Acquitte la fin d'un chargement différé et complet. */
 void ack_loaded_binary(GBinaryLoader *, GStudyProject *);
 
-/* Attache un fichier donné à un projet donné. */
-void g_study_project_attach_binary(GStudyProject *, GLoadedBinary *);
+/* Attache un contenu donné à un projet donné. */
+void g_study_project_attach_content(GStudyProject *, GLoadedContent *);
 
-/* Détache un fichier donné à un projet donné. */
-void g_study_project_detach_binary(GStudyProject *, GLoadedBinary *);
+/* Détache un contenu donné d'un projet donné. */
+void g_study_project_detach_content(GStudyProject *, GLoadedContent *);
 
 /* Met en place un projet à l'écran. */
 void g_study_project_display(const GStudyProject *);
@@ -111,25 +110,8 @@ void g_study_project_display(const GStudyProject *);
 /* Supprime de l'écran un projet en place. */
 void g_study_project_hide(const GStudyProject *);
 
-/* Fournit l'ensemble des binaires associés à un projet. */
-GLoadedBinary **g_study_project_get_binaries(const GStudyProject *, size_t *);
-
-
-
-/* ----------------------- VUES ET BASCULEMENT ENTRE LES VUES ----------------------- */
-
-
-/* Met en place un ensemble de vues pour un binaire. */
-GPanelItem *setup_new_panel_item_for_binary(GStudyProject *, GLoadedBinary *, BinaryView, GtkDisplayPanel **);
-
-/* Fournit la station d'accueil d'un panneau d'affichage. */
-GtkDockStation *get_dock_station_for_view_panel(GtkDisplayPanel *);
-
-/* Fournit le support défilant d'un panneau d'affichage. */
-GtkWidget *get_scroll_window_for_view_panel(GtkDisplayPanel *);
-
-/* Fournit une vision alternative d'un panneau d'affichage. */
-GtkDisplayPanel *get_alt_view_for_view_panel(GtkDisplayPanel *, BinaryView);
+/* Fournit l'ensemble des contenus associés à un projet. */
+GLoadedContent **g_study_project_get_contents(GStudyProject *, size_t *);
 
 
 
diff --git a/src/glibext/gloadedpanel-int.h b/src/glibext/gloadedpanel-int.h
index 8686d1b..904041d 100644
--- a/src/glibext/gloadedpanel-int.h
+++ b/src/glibext/gloadedpanel-int.h
@@ -29,6 +29,12 @@
 
 
 
+/* Définit le contenu associé à un panneau de chargement. */
+typedef void (* set_loaded_panel_content_fc) (GLoadedPanel *, GLoadedContent *);
+
+/* Fournit le contenu associé à un panneau de chargement. */
+typedef GLoadedContent * (* get_loaded_panel_content_fc) (const GLoadedPanel *);
+
 /* Place en cache un rendu destiné à l'aperçu graphique rapide. */
 typedef void (* cache_loaded_glance_fc) (GLoadedPanel *, cairo_t *, const GtkAllocation *, double);
 
@@ -38,6 +44,9 @@ struct _GLoadedPanelIface
 {
     GTypeInterface base_iface;              /* A laisser en premier        */
 
+    set_loaded_panel_content_fc set_content;/* Définition du contenu       */
+    get_loaded_panel_content_fc get_content;/* Récupération du contenu     */
+
     cache_loaded_glance_fc cache_glance;    /* Cache de la mignature       */
 
 };
diff --git a/src/glibext/gloadedpanel.c b/src/glibext/gloadedpanel.c
index fa12ec7..4d5a1e1 100644
--- a/src/glibext/gloadedpanel.c
+++ b/src/glibext/gloadedpanel.c
@@ -57,6 +57,58 @@ static void g_loaded_panel_default_init(GLoadedPanelInterface *iface)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : panel   = composant GTK à compléter.                         *
+*                content = contenu quelconque chargé en mémoire.              *
+*                                                                             *
+*  Description : Définit le contenu associé à un panneau de chargement.       *
+*                                                                             *
+*  Retour      :                                                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_loaded_panel_set_content(GLoadedPanel *panel, GLoadedContent *content)
+{
+    GLoadedPanelIface *iface;               /* Interface utilisée          */
+
+    g_object_ref(G_OBJECT(content));
+
+    iface = G_LOADED_PANEL_GET_IFACE(panel);
+
+    iface->set_content(panel, content);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = composant GTK à consulter.                           *
+*                                                                             *
+*  Description : Fournit le contenu associé à un panneau de chargement.       *
+*                                                                             *
+*  Retour      : Contenu quelconque chargé en mémoire.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GLoadedContent *g_loaded_panel_get_content(const GLoadedPanel *panel)
+{
+    GLoadedContent *result;                 /* Contenu à retourner         */
+    GLoadedPanelIface *iface;               /* Interface utilisée          */
+
+    iface = G_LOADED_PANEL_GET_IFACE(panel);
+
+    result = iface->get_content(panel);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : panel = composant GTK à manipuler.                           *
 *                cairo = assistant pour la création de rendus.                *
 *                area  = taille de la surface réduite à disposition.          *
diff --git a/src/glibext/gloadedpanel.h b/src/glibext/gloadedpanel.h
index 51f4f36..c2c9e85 100644
--- a/src/glibext/gloadedpanel.h
+++ b/src/glibext/gloadedpanel.h
@@ -29,13 +29,16 @@
 #include <gtk/gtk.h>
 
 
+#include "../analysis/loaded.h"
 
-#define G_TYPE_LOADED_PANEL               (g_loaded_panel_get_type())
-#define G_LOADED_PANEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADED_PANEL, GLoadedPanel))
-#define G_LOADED_PANEL_CLASS(vtable)      (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LOADED_PANEL, GLoadedPanelIface))
-#define GTK_IS_LOADED_PANEL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADED_PANEL))
-#define GTK_IS_LOADED_PANEL_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LOADED_PANEL))
-#define G_LOADED_PANEL_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LOADED_PANEL, GLoadedPanelIface))
+
+
+#define G_TYPE_LOADED_PANEL             (g_loaded_panel_get_type())
+#define G_LOADED_PANEL(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADED_PANEL, GLoadedPanel))
+#define G_LOADED_PANEL_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LOADED_PANEL, GLoadedPanelIface))
+#define G_IS_LOADED_PANEL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADED_PANEL))
+#define G_IS_LOADED_PANEL_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LOADED_PANEL))
+#define G_LOADED_PANEL_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LOADED_PANEL, GLoadedPanelIface))
 
 
 /* Composant d'affichage basique (coquille vide) */
@@ -48,6 +51,12 @@ typedef struct _GLoadedPanelIface GLoadedPanelIface;
 /* Détermine le type d'une interface pour la mise en place de lignes. */
 GType g_loaded_panel_get_type(void) G_GNUC_CONST;
 
+/* Définit le contenu associé à un panneau de chargement. */
+void g_loaded_panel_set_content(GLoadedPanel *, GLoadedContent *);
+
+/* Fournit le contenu associé à un panneau de chargement. */
+GLoadedContent *g_loaded_panel_get_content(const GLoadedPanel *);
+
 /* Place en cache un rendu destiné à l'aperçu graphique rapide. */
 void g_loaded_panel_cache_glance(GLoadedPanel *, cairo_t *, const GtkAllocation *, double);
 
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 413af86..b8cba94 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -34,6 +34,7 @@
 #include "../gtkbufferdisplay.h"
 #include "../gtkdisplaypanel.h"
 #include "../../common/sort.h"
+#include "../../glibext/gloadedpanel.h"
 
 
 
@@ -313,9 +314,11 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
     g_object_ref(G_OBJECT(result->block));
 
     result->display = gtk_block_display_new();
-
     gtk_widget_show(result->display);
-    gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->display), binary, BVW_GRAPH);
+
+    g_loaded_panel_set_content(G_LOADED_PANEL(result->display), G_LOADED_CONTENT(binary));
+
+    gtk_block_display_override_view_index(GTK_BLOCK_DISPLAY(result->display), BVW_GRAPH);
 
     gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->display), true);
 
diff --git a/src/gtkext/gtkblockdisplay.c b/src/gtkext/gtkblockdisplay.c
index b39b561..e4d9d48 100644
--- a/src/gtkext/gtkblockdisplay.c
+++ b/src/gtkext/gtkblockdisplay.c
@@ -26,6 +26,7 @@
 
 #include "gtkbufferdisplay-int.h"
 #include "../arch/operand.h"
+#include "../analysis/loaded.h"
 
 
 
@@ -249,7 +250,7 @@ static gboolean gtk_block_display_button_press(GtkWidget *widget, GdkEventButton
 
         view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display));
 
-        changed = g_buffer_view_highlight_segments(view, real_x, real_y, GTK_DISPLAY_PANEL(display)->display);
+        changed = g_buffer_view_highlight_segments(view, real_x, real_y, GTK_DISPLAY_PANEL(display)->display_options);
 
         g_object_unref(G_OBJECT(view));
 
@@ -300,7 +301,7 @@ static gboolean gtk_block_display_query_tooltip(GtkWidget *widget, gint x, gint
     real_y = y;
     gtk_display_panel_compute_real_coord(panel, &real_x, &real_y);
 
-    creator = g_buffer_view_find_creator(GTK_BUFFER_DISPLAY(display)->view, real_x, real_y, panel->display);
+    creator = g_buffer_view_find_creator(GTK_BUFFER_DISPLAY(display)->view, real_x, real_y, panel->display_options);
 
     if (creator != NULL)
     {
@@ -400,7 +401,7 @@ static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *display,
 
     view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display));
 
-    result = g_buffer_view_highlight_segments(view, area->x, area->y, GTK_DISPLAY_PANEL(display)->display);
+    result = g_buffer_view_highlight_segments(view, area->x, area->y, GTK_DISPLAY_PANEL(display)->display_options);
 
     g_object_unref(G_OBJECT(view));
 
@@ -410,3 +411,28 @@ static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *display,
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : display = composant GTK d'affichage.                         *
+*                index   = indice de type de vue effectif.                    *
+*                                                                             *
+*  Description : Force un type de vue pour les options de rendu.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void gtk_block_display_override_view_index(GtkBlockDisplay *display, unsigned int index)
+{
+    GtkDisplayPanel *panel;                 /* Version de plus haut niveau */
+
+    panel = GTK_DISPLAY_PANEL(display);
+
+    panel->view_index = index;
+    panel->display_options = g_loaded_content_get_all_display_options(G_LOADED_CONTENT(panel->binary), index);
+
+}
diff --git a/src/gtkext/gtkblockdisplay.h b/src/gtkext/gtkblockdisplay.h
index 1455690..b394a01 100644
--- a/src/gtkext/gtkblockdisplay.h
+++ b/src/gtkext/gtkblockdisplay.h
@@ -51,6 +51,9 @@ GType gtk_block_display_get_type(void);
 /* Crée un nouveau composant pour l'affichage de bloc en ASM. */
 GtkWidget *gtk_block_display_new(void);
 
+/* Force un type de vue pour les options de rendu. */
+void gtk_block_display_override_view_index(GtkBlockDisplay *, unsigned int);
+
 
 
 #endif  /* _GTKEXT_GTKBLOCKDISPLAY_H */
diff --git a/src/gtkext/gtkbufferdisplay.c b/src/gtkext/gtkbufferdisplay.c
index ff70032..c1311c5 100644
--- a/src/gtkext/gtkbufferdisplay.c
+++ b/src/gtkext/gtkbufferdisplay.c
@@ -488,7 +488,7 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr)
         area.x -= virt_x;
         virt_y += area.y;
 
-        g_buffer_view_draw(display->view, cr, virt_y, &area, parent->display, selected);
+        g_buffer_view_draw(display->view, cr, virt_y, &area, parent->display_options, selected);
 
     }
 
@@ -571,7 +571,7 @@ static gboolean gtk_buffer_display_key_press(GtkWidget *widget, GdkEventKey *eve
         ctrl = (event->state & GDK_CONTROL_MASK);
         area = display->caret;
 
-        status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display, &area, &addr);
+        status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display_options, &area, &addr);
 
         if (status)
         {
@@ -607,7 +607,7 @@ static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *display,
     if (width != NULL)
     {
         if (display->view != NULL)
-            *width = g_buffer_view_get_width(display->view, GTK_DISPLAY_PANEL(display)->display);
+            *width = g_buffer_view_get_width(display->view, GTK_DISPLAY_PANEL(display)->display_options);
         else
             *width = 0;
     }
@@ -737,7 +737,7 @@ static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *d
 
     if (result)
     {
-        *x += g_buffer_view_get_margin(display->view, GTK_DISPLAY_PANEL(display)->display);
+        *x += g_buffer_view_get_margin(display->view, GTK_DISPLAY_PANEL(display)->display_options);
 
         height = gtk_widget_get_allocated_height(GTK_WIDGET(display));
 
@@ -874,7 +874,7 @@ static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, gint x,
 
     panel = GTK_DISPLAY_PANEL(display);
 
-    result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display, &new, &addr);
+    result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display_options, &new, &addr);
 
     if (result)
         gtk_buffer_display_relocate_caret(display, &new, &addr);
diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h
index a2170e7..4425427 100644
--- a/src/gtkext/gtkdisplaypanel-int.h
+++ b/src/gtkext/gtkdisplaypanel-int.h
@@ -76,8 +76,8 @@ struct _GtkDisplayPanel
     GtkScrollablePolicy vscroll_policy;     /* Politique verticale         */           
 
     bool show_border;                       /* Affichage d'une bordure ?   */
-    BinaryView content;                     /* Type de contenu             */
-    const bool *display;                    /* Affichage des colonnes ?    */
+    unsigned int view_index;                /* Indice du type de contenu   */
+    bool *display_options;                  /* Affichage des colonnes ?    */
 
     GLoadedBinary *binary;                  /* Binaire à visualiser        */
 
diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c
index 003ac5f..620a1b1 100644
--- a/src/gtkext/gtkdisplaypanel.c
+++ b/src/gtkext/gtkdisplaypanel.c
@@ -87,6 +87,17 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDispl
 /* Réagit à un changement des règles d'affichage. */
 static void on_view_panel_binary_display_change(GLoadedBinary *, BinaryView, BufferLineColumn, GtkDisplayPanel *);
 
+
+
+/* ----------------------- INTERFACE DE PANNEAU DE CHARGEMENT ----------------------- */
+
+
+/* Associe à un panneau d'affichage un binaire chargé. */
+static void gtk_display_panel_set_content(GtkDisplayPanel *, GLoadedContent *);
+
+/* Fournit le contenu associé à un panneau de chargement. */
+static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *);
+
 /* Place en cache un rendu destiné à l'aperçu graphique rapide. */
 static void gtk_display_panel_cache_glance(GtkDisplayPanel *, cairo_t *, const GtkAllocation *, double);
 
@@ -190,6 +201,9 @@ static void gtk_display_panel_init(GtkDisplayPanel *panel)
 
 static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *iface)
 {
+    iface->set_content = (set_loaded_panel_content_fc)gtk_display_panel_set_content;
+    iface->get_content = (get_loaded_panel_content_fc)gtk_display_panel_get_content;
+
     iface->cache_glance = (cache_loaded_glance_fc)gtk_display_panel_cache_glance;
 
 }
@@ -677,25 +691,6 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDi
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel = composant GTK à consulter.                           *
-*                                                                             *
-*  Description : Indique le type de contenu représenté par le composant.      *
-*                                                                             *
-*  Retour      : Identifiant d'un type de représentation de contenu.          *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-BinaryView gtk_display_panel_describe_content(const GtkDisplayPanel *panel)
-{
-    return panel->content;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : panel = composant GTK à mettre à jour.                       *
 *                show  = état de l'affichage auquel parvenir.                 *
 *                                                                             *
@@ -814,36 +809,6 @@ void gtk_display_panel_draw_border(GtkDisplayPanel *panel, cairo_t *cr)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel  = composant GTK à mettre à jour.                      *
-*                binary = binaire associé à intégrer.                         *
-*                view   = aspect du binaire à présenter.                      *
-*                                                                             *
-*  Description : Associe à un panneau d'affichage un binaire chargé.          *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void gtk_display_panel_attach_binary(GtkDisplayPanel *panel, GLoadedBinary *binary, BinaryView view)
-{
-    g_object_ref(G_OBJECT(binary));
-    panel->binary = binary;
-
-    panel->content = view;
-    panel->display = g_loaded_binary_get_column_display(binary, view);
-
-    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach != NULL) /* REMME */
-        GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach(panel, binary);
-
-    g_signal_connect(binary, "display-changed", G_CALLBACK(on_view_panel_binary_display_change), panel);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : binary = bianire dont les consignes d'affichage ont évolué.  *
 *                view   = type d'affichage à considérer.                      *
 *                col    = colonne dont le statut a changé.                    *
@@ -859,7 +824,7 @@ void gtk_display_panel_attach_binary(GtkDisplayPanel *panel, GLoadedBinary *bina
 
 static void on_view_panel_binary_display_change(GLoadedBinary *binary, BinaryView view, BufferLineColumn col, GtkDisplayPanel *panel)
 {
-    if (panel->content == view)
+    if (panel->view_index == view)
     {
         gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel)));
         gtk_widget_queue_resize(GTK_WIDGET(panel));
@@ -1067,35 +1032,6 @@ bool gtk_display_panel_get_position(const GtkDisplayPanel *panel, GBufferLine **
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : panel = composant GTK à manipuler.                           *
-*                cairo = assistant pour la création de rendus.                *
-*                area  = taille de la surface réduite à disposition.          *
-*                scale = échelle vis à vis de la taille réelle.               *
-*                                                                             *
-*  Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void gtk_display_panel_cache_glance(GtkDisplayPanel *panel, cairo_t *cairo, const GtkAllocation *area, double scale)
-{
-    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance != NULL)
-        GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance(panel, cairo, area, scale);
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                             CONVERSIONS DE COORDONNEES                             */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : panel = composant GTK à consulter.                           *
 *                event = informations liées à l'événement.                    *
 *                                                                             *
@@ -1165,3 +1101,84 @@ void gtk_display_panel_compute_relative_coords(GtkDisplayPanel *panel, gint *x,
         *y -= gtk_adjustment_get_value(panel->vadjustment);
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         INTERFACE DE PANNEAU DE CHARGEMENT                         */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel   = composant GTK à mettre à jour.                     *
+*                content = binaire associé à intégrer.                        *
+*                                                                             *
+*  Description : Associe à un panneau d'affichage un binaire chargé.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_display_panel_set_content(GtkDisplayPanel *panel, GLoadedContent *content)
+{
+    panel->view_index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel));
+
+    panel->display_options = g_loaded_content_get_all_display_options(content, panel->view_index);
+
+    panel->binary = G_LOADED_BINARY(content);
+
+    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach != NULL) /* REMME */
+        GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach(panel, panel->binary);
+
+    g_signal_connect(content, "display-changed", G_CALLBACK(on_view_panel_binary_display_change), panel);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = composant GTK à consulter.                           *
+*                                                                             *
+*  Description : Fournit le contenu associé à un panneau de chargement.       *
+*                                                                             *
+*  Retour      : Contenu quelconque chargé en mémoire.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *panel)
+{
+    GLoadedContent *result;                 /* Contenu à retourner         */
+
+    result = G_LOADED_CONTENT(panel->binary);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = composant GTK à manipuler.                           *
+*                cairo = assistant pour la création de rendus.                *
+*                area  = taille de la surface réduite à disposition.          *
+*                scale = échelle vis à vis de la taille réelle.               *
+*                                                                             *
+*  Description : Place en cache un rendu destiné à l'aperçu graphique rapide. *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void gtk_display_panel_cache_glance(GtkDisplayPanel *panel, cairo_t *cairo, const GtkAllocation *area, double scale)
+{
+    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance != NULL)
+        GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance(panel, cairo, area, scale);
+
+}
diff --git a/src/gtkext/gtkdisplaypanel.h b/src/gtkext/gtkdisplaypanel.h
index 3ea967a..7d4c824 100644
--- a/src/gtkext/gtkdisplaypanel.h
+++ b/src/gtkext/gtkdisplaypanel.h
@@ -50,15 +50,9 @@ typedef struct _GtkDisplayPanelClass GtkDisplayPanelClass;
 /* Détermine le type du composant d'affichage générique. */
 GType gtk_display_panel_get_type(void);
 
-/* Indique le type de contenu représenté par le composant. */
-BinaryView gtk_display_panel_describe_content(const GtkDisplayPanel *);
-
 /* Définit si une bordure est à afficher. */
 void gtk_display_panel_show_border(GtkDisplayPanel *, bool);
 
-/* Associe à un panneau d'affichage un binaire chargé. */
-void gtk_display_panel_attach_binary(GtkDisplayPanel *, GLoadedBinary *, BinaryView);
-
 /* Définit si les adresses doivent apparaître dans le rendu. */
 void gtk_display_panel_set_addresses_display(GtkDisplayPanel *, bool);
 
diff --git a/src/gui/editor.c b/src/gui/editor.c
index 6785753..d1f90d5 100644
--- a/src/gui/editor.c
+++ b/src/gui/editor.c
@@ -47,6 +47,7 @@
 #include "../core/global.h"
 #include "../core/params.h"
 #include "../gtkext/easygtk.h"
+#include "../gtkext/gtkdisplaypanel.h"
 #include "../gtkext/gtkdockable.h"
 #include "../gtkext/gtkdockstation.h"
 #include "../gtkext/support.h"
@@ -214,6 +215,11 @@ static void notify_paned_handle_position_change(GObject *, GParamSpec *, gpointe
 /* Réagit à un changement du projet principal. */
 static void notify_editor_project_change(GStudyProject *, bool);
 
+/* Assure un positionnement initial idéal. */
+static gboolean scroll_for_the_first_time(GtkWidget *, GdkEvent *, GLoadedContent *);
+
+/* Affiche le contenu qui vient de rejoindre un projet donné. */
+void on_editor_loaded_content_added(GStudyProject *, GLoadedContent *, void *);
 
 
 
@@ -1612,7 +1618,12 @@ static void notify_editor_project_change(GStudyProject *project, bool new)
     if (new)
     {
 
-        /* ... */
+
+        g_signal_connect(project, "content-added", G_CALLBACK(on_editor_loaded_content_added), NULL);
+
+
+
+        /* TODO : show_all()... */
 
 
     }
@@ -1623,9 +1634,86 @@ static void notify_editor_project_change(GStudyProject *project, bool new)
         g_study_project_hide(project);
 
 
+        g_signal_handlers_disconnect_by_func(project, G_CALLBACK(on_editor_loaded_content_added), NULL);
+
 
     }
 
 
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : project = project impliqué dans l'opération.                 *
+*                content = nouveau contenu à présenter dans l'éditeur.        *
+*                unused  = adresse non utilisée ici.                          *
+*                                                                             *
+*  Description : Affiche le contenu qui vient de rejoindre un projet donné.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void on_editor_loaded_content_added(GStudyProject *project, GLoadedContent *content, void *unused)
+{
+    GtkWidget *selected;                    /* Interface de prédilection   */
+    const char *name;                       /* Titre associé au binaire    */
+    const char *lname;                      /* Description du binaire      */
+    GPanelItem *panel;                      /* Nouveau panneau à integrer  */
+
+    selected = g_loaded_content_build_view(content, 0);
+
+    name = g_loaded_content_describe(content, false);
+    lname = g_loaded_content_describe(content, true);
+
+    panel = g_panel_item_new(PIP_BINARY_VIEW, name, lname, selected, true, "N");
+    register_panel_item(panel, get_main_configuration());
+
+    g_signal_connect(selected, "size-allocate", G_CALLBACK(scroll_for_the_first_time), content);
+
+    g_panel_item_dock(panel);
+
+    update_project_area(project);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget  = composant d'affichage nouvellement porté à l'écran.*
+*                event   = informations liées à l'événement.                  *
+*                content = contenu chargé associé au composant d'affichage.   *
+*                                                                             *
+*  Description : Assure un positionnement initial idéal.                      *
+*                                                                             *
+*  Retour      : FALSE.                                                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GLoadedContent *content)
+{
+    GExeFormat *format;                 /* Format associé au binaire       */
+    vmpa2t target;                      /* Position initiale à viser       */
+
+    g_signal_handlers_disconnect_by_func(widget, G_CALLBACK(scroll_for_the_first_time), content);
+
+    if (G_IS_LOADED_BINARY(content))
+    {
+        format = g_loaded_binary_get_format(G_LOADED_BINARY(content));
+
+        if (g_exe_format_get_main_address(format, &target))
+            gtk_display_panel_request_move(GTK_DISPLAY_PANEL(widget), &target);
+
+        g_object_unref(G_OBJECT(format));
+
+    }
+
+    return FALSE;
+
+}
diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c
index c46c017..5d027a0 100644
--- a/src/gui/menus/project.c
+++ b/src/gui/menus/project.c
@@ -46,8 +46,8 @@ static void mcb_project_add_shellcode(GtkMenuItem *, GMenuBar *);
 /* Affiche la boîte d'ajout d'un binaire au projet courant. */
 static void mcb_project_add_binary_file(GtkMenuItem *, GMenuBar *);
 
-/* Retire un binaire du projet indiqué. */
-static void mcb_project_remove_binary(GtkMenuItem *, GStudyProject *);
+/* Retire un contenu du projet indiqué. */
+static void mcb_project_remove_content(GtkMenuItem *, GStudyProject *);
 
 
 
@@ -122,8 +122,8 @@ void update_menu_project_for_project(GtkWidget *widget, GStudyProject *project,
     GtkWidget *menubar;                     /* Support pour éléments       */
     GList *list;                            /* Liste des éléments en place */
     GList *iter;                            /* Boucle de parcours #1       */
-    size_t count;                           /* Nombre de binaires attachés */
-    GLoadedBinary **binaries;               /* Liste de ces binaires       */
+    size_t count;                           /* Nombre de contenus attachés */
+    GLoadedContent **contents;              /* Liste de ces contenus       */
     size_t i;                               /* Boucle de parcours #2       */
     const char *desc;                       /* Description à afficher      */
     GtkWidget *submenuitem;                 /* Sous-menu à ajouter         */
@@ -142,23 +142,26 @@ void update_menu_project_for_project(GtkWidget *widget, GStudyProject *project,
 
     /* Ajout des entrées */ 
 
-    binaries = g_study_project_get_binaries(project, &count);
+    contents = g_study_project_get_contents(project, &count);
 
     for (i = 0; i < count; i++)
     {
-        desc = g_loaded_binary_get_name(binaries[i], true);
+        desc = g_loaded_content_describe(contents[i], true);
 
         submenuitem = qck_create_menu_item(NULL, NULL, desc,
-                                           G_CALLBACK(mcb_project_remove_binary), project);
-        g_object_set_data(G_OBJECT(submenuitem), "binary", binaries[i]);
+                                           G_CALLBACK(mcb_project_remove_content), project);
+        g_object_set_data_full(G_OBJECT(submenuitem), "content", contents[i], g_object_unref);
         gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
-        g_object_unref(G_OBJECT(binaries[i]));
+        /**
+         * Note : l'appel à g_object_unref() est réalisé lorsque la référence
+         *        est retirée du menu.
+         */
 
     }
 
-    if (binaries != NULL)
-        free(binaries);
+    if (contents != NULL)
+        free(contents);
 
     gtk_widget_set_sensitive(menuitem, count > 0);
 
@@ -304,7 +307,7 @@ static void mcb_project_add_binary_file(GtkMenuItem *menuitem, GMenuBar *bar)
 *  Paramètres  : menuitem = élément de menu sélectionné.                      *
 *                project  = projet d'appartenance du binaire à traiter.       *
 *                                                                             *
-*  Description : Retire un binaire du projet indiqué.                         *
+*  Description : Retire un contenu du projet indiqué.                         *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -312,13 +315,17 @@ static void mcb_project_add_binary_file(GtkMenuItem *menuitem, GMenuBar *bar)
 *                                                                             *
 ******************************************************************************/
 
-static void mcb_project_remove_binary(GtkMenuItem *menuitem, GStudyProject *project)
+static void mcb_project_remove_content(GtkMenuItem *menuitem, GStudyProject *project)
 {
-    GLoadedBinary *binary;                  /* Binaire à retirer           */
+    GObject *ref;                           /* Espace de référencement     */
+    GLoadedContent *content;                /* Contenu à retirer           */
 
-    binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(menuitem), "binary"));
+    ref = G_OBJECT(menuitem);
 
-    g_study_project_detach_binary(project, binary);
-    g_object_unref(G_OBJECT(binary));
+    content = G_LOADED_CONTENT(g_object_get_data(ref, "content"));
+
+    g_study_project_detach_content(project, content);
+
+    g_object_set_data(ref, "content", NULL);
 
 }
diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c
index 4298805..81b06d6 100644
--- a/src/gui/menus/view.c
+++ b/src/gui/menus/view.c
@@ -35,7 +35,7 @@
 #include "../core/global.h"
 #include "../core/items.h"
 #include "../core/panels.h"
-#include "../../analysis/project.h"
+#include "../../analysis/loaded.h"
 #include "../../gtkext/easygtk.h"
 #include "../../gtkext/gtkblockdisplay.h"
 #include "../../gtkext/gtkgraphdisplay.h"
@@ -125,17 +125,17 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
 
     submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_off", _("Physical offset"),
                                              G_CALLBACK(mcb_view_display_column), NULL);
-    g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_PHYSICAL));
+    g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_PHYSICAL));
     gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
     submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_addr", _("Virtual address"),
                                              G_CALLBACK(mcb_view_display_column), NULL);
-    g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_VIRTUAL));
+    g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_VIRTUAL));
     gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
     submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_code", _("Binary code"),
                                              G_CALLBACK(mcb_view_display_column), NULL);
-    g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_BINARY));
+    g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_BINARY));
     gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
 
     /* - */
@@ -175,8 +175,8 @@ void update_menu_view_for_view(GtkWidget *widget, GtkDisplayPanel *panel, GMenuB
     GtkRadioMenuItem *item;                 /* Elément de menu arbitraire  */
     GSList *radios;                         /* Liste des menus d'affichage */
     GSList *found;                          /* Elément de menu à activer   */
-    BinaryView content;                     /* Type de vue active          */
-    GLoadedBinary *binary;                  /* Binaire courant             */
+    GLoadedContent *content;                /* Contenu global représenté   */
+    unsigned int view_index;                /* Indice de représentation    */
     const bool *display;                    /* Règles d'affichage courantes*/
     GtkWidget *submenuitem;                 /* Sous-élément de menu        */
     bool status;                            /* Consigne d'affichage        */
@@ -226,13 +226,13 @@ void update_menu_view_for_view(GtkWidget *widget, GtkDisplayPanel *panel, GMenuB
 
     /* - */
 
-    content = gtk_display_panel_describe_content(panel);
+    content = g_loaded_panel_get_content(G_LOADED_PANEL(panel));
 
-    binary = get_current_binary();
+    view_index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel));
 
-    display = g_loaded_binary_get_column_display(binary, content);
+    display = g_loaded_content_get_all_display_options(content, view_index);
 
-    g_object_unref(G_OBJECT(binary));
+    g_object_unref(G_OBJECT(content));
 
     /* Positions physiques */
 
@@ -465,11 +465,12 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused)
 {
     GSList *group;                          /* Liste de menus radio        */
     GSList *iter;                           /* Boucle de parcours          */
-    BinaryView wanted;                      /* Nouvelle vue à présenter    */
-    GtkDisplayPanel *panel;                 /* Afficheur effectif de code  */
+    unsigned int wanted;                    /* Nouvelle vue à présenter    */
+    GLoadedPanel *panel;                    /* Afficheur effectif de code  */
     GtkDockStation *station;                /* Base du remplacement        */
-    GtkWidget *scroll;                      /* Nouveau support à utiliser  */
-    GtkDisplayPanel *new;                   /* Nouvel afficheur de code    */
+    GLoadedContent *content;                /* Contenu représenté          */
+    GtkWidget *support;                     /* Nouvel afficheur généraliste*/
+    GtkWidget *new;                         /* Panneau encapsulé           */
 
     /* On ne traite qu'une seule fois ! */
     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return;
@@ -483,16 +484,17 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused)
         wanted = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view"));
 
         panel = get_current_view();
-        station = get_dock_station_for_view_panel(panel);
+        station = get_dock_station_for_view_panel(GTK_WIDGET(panel));
 
-        /* En vue du retrait de la station d'accueil... */
-        scroll = get_scroll_window_for_view_panel(panel);
-        g_object_ref(G_OBJECT(scroll));
+        content = g_loaded_panel_get_content(panel);
 
-        new = get_alt_view_for_view_panel(panel, wanted);
-        scroll = get_scroll_window_for_view_panel(new);
+        support = g_loaded_content_build_view(content, wanted);
 
-        gtk_dock_panel_change_active_widget(station, scroll);
+        g_object_unref(G_OBJECT(content));
+
+        gtk_dock_panel_change_active_widget(station, support);
+
+        new = get_loaded_panel_from_built_view(support);
 
         change_editor_items_current_view(G_LOADED_PANEL(new));
 
@@ -518,25 +520,25 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused)
 
 static void mcb_view_display_column(GtkCheckMenuItem *menuitem, gpointer unused)
 {
-    BufferLineColumn col;                   /* Colonne à traiter           */
-    GLoadedBinary *binary;                  /* Binaire courant             */
-    GtkDisplayPanel *panel;                 /* Affichage courant           */
-    BinaryView view;                        /* Type de vue représentée     */
+    unsigned int option;                    /* Paramètre à traiter         */
     gboolean active;                        /* Etat de sélection du menu   */
+    GLoadedPanel *panel;                    /* Afficheur effectif de code  */
+    GLoadedContent *content;                /* Contenu représenté          */
+    unsigned int index;                     /* Indice de la vue courante   */
 
-    col = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_col"));
+    option = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_opt"));
 
-    binary = get_current_binary();
+    active = gtk_check_menu_item_get_active(menuitem);
 
     panel = get_current_view();
-    view = gtk_display_panel_describe_content(panel);
-    g_object_unref(G_OBJECT(panel));
+    content = g_loaded_panel_get_content(panel);
 
-    active = gtk_check_menu_item_get_active(menuitem);
+    index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel));
 
-    g_loaded_binary_set_column_display(binary, view, col, active);
+    g_loaded_content_set_display_option(content, index, option, active);
 
-    g_object_unref(G_OBJECT(binary));
+    g_object_unref(G_OBJECT(content));
+    g_object_unref(G_OBJECT(panel));
 
 }
 
-- 
cgit v0.11.2-87-g4458