From da22d42c9644de808dfc3484352c444ee4176bee Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 12 Mar 2016 22:31:35 +0100
Subject: Loaded all custom parameters storing positions of panels divisions.

---
 ChangeLog                   |  16 +++
 src/core/params.c           |   2 +
 src/glibext/configuration.c | 257 ++++++++++++++++++++++++++++++++++++--
 src/glibext/configuration.h |  59 ++++++++-
 src/gui/editor.c            | 297 +++++++++++++++++++++-----------------------
 src/main.c                  |   1 +
 6 files changed, 465 insertions(+), 167 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 26b669b..8d2d068 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 16-03-12  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/core/params.c:
+	Load all custom parameters storing positions of panels divisions.
+
+	* src/glibext/configuration.c:
+	* src/glibext/configuration.h:
+	Define groups of arbitrary parameters. Typo.
+
+	* src/gui/editor.c:
+	Clean the code. Give a new path to each complex node and use it
+	as a key for the global configuration.
+
+	* src/main.c:
+	Fix a compilation warning.
+
+16-03-12  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/gtkext/easygtk.c:
 	* src/gtkext/easygtk.h:
 	Compute the coordinates of a popup menu attached to a given widget.
diff --git a/src/core/params.c b/src/core/params.c
index 799798d..52dae76 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -168,6 +168,8 @@ bool load_main_config_parameters(void)
     param = g_generic_config_create_param(config, MPK_AUTO_SAVE, CPT_BOOLEAN, true);
     if (param == NULL) return false;
 
+    g_generic_config_create_group(config, "gui.panels.positions", CPT_INTEGER);
+
     return true;
 
 }
diff --git a/src/glibext/configuration.c b/src/glibext/configuration.c
index 8717fb4..069dbc3 100644
--- a/src/glibext/configuration.c
+++ b/src/glibext/configuration.c
@@ -105,6 +105,44 @@ static bool g_config_param_write(GCfgParam *, xmlDocPtr, xmlXPathContextPtr);
 
 
 
+/* --------------------- PARTIES IMPREVISIBLES DE CONFIGURATION --------------------- */
+
+
+/* Groupe de paramètres non fixés à l'avance (instance) */
+struct _GCfgGroup
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    char *root;                             /* Chemin d'accès commun       */
+    ConfigParamType type;                   /* Type de valeur              */
+
+};
+
+/* Groupe de paramètres non fixés à l'avance (classe) */
+struct _GCfgGroupClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des groupes de paramètres. */
+static void g_config_group_class_init(GCfgGroupClass *);
+
+/* Initialise une instance de groupe de paramètres. */
+static void g_config_group_init(GCfgGroup *);
+
+/* Supprime toutes les références externes. */
+static void g_config_group_dispose(GCfgGroup *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_config_group_finalize(GCfgGroup *);
+
+/* Charge tous les paramètres correspondants au groupe. */
+static void g_config_group_load(GCfgGroup *, GGenConfig *, xmlXPathContextPtr);
+
+
+
 /* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */
 
 
@@ -115,6 +153,7 @@ struct _GGenConfig
 
     char *filename;                         /* CHemin d'accès complet      */
 
+    GList *groups;                          /* Groupes d'éléments non fixés*/
     GList *params;                          /* Eléments de configuration   */
     GRWLock params_access;                  /* Verrou de protection        */
 
@@ -147,7 +186,7 @@ static void g_generic_config_finalize(GGenConfig *);
 /* ---------------------------------------------------------------------------------- */
 
 
-/* Indique le type défini par la GLib pour les configurations géénriques. */
+/* Indique le type défini par la GLib pour les configurations génériques. */
 G_DEFINE_TYPE(GCfgParam, g_config_param, G_TYPE_OBJECT);
 
 
@@ -257,9 +296,9 @@ static void g_config_param_finalize(GCfgParam *param)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : path   = chemin d'accès à un paramètre en guise de clef.     *
-*                type   = type de paramètre à installer.                      *
-*                ...    = valeur par défaut du paramètre.                     *
+*  Paramètres  : path = chemin d'accès à un paramètre en guise de clef.       *
+*                type = type de paramètre à installer.                        *
+*                ...  = valeur par défaut du paramètre.                       *
 *                                                                             *
 *  Description : Crée un paramètre de configuration.                          *
 *                                                                             *
@@ -352,7 +391,7 @@ GCfgParam *g_config_param_new_empty(const char *path, ConfigParamType type)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : config  = paramètre de configuration à charger.              *
+*  Paramètres  : param   = paramètre de configuration à charger.              *
 *                context = contexte de lecture d'un fichier XML.              *
 *                                                                             *
 *  Description : Lit un paramètre de configuration depuis un fichier.         *
@@ -412,7 +451,7 @@ static bool g_config_param_read(GCfgParam *param, xmlXPathContextPtr context)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : config  = paramètre de configuration à charger.              *
+*  Paramètres  : param   = paramètre de configuration à charger.              *
 *                xdoc    = document XML à mettre en place.                    *
 *                context = contexte de lecture d'un fichier XML.              *
 *                                                                             *
@@ -834,6 +873,172 @@ void g_config_param_get_value(GCfgParam *param, ...)
 
 
 /* ---------------------------------------------------------------------------------- */
+/*                       PARTIES IMPREVISIBLES DE CONFIGURATION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour les groupes de paramètres non prévisibiles. */
+G_DEFINE_TYPE(GCfgGroup, g_config_group, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des groupes de paramètres.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_config_group_class_init(GCfgGroupClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_config_group_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_config_group_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : group = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance de groupe de paramètres.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_config_group_init(GCfgGroup *group)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : group = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_config_group_dispose(GCfgGroup *group)
+{
+    G_OBJECT_CLASS(g_config_group_parent_class)->dispose(G_OBJECT(group));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : group = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_config_group_finalize(GCfgGroup *group)
+{
+    free(group->root);
+
+    G_OBJECT_CLASS(g_config_group_parent_class)->finalize(G_OBJECT(group));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : root = base du chemin d'accès à un groupe de paramètres.     *
+*                type = type de groupètre à installer.                        *
+*                                                                             *
+*  Description : Crée un groupe de paramètres de configuration.               *
+*                                                                             *
+*  Retour      : Groupe mis en place.                                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GCfgGroup *g_config_group_new(const char *root, ConfigParamType type)
+{
+    GCfgGroup *result;                      /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_CFG_GROUP, NULL);
+
+    result->root = strdup(root);
+    result->type = type;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : group   = groupe de paramètres de configuration à étudier.   *
+*                context = contexte de lecture d'un fichier XML.              *
+*                                                                             *
+*  Description : Charge tous les paramètres correspondants au groupe.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_config_group_load(GCfgGroup *group, GGenConfig *config, xmlXPathContextPtr context)
+{
+    char *access;                           /* Chemin d'accès XML          */
+    xmlXPathObjectPtr xpathObj;             /* Cible d'une recherche       */
+    int i;                                  /* Boucle de parcours          */
+    char *key;                              /* Clef d'accès à un paramètre */
+    GCfgParam *param;                       /* Nouveau paramètre à ajouter */
+
+    access = strdup(group->root);
+    access = strrpl(access, ".", "/");
+    access = stradd(access, "/*");
+    access = strprep(access, "/ChrysalideConfig/");
+
+    xpathObj = get_node_xpath_object(context, access);
+
+    for (i = 0; i < XPATH_OBJ_NODES_COUNT(xpathObj); i++)
+    {
+        asprintf(&key, "gui.panels.positions.%s", NODE_FROM_PATH_OBJ(xpathObj, i)->name);
+
+        param = g_config_param_new(key, CPT_INTEGER, -1);
+        _g_generic_config_add_param(config, param, false);
+
+        free(key);
+
+    }
+
+    if(xpathObj != NULL)    /* FIXME */
+        xmlXPathFreeObject(xpathObj);
+
+    free(access);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
 /*                         GESTION GENERIQUE DE CONFIGURATION                         */
 /* ---------------------------------------------------------------------------------- */
 
@@ -1046,6 +1251,13 @@ bool g_generic_config_read(GGenConfig *config)
 
     g_generic_config_rlock(config);
 
+    for (iter = g_list_first(config->groups);
+         iter != NULL;
+         iter = g_list_next(iter))
+    {
+        g_config_group_load(G_CFG_GROUP(iter->data), config, context);
+    }
+
     for (result = true, iter = g_list_first(config->params);
          result && iter != NULL;
          iter = g_list_next(iter))
@@ -1108,6 +1320,30 @@ bool g_generic_config_write(GGenConfig *config)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : config = configuration à mettre à jour.                      *
+*                param  = groupe de paramètres à prendre en compte.           *
+*                                                                             *
+*  Description : Ajoute la définition d'un groupe à une configuration.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_generic_config_add_group(GGenConfig *config, GCfgGroup *group)
+{
+    g_generic_config_wlock(config);
+
+    config->groups = g_list_append(config->groups, group);
+
+    g_generic_config_wunlock(config);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : config = ensemble de paramètres de configuration.            *
 *                path   = chemin d'accès au paramètre visé.                   *
 *                lock   = pose un verrou si ce n'est déjà fait.               *
@@ -1145,6 +1381,7 @@ GCfgParam *_g_generic_config_search(GGenConfig *config, const char *path, bool l
 *                                                                             *
 *  Paramètres  : config = configuration à mettre à jour.                      *
 *                param  = paramètre à intégrer dans la configuration.         *
+*                lock   = pose un verrou si ce n'est déjà fait.               *
 *                                                                             *
 *  Description : Ajoute un paramètre à une configuration.                     *
 *                                                                             *
@@ -1154,14 +1391,15 @@ GCfgParam *_g_generic_config_search(GGenConfig *config, const char *path, bool l
 *                                                                             *
 ******************************************************************************/
 
-GCfgParam *g_generic_config_add_param(GGenConfig *config, GCfgParam *param)
+GCfgParam *_g_generic_config_add_param(GGenConfig *config, GCfgParam *param, bool lock)
 {
     const char *path;                       /* Chemin d'accès unique       */
     GCfgParam *old;                         /* Test de présence            */
 
     path = g_config_param_get_path(param);
 
-    g_generic_config_wlock(config);
+    if (lock)
+        g_generic_config_wlock(config);
 
     old = _g_generic_config_search(config, path, false);
     if (old != NULL)
@@ -1172,7 +1410,8 @@ GCfgParam *g_generic_config_add_param(GGenConfig *config, GCfgParam *param)
 
     config->params = g_list_append(config->params, param);
 
-    g_generic_config_wunlock(config);
+    if (lock)
+        g_generic_config_wunlock(config);
 
     return param;
 
diff --git a/src/glibext/configuration.h b/src/glibext/configuration.h
index 84d494f..016a382 100644
--- a/src/glibext/configuration.h
+++ b/src/glibext/configuration.h
@@ -71,7 +71,7 @@ typedef struct _GCfgParam GCfgParam;
 typedef struct _GCfgParamClass GCfgParamClass;
 
 
-/* Indique le type défini par la GLib pour les configurations géénriques. */
+/* Indique le type défini par la GLib pour les configurations génériques. */
 GType g_config_param_get_type(void);
 
 /* Crée un paramètre de configuration. */
@@ -106,6 +106,32 @@ void g_config_param_get_value(GCfgParam *, ...);
 
 
 
+/* --------------------- PARTIES IMPREVISIBLES DE CONFIGURATION --------------------- */
+
+
+#define G_TYPE_CFG_GROUP                (g_config_group_get_type())
+#define G_CFG_GROUP(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CFG_GROUP, GCfgGroup))
+#define G_IS_CFG_GROUP(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CFG_GROUP))
+#define G_CFG_GROUP_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CFG_GROUP, GCfgGroupClass))
+#define G_IS_CFG_GROUP_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CFG_GROUP))
+#define G_CFG_GROUP_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CFG_GROUP, GCfgGroupClass))
+
+
+/* Groupe de paramètres non fixés à l'avance (instance) */
+typedef struct _GCfgGroup GCfgGroup;
+
+/* Groupe de paramètres non fixés à l'avance (classe) */
+typedef struct _GCfgGroupClass GCfgGroupClass;
+
+
+/* Indique le type défini par la GLib pour les groupes de paramètres non prévisibiles. */
+GType g_config_group_get_type(void);
+
+/* Crée un groupe de paramètres de configuration. */
+GCfgGroup *g_config_group_new(const char *, ConfigParamType);
+
+
+
 /* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */
 
 
@@ -150,6 +176,18 @@ bool g_generic_config_read(GGenConfig *);
 /* Ecrit la configuration dans un fichier. */
 bool g_generic_config_write(GGenConfig *);
 
+/* Ajoute la définition d'un groupe à une configuration. */
+void g_generic_config_add_group(GGenConfig *, GCfgGroup *);
+
+
+#define g_generic_config_create_group(c, p, t)                  \
+    ({                                                          \
+        GCfgGroup *__group;                                     \
+        __group = g_config_group_new(p, t);                     \
+        g_generic_config_add_group(c, __group);                 \
+    })
+
+
 /* Retrouve un élément de configuration par son chemin. */
 GCfgParam *_g_generic_config_search(GGenConfig *, const char *, bool);
 
@@ -176,9 +214,11 @@ GCfgParam *_g_generic_config_search(GGenConfig *, const char *, bool);
 
 
 /* Ajoute un paramètre à une configuration. */
-GCfgParam *g_generic_config_add_param(GGenConfig *, GCfgParam *);
+GCfgParam *_g_generic_config_add_param(GGenConfig *, GCfgParam *, bool);
 
 
+#define g_generic_config_add_param(c, p) _g_generic_config_add_param(c, p, true)
+
 #define g_generic_config_create_param(c, p, t, ...)             \
     ({                                                          \
         GCfgParam *__result;                                    \
@@ -188,6 +228,21 @@ GCfgParam *g_generic_config_add_param(GGenConfig *, GCfgParam *);
     })
 
 
+#define g_generic_config_create_or_udpdate_param(c, p, t, ...)  \
+    ({                                                          \
+        GCfgParam *__param;                                     \
+        __param = g_generic_config_search(c, p);                \
+        if (__param == NULL)                                    \
+        {                                                       \
+            __param = g_config_param_new(p, t, __VA_ARGS__);    \
+            __param = g_generic_config_add_param(c, __param);   \
+        }                                                       \
+        if (__param != NULL)                                    \
+            g_config_param_set_value(__param, __VA_ARGS__);     \
+        __param != NULL ? true : false;                         \
+    })
+
+
 /* Retire un paramètre d'une configuration. */
 void g_generic_config_delete_param(GGenConfig *, const char *);
 
diff --git a/src/gui/editor.c b/src/gui/editor.c
index e5ec4d7..f29ffe7 100644
--- a/src/gui/editor.c
+++ b/src/gui/editor.c
@@ -100,6 +100,8 @@ typedef struct _panel_node
 {
     struct _panel_node *parent;             /* Noeud parent                */
 
+    char *path;                             /* Chemin du nom courant       */
+
     union
     {
         GtkWidget *widget;                  /* Accès généraliste           */
@@ -111,10 +113,7 @@ typedef struct _panel_node
     union
     {
         /* Version simple */
-        struct
-        {
-            char *path;                     /* Chemin du nom courant       */
-        };
+        /* ... */
 
         /* Version composée */
         struct
@@ -152,8 +151,8 @@ static void switch_panel_node_into_paned(panel_node *, bool, bool);
 /* Met en place un nouveau noeud dans une division. */
 static void attach_panel_node_to_paned(panel_node *, panel_node *, bool);
 
-/* Obtient la désignation d'un élément hiérarchie des noeuds. */
-static char *get_panel_node_path(const panel_node *);
+/* Met à jour en cascade les chemins d'accès aux noeuds. */
+static void update_path_of_paned_nodes(panel_node *, const char *);
 
 /* Détermine la plus grande longueur commune entre éléments. */
 static size_t compute_path_common_length(const panel_node *, const char *);
@@ -164,6 +163,9 @@ static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *,
 /* Tente de mettre la main sur une station d'accueil. */
 static panel_node *find_node_for_station(panel_node *, GtkWidget *);
 
+/* Tente de mettre la main sur un panneau de division graphique. */
+static panel_node *find_node_for_paned(panel_node *, GtkWidget *);
+
 /* Efface de l'organisation un noeud donné en place. */
 static void delete_panel_node(panel_node *);
 
@@ -187,6 +189,8 @@ static void on_dock_menu_request(GtkDockStation *, GtkWidget *, GObject *);
 /* Réagit à une demande de fermeture du panneau courant. */
 static void on_dock_close_request(GtkDockStation *, GtkWidget *, GObject *);
 
+/* Réagit à une variation dans une séparation de panneaux. */
+static void notify_paned_handle_position_change(GObject *, GParamSpec *, gpointer);
 
 
 
@@ -436,11 +440,6 @@ static void on_destroy_editor(GtkWidget *widget, gpointer data)
     project = get_current_project();
     if (project != NULL) g_object_unref(G_OBJECT(project));
 
-    //if (!result)
-        save_panel_nodes();
-
-
-
     /* Fermeture propre */
 
     /* ... */
@@ -587,6 +586,8 @@ static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool firs
 
     memcpy(moved, node, sizeof(panel_node));
 
+    node->path = NULL;
+
     if (!IS_SIMPLE_NODE(moved))
     {
         moved->first->parent = moved;
@@ -600,6 +601,8 @@ static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool firs
     else
         node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
 
+    g_signal_connect(node->paned, "notify::position", G_CALLBACK(notify_paned_handle_position_change), NULL);
+
     gtk_widget_show(node->paned);
 
     if (parent == NULL)
@@ -607,54 +610,6 @@ static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool firs
     else
         attach_panel_node_to_paned(parent, node, parent->first == node);
 
-
-
-
-    /* Premier ajustement */
-
-    void split_paned_support(GtkWidget *support, GdkRectangle *alloc, gpointer data)
-    {
-        GtkOrientation orientation;
-        gint position;
-
-        orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(support));
-
-        if (orientation == GTK_ORIENTATION_HORIZONTAL)
-            position = alloc->width / 2;
-        else
-            position = alloc->height / 2;
-
-        /*
-        if (position < 50)
-        position *= 2;
-        */
-
-        gtk_paned_set_position(GTK_PANED(support), position);
-
-        fprintf(stderr, "widget size is currently %dx%d\n", alloc->width, alloc->height);
-
-
-        fprintf(stderr, "position = %d\n", position);
-
-        fprintf(stderr, "---\n");
-
-
-        g_signal_handlers_disconnect_by_func(support, G_CALLBACK(split_paned_support), NULL);
-
-    }
-
-    //g_signal_connect(current->paned, "size-allocate", G_CALLBACK(split_paned_support), NULL);
-
-    static int __counter = 0;
-
-
-
-    if (++__counter == 4)
-        gtk_paned_set_position(GTK_PANED(node->paned), 100);
-
-
-
-
     /* Replace le composant d'origine */
 
     attach_panel_node_to_paned(node, moved, first);
@@ -683,8 +638,13 @@ static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, boo
     /* On se trouve à la racine... */
 
     if (parent == NULL)
+    {
         gtk_container_add(GTK_CONTAINER(_support), node->widget);
 
+        update_path_of_paned_nodes(node, "");
+
+    }
+
     else
     {
         /* Raccordement hiérarchique */
@@ -703,6 +663,10 @@ static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, boo
         else
             gtk_paned_pack2(GTK_PANED(parent->paned), node->widget, TRUE, FALSE);
 
+        /* Mise à jour des chemins */
+
+        update_path_of_paned_nodes(node, parent->path);
+
     }
 
 }
@@ -710,40 +674,57 @@ static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, boo
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : node = noeud dont la désignation est à obtenir.              *
+*  Paramètres  : node = noeud dont le chemin est à mettre à jour.             *
+*                root = chemin menant au niveau précédent.                    *
 *                                                                             *
-*  Description : Obtient la désignation d'un élément hiérarchie des noeuds.   *
+*  Description : Met à jour en cascade les chemins d'accès aux noeuds.        *
 *                                                                             *
-*  Retour      : Chaîne construite à libérer de la mémoire après usage.       *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static char *get_panel_node_path(const panel_node *node)
+static void update_path_of_paned_nodes(panel_node *node, const char *root)
 {
-    char *result;                           /* Valeur à retourner          */
-    char *extra;                            /* Complément à ajouter        */
-
-    if (IS_SIMPLE_NODE(node))
-        result = strdup(node->path);
+    GtkOrientation orientation;             /* Orientation du support      */
+    char *key;                              /* Clef d'accès à un paramètre */
+    gint position;                          /* Nouvelle position de barre  */
 
-    else
+    if (!IS_SIMPLE_NODE(node))
     {
-        result = get_panel_node_path(node->first);
+        /* Reconstruction locale */
 
-        extra = get_panel_node_path(node->second);
-        result = stradd(result, "-");
-        result = stradd(result, extra);
-        free(extra);
+        if (node->path != NULL)
+            free(node->path);
 
-        result = strprep(result, "(");
-        result = stradd(result, ")");
+        node->path = strdup(root);
 
+        orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(node->paned));
 
-    }
+        if (orientation == GTK_ORIENTATION_HORIZONTAL)
+            node->path = stradd(node->path, "h");
+        else
+            node->path = stradd(node->path, "v");
 
-    return result;
+        /* Rechargement de la position ? */
+
+        asprintf(&key, "gui.panels.positions.%s", node->path);
+
+        if (g_generic_config_get_value(get_main_configuration(), key, &position))
+            gtk_paned_set_position(GTK_PANED(node->paned), position);
+
+        free(key);
+
+        /* Propagation de la mise à jour */
+
+        if (node->first)
+            update_path_of_paned_nodes(node->first, node->path);
+
+        if (node->second != NULL)
+            update_path_of_paned_nodes(node->second, node->path);
+
+    }
 
 }
 
@@ -865,8 +846,9 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
         common2 = compute_path_common_length(node->second, path);
 
 
-        fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, get_panel_node_path(node->first));
-        fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, get_panel_node_path(node->second));
+
+        fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, node->first->path);
+        fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, node->second->path);
 
 
         /* Si une descente est possible... */
@@ -909,7 +891,8 @@ static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : node = point de départ des recherches locales.               *
+*  Paramètres  : node    = point de départ des recherches locales.            *
+*                station = composant graphique à retrouver.                   *
 *                                                                             *
 *  Description : Tente de mettre la main sur une station d'accueil.           *
 *                                                                             *
@@ -942,6 +925,47 @@ static panel_node *find_node_for_station(panel_node *node, GtkWidget *station)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : node  = point de départ des recherches locales.              *
+*                paned = composant graphique à retrouver.                     *
+*                                                                             *
+*  Description : Tente de mettre la main sur un panneau de division graphique.*
+*                                                                             *
+*  Retour      : Eventuel noeud trouvé ou NULL.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static panel_node *find_node_for_paned(panel_node *node, GtkWidget *paned)
+{
+    panel_node *result;                     /* Bilan à remonter            */
+
+    if (IS_SIMPLE_NODE(node))
+        result = NULL;
+
+    else
+    {
+        if (node->paned == paned)
+            result = node;
+
+        else
+        {
+            result = find_node_for_paned(node->first, paned);
+
+            if (result == NULL)
+                result = find_node_for_paned(node->second, paned);
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : node = noeud à supprimer de l'arbre des noeuds.              *
 *                                                                             *
 *  Description : Efface de l'organisation un noeud donné en place.            *
@@ -1014,81 +1038,6 @@ static void delete_panel_node(panel_node *node)
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-#if 1
-
-
-#include "../core/params.h"
-
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : current = point de départ de la réorganisation graphique.    *
-*                                                                             *
-*  Description : Met à jour l'affichage suite à un changement hiérarchique.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void save_panel_nodes(void)
-{
-
-
-    fprintf(stderr, "Passage avec %p\n", _nodes);
-
-    return;
-    void store_handle_position(panel_node *node, GGenConfig *config)
-    {
-
-        size_t i;
-
-        for (i = 0; i < 0/*node->depth*/; i++)
-            fprintf(stderr, "  ");
-
-
-        ///fprintf(stderr, "[%s] %s\n", node->path, node->simple ? "[+]" : ">>");
-
-
-        if (0/*!node->simple*/)
-        {
-            store_handle_position(node->first, config);
-            store_handle_position(node->second, config);
-        }
-
-
-    }
-
-
-    //get_main_configuration()
-
-
-    store_handle_position(_nodes, NULL);
-
-    fflush(NULL);
-
-
-}
-
-#endif
-
-
-
-
-
 /* ---------------------------------------------------------------------------------- */
 /*                     INTERACTIONS GRAPHIQUES LIEES AUX PANNEAUX                     */
 /* ---------------------------------------------------------------------------------- */
@@ -1340,3 +1289,39 @@ static void on_dock_close_request(GtkDockStation *station, GtkWidget *button, GO
     g_panel_item_undock(panel);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : obj    = objet à l'origine de la procédure.                  *
+*                pspec  = spécification de l'attribut qui a varié.            *
+*                unused = adresse non utilisée ici.                           *
+*                                                                             *
+*  Description : Réagit à une variation dans une séparation de panneaux.      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void notify_paned_handle_position_change(GObject *obj, GParamSpec *pspec, gpointer unused)
+{
+    GtkPaned *paned;                        /* Panneau concerné            */
+    panel_node *node;                       /* Noeud hiérarchique associé  */
+    gint position;                          /* Nouvelle position de barre  */
+    char *key;                              /* Clef d'accès à un paramètre */
+
+    paned = GTK_PANED(obj);
+
+    node = find_node_for_paned(_nodes, GTK_WIDGET(paned));
+
+    position = gtk_paned_get_position(paned);
+
+    asprintf(&key, "gui.panels.positions.%s", node->path);
+
+    g_generic_config_create_or_udpdate_param(get_main_configuration(), key, CPT_INTEGER, position);
+
+    free(key);
+
+}
diff --git a/src/main.c b/src/main.c
index 74ba72f..2de2379 100644
--- a/src/main.c
+++ b/src/main.c
@@ -37,6 +37,7 @@
 #include "glibext/gbinportion.h"
 #include "gtkext/theme.h"
 #include "gui/editor.h"
+#include "gui/core/core.h"
 #include "plugins/pglist.h"
 
 
-- 
cgit v0.11.2-87-g4458