From 1c2949f6828b995c7b9f8feba8fd7214f52f8f4d Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 12 Sep 2019 00:08:42 +0200
Subject: Built suitable dynamic labels for bookmarks.

---
 plugins/pychrysalide/analysis/db/item.c | 43 +++++++++++++++++++++++++++++++++
 src/analysis/db/item-int.h              |  7 ++----
 src/analysis/db/item.c                  | 34 +++++++++++++++++---------
 src/analysis/db/item.h                  |  2 +-
 src/analysis/db/items/bookmark.c        | 27 ++++++++++++++++++---
 src/analysis/db/items/comment.c         |  9 ++++---
 src/analysis/db/items/move.c            |  9 ++++---
 src/analysis/db/items/switcher.c        |  9 ++++---
 src/gui/panels/history.c                | 14 +++++++++--
 9 files changed, 121 insertions(+), 33 deletions(-)

diff --git a/plugins/pychrysalide/analysis/db/item.c b/plugins/pychrysalide/analysis/db/item.c
index bbaa21b..7bb96c2 100644
--- a/plugins/pychrysalide/analysis/db/item.c
+++ b/plugins/pychrysalide/analysis/db/item.c
@@ -25,6 +25,7 @@
 #include "item.h"
 
 
+#include <malloc.h>
 #include <pygobject.h>
 
 
@@ -44,6 +45,9 @@ static PyObject *py_db_item_add_flag(PyObject *, PyObject *);
 /* Retire une propriété à un élément de base de données. */
 static PyObject *py_db_item_remove_flag(PyObject *, PyObject *);
 
+/* Décrit l'élément de collection en place. */
+static PyObject *py_db_item_get_label(PyObject *, void *);
+
 /* Indique si l'élément contient des données à oublier ou non. */
 static PyObject *py_db_item_get_volatile(PyObject *, void *);
 
@@ -142,6 +146,44 @@ static PyObject *py_db_item_remove_flag(PyObject *self, PyObject *args)
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
+*  Description : Décrit l'élément de collection en place.                     *
+*                                                                             *
+*  Retour      : Chaîne de caractère correspondante.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_item_get_label(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GDbItem *item;                          /* Elément à consulter         */
+    char *label;                            /* Etiquette de représentation */
+
+#define DB_ITEM_LABEL_ATTRIB PYTHON_GET_DEF_FULL            \
+(                                                           \
+    label, py_db_item,                                      \
+    "String describing the effect of the database item."    \
+)
+
+    item = G_DB_ITEM(pygobject_get(self));
+
+    label = g_db_item_get_label(item);
+
+    result = PyUnicode_FromString(label);
+
+    free(label);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
 *  Description : Indique si l'élément contient des données à oublier ou non.  *
 *                                                                             *
 *  Retour      : Etat de la sauegarde de l'élément consulté.                  *
@@ -259,6 +301,7 @@ PyTypeObject *get_python_db_item_type(void)
             "volatile", py_db_item_get_volatile, py_db_item_set_volatile,
             "Define if a Database item can be forgotten.", NULL
         },
+        DB_ITEM_LABEL_ATTRIB,
         DB_ITEM_FLAGS_ATTRIB,
         { NULL }
     };
diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h
index 923ea3a..e530442 100644
--- a/src/analysis/db/item-int.h
+++ b/src/analysis/db/item-int.h
@@ -46,7 +46,7 @@ typedef bool (* unpack_db_item_fc) (GDbItem *, packed_buffer *);
 typedef bool (* pack_db_item_fc) (const GDbItem *, packed_buffer *);
 
 /* Construit la description humaine d'un signet sur un tampon. */
-typedef void (* build_item_label_fc) (GDbItem *);
+typedef char * (* build_item_label_fc) (GDbItem *);
 
 /* Exécute un élément de collection sur un binaire. */
 typedef bool (* run_item_fc) (GDbItem *, GLoadedBinary *);
@@ -69,8 +69,6 @@ struct _GDbItem
     rle_string author;                      /* Utilisateur d'origine       */
     rle_string tool;                        /* Eventuel outil automatique ?*/
 
-    char *label;                            /* Représentation humaine      */
-
     union
     {
         DbItemFlags flags;                  /* Propriétés de l'élément     */
@@ -111,8 +109,7 @@ struct _GDbItemClass
     SQLITE_TIMESTAMP_CREATE("created") ", "     \
     SQLITE_TIMESTAMP_CREATE("timestamp") ", "   \
     SQLITE_RLESTR_CREATE("author") ", "         \
-    SQLITE_RLESTR_CREATE("tool") ", "           \
-    SQLITE_RLESTR_CREATE("label")
+    SQLITE_RLESTR_CREATE("tool")
 
 
 
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c
index c59ef64..227d99f 100644
--- a/src/analysis/db/item.c
+++ b/src/analysis/db/item.c
@@ -159,9 +159,6 @@ static void g_db_item_finalize(GDbItem *item)
     exit_rle_string(&item->author);
     exit_rle_string(&item->tool);
 
-    if (item->label != NULL)
-        free(item->label);
-
     G_OBJECT_CLASS(g_db_item_parent_class)->finalize(G_OBJECT(item));
 
 }
@@ -224,6 +221,8 @@ void g_db_item_set_server_side(GDbItem *item)
 gint g_db_item_cmp(GDbItem *a, GDbItem *b, bool with)
 {
     gint result;                            /* Bilan à retourner           */
+    char *label_a;                          /* Etiquette de l'élément A    */
+    char *label_b;                          /* Etiquette de l'élément B    */
 
     if (with)
         result = cmp_timestamp(&a->timestamp, &b->timestamp);
@@ -234,7 +233,16 @@ gint g_db_item_cmp(GDbItem *a, GDbItem *b, bool with)
         result = cmp_timestamp(&a->created, &b->created);
 
     if (result == 0)
-        result = strcmp(g_db_item_get_label(a), g_db_item_get_label(b));
+    {
+        label_a = g_db_item_get_label(a);
+        label_b = g_db_item_get_label(b);
+
+        result = strcmp(label_a, label_b);
+
+        free(label_a);
+        free(label_b);
+
+    }
 
     return result;
 
@@ -449,21 +457,23 @@ bool g_db_item_cancel(GDbItem *item, GLoadedBinary *binary)
 *                                                                             *
 *  Description : Décrit l'élément de collection en place.                     *
 *                                                                             *
-*  Retour      : Chaîne de caractère correspondante.                          *
+*  Retour      : Description humaine mise en place à libérer après usage.     *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-const char *g_db_item_get_label(GDbItem *item)
+char *g_db_item_get_label(GDbItem *item)
 {
-    if (item->label == NULL)
-    {
-        G_DB_ITEM_GET_CLASS(item)->build_label(item);
-        assert(item->label != NULL);
-    }
+    char *result;                           /* Description à retourner     */
+    GDbItemClass *class;                    /* Classe de l'instance        */
+
+    class = G_DB_ITEM_GET_CLASS(item);
 
-    return item->label;
+    result = class->build_label(item);
+    assert(result != NULL);
+
+    return result;
 
 }
 
diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h
index 3444b73..383f9ed 100644
--- a/src/analysis/db/item.h
+++ b/src/analysis/db/item.h
@@ -95,7 +95,7 @@ bool g_db_item_apply(GDbItem *, GLoadedBinary *);
 bool g_db_item_cancel(GDbItem *, GLoadedBinary *);
 
 /* Décrit l'élément de collection en place. */
-const char *g_db_item_get_label(GDbItem *);
+char *g_db_item_get_label(GDbItem *);
 
 /* Fournit l'horodatage associé à l'élément de collection. */
 timestamp_t g_db_item_get_timestamp(const GDbItem *);
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 819528d..5715737 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -83,7 +83,7 @@ static bool g_db_bookmark_unpack(GDbBookmark *, packed_buffer *);
 static bool g_db_bookmark_pack(const GDbBookmark *, packed_buffer *);
 
 /* Construit la description humaine d'un signet sur un tampon. */
-static void g_db_bookmark_build_label(GDbBookmark *);
+static char *g_db_bookmark_build_label(GDbBookmark *);
 
 /* Exécute un signet sur un tampon de binaire chargé. */
 static bool g_db_bookmark_run(GDbBookmark *, GLoadedBinary *, bool *, bool);
@@ -414,15 +414,34 @@ static bool g_db_bookmark_pack(const GDbBookmark *bookmark, packed_buffer *pbuf)
 *                                                                             *
 *  Description : Construit la description humaine d'un signet sur un tampon.  *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Chaîne de caractère correspondante.                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_bookmark_build_label(GDbBookmark *bookmark)
+static char *g_db_bookmark_build_label(GDbBookmark *bookmark)
 {
-    asprintf(&G_DB_ITEM(bookmark)->label, _("Bookmark \"%s\""), get_rle_string(&bookmark->comment));
+    char *result;                           /* Description à retourner     */
+    DbItemFlags flags;                      /* Propriétés de l'élément     */
+    const char *prefix;                     /* Préfixe à ajouter           */
+    const char *text;                       /* Commentaire associé         */
+
+    flags = g_db_item_get_flags(G_DB_ITEM(bookmark));
+
+    if (flags & DIF_ERASER)
+        prefix = _("Removed");
+    else
+        prefix = _("Created");
+
+    text = get_rle_string(&bookmark->comment);
+
+    if (text != NULL)
+        asprintf(&result, _("%s bookmark \"%s\""), prefix, text);
+    else
+        asprintf(&result, _("%s empty bookmark"), prefix);
+
+    return result;
 
 }
 
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 331ff2d..22ae46f 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -102,7 +102,7 @@ static bool g_db_comment_unpack(GDbComment *, packed_buffer *);
 static bool g_db_comment_pack(GDbComment *, packed_buffer *);
 
 /* Construit la description humaine d'un commentaire. */
-static void g_db_comment_build_label(GDbComment *);
+static char *g_db_comment_build_label(GDbComment *);
 
 /* Exécute l'impression de commentaire dans du code de binaire. */
 static bool g_db_comment_run(GDbComment *, GLoadedBinary *, bool);
@@ -581,14 +581,15 @@ static bool g_db_comment_pack(GDbComment *comment, packed_buffer *pbuf)
 *                                                                             *
 *  Description : Construit la description humaine d'un commentaire.           *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Chaîne de caractère correspondante.                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_comment_build_label(GDbComment *comment)
+static char *g_db_comment_build_label(GDbComment *comment)
 {
+#if 0
     VMPA_BUFFER(loc);                       /* Indication de position      */
     size_t count;                           /* Nombre d'éléments textuels  */
 
@@ -608,6 +609,8 @@ static void g_db_comment_build_label(GDbComment *comment)
         else
             asprintf(&G_DB_ITEM(comment)->label, _("Enter comment area at %s"), loc);
     }
+#endif
+    return NULL;
 
 }
 
diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c
index 0c53e67..c213786 100644
--- a/src/analysis/db/items/move.c
+++ b/src/analysis/db/items/move.c
@@ -84,7 +84,7 @@ static bool g_db_move_unpack(GDbMove *, packed_buffer *);
 static bool g_db_move_pack(const GDbMove *, packed_buffer *);
 
 /* Construit la description humaine d'un déplacement. */
-static void g_db_move_build_label(GDbMove *);
+static char *g_db_move_build_label(GDbMove *);
 
 /* Exécute un déplacement dans une zone de code. */
 static bool g_db_move_run(const GDbMove *, GLineCursor *);
@@ -380,14 +380,15 @@ static bool g_db_move_pack(const GDbMove *move, packed_buffer *pbuf)
 *                                                                             *
 *  Description : Construit la description humaine d'un déplacement.           *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Chaîne de caractère correspondante.                          *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_move_build_label(GDbMove *move)
+static char *g_db_move_build_label(GDbMove *move)
 {
+#if 0
     char *src_label;                        /* Indication de position #1   */
     char *dest_label;                       /* Indication de position #2   */
 
@@ -398,6 +399,8 @@ static void g_db_move_build_label(GDbMove *move)
 
     free(src_label);
     free(dest_label);
+#endif
+    return NULL;
 
 }
 
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index b786182..49486f4 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -84,7 +84,7 @@ static bool g_db_switcher_unpack(GDbSwitcher *, packed_buffer *);
 static bool g_db_switcher_pack(const GDbSwitcher *, packed_buffer *);
 
 /* Construit la description humaine d'un signet sur un tampon. */
-static void g_db_switcher_build_label(GDbSwitcher *);
+static char *g_db_switcher_build_label(GDbSwitcher *);
 
 /* Exécute une bascule d'affichage d'opérande sur un binaire. */
 static bool g_db_switcher_run(GDbSwitcher *, GLoadedBinary *, ImmOperandDisplay *, ImmOperandDisplay);
@@ -450,14 +450,15 @@ static bool g_db_switcher_pack(const GDbSwitcher *switcher, packed_buffer *pbuf)
 *                                                                             *
 *  Description : Construit la description humaine d'un signet sur un tampon.  *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Description humaine mise en place à libérer après usage.     *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_switcher_build_label(GDbSwitcher *switcher)
+static char *g_db_switcher_build_label(GDbSwitcher *switcher)
 {
+#if 0
     VMPA_BUFFER(loc);                       /* Indication de position      */
 
     vmpa2_to_string(&switcher->addr, MDS_UNDEFINED, loc, NULL);
@@ -483,6 +484,8 @@ static void g_db_switcher_build_label(GDbSwitcher *switcher)
             assert(false);
             break;
     }
+#endif
+    return NULL;
 
 }
 
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index ac33c2c..cfea509 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -280,6 +280,7 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo
     GList *items;                           /* Liste des éléments groupés  */
     GList *i;                               /* Boucle de parcours #2       */
     GDbItem *item;                          /* Elément à intégrer          */
+    char *label;                            /* Etiquette de représentation */
     GtkTreeIter iter;                       /* Point d'insertion           */
 
     if (G_IS_LOADED_BINARY(new))
@@ -335,14 +336,18 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo
         {
             item = G_DB_ITEM(i->data);
 
+            label = g_db_item_get_label(item);
+
             gtk_list_store_append(store, &iter);
             gtk_list_store_set(store, &iter,
                                HTC_ITEM, item,
                                //HTC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img,
                                HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey",
-                               HTC_LABEL, g_db_item_get_label(item),
+                               HTC_LABEL, label,
                                -1);
 
+            free(label);
+
         }
 
         g_signal_connect_to_main(collections[k], "content-changed", G_CALLBACK(on_history_changed), panel,
@@ -383,6 +388,7 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem *
     GtkListStore *store;                    /* Modèle de gestion courant   */
     GtkTreeModel *model;                    /* Modèle de gestion générique */
     GtkTreeSelection *selection;            /* Nouvelle sélection à établir*/
+    char *label;                            /* Etiquette de représentation */
     GtkTreeIter iter;                       /* Boucle de parcours          */
 
     builder = G_PANEL_ITEM(panel)->builder;
@@ -428,14 +434,18 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem *
     {
         case DBA_ADD_ITEM:
 
+            label = g_db_item_get_label(item);
+
             gtk_list_store_append(store, &iter);
             gtk_list_store_set(store, &iter,
                                HTC_ITEM, item,
                                //HTC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img,
                                HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey",
-                               HTC_LABEL, g_db_item_get_label(item),
+                               HTC_LABEL, label,
                                -1);
 
+            free(label);
+
             break;
 
         case DBA_REM_ITEM:
-- 
cgit v0.11.2-87-g4458