summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/panels/bookmarks.c30
-rw-r--r--src/gui/panels/regedit.c4
-rw-r--r--src/gui/panels/strings.c702
3 files changed, 642 insertions, 94 deletions
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index e9ab0d1..60daf67 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -38,9 +38,9 @@
#include "panel-int.h"
#include "../../analysis/db/items/bookmark.h"
-#include "../../core/params.h"
#include "../../common/cpp.h"
#include "../../common/extstr.h"
+#include "../../core/params.h"
#include "../../gtkext/easygtk.h"
#include "../../gtkext/support.h"
@@ -141,7 +141,7 @@ static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTr
/* Démarre l'actualisation du filtrage des paramètres. */
static void on_param_search_changed(GtkSearchEntry *, GBookmarksPanel *);
-/*Détermine si un paramètre doit être filtré ou non. */
+/* Détermine si un paramètre doit être filtré ou non. */
static bool is_param_filtered(GBookmarksPanel *, const char *);
@@ -153,7 +153,7 @@ static bool is_param_filtered(GBookmarksPanel *, const char *);
static gboolean on_button_press_over_bookmarks(GtkWidget *, GdkEventButton *, GBookmarksPanel *);
/* Construit le menu contextuel pour les signets. */
-GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *);
+static GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *);
/* Fournit le signet sélectionné dans la liste. */
static GDbBookmark *get_selected_panel_bookmark(GtkTreeView *, GtkTreeIter *);
@@ -807,7 +807,7 @@ static gint compare_bookmarks_list_columns(GtkTreeModel *model, GtkTreeIter *a,
result = (value_a == NULL ? -1 : 1);
}
else
- result = g_utf8_collate(value_a,value_b);
+ result = g_utf8_collate(value_a, value_b);
g_free(value_a);
g_free(value_b);
@@ -836,9 +836,6 @@ static gboolean on_key_pressed_over_params(GtkTreeView *treeview, GdkEventKey *e
const gchar *accelerator; /* Combinaison de raccourci */
guint accel_key; /* Touche de raccourci */
GdkModifierType accel_mod; /* Modifiateurs attendus aussi */
- GtkTreeIter iter; /* Point de la sélection */
- GtkTreeModel *model; /* Gestionnaire de données */
- GtkTreePath *path; /* Chemin d'accès à ce point */
if (!g_generic_config_get_value(get_main_configuration(), MPK_KEYBINDINGS_EDIT, &accelerator))
return FALSE;
@@ -849,22 +846,7 @@ static gboolean on_key_pressed_over_params(GtkTreeView *treeview, GdkEventKey *e
gtk_accelerator_parse(accelerator, &accel_key, &accel_mod);
if (event->keyval == accel_key && event->state == accel_mod)
- {
- /* FIXME : unref(result) */
- if (get_selected_panel_bookmark(treeview, &iter) != NULL)
- {
- model = gtk_tree_view_get_model(treeview);
- path = gtk_tree_model_get_path(model, &iter);
-
- gtk_tree_view_set_cursor(treeview, path,
- gtk_tree_view_get_column(treeview, BMC_COMMENT - BMC_PHYSICAL),
- TRUE);
-
- gtk_tree_path_free(path);
-
- }
-
- }
+ mcb_bookmarks_panel_edit(NULL, panel);
return FALSE;
@@ -1112,7 +1094,7 @@ static gboolean on_button_press_over_bookmarks(GtkWidget *widget, GdkEventButton
* *
******************************************************************************/
-GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *panel)
+static GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *panel)
{
GtkWidget *result; /* Support à retourner */
GtkWidget *submenuitem; /* Sous-élément de menu */
diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c
index 3145385..a187a2d 100644
--- a/src/gui/panels/regedit.c
+++ b/src/gui/panels/regedit.c
@@ -127,7 +127,7 @@ static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTr
/* Démarre l'actualisation du filtrage des paramètres. */
static void on_param_search_changed(GtkSearchEntry *, GRegeditPanel *);
-/*Détermine si un paramètre doit être filtré ou non. */
+/* Détermine si un paramètre doit être filtré ou non. */
static bool is_param_filtered(GRegeditPanel *, const char *);
@@ -650,7 +650,7 @@ static gint compare_config_list_columns(GtkTreeModel *model, GtkTreeIter *a, Gtk
result = (value_a == NULL ? -1 : 1);
}
else
- result = g_utf8_collate(value_a,value_b);
+ result = g_utf8_collate(value_a, value_b);
g_free(value_a);
g_free(value_b);
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index b68a0e8..f1397a8 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -26,10 +26,12 @@
#include <inttypes.h>
+#include <regex.h>
#include "panel-int.h"
#include "../../common/extstr.h"
+#include "../../core/params.h"
#include "../../gtkext/easygtk.h"
@@ -43,11 +45,11 @@ struct _GStringsPanel
GPanelItem parent; /* A laisser en premier */
GtkTreeView *treeview; /* Composant d'affichage */
- GtkTreeStore *store; /* Modèle de gestion */
+ regex_t *filter; /* Filtre appliqué ou NULL */
- GLoadedBinary *binary; /* Binaire à prendre en compte */
+ GtkMenu *menu; /* Menu contextuel pour param. */
- GtkWidget *menubar; /* Support pour l'édition */
+ GLoadedBinary *binary; /* Binaire en cours d'analyse */
};
@@ -63,9 +65,12 @@ struct _GStringsPanelClass
/* Colonnes de la liste des symboles */
typedef enum _StringsColumn
{
- STC_ADDRESS, /* Adresse mémoire du symbole */
- STC_STRING, /* Désignation humaine */
- STC_RAW, /* Données non retouchées */
+ STC_STRING, /* Elément GLib représenté */
+
+ STC_PHYSICAL, /* Adresse phyisque */
+ STC_VIRTUAL, /* Adresse virtuelle */
+ STC_NAME, /* Désignation humaine */
+ STC_VALUE, /* Chaîne de caractères */
STC_COUNT /* Nombre de colonnes */
@@ -89,14 +94,57 @@ static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *
-/* ------------------------- GESTIONS DES MENUS CONTEXTUELS ------------------------- */
-/* Affiche le menu d'édition propre aux chaînes trouvées. */
-static gboolean on_strings_button_press_event(GtkTreeView *, GdkEventButton *, GStringsPanel *);
+/* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */
+
+
+/* Réagit au changement de sélection des chaînes textuelles. */
+static void on_strings_selection_change(GtkTreeSelection *, GStringsPanel *);
+
+/* Etablit une comparaison entre deux chaînes de caractères. */
+static gint compare_strings_list_columns(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer);
+
+/* Réagit à une pression sur <Shift+F2> et simule l'édition. */
+static gboolean on_key_pressed_over_strings(GtkTreeView *, GdkEventKey *, GStringsPanel *);
+
+/* Réagit à une édition de l'étiquette d'une chaîne textuelle. */
+static void on_string_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTreeStore *);
+
+
+
+/* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */
+
+
+/* Démarre l'actualisation du filtrage des paramètres. */
+static void on_string_search_changed(GtkSearchEntry *, GStringsPanel *);
+
+/* Détermine si une chaîne textuelle doit être filtrée ou non. */
+static bool is_string_filtered(GStringsPanel *, const char *, const char *);
+
+
+
+/* ------------------------ ATTRIBUTION D'UN MENU CONTEXTUEL ------------------------ */
+
+
+/* Assure la gestion des clics de souris sur les signets. */
+static gboolean on_button_press_over_strings(GtkWidget *, GdkEventButton *, GStringsPanel *);
+
+/* Construit le menu contextuel pour les signets. */
+static GtkMenu *build_strings_panel_menu(GStringsPanel *);
+
+/* Fournit le signet sélectionné dans la liste. */
+static GBinSymbol *get_selected_panel_symbol(GtkTreeView *, GtkTreeIter *);
+
+/* Réagit avec le menu "Editer le nom". */
+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 "Filtrer...". */
+static void mcb_strings_panel_filter(GtkMenuItem *, GStringsPanel *);
-/* Réagit avec le menu "--- -> Copier". */
-static void mcb_strings_copy(GtkMenuItem *, GtkTreeView *);
@@ -154,67 +202,123 @@ static void g_strings_panel_init(GStringsPanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
GObject *ref; /* Espace de référencement */
- GtkWidget *scrollwnd; /* Support défilant */
+ GtkWidget *label; /* Etiquette à utiliser */
+ GtkWidget *search; /* Zone de recherche */
+ GtkWidget *scrolled; /* Fenêtre défilante */
GtkTreeStore *store; /* Modèle de gestion */
GtkWidget *treeview; /* Affichage de la liste */
GtkCellRenderer *renderer; /* Moteur de rendu de colonne */
GtkTreeViewColumn *column; /* Colonne de la liste */
- GtkWidget *submenuitem; /* Sous-élément de menu */
+ GtkTreeSortable *sortable; /* Autre vision de la liste */
+ GtkTreeSelection *select; /* Sélection dans la liste */
base = G_EDITOR_ITEM(panel);
- base->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
+ base->widget = gtk_grid_new();
gtk_widget_show(base->widget);
+ gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8);
+
ref = G_OBJECT(base->widget);
g_object_set_data(ref, "panel", panel);
- /* Liste des chaînes */
+ /* Partie recherche */
+
+ label = qck_create_label(NULL, NULL, _("Look for:"));
+ g_object_set(label, "margin", 8, NULL);
+ gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1);
+
+ search = gtk_search_entry_new();
+ g_signal_connect(search, "search-changed", G_CALLBACK(on_string_search_changed), panel);
+ gtk_widget_show(search);
+ gtk_widget_set_hexpand(search, TRUE);
+ gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1);
- scrollwnd = gtk_scrolled_window_new(NULL, NULL);
- gtk_widget_show(scrollwnd);
- gtk_box_pack_start(GTK_BOX(base->widget), scrollwnd, TRUE, TRUE, 0);
+ /* Partie paramètres */
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwnd), GTK_SHADOW_IN);
+ scrolled = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_show(scrolled);
+ gtk_widget_set_vexpand(scrolled, TRUE);
+ gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1);
- store = gtk_tree_store_new(STC_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
- g_object_set_data(G_OBJECT(panel), "store", store);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+
+ store = gtk_tree_store_new(STC_COUNT, G_TYPE_OBJECT,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+ panel->treeview = GTK_TREE_VIEW(treeview);
+
+ g_signal_connect(G_OBJECT(treeview), "button-press-event",
+ G_CALLBACK(on_button_press_over_strings), panel);
+ g_signal_connect(G_OBJECT(treeview), "key-press-event",
+ G_CALLBACK(on_key_pressed_over_strings), panel);
+
gtk_widget_show(treeview);
- gtk_container_add(GTK_CONTAINER(scrollwnd), treeview);
+ gtk_container_add(GTK_CONTAINER(scrolled), treeview);
g_object_unref(G_OBJECT(store));
- column = gtk_tree_view_column_new();
+ /* Cellules d'affichage */
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Physical address"), renderer,
+ "text", STC_PHYSICAL,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(column, STC_PHYSICAL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- gtk_tree_view_set_expander_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Address"), renderer,
- "text", STC_ADDRESS, NULL);
+ column = gtk_tree_view_column_new_with_attributes(_("Virtual address"), renderer,
+ "text", STC_VIRTUAL,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(column, STC_VIRTUAL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("String"), renderer,
- "markup", STC_STRING, NULL);
+ g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
+ g_signal_connect(renderer, "edited", G_CALLBACK(on_string_value_edited), store);
+ column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer,
+ "text", STC_NAME,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(column, STC_NAME);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- /* Menu contextuel */
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Value"), renderer,
+ "markup", STC_VALUE,
+ NULL);
+ gtk_tree_view_column_set_sort_column_id(column, STC_VALUE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- panel->menubar = gtk_menu_new();
+ /* Tri de la liste */
- submenuitem = qck_create_menu_item(NULL, NULL, _("_Copy"),
- G_CALLBACK(mcb_strings_copy), treeview);
- gtk_container_add(GTK_CONTAINER(panel->menubar), submenuitem);
+ sortable = GTK_TREE_SORTABLE(store);
- submenuitem = qck_create_menu_item(NULL, NULL, _("_Find references..."), NULL, NULL);
- gtk_container_add(GTK_CONTAINER(panel->menubar), submenuitem);
+ gtk_tree_sortable_set_sort_func(sortable, STC_PHYSICAL, compare_strings_list_columns,
+ GINT_TO_POINTER(STC_PHYSICAL), NULL);
+
+ gtk_tree_sortable_set_sort_func(sortable, STC_VIRTUAL, compare_strings_list_columns,
+ GINT_TO_POINTER(STC_VIRTUAL), NULL);
+
+ gtk_tree_sortable_set_sort_func(sortable, STC_NAME, compare_strings_list_columns,
+ GINT_TO_POINTER(STC_NAME), NULL);
+
+ gtk_tree_sortable_set_sort_func(sortable, STC_VALUE, compare_strings_list_columns,
+ GINT_TO_POINTER(STC_VALUE), NULL);
- g_signal_connect(G_OBJECT(treeview), "button_release_event",
- G_CALLBACK(on_strings_button_press_event), panel);
+ gtk_tree_sortable_set_sort_column_id(sortable, STC_VIRTUAL, GTK_SORT_ASCENDING);
+
+ /* Prise en compte de la sélection */
+
+ 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);
+
+ /* Préparation du menu contextuel */
+
+ panel->menu = build_strings_panel_menu(panel);
}
@@ -312,6 +416,12 @@ GPanelItem *create_strings_panel(GObject *ref)
}
+
+/* ---------------------------------------------------------------------------------- */
+/* AFFICHAGE A L'AIDE D'UNE LISTE */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : panel = panneau à mettre à jour. *
@@ -328,12 +438,19 @@ GPanelItem *create_strings_panel(GObject *ref)
static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBinary *binary)
{
GtkTreeStore *store; /* Modèle de gestion */
+ GArchProcessor *proc; /* Architecture du binaire */
+ MemoryDataSize msize; /* Taille par défaut */
GExeFormat *format; /* Format de travail */
+ GBinContent *content; /* Contenu binaire en mémoire */
size_t count; /* Nombre des chaînes */
GBinSymbol **symbols; /* Liste des chaînes trouvées */
size_t i; /* Boucle de parcours */
- char address[VMPA_MAX_SIZE]; /* Conversion de l'adresse */
- const char *raw; /* Texte brut trouvé */
+ const mrange_t *range; /* Couverture mémoire */
+ const vmpa2t *addr; /* Adressse liée à la chaîne */
+ VMPA_BUFFER(phys); /* Position physique */
+ VMPA_BUFFER(virt); /* Adresse virtuelle */
+ const char *label; /* Etiquette liée au symbole */
+ vmpa2t pos; /* Tête de lecture modifiable */
char *text; /* Version imprimable du texte */
GtkTreeIter iter; /* Point d'insertion */
@@ -347,23 +464,52 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
if (panel->binary != NULL)
g_object_ref(G_OBJECT(panel->binary));
+ store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview));
+ gtk_tree_store_clear(store);
+
+ /* Si le panneau actif ne représente pas un binaire... */
+
+ if (binary == NULL) return;
+
/* Actualisation de l'affichage */
- store = g_object_get_data(G_OBJECT(panel), "store");
+ proc = g_loaded_binary_get_processor(binary);
+ msize = g_arch_processor_get_memory_size(proc);
+ g_object_unref(G_OBJECT(proc));
format = g_loaded_binary_get_format(binary);
+ content = g_binary_format_get_conten_(G_BIN_FORMAT(format));
+
symbols = g_binary_format_get_symbols(G_BIN_FORMAT(format), &count);
for (i = 0; i < count; i++)
{
- if (g_binary_symbol_get_target_type(symbols[i]) != STP_STRING) continue;
+ if (g_binary_symbol_get_target_type(symbols[i]) != STP_RO_STRING) continue;
+
+ range = g_binary_symbol_get_range(symbols[i]);
+ addr = get_mrange_addr(range);
+
+ vmpa2_phys_to_string(addr, msize, phys, NULL);
+ vmpa2_virt_to_string(addr, msize, virt, NULL);
- /* FIXME : adresses autres que 32 bits */
- snprintf(address, VMPA_MAX_SIZE, "0x%08" PRIx64, g_binary_symbol_get_address(symbols[i]));
+ label = g_binary_symbol_get_label(symbols[i]);
- raw = g_binary_symbol_to_string(symbols[i]);
+ text = (char *)calloc(get_mrange_length(range) + 1, sizeof(char));
+
+ copy_vmpa(&pos, addr);
+
+ if (!g_binary_content_get_raw(content, &pos, get_mrange_length(range), (uint8_t *)text))
+ {
+ free(text);
+ continue;
+ }
+
+ if (is_string_filtered(panel, label, text))
+ {
+ free(text);
+ continue;
+ }
- text = strdup(raw);
text = strrpl(text, "&", "&amp;");
text = strrpl(text, "<", "&lt;");
text = strrpl(text, ">", "&gt;");
@@ -372,9 +518,11 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store, &iter,
- STC_ADDRESS, address,
- STC_STRING, text,
- STC_RAW, raw,
+ STC_STRING, symbols[i],
+ STC_PHYSICAL, phys,
+ STC_VIRTUAL, virt,
+ STC_NAME, label,
+ STC_VALUE, text,
-1);
free(text);
@@ -384,19 +532,92 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
}
+/******************************************************************************
+* *
+* Paramètres : selection = sélection modifiée. *
+* panel = structure contenant les informations maîtresses. *
+* *
+* Description : Réagit au changement de sélection des chaînes textuelles. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_strings_selection_change(GtkTreeSelection *selection, GStringsPanel *panel)
+{
+ GtkTreeIter iter; /* Point de sélection */
+ GtkTreeModel *model; /* Modèle de gestion */
+ GBinSymbol *symbol; /* Symbole en cours d'étude */
+ const vmpa2t *addr; /* Adressse associée au signet */
+ GtkViewPanel *vpanel; /* Afficheur effectif de code */
-/* ---------------------------------------------------------------------------------- */
-/* GESTIONS DES MENUS CONTEXTUELS */
-/* ---------------------------------------------------------------------------------- */
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, STC_STRING, &symbol, -1);
+
+ addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
+
+ vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(panel));
+ gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
+
+ g_object_unref(G_OBJECT(symbol));
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : model = gestionnaire du tableau de données. *
+* a = première ligne de données à traiter. *
+* b = seconde ligne de données à traiter. *
+* column = indice de la colonne à considérer, encodée. *
+* *
+* Description : Etablit une comparaison entre deux chaînes de caractères. *
+* *
+* Retour : Indication de tri entre les deux lignes fournies. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gint compare_strings_list_columns(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer column)
+{
+ gint result; /* Valeur calculée à retourner */
+ gchar *value_a; /* Cellule de la ligne 'a' */
+ gchar *value_b; /* Cellule de la ligne 'b' */
+
+ gtk_tree_model_get(model, a, GPOINTER_TO_INT(column), &value_a, -1);
+ gtk_tree_model_get(model, b, GPOINTER_TO_INT(column), &value_b, -1);
+
+ if (value_a == NULL || value_b == NULL)
+ {
+ if (value_a == NULL && value_b == NULL)
+ result = 0;
+ else
+ result = (value_a == NULL ? -1 : 1);
+ }
+ else
+ result = g_utf8_collate(value_a, value_b);
+
+ g_free(value_a);
+ g_free(value_b);
+
+ return result;
+
+}
/******************************************************************************
* *
-* Paramètres : treeview = composant GTK visé par l'opération. *
+* Paramètres : treeview = composant graphique présentant les paramètres. *
* event = informations liées à l'événement. *
-* data = référence vers le panneau contenant le menu. *
+* panel = panneau d'affichage sur lequel s'appuyer. *
* *
-* Description : Affiche le menu d'édition propre aux chaînes trouvées. *
+* Description : Réagit à une pression sur <Shift+F2> et simule l'édition. *
* *
* Retour : FALSE pour poursuivre la propagation de l'événement. *
* *
@@ -404,22 +625,302 @@ static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBin
* *
******************************************************************************/
-static gboolean on_strings_button_press_event(GtkTreeView *treeview, GdkEventButton *event, GStringsPanel *panel)
+static gboolean on_key_pressed_over_strings(GtkTreeView *treeview, GdkEventKey *event, GStringsPanel *panel)
+{
+ const gchar *accelerator; /* Combinaison de raccourci */
+ guint accel_key; /* Touche de raccourci */
+ GdkModifierType accel_mod; /* Modifiateurs attendus aussi */
+
+ if (!g_generic_config_get_value(get_main_configuration(), MPK_KEYBINDINGS_EDIT, &accelerator))
+ return FALSE;
+
+ if (accelerator == NULL)
+ return FALSE;
+
+ gtk_accelerator_parse(accelerator, &accel_key, &accel_mod);
+
+ if (event->keyval == accel_key && event->state == accel_mod)
+ mcb_strings_panel_edit(NULL, panel);
+
+ return FALSE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : renderer = moteur de rendu pour la cellule. *
+* path = chemin d'accès vers la cellule éditée. *
+* new = nouvelle valeur sous forme de texte à valider. *
+* store = gestionnaire des données de la liste affichée. *
+* *
+* Description : Réagit à une édition de l'étiquette d'une chaîne textuelle. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, gchar *new, GtkTreeStore *store)
+{
+ GtkTreePath *tree_path; /* Chemin d'accès natif */
+ GtkTreeIter iter; /* Point de la modification */
+ GBinSymbol *symbol; /* Symbole à actualiser */
+
+ tree_path = gtk_tree_path_new_from_string(path);
+ if (tree_path == NULL) return;
+
+ if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, tree_path))
+ goto opve_bad_iter;
+
+ gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, STC_STRING, &symbol, -1);
+
+ g_binary_symbol_set_label(symbol, new);
+
+ g_object_unref(G_OBJECT(symbol));
+
+ opve_bad_iter:
+
+ gtk_tree_path_free(tree_path);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* FILTRAGE DES SYMBOLES PRESENTS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : entry = entrée de texte contenant le filtre brut. *
+* panel = panneau assurant l'affichage des paramètres. *
+* *
+* Description : Démarre l'actualisation du filtrage des paramètres. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_string_search_changed(GtkSearchEntry *entry, GStringsPanel *panel)
{
- gboolean result; /* Bilan d'action à renvoyer */
+ const gchar *text; /* Texte de l'utilisateur */
+ int ret; /* Bilan de mise en place */
+ GdkRGBA error; /* Couleur d'erreur */
+
+ if (panel->filter != NULL)
+ {
+ regfree(panel->filter);
+ free(panel->filter);
+ panel->filter = NULL;
+ }
- result = FALSE;
+ text = gtk_entry_get_text(GTK_ENTRY(entry));
- if (event->type == GDK_BUTTON_RELEASE && event->button == 3)
+ if (strlen(text) > 0)
{
- gtk_menu_popup(GTK_MENU(panel->menubar),
- NULL, NULL, NULL, NULL,
- event->button, event->time);
+ panel->filter = (regex_t *)calloc(1, sizeof(regex_t));
+ ret = regcomp(panel->filter, text, REG_EXTENDED);
+
+ if (ret != 0)
+ {
+ free(panel->filter);
+ panel->filter = NULL;
+
+ error.red = 1.0;
+ error.green = 0.0;
+ error.blue = 0.0;
+ error.alpha = 1.0;
+ gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error);
+
+ return;
+
+ }
+
+ }
+
+ gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL);
+
+ change_strings_panel_current_binary(panel, panel->binary);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau assurant l'affichage des paramètres. *
+* label = étiquette liée au symbole à traiter. *
+* value = chaîne de caractères représentée par le symbole. *
+* *
+* Description : Détermine si une chaîne textuelle doit être filtrée ou non. *
+* *
+* Retour : true si le symbole ne doit pas être affiché, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool is_string_filtered(GStringsPanel *panel, const char *label, const char *value)
+{
+ bool result; /* Bilan à retourner */
+ regmatch_t match; /* Récupération des trouvailles*/
+ int ret; /* Bilan du filtrage */
- result = TRUE;
+ if (panel->filter == NULL)
+ return false;
+ result = false;
+
+ if (label != NULL)
+ {
+ ret = regexec(panel->filter, label, 1, &match, 0);
+ result |= (ret != REG_NOMATCH);
}
+ ret = regexec(panel->filter, value, 1, &match, 0);
+ result |= (ret != REG_NOMATCH);
+
+ return !result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ATTRIBUTION D'UN MENU CONTEXTUEL */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant GTK visé par l'opération. *
+* event = informations liées à l'événement. *
+* panel = informations liées au panneau associé. *
+* *
+* Description : Assure la gestion des clics de souris sur les signets. *
+* *
+* Retour : FALSE pour poursuivre la propagation de l'événement. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean on_button_press_over_strings(GtkWidget *widget, GdkEventButton *event, GStringsPanel *panel)
+{
+ GtkTreeSelection *selection; /* Sélection courante */
+ GtkTreeIter iter; /* Point de sélection */
+ GtkTreeModel *model; /* Modèle de gestion */
+ GBinSymbol *symbol; /* Symbole en cours d'étude */
+ const vmpa2t *addr; /* Adressse associée au signet */
+ GtkViewPanel *vpanel; /* Afficheur effectif de code */
+
+ switch (event->button)
+ {
+ case 1:
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, STC_STRING, &symbol, -1);
+
+ addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
+
+ vpanel = g_editor_item_get_current_view(G_EDITOR_ITEM(panel));
+ gtk_view_panel_scroll_to_address(vpanel, addr, SPT_CENTER);
+
+ g_object_unref(G_OBJECT(symbol));
+
+ }
+
+ break;
+
+ case 3:
+ if (event->type == GDK_BUTTON_RELEASE)
+ gtk_menu_popup(panel->menu, NULL, NULL, NULL, NULL, event->button, event->time);
+ break;
+
+ }
+
+ return FALSE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau d'affichage des signets liés à un binaire. *
+* *
+* Description : Construit le menu contextuel pour les signets. *
+* *
+* Retour : Panneau de menus mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkMenu *build_strings_panel_menu(GStringsPanel *panel)
+{
+ GtkWidget *result; /* Support à retourner */
+ GtkWidget *submenuitem; /* Sous-élément de menu */
+
+ result = gtk_menu_new();
+
+ submenuitem = qck_create_menu_item(NULL, NULL, _("_Edit name"), NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(result), submenuitem);
+
+ submenuitem = qck_create_menu_item(NULL, NULL, _("_Copy to clipboard"),
+ 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);
+ 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);
+ gtk_container_add(GTK_CONTAINER(result), submenuitem);
+
+ return GTK_MENU(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : treeview = liste d'affichage à consulter. *
+* save = zone de conservation du point de trouvaille. [OUT]*
+* *
+* Description : Fournit le signet sélectionné dans la liste. *
+* *
+* Retour : Signet en cours d'édition ou NULL en cas de soucis. *
+* *
+* Remarques : Le résultat non nul est à déréférencer après usage. *
+* *
+******************************************************************************/
+
+static GBinSymbol *get_selected_panel_symbol(GtkTreeView *treeview, GtkTreeIter *save)
+{
+ GBinSymbol *result; /* Chaîne textuelle à renvoyer */
+ GtkTreeSelection *selection; /* Représentation de sélection */
+ GtkTreeModel *model; /* Gestionnaire des données */
+ GtkTreeIter iter; /* Point de la sélection */
+
+ result = NULL;
+
+ selection = gtk_tree_view_get_selection(treeview);
+
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ gtk_tree_model_get(model, &iter, STC_STRING, &result, -1);
+
+ if (save != NULL)
+ *save = iter;
+
return result;
}
@@ -428,9 +929,46 @@ static gboolean on_strings_button_press_event(GtkTreeView *treeview, GdkEventBut
/******************************************************************************
* *
* 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 "Editer le nom". *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void mcb_strings_panel_edit(GtkMenuItem *menuitem, GStringsPanel *panel)
+{
+ GtkTreeIter iter; /* Point de la sélection */
+ GBinSymbol *symbol; /* Symbole sélectionné */
+ GtkTreeModel *model; /* Gestionnaire de données */
+ GtkTreePath *path; /* Chemin d'accès à ce point */
+
+ symbol = get_selected_panel_symbol(panel->treeview, &iter);
+ if (symbol == NULL) return;
+
+ model = gtk_tree_view_get_model(panel->treeview);
+ path = gtk_tree_model_get_path(model, &iter);
+
+ gtk_tree_view_set_cursor(panel->treeview, path,
+ gtk_tree_view_get_column(panel->treeview, STC_NAME - STC_PHYSICAL),
+ TRUE);
+
+ gtk_tree_path_free(path);
+
+ g_object_unref(G_OBJECT(symbol));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : menuitem = élément de menu sélectionné. *
* treeview = arbre contenant la sélection à exporter. *
* *
-* Description : Réagit avec le menu "--- -> Copier". *
+* Description : Réagit avec le menu "Copier dans le presse-papiers". *
* *
* Retour : - *
* *
@@ -438,7 +976,7 @@ static gboolean on_strings_button_press_event(GtkTreeView *treeview, GdkEventBut
* *
******************************************************************************/
-static void mcb_strings_copy(GtkMenuItem *menuitem, GtkTreeView *treeview)
+static void mcb_strings_panel_copy(GtkMenuItem *menuitem, GStringsPanel *panel)
{
GtkTreeSelection *selection; /* Sélection de l'arbre */
GtkTreeIter iter; /* Point de sélection */
@@ -446,11 +984,11 @@ static void mcb_strings_copy(GtkMenuItem *menuitem, GtkTreeView *treeview)
gchar *string; /* Chaîne sélectionnée */
GtkClipboard *clipboard; /* Presse-papiers d'arrivée */
- selection = gtk_tree_view_get_selection(treeview);
+ selection = gtk_tree_view_get_selection(panel->treeview);
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
- gtk_tree_model_get(model, &iter, STC_RAW, &string, -1);
+ gtk_tree_model_get(model, &iter, STC_VALUE, &string, -1);
if (string != NULL)
{
@@ -465,3 +1003,31 @@ static void mcb_strings_copy(GtkMenuItem *menuitem, GtkTreeView *treeview)
}
}
+
+
+/******************************************************************************
+* *
+* 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 : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void mcb_strings_panel_filter(GtkMenuItem *menuitem, GStringsPanel *panel)
+{
+#if 0
+ GCfgParam *param; /* Paramètre sélectionné */
+
+ param = get_selected_panel_symbol(panel->treeview, NULL);
+ if (param == NULL) return;
+
+ g_config_param_make_empty(param);
+
+ g_object_unref(G_OBJECT(param));
+#endif
+}