From e0d03e3eddb9d240cc21ac1b7a7ade915fd17942 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 16 Jul 2018 16:31:40 +0200
Subject: Updated the move entry from database items.

---
 configure.ac                     |   2 +-
 src/analysis/db/items/bookmark.c |  18 ++-
 src/analysis/db/items/bookmark.h |   2 -
 src/analysis/db/items/comment.c  |  18 ++-
 src/analysis/db/items/comment.h  |   2 -
 src/analysis/db/items/move.c     | 135 +++++++++++---------
 src/analysis/db/items/move.h     |  16 +--
 src/analysis/db/items/switcher.c |  26 ++--
 src/analysis/db/items/switcher.h |   2 -
 src/arch/vmpa.c                  |  47 ++++++-
 src/arch/vmpa.h                  |  13 +-
 src/glibext/gbinarycursor.c      | 257 +++++++++++++++++++++++++++++++++++++++
 src/glibext/gbinarycursor.h      |  14 +++
 src/glibext/glinecursor-int.h    |  34 ++++++
 src/glibext/glinecursor.c        | 216 ++++++++++++++++++++++++++++++++
 src/glibext/glinecursor.h        |  41 +++++++
 src/glibext/gloadedpanel-int.h   |   4 +
 src/glibext/gloadedpanel.c       |  29 +++++
 src/glibext/gloadedpanel.h       |   3 +
 src/gtkext/gtkdisplaypanel-int.h |   2 -
 src/gtkext/gtkdisplaypanel.c     |  18 +--
 src/gui/core/items.c             |  38 +++---
 22 files changed, 796 insertions(+), 141 deletions(-)

diff --git a/configure.ac b/configure.ac
index fb16dcc..09af338 100644
--- a/configure.ac
+++ b/configure.ac
@@ -326,7 +326,7 @@ AC_SUBST(LIBPYGOBJECT_LIBS)
 
 AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h])
 
-AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,UINT64\nVOID:BOOLEAN,ULONG,ULONG\nVOID:INT,INT" > src/glibext/chrysamarshal.list])
+AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,UINT64\nVOID:BOOLEAN,ULONG,ULONG\nVOID:INT,INT\nVOID:OBJECT,BOOLEAN" > src/glibext/chrysamarshal.list])
 
 AC_CONFIG_FILES([Makefile
                  pixmaps/Makefile
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 2fa2544..712a5eb 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -747,17 +747,27 @@ GBookmarkCollection *g_bookmark_collection_new(void)
 
 static bool g_bookmark_collection_create_db_table(const GBookmarkCollection *collec, sqlite3 *db)
 {
-    char *sql;                              /* Requête à exécuter          */
-    int ret;                                /* Bilan de la création        */
+    const char *sql;                        /* Patron de Requête SQL       */
+    char *addr_fields;                      /* Champs pour l'adresse       */
+    char *request;                          /* Requête à exécuter          */
     char *msg;                              /* Message d'erreur            */
+    int ret;                                /* Bilan de la création        */
 
     sql = "CREATE TABLE Bookmarks ("            \
              SQLITE_DB_ITEM_CREATE ", "         \
-             SQLITE_SIMPLE_VMPA_CREATE ", "     \
+             "%%s, "                            \
              SQLITE_RLESTR_CREATE("comment")    \
           ");";
 
+    addr_fields = create_vmpa_db_table(NULL);
+
+    asprintf(&request, sql, addr_fields);
+
     ret = sqlite3_exec(db, sql, NULL, NULL, &msg);
+
+    free(addr_fields);
+    free(request);
+
     if (ret != SQLITE_OK)
     {
         fprintf(stderr, "sqlite3_exec(): %s\n", msg);
@@ -791,7 +801,7 @@ static bool g_bookmark_collection_setup_load(GBookmarkCollection *collec, bound_
                                                                                    values, count);
     if (!status) return false;
 
-    if (!setup_load_for_vmpa(NULL, NULL, values, count))
+    if (!setup_load_for_vmpa(NULL, values, count))
         return false;
 
     if (!setup_load_of_rle_string(NULL, "comment", values, count))
diff --git a/src/analysis/db/items/bookmark.h b/src/analysis/db/items/bookmark.h
index 2dee2f2..a8526f7 100644
--- a/src/analysis/db/items/bookmark.h
+++ b/src/analysis/db/items/bookmark.h
@@ -27,8 +27,6 @@
 
 
 #include <glib-object.h>
-#include <sqlite3.h>
-#include <stdbool.h>
 
 
 #include "../../../arch/vmpa.h"
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 57bb017..182b2d0 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -1587,20 +1587,30 @@ GCommentCollection *g_comment_collection_new(void)
 
 static bool g_comment_collection_create_db_table(const GCommentCollection *collec, sqlite3 *db)
 {
-    char *sql;                              /* Requête à exécuter          */
-    int ret;                                /* Bilan de la création        */
+    const char *sql;                        /* Patron de Requête SQL       */
+    char *addr_fields;                      /* Champs pour l'adresse       */
+    char *request;                          /* Requête à exécuter          */
     char *msg;                              /* Message d'erreur            */
+    int ret;                                /* Bilan de la création        */
 
     sql = "CREATE TABLE Comments ("             \
              SQLITE_DB_ITEM_CREATE ", "         \
-             SQLITE_SIMPLE_VMPA_CREATE ", "     \
+             "%%s, "                            \
              "flags INTEGER, "                  \
              SQLITE_RLESTR_CREATE("text") ", "  \
              "inlined INTEGER, "                \
              "repeatable INTEGER"               \
           ");";
 
+    addr_fields = create_vmpa_db_table(NULL);
+
+    asprintf(&request, sql, addr_fields);
+
     ret = sqlite3_exec(db, sql, NULL, NULL, &msg);
+
+    free(addr_fields);
+    free(request);
+
     if (ret != SQLITE_OK)
     {
         fprintf(stderr, "sqlite3_exec(): %s\n", msg);
@@ -1635,7 +1645,7 @@ static bool g_comment_collection_setup_load(GCommentCollection *collec, bound_va
                                                                                   values, count);
     if (!status) return false;
 
-    if (!setup_load_for_vmpa(NULL, NULL, values, count))
+    if (!setup_load_for_vmpa(NULL, values, count))
         return false;
 
     *count += 1;
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
index 1558228..31124ac 100644
--- a/src/analysis/db/items/comment.h
+++ b/src/analysis/db/items/comment.h
@@ -27,8 +27,6 @@
 
 
 #include <glib-object.h>
-#include <sqlite3.h>
-#include <stdbool.h>
 
 
 #include "../../../arch/vmpa.h"
diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c
index e0e726a..5653649 100644
--- a/src/analysis/db/items/move.c
+++ b/src/analysis/db/items/move.c
@@ -36,10 +36,9 @@
 #include "../collection-int.h"
 #include "../item-int.h"
 #include "../../../gui/core/global.h"
-#include "../../../glibext/gbinarycursor.h" // REMME
-#include "../../../gtkext/gtkdisplaypanel.h"
-
-
+#include "../../../glibext/gbinarycursor.h"
+#include "../../../glibext/gloadedpanel.h"
+#include "../../../gtkext/gtkdisplaypanel.h" // REMME
 
 
 
@@ -51,8 +50,8 @@ struct _GDbMove
 {
     GDbItem parent;                         /* A laisser en premier        */
 
-    vmpa2t src;                             /* Emplacement de départ       */
-    vmpa2t dest;                            /* Emplacement d'arrivée       */
+    GLineCursor *src;                       /* Emplacement de départ       */
+    GLineCursor *dest;                      /* Emplacement d'arrivée       */
 
 };
 
@@ -64,7 +63,6 @@ struct _GDbMoveClass
 };
 
 
-
 /* Initialise la classe des déplacements au sein de codes. */
 static void g_db_move_class_init(GDbMoveClass *);
 
@@ -90,7 +88,7 @@ static bool g_db_move_pack(const GDbMove *, packed_buffer *);
 static void g_db_move_build_label(GDbMove *);
 
 /* Exécute un déplacement dans une zone de code. */
-static bool g_db_move_run(const GDbMove *, const vmpa2t *);
+static bool g_db_move_run(const GDbMove *, GLineCursor *);
 
 /* Applique un déplacement au sein d'une zone de code. */
 static bool g_db_move_apply(GDbMove *, GLoadedBinary *);
@@ -106,7 +104,6 @@ static bool g_db_move_load(GDbMove *, const bound_value *, size_t);
 
 
 
-
 /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
 
 
@@ -230,6 +227,9 @@ static void g_db_move_init(GDbMove *move)
 
 static void g_db_move_dispose(GDbMove *move)
 {
+    g_object_unref(G_OBJECT(move->src));
+    g_object_unref(G_OBJECT(move->dest));
+
     G_OBJECT_CLASS(g_db_move_parent_class)->dispose(G_OBJECT(move));
 
 }
@@ -267,14 +267,14 @@ static void g_db_move_finalize(GDbMove *move)
 *                                                                             *
 ******************************************************************************/
 
-GDbMove *g_db_move_new(const vmpa2t *src, const vmpa2t *dest)
+GDbMove *g_db_move_new(const GLineCursor *src, const GLineCursor *dest)
 {
     GDbMove *result;                        /* Instance à retourner        */
 
     result = g_object_new(G_TYPE_DB_MOVE, NULL);
 
-    copy_vmpa(&result->src, src);
-    copy_vmpa(&result->dest, dest);
+    result->src = g_line_cursor_duplicate(src);
+    result->dest = g_line_cursor_duplicate(dest);
 
     return result;
 
@@ -299,10 +299,10 @@ static gint g_db_move_cmp(GDbMove *a, GDbMove *b, bool with)
 {
     gint result;                            /* Bilan de la comparaison     */
 
-    result = cmp_vmpa(&a->src, &b->src);
+    result = g_line_cursor_compare(a->src, b->src);
 
     if (result == 0)
-        result = cmp_vmpa(&a->dest, &b->dest);
+        result = g_line_cursor_compare(a->dest, b->dest);
 
     if (result == 0)
         result = G_DB_ITEM_CLASS(g_db_move_parent_class)->cmp(G_DB_ITEM(a), G_DB_ITEM(b), with);
@@ -331,11 +331,14 @@ static bool g_db_move_unpack(GDbMove *move, packed_buffer *pbuf)
 
     result = G_DB_ITEM_CLASS(g_db_move_parent_class)->unpack(G_DB_ITEM(move), pbuf);
 
+    move->src = g_binary_cursor_new();
+    move->dest = g_binary_cursor_new();
+
     if (result)
-        result = unpack_vmpa(&move->src, pbuf);
+        result = g_line_cursor_unserialize(move->src, pbuf);
 
     if (result)
-        result = unpack_vmpa(&move->dest, pbuf);
+        result = g_line_cursor_unserialize(move->dest, pbuf);
 
     return result;
 
@@ -362,10 +365,10 @@ static bool g_db_move_pack(const GDbMove *move, packed_buffer *pbuf)
     result = G_DB_ITEM_CLASS(g_db_move_parent_class)->pack(G_DB_ITEM(move), pbuf);
 
     if (result)
-        result = pack_vmpa(&move->src, pbuf);
+        result = g_line_cursor_serialize(move->src, pbuf);
 
     if (result)
-        result = pack_vmpa(&move->dest, pbuf);
+        result = g_line_cursor_serialize(move->dest, pbuf);
 
     return result;
 
@@ -386,22 +389,24 @@ static bool g_db_move_pack(const GDbMove *move, packed_buffer *pbuf)
 
 static void g_db_move_build_label(GDbMove *move)
 {
-    VMPA_BUFFER(src_loc);                   /* Indication de position #1   */
-    VMPA_BUFFER(dest_loc);                  /* Indication de position #2   */
+    char *src_label;                        /* Indication de position #1   */
+    char *dest_label;                       /* Indication de position #2   */
 
-    vmpa2_to_string(&move->src, MDS_UNDEFINED, src_loc, NULL);
+    src_label = g_line_cursor_build_label(move->src);
+    dest_label = g_line_cursor_build_label(move->dest);
 
-    vmpa2_to_string(&move->dest, MDS_UNDEFINED, dest_loc, NULL);
+    asprintf(&G_DB_ITEM(move)->label, _("Move from %s to %s"), src_label, dest_label);
 
-    asprintf(&G_DB_ITEM(move)->label, _("Move from %s to %s"), src_loc, dest_loc);
+    free(src_label);
+    free(dest_label);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : move = informations de déplacement à consulter.              *
-*                addr = localisation à placer bien en évidence.               *
+*  Paramètres  : move   = informations de déplacement à consulter.            *
+*                cursor = localisation à placer bien en évidence.             *
 *                                                                             *
 *  Description : Exécute un déplacement dans une zone de code.                *
 *                                                                             *
@@ -411,14 +416,14 @@ static void g_db_move_build_label(GDbMove *move)
 *                                                                             *
 ******************************************************************************/
 
-static bool g_db_move_run(const GDbMove *move, const vmpa2t *addr)
+static bool g_db_move_run(const GDbMove *move, GLineCursor *cursor)
 {
-    GtkDisplayPanel *panel;                 /* Afficheur effectif de code  */
+    GLoadedPanel *panel;                    /* Afficheur effectif de code  */
 
     typedef struct _move_params
     {
-        GtkDisplayPanel *panel;             /* Afficheur effectif de code  */
-        vmpa2t addr;                        /* Adresse de déplacement      */
+        GLoadedPanel *panel;                /* Afficheur effectif de code  */
+        GLineCursor *cursor;                /* Emplacement à rejoindre     */
 
     } move_params;
 
@@ -429,6 +434,7 @@ static bool g_db_move_run(const GDbMove *move, const vmpa2t *addr)
     void delete_move_params(move_params *p)
     {
         g_object_unref(G_OBJECT(p->panel));
+        g_object_unref(G_OBJECT(p->cursor));
 
         free(p);
 
@@ -438,14 +444,7 @@ static bool g_db_move_run(const GDbMove *move, const vmpa2t *addr)
 
     gboolean do_move_in_main_loop(move_params *p)
     {
-        GLineCursor *___tmp;
-
-        ___tmp = g_binary_cursor_new();
-        g_binary_cursor_update(G_BINARY_CURSOR(___tmp), &p->addr);
-
-        gtk_display_panel_scroll_to_cursor(p->panel, ___tmp, SPT_CENTER);
-
-        g_object_unref(G_OBJECT(___tmp));
+        gtk_display_panel_scroll_to_cursor(p->panel, p->cursor, SPT_CENTER);
 
         return G_SOURCE_REMOVE;
 
@@ -455,13 +454,15 @@ static bool g_db_move_run(const GDbMove *move, const vmpa2t *addr)
 
     panel = get_current_view();
 
-    if (GTK_IS_DISPLAY_PANEL(panel))
+    if (G_IS_LOADED_PANEL(panel))
     {
         params = (move_params *)calloc(1, sizeof(move_params));
 
-        params->panel = GTK_DISPLAY_PANEL(panel);
+        params->panel = panel;
+        params->cursor = cursor;
 
-        copy_vmpa(&params->addr, addr);
+        g_object_ref(G_OBJECT(params->panel));
+        g_object_ref(G_OBJECT(params->cursor));
 
         g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
                         (GSourceFunc)do_move_in_main_loop,
@@ -469,6 +470,9 @@ static bool g_db_move_run(const GDbMove *move, const vmpa2t *addr)
 
     }
 
+    if (panel != NULL)
+        g_object_unref(G_OBJECT(panel));
+
     return true;
 
 }
@@ -491,7 +495,7 @@ static bool g_db_move_apply(GDbMove *move, GLoadedBinary *binary)
 {
     bool result;                            /* Bilan à faire remonter      */
 
-    result = g_db_move_run(move, &move->dest);
+    result = g_db_move_run(move, move->dest);
 
     return result;
 
@@ -515,7 +519,7 @@ static bool g_db_move_cancel(GDbMove *move, GLoadedBinary *binary)
 {
     bool result;                            /* Bilan à faire remonter      */
 
-    result = g_db_move_run(move, &move->src);
+    result = g_db_move_run(move, move->src);
 
     return result;
 
@@ -543,10 +547,10 @@ static bool g_db_move_prepare_db_statement(const GDbMove *move, bound_value **va
     status = G_DB_ITEM_CLASS(g_db_move_parent_class)->prepare_stmt(G_DB_ITEM(move), values, count);
     if (!status) return false;
 
-    status = prepare_vmpa_db_statement(&move->src, "src", values, count);
+    status = g_line_cursor_prepare_db_statement(move->src, "src", values, count);
     if (!status) return false;
 
-    status = prepare_vmpa_db_statement(&move->dest, "dest", values, count);
+    status = g_line_cursor_prepare_db_statement(move->src, "dest", values, count);
     if (!status) return false;
 
     return true;
@@ -574,9 +578,11 @@ static bool g_db_move_load(GDbMove *move, const bound_value *values, size_t coun
 
     result = G_DB_ITEM_CLASS(g_db_move_parent_class)->load(G_DB_ITEM(move), values, count);
 
-    result &= load_vmpa(&move->src, "src", values, count);
+    if (result)
+        result = g_line_cursor_load(move->src, "src", values, count);
 
-    result &= load_vmpa(&move->dest, "dest", values, count);
+    if (result)
+        result = g_line_cursor_load(move->dest, "dest", values, count);
 
     return result;
 
@@ -721,17 +727,30 @@ GMoveCollection *g_move_collection_new(void)
 
 static bool g_move_collection_create_db_table(const GMoveCollection *collec, sqlite3 *db)
 {
-    char *sql;                              /* Requête à exécuter          */
-    int ret;                                /* Bilan de la création        */
+    const char *sql;                        /* Patron de Requête SQL       */
+    char *src_fields;                       /* Champs pour la source       */
+    char *dest_fields;                      /* Champs pour la destination  */
+    char *request;                          /* Requête à exécuter          */
     char *msg;                              /* Message d'erreur            */
+    int ret;                                /* Bilan de la création        */
 
-    sql = "CREATE TABLE Moves ("                \
-             SQLITE_DB_ITEM_CREATE ", "         \
-             SQLITE_VMPA_CREATE("src") ", "     \
-             SQLITE_VMPA_CREATE("dest")         \
+    sql = "CREATE TABLE Moves ("            \
+             SQLITE_DB_ITEM_CREATE ", "     \
+             "%%s, "                        \
+             "%%s"                          \
           ");";
 
+    src_fields = g_binary_cursor_create_db_table("src");
+    dest_fields = g_binary_cursor_create_db_table("dest");
+
+    asprintf(&request, sql, src_fields, dest_fields);
+
     ret = sqlite3_exec(db, sql, NULL, NULL, &msg);
+
+    free(src_fields);
+    free(dest_fields);
+    free(request);
+
     if (ret != SQLITE_OK)
     {
         fprintf(stderr, "sqlite3_exec(): %s\n", msg);
@@ -765,10 +784,10 @@ static bool g_move_collection_setup_load(GMoveCollection *collec, bound_value **
                                                                                    values, count);
     if (!status) return false;
 
-    if (!setup_load_for_vmpa(NULL, "src", values, count))
+    if (!g_binary_cursor_setup_load("src", values, count))
         return false;
 
-    if (!setup_load_for_vmpa(NULL, "dest", values, count))
+    if (!g_binary_cursor_setup_load("dest", values, count))
         return false;
 
     return true;
@@ -793,14 +812,14 @@ static bool g_move_collection_setup_load(GMoveCollection *collec, bound_value **
 static GDbItem *g_move_collection_has_key(GMoveCollection *collec, va_list ap)
 {
     GDbItem *result;                        /* Bilan à retourner           */
-    vmpa2t *ref;                            /* Adresse de référence        */
+    const GLineCursor *ref;                 /* Emplacement de référence    */
     GList *items;                           /* Eléments déjà en place      */
     GList *iter;                            /* Boucle de parcours          */
-    GDbMove *bm;                        /* Signet à consulter          */
+    GDbMove *bm;                            /* Signet à consulter          */
 
     result = NULL;
 
-    ref = va_arg(ap, vmpa2t *);
+    ref = va_arg(ap, const GLineCursor *);
 
     items = g_db_collection_list_items(G_DB_COLLECTION(collec));
 
@@ -808,7 +827,7 @@ static GDbItem *g_move_collection_has_key(GMoveCollection *collec, va_list ap)
     {
         bm = G_DB_MOVE(iter->data);
 
-        if (cmp_vmpa(&bm->src, ref) != 0)
+        if (g_line_cursor_compare(bm->src, ref) == 0)
 
             /**
              * Un verrou est sensé être posé, donc il n'y a pas besoin
diff --git a/src/analysis/db/items/move.h b/src/analysis/db/items/move.h
index 167b969..dbd24f9 100644
--- a/src/analysis/db/items/move.h
+++ b/src/analysis/db/items/move.h
@@ -26,11 +26,9 @@
 
 
 #include <glib-object.h>
-#include <sqlite3.h>
-#include <stdbool.h>
 
 
-#include "../../../arch/vmpa.h"
+#include "../../../glibext/glinecursor.h"
 
 
 
@@ -56,18 +54,8 @@ typedef struct _GDbMoveClass GDbMoveClass;
 GType g_db_move_get_type(void);
 
 /* Organise un déplacement d'une position à une autre. */
-GDbMove *g_db_move_new(const vmpa2t *, const vmpa2t *);
+GDbMove *g_db_move_new(const GLineCursor *, const GLineCursor *);
 
-#if 0
-/* Fournit l'adresse associée à un signet. */
-const vmpa2t *g_db_move_get_address(GDbMove *);
-
-/* Fournit le commentaire associé à un signet. */
-const char *g_db_move_get_comment(const GDbMove *);
-
-/* Définit le commentaire associé à un signet. */
-void g_db_move_set_comment(GDbMove *, const char *);
-#endif
 
 
 /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index b583b65..58e4c7f 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -871,18 +871,28 @@ GSwitcherCollection *g_switcher_collection_new(void)
 
 static bool g_switcher_collection_create_db_table(const GSwitcherCollection *collec, sqlite3 *db)
 {
-    char *sql;                              /* Requête à exécuter          */
-    int ret;                                /* Bilan de la création        */
+    const char *sql;                        /* Patron de Requête SQL       */
+    char *addr_fields;                      /* Champs pour l'adresse       */
+    char *request;                          /* Requête à exécuter          */
     char *msg;                              /* Message d'erreur            */
+    int ret;                                /* Bilan de la création        */
 
-    sql = "CREATE TABLE Switchers ("            \
-             SQLITE_DB_ITEM_CREATE ", "         \
-             SQLITE_SIMPLE_VMPA_CREATE ", "     \
-             "op_index INTEGER, "               \
-             "type INTEGER"                     \
+    sql = "CREATE TABLE Switchers ("        \
+             SQLITE_DB_ITEM_CREATE ", "     \
+             "%%s, "                        \
+             "op_index INTEGER, "           \
+             "type INTEGER"                 \
           ");";
 
+    addr_fields = create_vmpa_db_table(NULL);
+
+    asprintf(&request, sql, addr_fields);
+
     ret = sqlite3_exec(db, sql, NULL, NULL, &msg);
+
+    free(addr_fields);
+    free(request);
+
     if (ret != SQLITE_OK)
     {
         fprintf(stderr, "sqlite3_exec(): %s\n", msg);
@@ -917,7 +927,7 @@ static bool g_switcher_collection_setup_load(GSwitcherCollection *collec, bound_
                                                                                    values, count);
     if (!status) return false;
 
-    if (!setup_load_for_vmpa(NULL, NULL, values, count))
+    if (!setup_load_for_vmpa(NULL, values, count))
         return false;
 
     *count += 2;
diff --git a/src/analysis/db/items/switcher.h b/src/analysis/db/items/switcher.h
index 651b3d7..4947383 100644
--- a/src/analysis/db/items/switcher.h
+++ b/src/analysis/db/items/switcher.h
@@ -26,8 +26,6 @@
 
 
 #include <glib-object.h>
-#include <sqlite3.h>
-#include <stdbool.h>
 
 
 #include "../../../arch/immediate.h"
diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c
index 7abb5de..8de2599 100644
--- a/src/arch/vmpa.c
+++ b/src/arch/vmpa.c
@@ -34,6 +34,9 @@
 #include <i18n.h>
 
 
+#include "../common/extstr.h"
+
+
 
 /* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */
 
@@ -673,8 +676,46 @@ vmpa2t *string_to_vmpa_virt(const char *buffer)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : addr   = localisation dont la définition est à consulter.    *
-*                base   = tronc commun pour les champs de la base de données. *
+*  Paramètres  : base = tronc commun pour les champs de la base de données.   *
+*                                                                             *
+*  Description : Donne les éléments requis pour la construction d'une table.  *
+*                                                                             *
+*  Retour      : Partie de requête à insérer dans la requête globale.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *create_vmpa_db_table(const char *base)
+{
+    char *result;
+
+    if (base != NULL)
+    {
+        result = strdup(base);
+        result = stradd(result, "_");
+    }
+    else
+        result = NULL;
+
+    result = stradd(result, "phys INTEGER, ");
+
+    if (base != NULL)
+    {
+        result = stradd(result, base);
+        result = stradd(result, "_");
+    }
+
+    result = stradd(result, "virt INTEGER");
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : base   = tronc commun pour les champs de la base de données. *
 *                values = tableau d'éléments à compléter. [OUT]               *
 *                count  = nombre de descriptions renseignées. [OUT]           *
 *                                                                             *
@@ -686,7 +727,7 @@ vmpa2t *string_to_vmpa_virt(const char *buffer)
 *                                                                             *
 ******************************************************************************/
 
-bool setup_load_for_vmpa(const vmpa2t *addr, const char *base, bound_value **values, size_t *count)
+bool setup_load_for_vmpa(const char *base, bound_value **values, size_t *count)
 {
     bound_value *value;                     /* Valeur à éditer / définir   */
 
diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index a1c60dd..d2cc39b 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -142,18 +142,11 @@ vmpa2t *string_to_vmpa_phy(const char *);
 /* Transforme une chaîne de caractères en adresse virtuelle. */
 vmpa2t *string_to_vmpa_virt(const char *);
 
-/* Définition du tronc commun pour les créations SQLite */
-
-#define SQLITE_SIMPLE_VMPA_CREATE  \
-    "phys INTEGER, "               \
-    "virt INTEGER"
-
-#define SQLITE_VMPA_CREATE(bn)     \
-    bn "_phys INTEGER, "           \
-    bn "_virt _INTEGER"
+/* Donne les éléments requis pour la construction d'une table. */
+char *create_vmpa_db_table(const char *);
 
 /* Décrit les colonnes utiles à un chargement de données. */
-bool setup_load_for_vmpa(const vmpa2t *, const char *, bound_value **, size_t *);
+bool setup_load_for_vmpa(const char *, bound_value **, size_t *);
 
 /* Charge les valeurs utiles pour une localisation. */
 bool load_vmpa(vmpa2t *, const char *, const bound_value *, size_t);
diff --git a/src/glibext/gbinarycursor.c b/src/glibext/gbinarycursor.c
index c614058..0c2a197 100644
--- a/src/glibext/gbinarycursor.c
+++ b/src/glibext/gbinarycursor.c
@@ -28,6 +28,9 @@
 
 
 
+/* ----------------------- FONCTIONNALITES D'UN SUIVI DE BASE ----------------------- */
+
+
 /* Suivi de positions dans un panneau de chargement (instance) */
 struct _GBinaryCursor
 {
@@ -57,12 +60,45 @@ static void g_binary_cursor_dispose(GBinaryCursor *);
 /* Procède à la libération totale de la mémoire. */
 static void g_binary_cursor_finalize(GBinaryCursor *);
 
+/* Réalise la copie d'un suivi d'emplacements. */
+static GLineCursor *g_binary_cursor_duplicate(const GBinaryCursor *);
+
 /* Compare deux suivis d'emplacements. */
 static int g_binary_cursor_compare(const GBinaryCursor *, const GBinaryCursor *);
 
 /* Détermine si un suivi d'emplacement est valide ou non. */
 static bool g_binary_cursor_is_valid(const GBinaryCursor *);
 
+/* Construit une étiquette de représentation d'un suivi. */
+static char *g_binary_cursor_build_label(const GBinaryCursor *);
+
+
+
+/* ---------------------- ENCADREMENT DES TRANSFERTS DE DONEES ---------------------- */
+
+
+/* Exporte la définition d'un emplacement dans un flux réseau. */
+static bool g_binary_cursor_serialize(const GBinaryCursor *, packed_buffer *);
+
+/* Importe la définition d'un emplacement depuis un flux réseau. */
+static bool g_binary_cursor_unserialize(GBinaryCursor *, packed_buffer *);
+
+
+
+/* ------------------------- LIENS AVEC UNE BASE DE DONNEES ------------------------- */
+
+
+/* Charge les valeurs utiles pour une localisation. */
+static bool g_binary_cursor_load(GBinaryCursor *, const char *, const bound_value *, size_t);
+
+/* Constitue les champs destinés à une insertion / modification. */
+static bool g_binary_cursor_prepare_db_statement(const GBinaryCursor *, const char *, bound_value **, size_t *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                         FONCTIONNALITES D'UN SUIVI DE BASE                         */
+/* ---------------------------------------------------------------------------------- */
 
 
 /* Détermine le type du gestionnaire de largeurs associées aux lignes. */
@@ -93,8 +129,18 @@ static void g_binary_cursor_class_init(GBinaryCursorClass *class)
 
     line = G_LINE_CURSOR_CLASS(class);
 
+    line->duplicate = (duplicate_cursor_fc)g_binary_cursor_duplicate;
     line->compare = (compare_cursor_fc)g_binary_cursor_compare;
     line->is_valid = (is_cursor_valid_fc)g_binary_cursor_is_valid;
+    line->build_label = (build_cursor_label_fc)g_binary_cursor_build_label;
+
+    line->serialize = (serialize_cursor_fc)g_binary_cursor_serialize;
+    line->unserialize = (unserialize_cursor_fc)g_binary_cursor_unserialize;
+
+    line->create_db = (create_cursor_db_table_fc)g_binary_cursor_create_db_table;
+    line->setup_load = (setup_cursor_load_fc)g_binary_cursor_setup_load;
+    line->load = (load_cursor_fc)g_binary_cursor_load;
+    line->prepare = (prepare_cursor_db_statement_fc)g_binary_cursor_prepare_db_statement;
 
 }
 
@@ -181,6 +227,31 @@ GLineCursor *g_binary_cursor_new(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : cursor = suivi d'emplacement à dupliquer.                    *
+*                                                                             *
+*  Description : Réalise la copie d'un suivi d'emplacements.                  *
+*                                                                             *
+*  Retour      : Nouvelle instance copiée.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GLineCursor *g_binary_cursor_duplicate(const GBinaryCursor *cursor)
+{
+    GLineCursor *result;                    /* Instance à retourner        */
+
+    result = g_binary_cursor_new();
+
+    g_binary_cursor_update(G_BINARY_CURSOR(cursor), &cursor->addr);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : cursor = premier suivi d'emplacement à comparer.             *
 *                other  = second suivi d'emplacement à comparer.              *
 *                                                                             *
@@ -228,6 +299,32 @@ static bool g_binary_cursor_is_valid(const GBinaryCursor *cursor)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : cursor = suivi d'emplacement à consulter.                    *
+*                                                                             *
+*  Description : Construit une étiquette de représentation d'un suivi.        *
+*                                                                             *
+*  Retour      : Etiquette à libérer de la mémoire après usage.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_binary_cursor_build_label(const GBinaryCursor *cursor)
+{
+    char *result;                           /* Etiquette à retourner       */
+    VMPA_BUFFER(loc);                       /* Indication de position      */
+
+    vmpa2_to_string(&cursor->addr, MDS_UNDEFINED, loc, NULL);
+
+    result = strdup(loc);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : cursor = suivi de positions à mettre à jour.                 *
 *                addr   = emplacement dans le binaire visé.                   *
 *                                                                             *
@@ -264,3 +361,163 @@ void g_binary_cursor_get_info(GBinaryCursor *cursor, vmpa2t *addr)
     copy_vmpa(addr, &cursor->addr);
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        ENCADREMENT DES TRANSFERTS DE DONEES                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à sauvegarder.                   *
+*                pbuf   = paquet de données où venir inscrire les infos.      *
+*                                                                             *
+*  Description : Exporte la définition d'un emplacement dans un flux réseau.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_cursor_serialize(const GBinaryCursor *cursor, packed_buffer *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = pack_vmpa(&cursor->addr, pbuf);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à charger. [OUT]                 *
+*                pbuf = paquet de données où venir inscrire les infos.        *
+*                                                                             *
+*  Description : Importe la définition d'un emplacement depuis un flux réseau.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_cursor_unserialize(GBinaryCursor *cursor, packed_buffer *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = unpack_vmpa(&cursor->addr, pbuf);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           LIENS AVEC UNE BASE DE DONNEES                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : base = tronc commun pour les champs de la base de données.   *
+*                                                                             *
+*  Description : Donne les éléments requis pour la construction d'une table.  *
+*                                                                             *
+*  Retour      : Partie de requête à insérer dans la requête globale.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *g_binary_cursor_create_db_table(const char *base)
+{
+    char *result;                           /* Requête à retourner         */
+
+    result = create_vmpa_db_table(base);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : base   = tronc commun pour les champs de la base de données. *
+*                values = tableau d'éléments à compléter. [OUT]               *
+*                count  = nombre de descriptions renseignées. [OUT]           *
+*                                                                             *
+*  Description : Décrit les colonnes utiles à un chargement de données.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_binary_cursor_setup_load(const char *base, bound_value **values, size_t *count)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = setup_load_for_vmpa(base, values, count);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions dont la définition est à définir.*
+*                base   = tronc commun pour les champs de la base de données. *
+*                values = tableau d'éléments à consulter.                     *
+*                count  = nombre de descriptions renseignées.                 *
+*                                                                             *
+*  Description : Charge les valeurs utiles pour une localisation.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_cursor_load(GBinaryCursor *cursor, const char *base, const bound_value *values, size_t count)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = load_vmpa(&cursor->addr, base, values, count);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à traiter.                       *
+*                base   = tronc commun pour les champs de la base de données. *
+*                values = couples de champs et de valeurs à lier. [OUT]       *
+*                count  = nombre de ces couples. [OUT]                        *
+*                                                                             *
+*  Description : Constitue les champs destinés à une insertion / modification.*
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou non.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_binary_cursor_prepare_db_statement(const GBinaryCursor *cursor, const char *base, bound_value **values, size_t *count)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = prepare_vmpa_db_statement(&cursor->addr, base, values, count);
+
+    return result;
+
+}
diff --git a/src/glibext/gbinarycursor.h b/src/glibext/gbinarycursor.h
index e6617b6..9846c59 100644
--- a/src/glibext/gbinarycursor.h
+++ b/src/glibext/gbinarycursor.h
@@ -33,6 +33,9 @@
 
 
 
+/* ----------------------- FONCTIONNALITES D'UN SUIVI DE BASE ----------------------- */
+
+
 #define G_TYPE_BINARY_CURSOR            (g_binary_cursor_get_type())
 #define G_BINARY_CURSOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BINARY_CURSOR, GBinaryCursor))
 #define G_BINARY_CURSOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BINARY_CURSOR, GBinaryCursorClass))
@@ -62,4 +65,15 @@ void g_binary_cursor_get_info(GBinaryCursor *, vmpa2t *);
 
 
 
+/* ------------------------- LIENS AVEC UNE BASE DE DONNEES ------------------------- */
+
+
+/* Donne les éléments requis pour la construction d'une table. */
+char *g_binary_cursor_create_db_table(const char *);
+
+/* Décrit les colonnes utiles à un chargement de données. */
+bool g_binary_cursor_setup_load(const char *, bound_value **, size_t *);
+
+
+
 #endif  /* _GLIBEXT_BINARYCURSOR_H */
diff --git a/src/glibext/glinecursor-int.h b/src/glibext/glinecursor-int.h
index 2c56331..b38e22e 100644
--- a/src/glibext/glinecursor-int.h
+++ b/src/glibext/glinecursor-int.h
@@ -29,12 +29,36 @@
 
 
 
+/* Réalise la copie d'un suivi d'emplacements. */
+typedef GLineCursor * (* duplicate_cursor_fc) (const GLineCursor *);
+
 /* Compare deux suivis d'emplacements. */
 typedef int (* compare_cursor_fc) (const GLineCursor *, const GLineCursor *);
 
 /* Détermine si un suivi d'emplacement est valide ou non. */
 typedef bool (* is_cursor_valid_fc) (const GLineCursor *);
 
+/* Construit une étiquette de représentation d'un suivi. */
+typedef char * (* build_cursor_label_fc) (const GLineCursor *);
+
+/* Exporte la définition d'un emplacement dans un flux réseau. */
+typedef bool (* serialize_cursor_fc) (const GLineCursor *, packed_buffer *);
+
+/* Importe la définition d'un emplacement depuis un flux réseau. */
+typedef bool (* unserialize_cursor_fc) (GLineCursor *, packed_buffer *);
+
+/* Donne les éléments requis pour la construction d'une table. */
+typedef char *(* create_cursor_db_table_fc) (const char *);
+
+/* Décrit les colonnes utiles à un chargement de données. */
+typedef bool (* setup_cursor_load_fc) (const char *, bound_value **, size_t *);
+
+/* Charge les valeurs utiles pour une localisation. */
+typedef bool (* load_cursor_fc) (GLineCursor *, const char *, const bound_value *, size_t);
+
+/* Constitue les champs destinés à une insertion / modification. */
+typedef bool (* prepare_cursor_db_statement_fc) (const GLineCursor *, const char *, bound_value **, size_t *);
+
 
 /* Suivi de positions dans un panneau de chargement (instance) */
 struct _GLineCursor
@@ -48,8 +72,18 @@ struct _GLineCursorClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
+    duplicate_cursor_fc duplicate;          /* Copie de curseur            */
     compare_cursor_fc compare;              /* Comparaison d'emplacements  */
     is_cursor_valid_fc is_valid;            /* Certificat de validité      */
+    build_cursor_label_fc build_label;      /* Obtention d'une étiquette   */
+
+    serialize_cursor_fc serialize;          /* Sauvegarde d'un emplacement */
+    unserialize_cursor_fc unserialize;      /* Chargement d'un emplacement */
+
+    create_cursor_db_table_fc create_db;    /* Création de table           */
+    setup_cursor_load_fc setup_load;        /* Préparation du chargement   */
+    load_cursor_fc load;                    /* Chargement de valeurs       */
+    prepare_cursor_db_statement_fc prepare; /* Préparation d'enregistrement*/
 
 };
 
diff --git a/src/glibext/glinecursor.c b/src/glibext/glinecursor.c
index b4f5811..0245ebd 100644
--- a/src/glibext/glinecursor.c
+++ b/src/glibext/glinecursor.c
@@ -31,6 +31,9 @@
 
 
 
+/* ----------------------- FONCTIONNALITES D'UN SUIVI DE BASE ----------------------- */
+
+
 /* Procède à l'initialisation d'une classe de suivi de position. */
 static void g_line_cursor_class_init(GLineCursorClass *);
 
@@ -45,6 +48,11 @@ static void g_line_cursor_finalize(GLineCursor *);
 
 
 
+/* ---------------------------------------------------------------------------------- */
+/*                         FONCTIONNALITES D'UN SUIVI DE BASE                         */
+/* ---------------------------------------------------------------------------------- */
+
+
 /* Détermine le type du gestionnaire de largeurs associées aux lignes. */
 G_DEFINE_TYPE(GLineCursor, g_line_cursor, G_TYPE_OBJECT);
 
@@ -131,6 +139,29 @@ static void g_line_cursor_finalize(GLineCursor *cursor)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : cursor = suivi d'emplacement à dupliquer.                    *
+*                                                                             *
+*  Description : Réalise la copie d'un suivi d'emplacements.                  *
+*                                                                             *
+*  Retour      : Nouvelle instance copiée.                                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GLineCursor *g_line_cursor_duplicate(const GLineCursor *cursor)
+{
+    GLineCursor *result;                    /* Instance à retourner        */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->duplicate(cursor);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : cursor = premier suivi d'emplacement à comparer.             *
 *                other  = second suivi d'emplacement à comparer.              *
 *                                                                             *
@@ -176,3 +207,188 @@ bool g_line_cursor_is_valid(const GLineCursor *cursor)
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi d'emplacement à consulter.                    *
+*                                                                             *
+*  Description : Construit une étiquette de représentation d'un suivi.        *
+*                                                                             *
+*  Retour      : Etiquette à libérer de la mémoire après usage.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *g_line_cursor_build_label(const GLineCursor *cursor)
+{
+    char *result;                           /* Etiquette à retourner       */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->build_label(cursor);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        ENCADREMENT DES TRANSFERTS DE DONEES                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à sauvegarder.                   *
+*                pbuf   = paquet de données où venir inscrire les infos.      *
+*                                                                             *
+*  Description : Exporte la définition d'un emplacement dans un flux réseau.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_line_cursor_serialize(const GLineCursor *cursor, packed_buffer *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->serialize(cursor, pbuf);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à charger. [OUT]                 *
+*                pbuf = paquet de données où venir inscrire les infos.        *
+*                                                                             *
+*  Description : Importe la définition d'un emplacement depuis un flux réseau.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_line_cursor_unserialize(GLineCursor *cursor, packed_buffer *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->unserialize(cursor, pbuf);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           LIENS AVEC UNE BASE DE DONNEES                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à traiter.                       *
+*                base   = tronc commun pour les champs de la base de données. *
+*                                                                             *
+*  Description : Donne les éléments requis pour la construction d'une table.  *
+*                                                                             *
+*  Retour      : Partie de requête à insérer dans la requête globale.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *g_line_cursor_create_db_table(const GLineCursor *cursor, const char *base)
+{
+    char *result;                           /* Requête à retourner         */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->create_db(base);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à traiter.                       *
+*                base   = tronc commun pour les champs de la base de données. *
+*                values = tableau d'éléments à compléter. [OUT]               *
+*                count  = nombre de descriptions renseignées. [OUT]           *
+*                                                                             *
+*  Description : Décrit les colonnes utiles à un chargement de données.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_line_cursor_setup_load(const GLineCursor *cursor, const char *base, bound_value **values, size_t *count)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->setup_load(base, values, count);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions dont la définition est à définir.*
+*                base   = tronc commun pour les champs de la base de données. *
+*                values = tableau d'éléments à consulter.                     *
+*                count  = nombre de descriptions renseignées.                 *
+*                                                                             *
+*  Description : Charge les valeurs utiles pour une localisation.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_line_cursor_load(GLineCursor *cursor, const char *base, const bound_value *values, size_t count)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->load(cursor, base, values, count);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : cursor = suivi de positions à traiter.                       *
+*                base   = tronc commun pour les champs de la base de données. *
+*                values = couples de champs et de valeurs à lier. [OUT]       *
+*                count  = nombre de ces couples. [OUT]                        *
+*                                                                             *
+*  Description : Constitue les champs destinés à une insertion / modification.*
+*                                                                             *
+*  Retour      : Bilan de l'opération : succès ou non.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_line_cursor_prepare_db_statement(const GLineCursor *cursor, const char *base, bound_value **values, size_t *count)
+{
+    bool result;                            /* Bilan à renvoyer            */
+
+    result = G_LINE_CURSOR_GET_CLASS(cursor)->prepare(cursor, base, values, count);
+
+    return result;
+
+}
diff --git a/src/glibext/glinecursor.h b/src/glibext/glinecursor.h
index 823adca..d9c16c4 100644
--- a/src/glibext/glinecursor.h
+++ b/src/glibext/glinecursor.h
@@ -29,6 +29,13 @@
 #include <stdbool.h>
 
 
+#include "../common/packed.h"
+#include "../common/sqlite.h"
+
+
+
+/* ----------------------- FONCTIONNALITES D'UN SUIVI DE BASE ----------------------- */
+
 
 #define G_TYPE_LINE_CURSOR            (g_line_cursor_get_type())
 #define G_LINE_CURSOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LINE_CURSOR, GLineCursor))
@@ -48,12 +55,46 @@ typedef struct _GLineCursorClass GLineCursorClass;
 /* Détermine le type du suivi de positions dans un panneau de chargement. */
 GType g_line_cursor_get_type(void);
 
+/* Réalise la copie d'un suivi d'emplacements. */
+GLineCursor *g_line_cursor_duplicate(const GLineCursor *);
+
 /* Compare deux suivis d'emplacements. */
 int g_line_cursor_compare(const GLineCursor *, const GLineCursor *);
 
 /* Détermine si un suivi d'emplacement est valide ou non. */
 bool g_line_cursor_is_valid(const GLineCursor *);
 
+/* Construit une étiquette de représentation d'un suivi. */
+char *g_line_cursor_build_label(const GLineCursor *);
+
+
+
+/* ---------------------- ENCADREMENT DES TRANSFERTS DE DONEES ---------------------- */
+
+
+/* Exporte la définition d'un emplacement dans un flux réseau. */
+bool g_line_cursor_serialize(const GLineCursor *, packed_buffer *);
+
+/* Importe la définition d'un emplacement depuis un flux réseau. */
+bool g_line_cursor_unserialize(GLineCursor *, packed_buffer *);
+
+
+
+/* ------------------------- LIENS AVEC UNE BASE DE DONNEES ------------------------- */
+
+
+/* Donne les éléments requis pour la construction d'une table. */
+char *g_line_cursor_create_db_table(const GLineCursor *, const char *);
+
+/* Décrit les colonnes utiles à un chargement de données. */
+bool g_line_cursor_setup_load(const GLineCursor *, const char *, bound_value **, size_t *);
+
+/* Charge les valeurs utiles pour une localisation. */
+bool g_line_cursor_load(GLineCursor *, const char *, const bound_value *, size_t);
+
+/* Constitue les champs destinés à une insertion / modification. */
+bool g_line_cursor_prepare_db_statement(const GLineCursor *, const char *, bound_value **, size_t *);
+
 
 
 #endif  /* _GLIBEXT_LINECURSOR_H */
diff --git a/src/glibext/gloadedpanel-int.h b/src/glibext/gloadedpanel-int.h
index b26ca06..dbe9c0c 100644
--- a/src/glibext/gloadedpanel-int.h
+++ b/src/glibext/gloadedpanel-int.h
@@ -58,6 +58,10 @@ struct _GLoadedPanelIface
 
     cache_loaded_glance_fc cache_glance;    /* Cache de la mignature       */
 
+    /* Signaux */
+
+    void (* move_request) (GLoadedPanel *, const GLineCursor *, gboolean);
+
 };
 
 
diff --git a/src/glibext/gloadedpanel.c b/src/glibext/gloadedpanel.c
index 5f43821..8bf750a 100644
--- a/src/glibext/gloadedpanel.c
+++ b/src/glibext/gloadedpanel.c
@@ -24,6 +24,7 @@
 #include "gloadedpanel.h"
 
 
+#include "chrysamarshal.h"
 #include "gloadedpanel-int.h"
 
 
@@ -51,6 +52,13 @@ G_DEFINE_INTERFACE(GLoadedPanel, g_loaded_panel, G_TYPE_OBJECT)
 
 static void g_loaded_panel_default_init(GLoadedPanelInterface *iface)
 {
+    g_signal_new("move-request",
+                 G_TYPE_LOADED_PANEL,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GLoadedPanelIface, move_request),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN,
+                 G_TYPE_NONE, 2, G_TYPE_LINE_CURSOR, G_TYPE_BOOLEAN);
 
 }
 
@@ -159,6 +167,27 @@ void g_loaded_panel_set_cursor(GLoadedPanel *panel, const GLineCursor *cursor)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : panel  = composant GTK à manipuler.                          *
+*                cursor = emplacement à cibler pour un déplacement.           *
+*                save   = le changement est-il majeur ?                       *
+*                                                                             *
+*  Description : Demande à qui veut répondre un déplacement du curseur.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_loaded_panel_request_move(GLoadedPanel *panel, const GLineCursor *cursor, gboolean save)
+{
+    g_signal_emit_by_name(panel, "move-request", cursor, save);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  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 5d22cdb..ffdb35b 100644
--- a/src/glibext/gloadedpanel.h
+++ b/src/glibext/gloadedpanel.h
@@ -64,6 +64,9 @@ GLineCursor *g_loaded_panel_get_cursor(const GLoadedPanel *);
 /* Définit le position courante dans un panneau de chargement. */
 void g_loaded_panel_set_cursor(GLoadedPanel *, const GLineCursor *);
 
+/* Demande à qui veut répondre un déplacement du curseur. */
+void g_loaded_panel_request_move(GLoadedPanel *, const GLineCursor *, gboolean);
+
 /* 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/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h
index f940212..fa67dbd 100644
--- a/src/gtkext/gtkdisplaypanel-int.h
+++ b/src/gtkext/gtkdisplaypanel-int.h
@@ -116,8 +116,6 @@ struct _GtkDisplayPanelClass
 
     /* Signaux */
 
-    void (* move_request) (GtkDisplayPanel *, const vmpa2t *);
-
     void (* caret_moved) (GtkDisplayPanel *, const vmpa2t *);
 
 };
diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c
index 12a6af4..15d257f 100644
--- a/src/gtkext/gtkdisplaypanel.c
+++ b/src/gtkext/gtkdisplaypanel.c
@@ -28,6 +28,7 @@
 
 
 #include "gtkdisplaypanel-int.h"
+#include "../glibext/gbinarycursor.h"    // REMME
 #include "../glibext/gloadedpanel-int.h"
 
 
@@ -154,14 +155,6 @@ static void gtk_display_panel_class_init(GtkDisplayPanelClass *class)
 
     panel_class->compute_inc = gtk_display_panel_compute_scroll_inc;
 
-    g_signal_new("move-request",
-                 GTK_TYPE_DISPLAY_PANEL,
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET(GtkDisplayPanelClass, move_request),
-                 NULL, NULL,
-                 g_cclosure_marshal_VOID__POINTER,
-                 G_TYPE_NONE, 1, G_TYPE_POINTER);
-
     g_signal_new("caret-moved",
                  GTK_TYPE_DISPLAY_PANEL,
                  G_SIGNAL_RUN_LAST,
@@ -1028,7 +1021,14 @@ void _gtk_display_panel_scroll_to_cursor(GtkDisplayPanel *panel, const GLineCurs
 
 void gtk_display_panel_request_move(GtkDisplayPanel *panel, const vmpa2t *addr)
 {
-    g_signal_emit_by_name(panel, "move-request", addr);
+    GLineCursor *___tmp;
+
+    ___tmp = g_binary_cursor_new();
+    g_binary_cursor_update(G_BINARY_CURSOR(___tmp), addr);
+
+    g_loaded_panel_request_move(G_LOADED_PANEL(panel), ___tmp, false);
+
+    g_object_unref(G_OBJECT(___tmp));
 
 }
 
diff --git a/src/gui/core/items.c b/src/gui/core/items.c
index fd78b41..a25d1b9 100644
--- a/src/gui/core/items.c
+++ b/src/gui/core/items.c
@@ -38,7 +38,7 @@ static GEditorItem *_editem_list = NULL;
 static gboolean notify_view_panel_focus_change(GLoadedPanel *, GdkEventFocus *, gpointer);
 
 /* Lance une procédure de déplacement de la position courante. */
-static void start_moving_to_address_in_view_panel(GtkDisplayPanel *, const vmpa2t *, gpointer);
+static void start_moving_to_cursor_in_loaded_panel(GLoadedPanel *, const GLineCursor *, gboolean, gpointer);
 
 /* Suit les changements de position dans du code d'assembleur. */
 static void track_caret_address_on_view_panel(GtkDisplayPanel *, const vmpa2t *, gpointer);
@@ -126,7 +126,8 @@ static gboolean notify_view_panel_focus_change(GLoadedPanel *panel, GdkEventFocu
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : panel  = composant d'affichage parcouru.                     *
-*                addr   = adresse de destination du curseur souhaitée.        *
+*                cursor = emplacement à cibler pour un déplacement.           *
+*                save   = le changement est-il majeur ?                       *
 *                unused = adresse non utilisée ici.                           *
 *                                                                             *
 *  Description : Lance une procédure de déplacement de la position courante.  *
@@ -137,36 +138,29 @@ static gboolean notify_view_panel_focus_change(GLoadedPanel *panel, GdkEventFocu
 *                                                                             *
 ******************************************************************************/
 
-static void start_moving_to_address_in_view_panel(GtkDisplayPanel *panel, const vmpa2t *addr, gpointer unused)
+static void start_moving_to_cursor_in_loaded_panel(GLoadedPanel *panel, const GLineCursor *cursor, gboolean save, gpointer unused)
 {
-    const vmpa2t *src;                      /* Position courante de curseur*/
-    GLineCursor *___tmp;
+    GLineCursor *src;                       /* Position courante de curseur*/
     GDbMove *move;                          /* Déplacement à organiser     */
     GLoadedBinary *binary;                  /* Binaire en cours d'étude    */
 
-    src = gtk_display_panel_get_caret_location(panel);
+    src = g_loaded_panel_get_cursor(panel);
 
-    /* S'il n'y a pas de passif, pas besoin d'historique */
-    if (src == NULL)
+    if (save && src != NULL)
     {
-        ___tmp = g_binary_cursor_new();
-        g_binary_cursor_update(G_BINARY_CURSOR(___tmp), addr);
+        move = g_db_move_new(src, cursor);
 
-        gtk_display_panel_scroll_to_cursor(panel, ___tmp, SPT_CENTER);
-
-        g_object_unref(G_OBJECT(___tmp));
+        binary = G_LOADED_BINARY(g_loaded_panel_get_content(panel));
+        g_loaded_binary_add_to_collection(binary, G_DB_ITEM(move));
+        g_object_unref(G_OBJECT(binary));
 
     }
 
     else
-    {
-        move = g_db_move_new(src, addr);
+        gtk_display_panel_scroll_to_cursor(panel, cursor, SPT_CENTER);
 
-        binary = gtk_display_panel_get_binary(panel);
-        g_loaded_binary_add_to_collection(binary, G_DB_ITEM(move));
-        g_object_unref(G_OBJECT(binary));
-
-    }
+    if (src != NULL)
+        g_object_unref(G_OBJECT(src));
 
 }
 
@@ -260,7 +254,7 @@ void change_editor_items_current_view(GLoadedPanel *panel)
         if (caret != NULL)
         {
             g_signal_handlers_disconnect_by_func(caret,
-                                                 G_CALLBACK(start_moving_to_address_in_view_panel),
+                                                 G_CALLBACK(start_moving_to_cursor_in_loaded_panel),
                                                  NULL);
             g_signal_handlers_disconnect_by_func(caret,
                                                  G_CALLBACK(track_caret_address_on_view_panel),
@@ -274,7 +268,7 @@ void change_editor_items_current_view(GLoadedPanel *panel)
         if (panel != NULL)
         {
             g_signal_connect(panel, "move-request",
-                             G_CALLBACK(start_moving_to_address_in_view_panel),
+                             G_CALLBACK(start_moving_to_cursor_in_loaded_panel),
                              NULL);
 
             g_signal_connect(panel, "caret-moved",
-- 
cgit v0.11.2-87-g4458