From b66aa52128ad47d7130f087509535989d507d15b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 10 Apr 2015 21:57:38 +0000
Subject: Extended the behavior of the strings panel.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@508 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                |  7 ++++
 src/core/params.c        |  3 ++
 src/core/params.h        |  1 +
 src/gui/panels/strings.c | 89 ++++++++++++++++++++++++++++++++++++++++++++----
 4 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a65a813..f971576 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+15-04-10  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/core/params.c:
+	* src/core/params.h:
+	* src/gui/panels/strings.c:
+	Extend the behavior of the strings panel.
+
 15-04-09  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/glibext/gbufferline.c:
diff --git a/src/core/params.c b/src/core/params.c
index 5e91faf..75722b6 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -153,6 +153,9 @@ bool load_main_config_parameters(void)
     param = g_generic_config_create_param(config, MPK_ELLIPSIS_TAB, CPT_INTEGER, 35);
     if (param == NULL) return false;
 
+    param = g_generic_config_create_param(config, MPK_DISPLAY_ON_SEL, CPT_BOOLEAN, false);
+    if (param == NULL) return false;
+
     param = g_generic_config_create_param(config, MPK_KEYBINDINGS_EDIT, CPT_STRING, "<Shift>F2");
     if (param == NULL) return false;
 
diff --git a/src/core/params.h b/src/core/params.h
index 6f8d62f..9eac629 100644
--- a/src/core/params.h
+++ b/src/core/params.h
@@ -45,6 +45,7 @@
 #define MPK_MAXIMIZED           "gui.editor.start_maximized"
 #define MPK_ELLIPSIS_HEADER     "gui.editor.panels.ellipsis_header"
 #define MPK_ELLIPSIS_TAB        "gui.editor.panels.ellipsis_tab"
+#define MPK_DISPLAY_ON_SEL      "gui.editor.panels.display_on_selection"
 #define MPK_KEYBINDINGS_EDIT    "gui.key_bindings.global.edit"
 #define MPK_AUTO_SAVE           "project.autosave"
 
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index f1397a8..b8f5eca 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -32,6 +32,7 @@
 #include "panel-int.h"
 #include "../../common/extstr.h"
 #include "../../core/params.h"
+#include "../../dialogs/gotox.h"
 #include "../../gtkext/easygtk.h"
 
 
@@ -128,7 +129,7 @@ static bool is_string_filtered(GStringsPanel *, const char *, const char *);
 
 
 /* Assure la gestion des clics de souris sur les signets. */
-static gboolean on_button_press_over_strings(GtkWidget *, GdkEventButton *, GStringsPanel *);
+static gboolean on_button_event_over_strings(GtkWidget *, GdkEventButton *, GStringsPanel *);
 
 /* Construit le menu contextuel pour les signets. */
 static GtkMenu *build_strings_panel_menu(GStringsPanel *);
@@ -142,6 +143,9 @@ static void mcb_strings_panel_edit(GtkMenuItem *, GStringsPanel *);
 /* Réagit avec le menu "Copier dans le presse-papiers". */
 static void mcb_strings_panel_copy(GtkMenuItem *, GStringsPanel *);
 
+/* Réagit avec le menu "Trouver les références...". */
+static void mcb_strings_panel_find_refs(GtkMenuItem *, GStringsPanel *);
+
 /* Réagit avec le menu "Filtrer...". */
 static void mcb_strings_panel_filter(GtkMenuItem *, GStringsPanel *);
 
@@ -211,6 +215,7 @@ static void g_strings_panel_init(GStringsPanel *panel)
     GtkTreeViewColumn *column;              /* Colonne de la liste         */
     GtkTreeSortable *sortable;              /* Autre vision de la liste    */
     GtkTreeSelection *select;               /* Sélection dans la liste     */
+    bool display;                           /* Affichage si sélection ?    */
 
     base = G_EDITOR_ITEM(panel);
 
@@ -251,7 +256,9 @@ static void g_strings_panel_init(GStringsPanel *panel)
     panel->treeview = GTK_TREE_VIEW(treeview);
 
     g_signal_connect(G_OBJECT(treeview), "button-press-event",
-                     G_CALLBACK(on_button_press_over_strings), panel);
+                     G_CALLBACK(on_button_event_over_strings), panel);
+    g_signal_connect(G_OBJECT(treeview), "button-release-event",
+                     G_CALLBACK(on_button_event_over_strings), panel);
     g_signal_connect(G_OBJECT(treeview), "key-press-event",
                      G_CALLBACK(on_key_pressed_over_strings), panel);
 
@@ -314,7 +321,11 @@ static void g_strings_panel_init(GStringsPanel *panel)
 
     select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
     gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
-    g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(on_strings_selection_change), panel);
+
+    g_generic_config_get_value(get_main_configuration(), MPK_DISPLAY_ON_SEL, &display);
+
+    if (display)
+        g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(on_strings_selection_change), panel);
 
     /* Préparation du menu contextuel */
 
@@ -809,7 +820,7 @@ static bool is_string_filtered(GStringsPanel *panel, const char *label, const ch
 *                                                                             *
 ******************************************************************************/
 
-static gboolean on_button_press_over_strings(GtkWidget *widget, GdkEventButton *event, GStringsPanel *panel)
+static gboolean on_button_event_over_strings(GtkWidget *widget, GdkEventButton *event, GStringsPanel *panel)
 {
     GtkTreeSelection *selection;            /* Sélection courante          */
     GtkTreeIter iter;                       /* Point de sélection          */
@@ -822,6 +833,9 @@ static gboolean on_button_press_over_strings(GtkWidget *widget, GdkEventButton *
     {
         case 1:
 
+            if (event->type != GDK_2BUTTON_PRESS)
+                break;
+
             selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
 
             if (gtk_tree_selection_get_selected(selection, &model, &iter))
@@ -877,13 +891,15 @@ static GtkMenu *build_strings_panel_menu(GStringsPanel *panel)
                                        G_CALLBACK(mcb_strings_panel_copy), panel);
     gtk_container_add(GTK_CONTAINER(result), submenuitem);
 
-    submenuitem = qck_create_menu_item(NULL, NULL, _("_Find references..."), NULL, NULL);
+    submenuitem = qck_create_menu_item(NULL, NULL, _("_Find references..."),
+                                       G_CALLBACK(mcb_strings_panel_find_refs), panel);
     gtk_container_add(GTK_CONTAINER(result), submenuitem);
 
     submenuitem = qck_create_menu_separator();
     gtk_container_add(GTK_CONTAINER(result), submenuitem);
 
-    submenuitem = qck_create_menu_item(NULL, NULL, _("Filter..."), G_CALLBACK(mcb_strings_panel_filter), panel);
+    submenuitem = qck_create_menu_item(NULL, NULL, _("Filter..."),
+                                       G_CALLBACK(mcb_strings_panel_filter), panel);
     gtk_container_add(GTK_CONTAINER(result), submenuitem);
 
     return GTK_MENU(result);
@@ -1010,6 +1026,67 @@ static void mcb_strings_panel_copy(GtkMenuItem *menuitem, GStringsPanel *panel)
 *  Paramètres  : menuitem = élément de menu sélectionné.                      *
 *                panel    = panneau d'affichage des signets liés à un binaire.*
 *                                                                             *
+*  Description : Réagit avec le menu "Trouver les références...".             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *panel)
+{
+    GBinSymbol *symbol;                     /* Symbole sélectionné         */
+    const mrange_t *range;                  /* Couverture en mémoire       */
+    GLoadedBinary *binary;                  /* Représentation binaire      */
+    GArchInstruction *list;                 /* Ensemble des instructions   */
+    GArchInstruction *instr;                /* Point de croisements        */
+    GObject *ref;                           /* Espace de référencements    */
+    GtkWidget *dialog;                      /* Boîte de dialogue à montrer */
+    vmpa2t *addr;                           /* Adresse de destination      */
+    GtkViewPanel *vpanel;                   /* Afficheur effectif de code  */
+
+    symbol = get_selected_panel_symbol(panel->treeview, NULL);
+    if (symbol == NULL) return;
+
+    range = g_binary_symbol_get_range(symbol);
+
+    binary = g_editor_item_get_current_binary(G_EDITOR_ITEM(panel));
+    list = g_loaded_binary_get_instructions(binary);
+
+    /**
+     * Se rapporter aux commentaires de mcb_edition_list_xrefs() pour les questions
+     * concernant l'usage d'une adresse d'instruction au lieu de son emplacement.
+     */
+    instr = g_arch_instruction_find_by_address(list, get_mrange_addr(range), true);
+
+    ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(panel));
+
+    dialog = create_gotox_dialog_for_cross_references(GTK_WINDOW(ref), binary, instr, true);
+
+    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
+    {
+        addr = get_address_from_gotox_dialog(dialog);
+
+        vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(panel));
+        gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
+
+        delete_vmpa(addr);
+
+    }
+
+    gtk_widget_destroy(dialog);
+
+    g_object_unref(G_OBJECT(symbol));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : menuitem = élément de menu sélectionné.                      *
+*                panel    = panneau d'affichage des signets liés à un binaire.*
+*                                                                             *
 *  Description : Réagit avec le menu "Filtrer...".                            *
 *                                                                             *
 *  Retour      : -                                                            *
-- 
cgit v0.11.2-87-g4458