From 59febc74741332fec4df71962fe9174d511df384 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 4 Jul 2021 22:55:30 +0200
Subject: Save all needed information into project files.

---
 plugins/pychrysalide/analysis/binary.c |  13 +-
 src/analysis/binary.c                  | 286 ++++++---------------------------
 src/analysis/binary.h                  |  14 +-
 src/analysis/project.c                 |  67 +-------
 src/gui/dialogs/snapshots.c            |   2 +-
 src/gui/dialogs/storage.c              | 142 ----------------
 src/gui/dialogs/storage.ui             | 193 ++++++----------------
 src/gui/panels/history.c               |   4 +-
 8 files changed, 106 insertions(+), 615 deletions(-)

diff --git a/plugins/pychrysalide/analysis/binary.c b/plugins/pychrysalide/analysis/binary.c
index 68f2d88..c9dc9c5 100644
--- a/plugins/pychrysalide/analysis/binary.c
+++ b/plugins/pychrysalide/analysis/binary.c
@@ -124,15 +124,13 @@ static PyObject *py_loaded_binary_new(PyTypeObject *type, PyObject *args, PyObje
 static PyObject *py_loaded_binary_get_client(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Bilan à retourner           */
-    int internal;                           /* Nature du client visé       */
-    int ret;                                /* Bilan de lecture des args.  */
     GLoadedBinary *binary;                  /* Binaire en cours d'analyse  */
     GAnalystClient *client;                 /* Eventuel client en place    */
 
 #define LOADED_BINARY_GET_CLIENT_METHOD PYTHON_METHOD_DEF               \
 (                                                                       \
-    get_client, "$self, /, internal=True",                              \
-    METH_VARARGS, py_loaded_binary,                                     \
+    get_client, "$self",                                                \
+    METH_NOARGS, py_loaded_binary,                                      \
     "Provide the client connected to an internal or remote server"      \
     " if defined, or return None otherwise.\n"                          \
     "\n"                                                                \
@@ -140,14 +138,9 @@ static PyObject *py_loaded_binary_get_client(PyObject *self, PyObject *args)
     " instance or *None*."                                              \
 )
 
-    internal = 1;
-
-    ret = PyArg_ParseTuple(args, "|p", &internal);
-    if (!ret) return NULL;
-
     binary = G_LOADED_BINARY(pygobject_get(self));
 
-    client = g_loaded_binary_get_client(binary, internal);
+    client = g_loaded_binary_get_client(binary);
 
     if (client != NULL)
     {
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 19b46a2..2b23eff 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -65,17 +65,11 @@ struct _GLoadedBinary
 {
     GObject parent;                         /* A laisser en premier        */
 
-    char *username;                         /* Identifiant de l'utilisateur*/
-    bool username_changed;                  /* Mémorise les changements    */
-
     bool use_remote;                        /* Enregistrements distants ?  */
     char *remote_host;                      /* Nom du serveur distant      */
     char *remote_port;                      /* Port du serveur distant     */
+    GAnalystClient *client;                 /* Enregistrements courants    */
 
-    GAnalystClient *local;                  /* Enregistrements locaux      */
-    GAnalystClient *remote;                 /* Enregistrements distants    */
-
-    DBStorage storages[DBF_COUNT];          /* Lieux d'enregistrement      */
     GList *collections;                     /* Ensemble de modifications   */
 
     GExeFormat *format;                     /* Format du binaire           */
@@ -246,17 +240,10 @@ static void g_loaded_binary_class_init(GLoadedBinaryClass *klass)
 
 static void g_loaded_binary_init(GLoadedBinary *binary)
 {
-    binary->username = strdup("default");
-
     binary->use_remote = false;
     binary->remote_host = strdup("localhost");
     binary->remote_port = strdup("1337");
 
-    binary->storages[DBF_BOOKMARKS] = DBS_ALL_LOCAL;
-    binary->storages[DBF_COMMENTS] = DBS_ALL_LOCAL;
-    binary->storages[DBF_MOVES] = DBS_ALL_LOCAL;
-    binary->storages[DBF_DISPLAY_SWITCHERS] = DBS_ALL_LOCAL;
-
     binary->collections = create_collections_list();
     attach_binary_to_collections(binary->collections, binary);
 
@@ -332,8 +319,7 @@ static void g_loaded_binary_dispose(GLoadedBinary *binary)
 {
     BinaryView i;                           /* Boucle de parcours          */
 
-    g_clear_object(&binary->local);
-    g_clear_object(&binary->remote);
+    g_clear_object(&binary->client);
 
     delete_collections_list(&binary->collections);
 
@@ -366,9 +352,8 @@ static void g_loaded_binary_dispose(GLoadedBinary *binary)
 
 static void g_loaded_binary_finalize(GLoadedBinary *binary)
 {
-    free(binary->username);
-
     free(binary->remote_host);
+    free(binary->remote_port);
 
     G_OBJECT_CLASS(g_loaded_binary_parent_class)->finalize(G_OBJECT(binary));
 
@@ -427,7 +412,6 @@ static bool g_loaded_binary_load_storage(GLoadedBinary *binary, xmlXPathContext
     char *value;                            /* Valeur lue à partie du XML  */
     char *access;                           /* Chemin d'accès à un élément */
     char *port;                             /* Port de communication       */
-    DBFeatures i;                           /* Boucle de parcours          */
 
     result = true;
 
@@ -441,21 +425,6 @@ static bool g_loaded_binary_load_storage(GLoadedBinary *binary, xmlXPathContext
 
     free(value);
 
-    /* Nom d'utilisateur */
-
-    access = strdup(storage_path);
-    access = stradd(access, "/Username");
-
-    value = get_node_text_value(context, access);
-
-    if (value != NULL)
-    {
-        g_loaded_binary_set_username(binary, value);
-        free(value);
-    }
-
-    free(access);
-
     /* Serveur distant */
 
     access = strdup(storage_path);
@@ -483,46 +452,6 @@ static bool g_loaded_binary_load_storage(GLoadedBinary *binary, xmlXPathContext
 
     free(access);
 
-    /* Fonctionnalités */
-
-    for (i = 0; i < DBF_COUNT; i++)
-    {
-        access = strdup(storage_path);
-        access = stradd(access, "/Features/");
-
-        switch (i)
-        {
-            case DBF_BOOKMARKS:
-                access = stradd(access, "Bookmarks");
-                break;
-            case DBF_COMMENTS:
-                access = stradd(access, "Comments");
-                break;
-            case DBF_MOVES:
-                access = stradd(access, "Moves");
-                break;
-            case DBF_DISPLAY_SWITCHERS:
-                access = stradd(access, "Segments");
-                break;
-            default:
-                /* Pour GCC */
-                assert(false);
-                break;
-        }
-
-        value = get_node_text_value(context, access);
-
-        if (value != NULL)
-        {
-            if (atoi(value) <= DBS_MAX)
-                g_loaded_binary_set_storage(binary, i, atoi(value));
-
-        }
-
-        free(access);
-
-    }
-
     if (binary->use_remote)
         g_loaded_binary_set_remote_storage_usage(binary, true);
 
@@ -555,7 +484,6 @@ static bool g_loaded_binary_save_storage(const GLoadedBinary *binary, xmlDoc *xd
     bool result;                            /* Bilan à faire remonter      */
     char *storage_path;                     /* Partie "Enregistrement"     */
     char *access;                           /* Chemin d'accès à un élément */
-    DBFeatures i;                           /* Boucle de parcours          */
 
     result = true;
 
@@ -565,15 +493,6 @@ static bool g_loaded_binary_save_storage(const GLoadedBinary *binary, xmlDoc *xd
     result &= add_string_attribute_to_node(xdoc, context, storage_path, "remote",
                                            binary->use_remote ? "true" : "false");
 
-    /* Nom d'utilisateur */
-
-    access = strdup(storage_path);
-    access = stradd(access, "/Username");
-
-    result &= add_content_to_node(xdoc, context, access, binary->username);
-
-    free(access);
-
     /* Serveur distant */
 
     access = strdup(storage_path);
@@ -585,39 +504,6 @@ static bool g_loaded_binary_save_storage(const GLoadedBinary *binary, xmlDoc *xd
 
     free(access);
 
-    /* Fonctionnalités */
-
-    for (i = 0; i < DBF_COUNT; i++)
-    {
-        access = strdup(storage_path);
-        access = stradd(access, "/Features/");
-
-        switch (i)
-        {
-            case DBF_BOOKMARKS:
-                access = stradd(access, "Bookmarks");
-                break;
-            case DBF_COMMENTS:
-                access = stradd(access, "Comments");
-                break;
-            case DBF_MOVES:
-                access = stradd(access, "Moves");
-                break;
-            case DBF_DISPLAY_SWITCHERS:
-                access = stradd(access, "Segments");
-                break;
-            default:
-                /* Pour GCC */
-                assert(false);
-                break;
-        }
-
-        result &= add_uint_content_to_node(xdoc, context, access, binary->storages[i]);
-
-        free(access);
-
-    }
-
     free(storage_path);
 
     return result;
@@ -629,52 +515,6 @@ static bool g_loaded_binary_save_storage(const GLoadedBinary *binary, xmlDoc *xd
 *                                                                             *
 *  Paramètres  : binary = élément binaire à consulter.                        *
 *                                                                             *
-*  Description : Identifie l'utilisateur analysant le binaire courant.        *
-*                                                                             *
-*  Retour      : Nom de l'utilisateur manipulant le binaire.                  *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-const char *g_loaded_binary_get_username(const GLoadedBinary *binary)
-{
-    return binary->username;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary   = élément binaire à consulter.                      *
-*                username = nom de l'utilisateur manipulant le binaire.       *
-*                                                                             *
-*  Description : Définit l'utilisateur analysant le binaire courant.          *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_loaded_binary_set_username(GLoadedBinary *binary, const char *username)
-{
-    bool changed;                           /* Note les changements        */
-
-    changed = (strcmp(binary->username, username) != 0);
-
-    free(binary->username);
-    binary->username = strdup(username);
-
-    binary->username_changed = changed;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary = élément binaire à consulter.                        *
-*                                                                             *
 *  Description : Détermine si tous les enregistrements sont locaux ou non.    *
 *                                                                             *
 *  Retour      : Statut de l'utilisation du serveur local.                    *
@@ -707,7 +547,7 @@ void g_loaded_binary_set_remote_storage_usage(GLoadedBinary *binary, bool use)
 {
     binary->use_remote = use;
 
-    g_clear_object(&binary->remote);
+    g_clear_object(&binary->client);
 
     if (use)
         g_loaded_binary_connect_remote(binary);
@@ -764,47 +604,6 @@ void g_loaded_binary_set_remote_server(GLoadedBinary *binary, const char *host,
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary  = élément binaire à consulter.                       *
-*                feature = fonctionnalité visée par la requête.               *
-*                                                                             *
-*  Description : Indique la forme d'enregistrement d'une fonctionnalité.      *
-*                                                                             *
-*  Retour      : Type d'enregistrement sélectionné.                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-DBStorage g_loaded_binary_get_storage(const GLoadedBinary *binary, DBFeatures feature)
-{
-    return binary->storages[feature];
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : binary  = élément binaire à consulter.                       *
-*                feature = fonctionnalité visée par la requête.               *
-*                storage = type d'enregistrement sélectionné.                 *
-*                                                                             *
-*  Description : Définit la forme d'enregistrement d'une fonctionnalité.      *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-void g_loaded_binary_set_storage(GLoadedBinary *binary, DBFeatures feature, DBStorage storage)
-{
-    binary->storages[feature] = storage;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : binary = élément binaire à manipuler.                        *
 *                                                                             *
 *  Description : Etablit une connexion au serveur interne en tant que client. *
@@ -829,9 +628,9 @@ static bool g_loaded_binary_connect_internal(GLoadedBinary *binary)
 
     /* Tentative de connexion */
 
-    binary->local = g_analyst_client_new(checksum, binary->collections);
+    binary->client = g_analyst_client_new(checksum, binary->collections);
 
-    result = g_hub_client_start_internal(G_HUB_CLIENT(binary->local));
+    result = g_hub_client_start_internal(G_HUB_CLIENT(binary->client));
 
     return result;
 
@@ -856,7 +655,7 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *binary)
     GBinContent *content;                   /* Contenu bianire manipulé    */
     const gchar *checksum;                  /* Identifiant de binaire      */
 
-    assert(binary->remote == NULL);
+    assert(binary->client == NULL);
 
     /* Détermination de l'identifiant */
 
@@ -866,9 +665,9 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *binary)
 
     /* Tentative de connexion */
 
-    binary->remote = g_analyst_client_new(checksum, binary->collections);
+    binary->client = g_analyst_client_new(checksum, binary->collections);
 
-    result = g_hub_client_start_remote(G_HUB_CLIENT(binary->remote),
+    result = g_hub_client_start_remote(G_HUB_CLIENT(binary->client),
                                        binary->remote_host, binary->remote_port, true);
 
     if (!result)
@@ -876,7 +675,7 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *binary)
         log_variadic_message(LMT_ERROR, _("Failed to connect to remote host '%s:%s'"),
                              binary->remote_host, binary->remote_port);
 
-        g_clear_object(&binary->remote);
+        g_clear_object(&binary->client);
 
     }
 
@@ -940,8 +739,7 @@ bool g_loaded_binary_save_cache(const GLoadedBinary *binary)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary   = élément binaire à consulter.                      *
-*                internal = sélectionne le client à renvoyer selon sa nature. *
+*  Paramètres  : binary = élément binaire à consulter.                        *
 *                                                                             *
 *  Description : Fournit un client assurant la liaison avec un serveur.       *
 *                                                                             *
@@ -951,14 +749,11 @@ bool g_loaded_binary_save_cache(const GLoadedBinary *binary)
 *                                                                             *
 ******************************************************************************/
 
-GAnalystClient *g_loaded_binary_get_client(const GLoadedBinary *binary, bool internal)
+GAnalystClient *g_loaded_binary_get_client(const GLoadedBinary *binary)
 {
     GAnalystClient *result;                 /* Instance à retourner        */
 
-    if (internal)
-        result = binary->local;
-    else
-        result = binary->remote;
+    result = binary->client;
 
     if (result != NULL)
         g_object_ref(G_OBJECT(result));
@@ -1054,15 +849,9 @@ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *binary, DBFe
 bool g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item)
 {
     bool result;                            /* Bilan à faire remonter      */
-    DBFeatures feature;                     /* Domaine de fonctionnalité   */
-    DBStorage storage;                      /* Forme d'enregistrement      */
     GAnalystClient *client;                 /* Liaison à utiliser          */
 
-    feature = g_db_item_get_feature(item);
-
-    storage = g_loaded_binary_get_storage(binary, feature);
-
-    client = g_loaded_binary_get_client(binary, storage == DBS_ALL_LOCAL);
+    client = g_loaded_binary_get_client(binary);
 
     if (client == NULL)
     {
@@ -1099,24 +888,13 @@ bool g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item)
 bool g_loaded_binary_set_last_active(GLoadedBinary *binary, timestamp_t timestamp)
 {
     bool result;                            /* Bilan à retourner           */
-    bool done;                              /* Suivi des actions menées    */
 
     result = true;
-    done = false;
 
-    if (binary->local != NULL)
-    {
-        result = g_analyst_client_set_last_active(binary->local, timestamp);
-        done = true;
-    }
-
-    if (result && binary->remote != NULL)
-    {
-        result = g_analyst_client_set_last_active(binary->remote, timestamp);
-        done = true;
-    }
+    if (binary->client != NULL)
+        result = g_analyst_client_set_last_active(binary->client, timestamp);
 
-    if (!done)
+    else
     {
         log_simple_message(LMT_ERROR, _("No connection to a server found in order to set timestamp"));
         result = false;
@@ -1530,6 +1308,9 @@ static bool g_loaded_binary_restore(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPat
 static bool g_loaded_binary_save(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPathContext *context, const char *path)
 {
     bool result;                            /* Bilan à faire remonter      */
+    GBinContent *content;                   /* Contenu brut à manipuler    */
+    const gchar *hash;                      /* Empreinte d'un contenu      */
+    char *key;                              /* Support associé au contenu  */
 
     /* Mise en cache des instructions */
 
@@ -1538,6 +1319,31 @@ static bool g_loaded_binary_save(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPathCo
     /* Elément divers associés au binaire */
 
     if (result)
+    {
+        content = g_loaded_content_get_content(G_LOADED_CONTENT(binary));
+
+        hash = g_binary_content_get_checksum(content);
+        result = add_string_attribute_to_node(xdoc, context, path, "hash", hash);
+
+        g_object_unref(G_OBJECT(content));
+
+    }
+
+    if (result)
+    {
+        key = g_loaded_content_get_format_name(G_LOADED_CONTENT(binary));
+        result = add_string_attribute_to_node(xdoc, context, path, "format", key);
+        free(key);
+    }
+
+    if (result)
+    {
+        key = g_arch_processor_get_key(binary->proc);
+        result = add_string_attribute_to_node(xdoc, context, path, "arch", key);
+        free(key);
+    }
+
+    if (result)
         result = g_loaded_binary_save_storage(binary, xdoc, context, path);
 
     if (result)
@@ -1546,7 +1352,7 @@ static bool g_loaded_binary_save(GLoadedBinary *binary, xmlDoc *xdoc, xmlXPathCo
     /* Sauvegarde côté serveur */
 
     if (result)
-        g_analyst_client_save(binary->local);
+        g_analyst_client_save(binary->client);
 
     return result;
 
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 56f21a1..0241381 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -81,12 +81,6 @@ GLoadedContent *g_loaded_binary_new(GExeFormat *);
 /* ------------------------- INFORMATIONS D'ENREGISTREMENTS ------------------------- */
 
 
-/* Identifie l'utilisateur analysant le binaire courant. */
-const char *g_loaded_binary_get_username(const GLoadedBinary *);
-
-/* Définit l'utilisateur analysant le binaire courant. */
-void g_loaded_binary_set_username(GLoadedBinary *, const char *);
-
 /* Détermine si tous les enregistrements sont locaux ou non. */
 bool g_loaded_binary_use_remote_storage(const GLoadedBinary *);
 
@@ -99,12 +93,6 @@ void g_loaded_binary_get_remote_server(const GLoadedBinary *, const char **, con
 /* Définit le serveur distant associé au binaire courant. */
 void g_loaded_binary_set_remote_server(GLoadedBinary *, const char *, const char *);
 
-/* Indique la forme d'enregistrement d'une fonctionnalité. */
-DBStorage g_loaded_binary_get_storage(const GLoadedBinary *, DBFeatures);
-
-/* Définit la forme d'enregistrement d'une fonctionnalité. */
-void g_loaded_binary_set_storage(GLoadedBinary *, DBFeatures, DBStorage);
-
 /* Sauvegarde le cache des instructions désassemblées. */
 bool g_loaded_binary_save_cache(const GLoadedBinary *);
 
@@ -114,7 +102,7 @@ bool g_loaded_binary_save_cache(const GLoadedBinary *);
 
 
 /* Fournit un client assurant la liaison avec un serveur. */
-GAnalystClient *g_loaded_binary_get_client(const GLoadedBinary *, bool);
+GAnalystClient *g_loaded_binary_get_client(const GLoadedBinary *);
 
 /* Fournit l'ensemble des collections utilisées par un binaire. */
 GDbCollection **g_loaded_binary_get_collections(const GLoadedBinary *, size_t *);
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 13985f3..b57afc7 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -381,14 +381,8 @@ bool g_study_project_save(GStudyProject *project, const char *filename)
     xmlDocPtr xdoc;                         /* Document XML à créer        */
     xmlXPathContextPtr context;             /* Contexte pour les recherches*/
     const char *final;                      /* Lieu d'enregistrement final */
-    size_t root_count;                      /* Quantité d'origines         */
     size_t i;                               /* Boucle de parcours          */
-    GBinContent *content;                   /* Contenu brut à manipuler    */
-    GBinContent *root;                      /* Contenu d'origine à traiter */
-    const gchar *hash;                      /* Empreinte d'un contenu      */
     char *access;                           /* Chemin pour une sous-config.*/
-    xmlXPathObjectPtr xobject;              /* Cible d'une recherche       */
-    char *format;                           /* Format associé à un élément */
 
     /* Forme générale */
 
@@ -401,85 +395,26 @@ bool g_study_project_save(GStudyProject *project, const char *filename)
         result = add_string_attribute_to_node(xdoc, context, "/ChrysalideProject", "version", PROJECT_XML_VERSION);
 
     if (result)
-        result = (ensure_node_exist(xdoc, context, "/ChrysalideProject/RootContents") != NULL);
-
-    if (result)
         result = (ensure_node_exist(xdoc, context, "/ChrysalideProject/LoadedContents") != NULL);
 
     final = filename != NULL ? filename : project->filename;
 
     /* Inscriptions des contenus */
 
-    root_count = 0;
-
     g_study_project_lock_contents(project);
 
     for (i = 0; i < project->count && result; i++)
     {
-        content = g_loaded_content_get_content(project->contents[i]);
-
-        /* Racine */
-
-        root = g_binary_content_get_root(content);
-
-        hash = g_binary_content_get_checksum(root);
-
-        asprintf(&access, "/ChrysalideProject/RootContents/Content[@hash='%s']", hash);
-
-        xobject = get_node_xpath_object(context, access);
-
-        free(access);
-
-        if (XPATH_OBJ_NODES_COUNT(xobject) == 0)
-        {
-            asprintf(&access, "/ChrysalideProject/RootContents/Content[position()=%zu]", ++root_count);
-
-            if (result)
-                result = (ensure_node_exist(xdoc, context, access) != NULL);
-
-            if (result)
-            {
-                hash = g_binary_content_get_checksum(content);
-                result = add_string_attribute_to_node(xdoc, context, access, "hash", hash);
-            }
-
-            if (result)
-                result = g_binary_content_save(root, xdoc, context, access, final);
-
-            free(access);
-
-        }
-
-        if(xobject != NULL)
-            xmlXPathFreeObject(xobject);
-
-        /* Charge utile */
-
         asprintf(&access, "/ChrysalideProject/LoadedContents/Content[position()=%zu]", i + 1);
 
         if (result)
             result = (ensure_node_exist(xdoc, context, access) != NULL);
 
         if (result)
-        {
-            hash = g_binary_content_get_checksum(content);
-            result = add_string_attribute_to_node(xdoc, context, access, "hash", hash);
-        }
-
-        if (result)
-        {
-            format = g_loaded_content_get_format_name(project->contents[i]);
-            result = add_string_attribute_to_node(xdoc, context, access, "format", format);
-            free(format);
-        }
-
-        if (result)
             result = g_loaded_content_save(project->contents[i], xdoc, context, access);
 
         free(access);
 
-        g_object_unref(G_OBJECT(content));
-
     }
 
     g_study_project_unlock_contents(project);
@@ -1093,7 +1028,7 @@ static GLoadingHandler *g_loading_handler_new_recovering(GStudyProject *project,
         {
             asprintf(&access, "/ChrysalideProject/RootContents/Content[position()=%zu]", i + 1);
 
-            content = g_binary_content_new_from_xml(context, access, project->filename);
+            content = NULL;//g_binary_content_new_from_xml(context, access, project->filename);
 
             free(access);
 
diff --git a/src/gui/dialogs/snapshots.c b/src/gui/dialogs/snapshots.c
index 53fc7b0..91bd70e 100644
--- a/src/gui/dialogs/snapshots.c
+++ b/src/gui/dialogs/snapshots.c
@@ -226,7 +226,7 @@ static void on_server_selection_changed(GtkComboBox *combo, GtkBuilder *builder)
 
     binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(builder), "binary"));
 
-    client = g_loaded_binary_get_client(binary, active == 0);
+    client = g_loaded_binary_get_client(binary);
 
     if (client == NULL)
     {
diff --git a/src/gui/dialogs/storage.c b/src/gui/dialogs/storage.c
index 4822231..b6fc920 100644
--- a/src/gui/dialogs/storage.c
+++ b/src/gui/dialogs/storage.c
@@ -33,27 +33,9 @@
 
 
 
-/* Colonnes de la liste des collections */
-typedef enum _CollecFeatureColumn
-{
-    CFC_COLLECTION,                         /* Instance GLib               */
-
-    CFC_NAME,                               /* Désignation humaine         */
-    CFC_LOCAL,                              /* Sauvegarde locale ?         */
-    CFC_REMOTE,                             /* Sauvegarde distante ?       */
-
-} CollecFeatureColumn;
-
-
 /* Réagit à un changement dans le choix du type de serveur. */
 static void on_server_use_toggled(GtkToggleButton *, GtkBuilder *);
 
-/* Bascule le lieu d'enregistrement d'un type de collection. */
-static void on_local_feature_toggled(GtkCellRendererToggle *, gchar *, GtkBuilder *);
-
-/* Bascule le lieu d'enregistrement d'un type de collection. */
-static void on_remote_feature_toggled(GtkCellRendererToggle *, gchar *, GtkBuilder *);
-
 
 
 /******************************************************************************
@@ -111,37 +93,10 @@ GtkWidget *create_storage_dialog(GLoadedBinary *binary, GtkWindow *parent, GtkBu
 
     on_server_use_toggled(use_remote, builder);
 
-    /* Intégration des différentes collections */
-
-    store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
-
-    collections = g_loaded_binary_get_collections(binary, &count);
-
-    for (i = 0; i < count; i++)
-    {
-        feature = g_db_collection_get_feature(collections[i]);
-
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter,
-                           CFC_COLLECTION, collections[i],
-                           CFC_NAME, g_db_collection_get_name(collections[i]),
-                           CFC_LOCAL, g_loaded_binary_get_storage(binary, feature) == DBS_ALL_LOCAL,
-                           CFC_REMOTE, g_loaded_binary_get_storage(binary, feature) != DBS_ALL_LOCAL,
-                           -1);
-
-        g_object_unref(G_OBJECT(collections[i]));
-
-    }
-
-    if (collections != NULL)
-        free(collections);
-
     /* Connexion des signaux */
 
     gtk_builder_add_callback_symbols(builder,
                                      BUILDER_CALLBACK(on_server_use_toggled),
-                                     BUILDER_CALLBACK(on_local_feature_toggled),
-                                     BUILDER_CALLBACK(on_remote_feature_toggled),
                                      NULL);
 
     gtk_builder_connect_signals(builder, builder);
@@ -188,82 +143,6 @@ static void on_server_use_toggled(GtkToggleButton *button, GtkBuilder *builder)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : renderer = rendu de cellule à l'origine de la procédure.     *
-*                path     = chemin d'accès à la ligne éditée.                 *
-*                builder  = espace de référencement global.                   *
-*                                                                             *
-*  Description : Bascule le lieu d'enregistrement d'un type de collection.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void on_local_feature_toggled(GtkCellRendererToggle *renderer, gchar *path, GtkBuilder *builder)
-{
-    GtkTreePath *access;                    /* Véritable chemin d'accès    */
-    GtkTreeModel *model;                    /* Modèle de gestion utilisé   */
-    GtkTreeIter iter;                       /* Point d'actualisation       */
-
-    access = gtk_tree_path_new_from_string(path);
-
-    model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store"));
-
-    if (gtk_tree_model_get_iter(model, &iter, access))
-    {
-        gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-                           CFC_LOCAL, true,
-                           CFC_REMOTE, false,
-                           -1);
-
-    }
-
-    gtk_tree_path_free(access);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : renderer = rendu de cellule à l'origine de la procédure.     *
-*                path     = chemin d'accès à la ligne éditée.                 *
-*                builder  = espace de référencement global.                   *
-*                                                                             *
-*  Description : Bascule le lieu d'enregistrement d'un type de collection.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void on_remote_feature_toggled(GtkCellRendererToggle *renderer, gchar *path, GtkBuilder *builder)
-{
-    GtkTreePath *access;                    /* Véritable chemin d'accès    */
-    GtkTreeModel *model;                    /* Modèle de gestion utilisé   */
-    GtkTreeIter iter;                       /* Point d'actualisation       */
-
-    access = gtk_tree_path_new_from_string(path);
-
-    model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store"));
-
-    if (gtk_tree_model_get_iter(model, &iter, access))
-    {
-        gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-                           CFC_LOCAL, false,
-                           CFC_REMOTE, true,
-                           -1);
-
-    }
-
-    gtk_tree_path_free(access);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : builder = espace de référencement global.                    *
 *                binary  = binaire chargé en mémoire à traiter.               *
 *                                                                             *
@@ -312,25 +191,4 @@ void update_binary_storage(GtkBuilder *builder, GLoadedBinary *binary)
 
     g_loaded_binary_set_remote_storage_usage(binary, active);
 
-    /* Type de conservation des éléments */
-
-    model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store"));
-
-    for (valid = gtk_tree_model_get_iter_first(model, &iter);
-         valid;
-         valid = gtk_tree_model_iter_next(model, &iter))
-    {
-        gtk_tree_model_get(model, &iter,
-                           CFC_COLLECTION, &collec,
-                           CFC_LOCAL, &local,
-                           -1);
-
-        feature = g_db_collection_get_feature(collec);
-
-        g_loaded_binary_set_storage(binary, feature, local ? DBS_ALL_LOCAL : DBS_ALL_REMOTE);
-
-        g_object_unref(G_OBJECT(collec));
-
-    }
-
 }
diff --git a/src/gui/dialogs/storage.ui b/src/gui/dialogs/storage.ui
index 0a9bb89..f079dab 100644
--- a/src/gui/dialogs/storage.ui
+++ b/src/gui/dialogs/storage.ui
@@ -1,55 +1,43 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.21.0 -->
+<!-- Generated with glade 3.37.0 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
   <object class="GtkAdjustment" id="port_adj">
     <property name="lower">1</property>
     <property name="upper">65535</property>
     <property name="value">0.01</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
-  <object class="GtkListStore" id="store">
-    <columns>
-      <!-- column-name collec -->
-      <column type="GObject"/>
-      <!-- column-name name -->
-      <column type="gchararray"/>
-      <!-- column-name local -->
-      <column type="gboolean"/>
-      <!-- column-name remote -->
-      <column type="gboolean"/>
-    </columns>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
   </object>
   <object class="GtkDialog" id="window">
-    <property name="can_focus">False</property>
+    <property name="can-focus">False</property>
     <property name="title" translatable="yes">Storage</property>
     <property name="modal">True</property>
-    <property name="window_position">center-on-parent</property>
-    <property name="default_width">500</property>
-    <property name="default_height">350</property>
-    <property name="type_hint">dialog</property>
+    <property name="window-position">center-on-parent</property>
+    <property name="default-width">500</property>
+    <property name="default-height">350</property>
+    <property name="type-hint">dialog</property>
     <child internal-child="vbox">
       <object class="GtkBox">
-        <property name="can_focus">False</property>
-        <property name="margin_left">8</property>
-        <property name="margin_right">8</property>
-        <property name="margin_top">8</property>
-        <property name="margin_bottom">8</property>
+        <property name="can-focus">False</property>
+        <property name="margin-left">8</property>
+        <property name="margin-right">8</property>
+        <property name="margin-top">8</property>
+        <property name="margin-bottom">8</property>
         <property name="orientation">vertical</property>
         <property name="spacing">2</property>
         <child internal-child="action_area">
           <object class="GtkButtonBox">
-            <property name="can_focus">False</property>
-            <property name="margin_top">8</property>
-            <property name="layout_style">end</property>
+            <property name="can-focus">False</property>
+            <property name="margin-top">8</property>
+            <property name="layout-style">end</property>
             <child>
               <object class="GtkButton" id="button1">
                 <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
+                <property name="use-stock">True</property>
               </object>
               <packing>
                 <property name="expand">True</property>
@@ -61,9 +49,9 @@
               <object class="GtkButton" id="button2">
                 <property name="label">gtk-apply</property>
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
+                <property name="use-stock">True</property>
               </object>
               <packing>
                 <property name="expand">True</property>
@@ -81,37 +69,37 @@
         <child>
           <object class="GtkBox">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can-focus">False</property>
             <property name="orientation">vertical</property>
             <property name="spacing">8</property>
             <child>
               <object class="GtkFrame">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
+                <property name="can-focus">False</property>
+                <property name="label-xalign">0</property>
+                <property name="shadow-type">none</property>
                 <child>
                   <object class="GtkAlignment">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="margin_top">8</property>
-                    <property name="left_padding">12</property>
+                    <property name="can-focus">False</property>
+                    <property name="margin-top">8</property>
+                    <property name="left-padding">12</property>
                     <child>
                       <object class="GtkBox">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
+                        <property name="can-focus">False</property>
                         <property name="orientation">vertical</property>
                         <property name="spacing">8</property>
                         <child>
                           <object class="GtkBox">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
+                            <property name="can-focus">False</property>
                             <property name="hexpand">True</property>
                             <property name="spacing">8</property>
                             <child>
                               <object class="GtkLabel" id="server_label">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
+                                <property name="can-focus">False</property>
                                 <property name="label" translatable="yes">Server:</property>
                               </object>
                               <packing>
@@ -123,7 +111,7 @@
                             <child>
                               <object class="GtkEntry" id="server">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
+                                <property name="can-focus">True</property>
                               </object>
                               <packing>
                                 <property name="expand">True</property>
@@ -134,7 +122,7 @@
                             <child>
                               <object class="GtkLabel" id="port_label">
                                 <property name="visible">True</property>
-                                <property name="can_focus">False</property>
+                                <property name="can-focus">False</property>
                                 <property name="label" translatable="yes">Port:</property>
                               </object>
                               <packing>
@@ -146,8 +134,8 @@
                             <child>
                               <object class="GtkSpinButton" id="port">
                                 <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="max_width_chars">5</property>
+                                <property name="can-focus">True</property>
+                                <property name="max-width-chars">5</property>
                                 <property name="text" translatable="yes">1</property>
                                 <property name="adjustment">port_adj</property>
                                 <property name="value">1</property>
@@ -168,7 +156,7 @@
                         <child>
                           <object class="GtkLabel">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
+                            <property name="can-focus">False</property>
                             <property name="label" translatable="yes">Note: database items will use internal storage as fallback if this server can not be contacted.</property>
                             <property name="wrap">True</property>
                             <property name="xalign">0</property>
@@ -187,9 +175,9 @@
                   <object class="GtkCheckButton" id="use_remote">
                     <property name="label" translatable="yes">Use a remote shared server</property>
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="draw_indicator">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="draw-indicator">True</property>
                     <signal name="toggled" handler="on_server_use_toggled" swapped="no"/>
                   </object>
                 </child>
@@ -200,92 +188,6 @@
                 <property name="position">0</property>
               </packing>
             </child>
-            <child>
-              <object class="GtkFrame">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="margin_top">8</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
-                <child>
-                  <object class="GtkAlignment">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="margin_top">8</property>
-                    <property name="left_padding">12</property>
-                    <child>
-                      <object class="GtkScrolledWindow">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="shadow_type">in</property>
-                        <child>
-                          <object class="GtkTreeView">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="model">store</property>
-                            <child internal-child="selection">
-                              <object class="GtkTreeSelection"/>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn">
-                                <property name="title" translatable="yes">Name</property>
-                                <property name="expand">True</property>
-                                <child>
-                                  <object class="GtkCellRendererText" id="name"/>
-                                  <attributes>
-                                    <attribute name="text">1</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn">
-                                <property name="title" translatable="yes">Local</property>
-                                <child>
-                                  <object class="GtkCellRendererToggle" id="local">
-                                    <property name="radio">True</property>
-                                    <signal name="toggled" handler="on_local_feature_toggled" swapped="no"/>
-                                  </object>
-                                  <attributes>
-                                    <attribute name="active">2</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn">
-                                <property name="title" translatable="yes">Remote</property>
-                                <child>
-                                  <object class="GtkCellRendererToggle" id="remote">
-                                    <property name="radio">True</property>
-                                    <signal name="toggled" handler="on_remote_feature_toggled" swapped="no"/>
-                                  </object>
-                                  <attributes>
-                                    <attribute name="active">3</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-                <child type="label">
-                  <object class="GtkLabel">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Database items</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
           </object>
           <packing>
             <property name="expand">True</property>
@@ -299,8 +201,17 @@
       <action-widget response="-6">button1</action-widget>
       <action-widget response="-10">button2</action-widget>
     </action-widgets>
-    <child>
-      <placeholder/>
-    </child>
+  </object>
+  <object class="GtkListStore" id="store">
+    <columns>
+      <!-- column-name collec -->
+      <column type="GObject"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name local -->
+      <column type="gboolean"/>
+      <!-- column-name remote -->
+      <column type="gboolean"/>
+    </columns>
   </object>
 </interface>
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index d6ca678..0b064f9 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -690,7 +690,7 @@ static void do_history_undo(GtkButton *button, GHistoryPanel *panel)
         {
             gtk_tree_model_get(model, &iter, HTC_ITEM, &item, -1);
 
-            client = g_loaded_binary_get_client(panel->binary, true);
+            client = g_loaded_binary_get_client(panel->binary);
             g_analyst_client_set_last_active(client, g_db_item_get_timestamp(item));
             g_object_unref(G_OBJECT(client));
 
@@ -738,7 +738,7 @@ static void do_history_redo(GtkButton *button, GHistoryPanel *panel)
     {
         gtk_tree_model_get(model, &iter, HTC_ITEM, &item, -1);
 
-        client = g_loaded_binary_get_client(panel->binary, true);
+        client = g_loaded_binary_get_client(panel->binary);
         g_analyst_client_set_last_active(client, g_db_item_get_timestamp(item));
         g_object_unref(G_OBJECT(client));
 
-- 
cgit v0.11.2-87-g4458