summaryrefslogtreecommitdiff
path: root/src/gui/panels/strings.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/panels/strings.c')
-rw-r--r--src/gui/panels/strings.c1015
1 files changed, 760 insertions, 255 deletions
diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c
index 7420ffe..4828038 100644
--- a/src/gui/panels/strings.c
+++ b/src/gui/panels/strings.c
@@ -25,19 +25,23 @@
#include "strings.h"
+#include <assert.h>
#include <string.h>
#include <inttypes.h>
#include "panel-int.h"
+#include "updating-int.h"
#include "../core/global.h"
#include "../dialogs/gotox.h"
#include "../../common/extstr.h"
#include "../../core/params.h"
+#include "../../core/queue.h"
#include "../../format/format.h"
#include "../../format/symiter.h"
#include "../../gtkext/easygtk.h"
#include "../../gtkext/gtkdockable-int.h"
+#include "../../gtkext/tmgt.h"
@@ -49,16 +53,14 @@ struct _GStringsPanel
{
GPanelItem parent; /* A laisser en premier */
- GtkTreeView *treeview; /* Composant d'affichage */
- const regex_t *filter; /* Filtre appliqué ou NULL */
+ GLoadedBinary *binary; /* Binaire en cours d'analyse */
GtkMenu *menu; /* Menu contextuel pour param. */
- GLoadedBinary *binary; /* Binaire en cours d'analyse */
+ size_t count; /* Quantité de symboles utiles */
};
-
/* Panneau d'aperçu de graphiques (classe) */
struct _GStringsPanelClass
{
@@ -70,27 +72,34 @@ struct _GStringsPanelClass
/* Colonnes de la liste des symboles */
typedef enum _StringsColumn
{
- STC_STRING, /* Elément GLib représenté */
+ STC_SYMBOL, /* Symbole représenté */
STC_PHYSICAL, /* Adresse phyisque */
STC_VIRTUAL, /* Adresse virtuelle */
STC_AREA, /* Zone de localisation */
STC_NAME, /* Désignation humaine */
STC_VALUE, /* Chaîne de caractères */
+ STC_ORIGINAL, /* Version brute d'origine */
+
+ STC_MATCHED, /* Correspondance établie ? */
STC_COUNT /* Nombre de colonnes */
} StringsColumn;
+/* Données utiles à la mise à jour */
+typedef struct _strings_update_data strings_update_data;
+
+
/* Initialise la classe des panneaux d'affichage de chaînes. */
static void g_strings_panel_class_init(GStringsPanelClass *);
/* Initialise une instance de panneau d'affichage des chaînes. */
static void g_strings_panel_init(GStringsPanel *);
-/* Procède à l'initialisation de l'interface de rassemblement. */
-static void g_strings_panel_dockable_interface_init(GtkDockableInterface *);
+/* Procède à l'initialisation de l'interface de mise à jour. */
+static void g_strings_panel_updatable_interface_init(GUpdatablePanelInterface *);
/* Supprime toutes les références externes. */
static void g_strings_panel_dispose(GStringsPanel *);
@@ -98,14 +107,6 @@ static void g_strings_panel_dispose(GStringsPanel *);
/* Procède à la libération totale de la mémoire. */
static void g_strings_panel_finalize(GStringsPanel *);
-
-
-/* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */
-
-
-/* Réagit à un changement d'affichage principal de contenu. */
-static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *);
-
/* Réagit au changement de sélection des chaînes textuelles. */
static void on_strings_selection_change(GtkTreeSelection *, gpointer);
@@ -116,18 +117,38 @@ static gint compare_strings_list_columns(GtkTreeModel *, GtkTreeIter *, GtkTreeI
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 *);
+static void on_string_name_edited(GtkCellRendererText *, gchar *, gchar *, GtkTreeModel *);
+/* Réagit à un changement d'affichage principal de contenu. */
+static void change_strings_panel_current_binary(GStringsPanel *, GLoadedBinary *);
-/* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */
+
+/* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */
+
+
+/* Réagit à un changement d'affichage principal de contenu. */
+static void reload_strings_for_new_list_view(const GStringsPanel *, GtkStatusStack *, activity_id_t, strings_update_data *);
+
+/* Met en surbrillance les éléments recherchés dans les noms. */
+static void update_string_label_in_list_view(GtkListStore *, GtkTreeIter *, const regmatch_t *);
+
+/* Met en surbrillance les éléments recherchés dans les valeurs. */
+static void update_string_value_in_list_view(GtkListStore *, GtkTreeIter *, const regmatch_t *);
+
+
+
+/* ------------------------- FILTRAGE DES CHAINES PRESENTES ------------------------- */
/* Démarre l'actualisation du filtrage des chaînes. */
-static void update_filtered_strings(GStringsPanel *, const regex_t *);
+static void update_filtered_strings(GStringsPanel *);
+
+/* Détermine si un noeud de l'arborescence doit être filtré. */
+static void update_string_node(const strings_update_data *, GtkListStore *, GtkTreeIter *);
-/* Détermine si une chaîne textuelle doit être filtrée ou non. */
-static bool is_string_filtered(GStringsPanel *, const char *, const char *);
+/* Exécute un nouveau filtrage des chaînes affichées. */
+static void do_filtering_on_strings(const GStringsPanel *, GtkStatusStack *, activity_id_t, strings_update_data *);
@@ -141,7 +162,7 @@ static gboolean on_button_event_over_strings(GtkWidget *, GdkEventButton *, GStr
static GtkMenu *build_strings_panel_menu(GStringsPanel *);
/* Fournit le signet sélectionné dans la liste. */
-static GBinSymbol *get_selected_panel_symbol(GtkTreeView *, GtkTreeIter *);
+static GBinSymbol *get_selected_panel_symbol(GStringsPanel *, GtkTreeIter *);
/* Réagit avec le menu "Editer le nom". */
static void mcb_strings_panel_edit(GtkMenuItem *, GStringsPanel *);
@@ -156,6 +177,41 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *, GStringsPanel *);
static void mcb_strings_panel_filter(GtkMenuItem *, GStringsPanel *);
+/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */
+
+
+/* Données utiles à la mise à jour */
+struct _strings_update_data
+{
+ size_t count; /* Qté d'inscriptions réalisées*/
+
+ regex_t *filter; /* Filtre appliqué ou NULL */
+
+};
+
+
+/* Détermine si un nom de symbole doit être filtré ou non. */
+static bool is_string_name_matching(const strings_update_data *, GtkTreeModel *, GtkTreeIter *, regmatch_t *);
+
+/* Détermine si une valeur de symbole doit être filtrée ou non. */
+static bool is_string_value_matching(const strings_update_data *, GtkTreeModel *, GtkTreeIter *, regmatch_t *);
+
+/* Prépare une opération de mise à jour de panneau. */
+static const char *g_strings_panel_setup(const GStringsPanel *, unsigned int, size_t *, strings_update_data **);
+
+/* Bascule l'affichage d'un panneau avant mise à jour. */
+static void g_strings_panel_introduce(const GStringsPanel *, unsigned int, strings_update_data *);
+
+/* Réalise une opération de mise à jour de panneau. */
+static void g_strings_panel_process(const GStringsPanel *, unsigned int, GtkStatusStack *, activity_id_t, strings_update_data *);
+
+/* Bascule l'affichage d'un panneau après mise à jour. */
+static void g_strings_panel_conclude(GStringsPanel *, unsigned int, strings_update_data *);
+
+/* Supprime les données dynamiques utilisées à la mise à jour. */
+static void g_strings_panel_clean_data(GUpdatablePanel *, unsigned int, strings_update_data *);
+
+
/* ---------------------------------------------------------------------------------- */
/* PARTIE PRINCIPALE DU PANNEAU */
@@ -164,7 +220,7 @@ static void mcb_strings_panel_filter(GtkMenuItem *, GStringsPanel *);
/* Indique le type définit pour un panneau d'affichage des chaînes. */
G_DEFINE_TYPE_WITH_CODE(GStringsPanel, g_strings_panel, G_TYPE_PANEL_ITEM,
- G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_strings_panel_dockable_interface_init));
+ G_IMPLEMENT_INTERFACE(G_TYPE_UPDATABLE_PANEL, g_strings_panel_updatable_interface_init));
/******************************************************************************
@@ -199,6 +255,13 @@ static void g_strings_panel_class_init(GStringsPanelClass *klass)
panel->unique = true;
panel->bindings = "<Shift>F12";
+ panel->can_search = true;
+ panel->can_be_closed = true;
+
+ panel->update_filtered = (update_filtered_fc)update_filtered_strings;
+
+ panel->gid = setup_tiny_global_work_group(1);
+
}
@@ -218,14 +281,13 @@ static void g_strings_panel_init(GStringsPanel *panel)
{
GEditorItem *base; /* Version basique d'instance */
GPanelItem *pitem; /* Version parente du panneau */
- GObject *ref; /* Espace de référencement */
- GtkTreeStore *store; /* Modèle de gestion */
- GtkWidget *treeview; /* Affichage de la liste */
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkTreeModelFilter *filter; /* Filtre pour l'arborescence */
+ GtkTreeView *treeview; /* Affichage de la liste */
GtkCellRenderer *renderer; /* Moteur de rendu de colonne */
GtkTreeViewColumn *column; /* Colonne de la liste */
+ GtkTreeModel *model; /* Modèle de gestion de liste */
GtkTreeSortable *sortable; /* Autre vision de la liste */
- GtkTreeSelection *select; /* Sélection dans la liste */
- bool display; /* Affichage si sélection ? */
/* Eléments de base */
@@ -242,37 +304,15 @@ static void g_strings_panel_init(GStringsPanel *panel)
/* Représentation graphique */
- base->widget = gtk_scrolled_window_new(NULL, NULL);
- gtk_widget_show(base->widget);
-
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(base->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(base->widget), GTK_SHADOW_IN);
-
- ref = G_OBJECT(base->widget);
- g_object_set_data(ref, "panel", panel);
-
- /* Partie chaînes */
-
- store = gtk_tree_store_new(STC_COUNT, G_TYPE_OBJECT,
- G_TYPE_STRING, 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_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);
+ builder = g_panel_item_build(pitem, "strings");
- gtk_widget_show(treeview);
- gtk_container_add(GTK_CONTAINER(base->widget), treeview);
-
- g_object_unref(G_OBJECT(store));
+ filter = GTK_TREE_MODEL_FILTER(gtk_builder_get_object(builder, "filter"));
+ gtk_tree_model_filter_set_visible_column(filter, STC_MATCHED);
/* Cellules d'affichage */
+ treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(_("Physical address"), renderer,
"text", STC_PHYSICAL,
@@ -295,9 +335,11 @@ static void g_strings_panel_init(GStringsPanel *panel)
gtk_tree_view_column_set_sort_column_id(column, STC_AREA);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+ model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "store"));
+
renderer = gtk_cell_renderer_text_new();
g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
- g_signal_connect(renderer, "edited", G_CALLBACK(on_string_value_edited), store);
+ g_signal_connect(renderer, "edited", G_CALLBACK(on_string_name_edited), model);
column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer,
"text", STC_NAME,
NULL);
@@ -313,7 +355,7 @@ static void g_strings_panel_init(GStringsPanel *panel)
/* Tri de la liste */
- sortable = GTK_TREE_SORTABLE(store);
+ sortable = GTK_TREE_SORTABLE(gtk_builder_get_object(builder, "store"));
gtk_tree_sortable_set_sort_func(sortable, STC_PHYSICAL, compare_strings_list_columns,
GINT_TO_POINTER(STC_PHYSICAL), NULL);
@@ -332,15 +374,15 @@ static void g_strings_panel_init(GStringsPanel *panel)
gtk_tree_sortable_set_sort_column_id(sortable, STC_VIRTUAL, GTK_SORT_ASCENDING);
- /* Prise en compte de la sélection */
+ /* Connexion des signaux */
- select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
- gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
+ gtk_builder_add_callback_symbols(builder,
+ "on_button_event_over_strings", G_CALLBACK(on_button_event_over_strings),
+ "on_key_pressed_over_strings", G_CALLBACK(on_key_pressed_over_strings),
+ "on_strings_selection_change", G_CALLBACK(on_strings_selection_change),
+ NULL);
- 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), NULL);
+ gtk_builder_connect_signals(builder, panel);
/* Préparation du menu contextuel */
@@ -351,9 +393,9 @@ static void g_strings_panel_init(GStringsPanel *panel)
/******************************************************************************
* *
-* Paramètres : iface = interface GTK à initialiser. *
+* Paramètres : iface = interface GLib à initialiser. *
* *
-* Description : Procède à l'initialisation de l'interface de rassemblement. *
+* Description : Procède à l'initialisation de l'interface de mise à jour. *
* *
* Retour : - *
* *
@@ -361,19 +403,14 @@ static void g_strings_panel_init(GStringsPanel *panel)
* *
******************************************************************************/
-static void g_strings_panel_dockable_interface_init(GtkDockableInterface *iface)
+static void g_strings_panel_updatable_interface_init(GUpdatablePanelInterface *iface)
{
- GtkDockableInterface *parent_iface; /* Définition précédente */
-
- parent_iface = (GtkDockableInterface *)g_type_interface_peek_parent(iface);
-
- iface->can_search = true;
- iface->can_be_closed = true;
-
- iface->get_name = parent_iface->get_name;
- iface->get_desc = parent_iface->get_desc;
- iface->get_widget = parent_iface->get_widget;
- iface->update_filtered = (update_filtered_data_fc)update_filtered_strings;
+ iface->setup = (setup_updatable_cb)g_strings_panel_setup;
+ iface->get_group = (get_updatable_group_cb)g_panel_item_get_group;
+ iface->introduce = (introduce_updatable_cb)g_strings_panel_introduce;
+ iface->process = (process_updatable_cb)g_strings_panel_process;
+ iface->conclude = (conclude_updatable_cb)g_strings_panel_conclude;
+ iface->clean = (clean_updatable_data_cb)g_strings_panel_clean_data;
}
@@ -442,143 +479,6 @@ GPanelItem *g_strings_panel_new(void)
}
-
-/* ---------------------------------------------------------------------------------- */
-/* AFFICHAGE A L'AIDE D'UNE LISTE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : panel = panneau à mettre à jour. *
-* binary = nouvelle instance de binaire analysé. *
-* *
-* Description : Réagit à un changement d'affichage principal de contenu. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-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 */
- GBinPortion *portions; /* Couche première de portions */
- GBinContent *content; /* Contenu binaire en mémoire */
- sym_iter_t *siter; /* Parcours des symboles */
- GBinSymbol *symbol; /* Symbole manipulé */
- 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 */
- GBinPortion *portion; /* Zone mémoire d'appartenance */
- const char *area; /* Description de la zone */
- 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 */
-
- /* Basculement du binaire utilisé */
-
- if (panel->binary != NULL)
- g_object_unref(G_OBJECT(panel->binary));
-
- panel->binary = binary;
-
- 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 */
-
- 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);
- portions = g_exe_format_get_portions(format);
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
-
- siter = create_symbol_iterator(G_BIN_FORMAT(format), 0);
-
- for (symbol = get_symbol_iterator_current(siter);
- symbol != NULL;
- symbol = get_symbol_iterator_next(siter))
- {
- if (g_binary_symbol_get_target_type(symbol) != STP_RO_STRING)
- goto cspcb_next;
-
- range = g_binary_symbol_get_range(symbol);
- addr = get_mrange_addr(range);
-
- vmpa2_phys_to_string(addr, msize, phys, NULL);
- vmpa2_virt_to_string(addr, msize, virt, NULL);
-
- portion = g_binary_portion_find_at_addr(portions, addr, (GdkRectangle []) { });
- area = g_binary_portion_get_desc(portion);
- g_object_unref(G_OBJECT(portion));
-
- label = g_binary_symbol_get_label(symbol);
-
- text = (char *)calloc(get_mrange_length(range) + 1, sizeof(char));
-
- copy_vmpa(&pos, addr);
-
- if (!g_binary_content_read_raw(content, &pos, get_mrange_length(range), (uint8_t *)text))
- {
- free(text);
- goto cspcb_next;
- }
-
- if (is_string_filtered(panel, label, text))
- {
- free(text);
- goto cspcb_next;
- }
-
- text = strrpl(text, "&", "&amp;");
- text = strrpl(text, "<", "&lt;");
- text = strrpl(text, ">", "&gt;");
- text = strrpl(text, "\r", "<b>\\r</b>");
- text = strrpl(text, "\n", "<b>\\n</b>");
-
- gtk_tree_store_append(store, &iter, NULL);
- gtk_tree_store_set(store, &iter,
- STC_STRING, symbol,
- STC_PHYSICAL, phys,
- STC_VIRTUAL, virt,
- STC_AREA, area,
- STC_NAME, label,
- STC_VALUE, text,
- -1);
-
- free(text);
-
- cspcb_next:
-
- g_object_unref(G_OBJECT(symbol));
-
- }
-
- delete_symbol_iterator(siter);
-
- g_object_unref(G_OBJECT(content));
- g_object_unref(G_OBJECT(portions));
- g_object_unref(G_OBJECT(format));
-
-}
-
-
/******************************************************************************
* *
* Paramètres : selection = sélection modifiée. *
@@ -602,7 +502,7 @@ static void on_strings_selection_change(GtkTreeSelection *selection, gpointer un
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
- gtk_tree_model_get(model, &iter, STC_STRING, &symbol, -1);
+ gtk_tree_model_get(model, &iter, STC_SYMBOL, &symbol, -1);
addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
@@ -703,7 +603,7 @@ static gboolean on_key_pressed_over_strings(GtkTreeView *treeview, GdkEventKey *
* 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. *
+* model = gestionnaire des données de la liste affichée. *
* *
* Description : Réagit à une édition de l'étiquette d'une chaîne textuelle. *
* *
@@ -713,7 +613,7 @@ static gboolean on_key_pressed_over_strings(GtkTreeView *treeview, GdkEventKey *
* *
******************************************************************************/
-static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, gchar *new, GtkTreeStore *store)
+static void on_string_name_edited(GtkCellRendererText *renderer, gchar *path, gchar *new, GtkTreeModel *model)
{
GtkTreePath *tree_path; /* Chemin d'accès natif */
GtkTreeIter iter; /* Point de la modification */
@@ -722,10 +622,10 @@ static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, g
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))
+ if (!gtk_tree_model_get_iter(model, &iter, tree_path))
goto opve_bad_iter;
- gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, STC_STRING, &symbol, -1);
+ gtk_tree_model_get(model, &iter, STC_SYMBOL, &symbol, -1);
g_binary_symbol_set_alt_label(symbol, new);
@@ -738,18 +638,64 @@ static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, g
}
+/******************************************************************************
+* *
+* Paramètres : panel = panneau à mettre à jour. *
+* binary = nouvelle instance de binaire analysé. *
+* *
+* Description : Réagit à un changement d'affichage principal de contenu. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void change_strings_panel_current_binary(GStringsPanel *panel, GLoadedBinary *binary)
+{
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkListStore *store; /* Modèle de gestion */
+
+ /* Basculement du binaire utilisé */
+
+ if (panel->binary != NULL)
+ g_object_unref(G_OBJECT(panel->binary));
+
+ panel->binary = binary;
+
+ if (panel->binary != NULL)
+ g_object_ref(G_OBJECT(panel->binary));
+
+ /* Réinitialisation */
+
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
+
+ gtk_list_store_clear(store);
+
+ /* Si le panneau actif représente un binaire, actualisation de l'affichage */
+
+ if (binary != NULL)
+ run_panel_update(G_UPDATABLE_PANEL(panel), PUI_0);
+
+}
+
+
/* ---------------------------------------------------------------------------------- */
-/* FILTRAGE DES SYMBOLES PRESENTS */
+/* AFFICHAGE A L'AIDE D'UNE LISTE */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : panel = panneau assurant l'affichage des paramètres. *
-* preg = expression régulière compilée à utiliser. *
+* Paramètres : panel = panneau à mettre à jour. *
+* status = barre de statut à tenir informée. *
+* id = identifiant pour le suivi de la progression. *
+* data = données complémentaire à manipuler. *
* *
-* Description : Démarre l'actualisation du filtrage des chaînes. *
+* Description : Réagit à un changement d'affichage principal de contenu. *
* *
* Retour : - *
* *
@@ -757,50 +703,289 @@ static void on_string_value_edited(GtkCellRendererText *renderer, gchar *path, g
* *
******************************************************************************/
-static void update_filtered_strings(GStringsPanel *panel, const regex_t *preg)
+static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStatusStack *status, activity_id_t id, strings_update_data *data)
{
- panel->filter = preg;
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkListStore *store; /* Modèle de gestion */
+ GArchProcessor *proc; /* Architecture utilisée */
+ MemoryDataSize size; /* Taille des localisations */
+ GExeFormat *format; /* Format associé au binaire */
+ GBinPortion *portions; /* Couche première de portions */
+ GBinContent *content; /* Contenu binaire en mémoire */
+ sym_iter_t *siter; /* Parcours des symboles */
+ GBinSymbol *symbol; /* Symbole manipulé */
+ 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 */
+ GBinPortion *portion; /* Zone mémoire d'appartenance */
+ const char *area; /* Description de la zone */
+ char *text; /* Texte original référencé */
+ vmpa2t pos; /* Tête de lecture modifiable */
+ GtkTreeIter iter; /* Point d'insertion */
+
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
+
+ proc = g_loaded_binary_get_processor(panel->binary);
+ size = g_arch_processor_get_memory_size(proc);
+ g_object_unref(G_OBJECT(proc));
+
+ format = g_loaded_binary_get_format(panel->binary);
+ portions = g_exe_format_get_portions(format);
+ content = g_binary_format_get_content(G_BIN_FORMAT(format));
+
+ siter = create_symbol_iterator(G_BIN_FORMAT(format), 0);
+
+ for (symbol = get_symbol_iterator_current(siter);
+ symbol != NULL;
+ symbol = get_symbol_iterator_next(siter))
+ {
+ if (g_binary_symbol_get_target_type(symbol) != STP_RO_STRING)
+ goto rsfnlv_next;
+
+ range = g_binary_symbol_get_range(symbol);
+ addr = get_mrange_addr(range);
+
+ vmpa2_phys_to_string(addr, size, phys, NULL);
+ vmpa2_virt_to_string(addr, size, virt, NULL);
+
+ portion = g_binary_portion_find_at_addr(portions, addr, (GdkRectangle []) { });
+ area = g_binary_portion_get_desc(portion);
+ g_object_unref(G_OBJECT(portion));
+
+ text = (char *)calloc(get_mrange_length(range) + 1, sizeof(char));
+
+ copy_vmpa(&pos, addr);
+
+ if (!g_binary_content_read_raw(content, &pos, get_mrange_length(range), (uint8_t *)text))
+ {
+ free(text);
+ goto rsfnlv_next;
+ }
+
+ addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
+ vmpa2_virt_to_string(addr, size, virt, NULL);
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ STC_SYMBOL, symbol,
+ STC_PHYSICAL, phys,
+ STC_VIRTUAL, virt,
+ STC_AREA, area,
+ STC_NAME, NULL,
+ STC_VALUE, NULL,
+ STC_ORIGINAL, text,
+ STC_MATCHED, false,
+ -1);
+
+ update_string_node(data, store, &iter);
+
+ data->count++;
+
+ free(text);
- change_strings_panel_current_binary(panel, panel->binary);
+ rsfnlv_next:
+
+ g_object_unref(G_OBJECT(symbol));
+
+ gtk_status_stack_update_activity_value(status, id, 1);
+
+ }
+
+ delete_symbol_iterator(siter);
+
+ g_object_unref(G_OBJECT(content));
+ g_object_unref(G_OBJECT(portions));
+ g_object_unref(G_OBJECT(format));
}
/******************************************************************************
* *
-* 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. *
+* Paramètres : store = gestionnaire de données pour une arborescence. *
+* iter = position des données traitées. *
+* match = correspondance avec un objet recherché. *
* *
-* Description : Détermine si une chaîne textuelle doit être filtrée ou non. *
+* Description : Met en surbrillance les éléments recherchés dans les noms. *
* *
-* Retour : true si le symbole ne doit pas être affiché, false sinon. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool is_string_filtered(GStringsPanel *panel, const char *label, const char *value)
+static void update_string_label_in_list_view(GtkListStore *store, GtkTreeIter *iter, const regmatch_t *match)
{
- bool result; /* Bilan à retourner */
+ GtkTreeModel *model; /* Autre vision du gestionnaire*/
+ char *original; /* Etiquette brute d'origine */
+ char *value; /* Etiquette mise en relief */
+
+ model = GTK_TREE_MODEL(store);
+
+ gtk_tree_model_get(model, iter, STC_ORIGINAL, &original, -1);
+
+ original = strrpl(original, "&", "&amp;");
+ original = strrpl(original, "<", "&lt;");
+ original = strrpl(original, ">", "&gt;");
+ original = strrpl(original, "\r", "<b>\\r</b>");
+ original = strrpl(original, "\n", "<b>\\n</b>");
+
+ value = build_highlighted_name(original, match, 0);
+
+ gtk_list_store_set(store, iter, STC_VALUE, value, -1);
+
+ free(original);
+ free(value);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : store = gestionnaire de données pour une arborescence. *
+* iter = position des données traitées. *
+* match = correspondance avec un objet recherché. *
+* *
+* Description : Met en surbrillance les éléments recherchés dans les valeurs.*
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void update_string_value_in_list_view(GtkListStore *store, GtkTreeIter *iter, const regmatch_t *match)
+{
+ GtkTreeModel *model; /* Autre vision du gestionnaire*/
+ char *original; /* Etiquette brute d'origine */
+ char *value; /* Etiquette mise en relief */
+
+ model = GTK_TREE_MODEL(store);
+
+ gtk_tree_model_get(model, iter, STC_ORIGINAL, &original, -1);
+
+ original = strrpl(original, "&", "&amp;");
+ original = strrpl(original, "<", "&lt;");
+ original = strrpl(original, ">", "&gt;");
+ original = strrpl(original, "\r", "<b>\\r</b>");
+ original = strrpl(original, "\n", "<b>\\n</b>");
+
+ value = build_highlighted_name(original, match, 0);
+
+ gtk_list_store_set(store, iter, STC_VALUE, value, -1);
+
+ free(original);
+ free(value);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* FILTRAGE DES CHAINES PRESENTES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau assurant l'affichage des chaînes. *
+* *
+* Description : Démarre l'actualisation du filtrage des chaînes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void update_filtered_strings(GStringsPanel *panel)
+{
+ run_panel_update(G_UPDATABLE_PANEL(panel), PUI_1);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = données complémentaire à manipuler. *
+* store = gestionnaire de l'ensemble des données. *
+* iter = localisation des données à analyser. *
+* *
+* Description : Détermine si un noeud de l'arborescence doit être filtré. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void update_string_node(const strings_update_data *data, GtkListStore *store, GtkTreeIter *iter)
+{
+ GtkTreeModel *model; /* Autre vision du gestionnaire*/
regmatch_t match; /* Récupération des trouvailles*/
- int ret; /* Bilan du filtrage */
+ bool name_matched; /* Correspondance de sélection */
+ bool value_matched; /* Correspondance de sélection */
+
+ model = GTK_TREE_MODEL(store);
+
+ name_matched = is_string_name_matching(data, model, iter, &match);
+
+ if (name_matched)
+ update_string_label_in_list_view(store, iter, &match);
+
+ value_matched = is_string_value_matching(data, model, iter, &match);
+
+ if (value_matched)
+ update_string_value_in_list_view(store, iter, &match);
+
+ if (name_matched || value_matched)
+ gtk_list_store_set(GTK_LIST_STORE(model), iter, STC_MATCHED, true, -1);
+ else
+ gtk_list_store_set(GTK_LIST_STORE(model), iter, STC_MATCHED, false, -1);
+
+}
+
- if (panel->filter == NULL)
- return false;
+/******************************************************************************
+* *
+* Paramètres : panel = panneau assurant l'affichage des chaînes. *
+* status = barre de statut à tenir informée. *
+* id = identifiant pour le suivi de la progression. *
+* data = données complémentaire à manipuler. *
+* *
+* Description : Exécute un nouveau filtrage des chaînes affichées. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void do_filtering_on_strings(const GStringsPanel *panel, GtkStatusStack *status, activity_id_t id, strings_update_data *data)
+{
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkListStore *store; /* Modèle de gestion */
- result = true;
- if (label != NULL)
+ gboolean filter_string_panel_iter(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer unused)
{
- ret = regexec(panel->filter, label, 1, &match, 0);
- result &= (ret == REG_NOMATCH);
+ update_string_node(data, store, iter);
+
+ gtk_status_stack_update_activity_value(status, id, 1);
+
+ return FALSE;
+
}
- ret = regexec(panel->filter, value, 1, &match, 0);
- result &= (ret == REG_NOMATCH);
- return result;
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
+
+ gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)filter_string_panel_iter, NULL);
}
@@ -845,7 +1030,7 @@ static gboolean on_button_event_over_strings(GtkWidget *widget, GdkEventButton *
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
- gtk_tree_model_get(model, &iter, STC_STRING, &symbol, -1);
+ gtk_tree_model_get(model, &iter, STC_SYMBOL, &symbol, -1);
addr = get_mrange_addr(g_binary_symbol_get_range(symbol));
@@ -918,8 +1103,8 @@ static GtkMenu *build_strings_panel_menu(GStringsPanel *panel)
/******************************************************************************
* *
-* Paramètres : treeview = liste d'affichage à consulter. *
-* save = zone de conservation du point de trouvaille. [OUT]*
+* Paramètres : panel = panneau concerné par l'opération. *
+* save = zone de conservation du point de trouvaille. [OUT] *
* *
* Description : Fournit le signet sélectionné dans la liste. *
* *
@@ -929,19 +1114,25 @@ static GtkMenu *build_strings_panel_menu(GStringsPanel *panel)
* *
******************************************************************************/
-static GBinSymbol *get_selected_panel_symbol(GtkTreeView *treeview, GtkTreeIter *save)
+static GBinSymbol *get_selected_panel_symbol(GStringsPanel *panel, GtkTreeIter *save)
{
GBinSymbol *result; /* Chaîne textuelle à renvoyer */
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkTreeView *treeview; /* Arborescence graphique */
GtkTreeSelection *selection; /* Représentation de sélection */
GtkTreeModel *model; /* Gestionnaire des données */
GtkTreeIter iter; /* Point de la sélection */
result = NULL;
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
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);
+ gtk_tree_model_get(model, &iter, STC_SYMBOL, &result, -1);
if (save != NULL)
*save = iter;
@@ -968,17 +1159,23 @@ static void mcb_strings_panel_edit(GtkMenuItem *menuitem, GStringsPanel *panel)
{
GtkTreeIter iter; /* Point de la sélection */
GBinSymbol *symbol; /* Symbole sélectionné */
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkTreeView *treeview; /* Arborescence graphique */
GtkTreeModel *model; /* Gestionnaire de données */
GtkTreePath *path; /* Chemin d'accès à ce point */
- symbol = get_selected_panel_symbol(panel->treeview, &iter);
+ symbol = get_selected_panel_symbol(panel, &iter);
if (symbol == NULL) return;
- model = gtk_tree_view_get_model(panel->treeview);
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
+ model = gtk_tree_view_get_model(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),
+ gtk_tree_view_set_cursor(treeview, path,
+ gtk_tree_view_get_column(treeview, STC_NAME - STC_PHYSICAL),
TRUE);
gtk_tree_path_free(path);
@@ -1003,13 +1200,19 @@ static void mcb_strings_panel_edit(GtkMenuItem *menuitem, GStringsPanel *panel)
static void mcb_strings_panel_copy(GtkMenuItem *menuitem, GStringsPanel *panel)
{
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkTreeView *treeview; /* Arborescence graphique */
GtkTreeSelection *selection; /* Sélection de l'arbre */
GtkTreeIter iter; /* Point de sélection */
GtkTreeModel *model; /* Modèle de gestion */
gchar *string; /* Chaîne sélectionnée */
GtkClipboard *clipboard; /* Presse-papiers d'arrivée */
- selection = gtk_tree_view_get_selection(panel->treeview);
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
+ selection = gtk_tree_view_get_selection(treeview);
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
@@ -1055,7 +1258,7 @@ static void mcb_strings_panel_find_refs(GtkMenuItem *menuitem, GStringsPanel *pa
vmpa2t *addr; /* Adresse de destination */
GLoadedPanel *display; /* Afficheur effectif de code */
- symbol = get_selected_panel_symbol(panel->treeview, NULL);
+ symbol = get_selected_panel_symbol(panel, NULL);
if (symbol == NULL) return;
range = g_binary_symbol_get_range(symbol);
@@ -1119,7 +1322,7 @@ 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);
+ param = get_selected_panel_symbol(panel, NULL);
if (param == NULL) return;
g_config_param_make_empty(param);
@@ -1127,3 +1330,305 @@ static void mcb_strings_panel_filter(GtkMenuItem *menuitem, GStringsPanel *panel
g_object_unref(G_OBJECT(param));
#endif
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MECANISMES DE MISE A JOUR DE PANNEAU */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : data = données complémentaire à manipuler. *
+* model = gestionnaire de l'ensemble des données. *
+* iter = localisation des données à analyser. *
+* match = récupération des trouvailles. [OUT] *
+* *
+* Description : Détermine si un nom de symbole doit être filtré ou non. *
+* *
+* Retour : true si le symbol ne doit pas être affiché, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool is_string_name_matching(const strings_update_data *data, GtkTreeModel *model, GtkTreeIter *iter, regmatch_t *match)
+{
+ bool result; /* Bilan à retourner */
+ GBinSymbol *symbol; /* Symbole manipulé */
+#ifndef NDEBUG
+ SymbolType type; /* Type associé au symbole */
+#endif
+ const char *label; /* Etiquette à analyser */
+
+ gtk_tree_model_get(model, iter, STC_SYMBOL, &symbol, -1);
+ assert(symbol != NULL);
+
+#ifndef NDEBUG
+
+ type = g_binary_symbol_get_target_type(symbol);
+
+ assert(type == STP_RO_STRING);
+
+#endif
+
+ label = g_binary_symbol_get_label(symbol);
+
+ if (label == NULL)
+ result = false;
+ else
+ result = is_content_matching(data->filter, label, match);
+
+ g_object_unref(G_OBJECT(symbol));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = données complémentaire à manipuler. *
+* model = gestionnaire de l'ensemble des données. *
+* iter = localisation des données à analyser. *
+* match = récupération des trouvailles. [OUT] *
+* *
+* Description : Détermine si une valeur de symbole doit être filtrée ou non. *
+* *
+* Retour : true si le symbol ne doit pas être affiché, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool is_string_value_matching(const strings_update_data *data, GtkTreeModel *model, GtkTreeIter *iter, regmatch_t *match)
+{
+ bool result; /* Bilan à retourner */
+ char *original; /* Etiquette brute d'origine */
+
+ gtk_tree_model_get(model, iter, STC_ORIGINAL, &original, -1);
+
+ result = is_content_matching(data->filter, original, match);
+
+ free(original);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau ciblé par une mise à jour. *
+* uid = identifiant de la phase de traitement. *
+* count = nombre d'étapes à prévoir dans le traitement. [OUT] *
+* data = données sur lesquelles s'appuyer ensuite. [OUT] *
+* *
+* Description : Prépare une opération de mise à jour de panneau. *
+* *
+* Retour : Description du message d'information. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const char *g_strings_panel_setup(const GStringsPanel *panel, unsigned int uid, size_t *count, strings_update_data **data)
+{
+ const char *result; /* Message à retourner */
+ GBinFormat *format; /* Format du binaire */
+ int ret; /* Bilan de mise en place */
+
+ *data = malloc(sizeof(strings_update_data));
+
+ switch (uid)
+ {
+ case PUI_0:
+
+ format = G_BIN_FORMAT(g_loaded_binary_get_format(panel->binary));
+
+ g_binary_format_lock_symbols_rd(format);
+ *count = g_binary_format_count_symbols(format);
+ g_binary_format_unlock_symbols_rd(format);
+
+ g_object_unref(G_OBJECT(format));
+
+ (*data)->count = 0;
+
+ result = _("Loading strings available in the binary format...");
+
+ break;
+
+ case PUI_1:
+
+ *count = panel->count;
+ (*data)->count = panel->count;
+
+ result = _("Filtering strings available in the binary format...");
+
+ break;
+
+ default: /* Pour GCC... */
+ assert(false);
+ result = "";
+ break;
+
+ }
+
+ if (G_PANEL_ITEM(panel)->filter != NULL)
+ {
+ (*data)->filter = (regex_t *)malloc(sizeof(regex_t));
+
+ ret = regcomp((*data)->filter, G_PANEL_ITEM(panel)->filter, REG_EXTENDED | REG_ICASE);
+ assert(ret == 0);
+
+ }
+
+ else
+ (*data)->filter = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau ciblé par une mise à jour. *
+* uid = identifiant de la phase de traitement. *
+* data = données préparées par l'appelant. *
+* *
+* Description : Bascule l'affichage d'un panneau avant mise à jour. *
+* *
+* Retour : - *
+* *
+* Remarques : Cette fonction est appelée depuis le contexte principal. *
+* *
+******************************************************************************/
+
+static void g_strings_panel_introduce(const GStringsPanel *panel, unsigned int uid, strings_update_data *data)
+{
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkTreeView *treeview; /* Arborescence graphique */
+ GtkTreeModel *model; /* Source de données associée */
+
+ /* Basculement de l'affichage hors ligne */
+
+ g_panel_item_switch_to_updating_mask(G_PANEL_ITEM(panel));
+
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
+ model = gtk_tree_view_get_model(treeview);
+
+ if (model != NULL)
+ {
+ g_object_ref(G_OBJECT(model));
+ gtk_tree_view_set_model(treeview, NULL);
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau ciblé par une mise à jour. *
+* uid = identifiant de la phase de traitement. *
+* status = barre de statut à tenir informée. *
+* id = identifiant pour le suivi de la progression. *
+* data = données préparées par l'appelant. *
+* *
+* Description : Réalise une opération de mise à jour de panneau. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_strings_panel_process(const GStringsPanel *panel, unsigned int uid, GtkStatusStack *status, activity_id_t id, strings_update_data *data)
+{
+ switch (uid)
+ {
+ case PUI_0:
+ reload_strings_for_new_list_view(panel, status, id, data);
+ break;
+
+ case PUI_1:
+ do_filtering_on_strings(panel, status, id, data);
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau ciblé par une mise à jour. *
+* uid = identifiant de la phase de traitement. *
+* data = données préparées par l'appelant. *
+* *
+* Description : Bascule l'affichage d'un panneau après mise à jour. *
+* *
+* Retour : - *
+* *
+* Remarques : Cette fonction est appelée depuis le contexte principal. *
+* *
+******************************************************************************/
+
+static void g_strings_panel_conclude(GStringsPanel *panel, unsigned int uid, strings_update_data *data)
+{
+ GtkBuilder *builder; /* Constructeur utilisé */
+ GtkTreeView *treeview; /* Arborescence graphique */
+ GtkTreeModel *model; /* Source de données associée */
+
+ if (g_atomic_int_get(&G_PANEL_ITEM(panel)->switched) > 1)
+ goto skip_this_step;
+
+ /* Mise à jour des compteurs */
+
+ panel->count = data->count;
+
+ /* Basculement de l'affichage en ligne */
+
+ builder = G_PANEL_ITEM(panel)->builder;
+
+ treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
+
+ model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "filter"));
+
+ g_object_ref(G_OBJECT(model));
+ gtk_tree_view_set_model(treeview, model);
+
+ skip_this_step:
+
+ g_panel_item_switch_to_updated_content(G_PANEL_ITEM(panel));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau ciblé par une mise à jour. *
+* uid = identifiant de la phase de traitement. *
+* data = données en place à nettoyer avant suppression. *
+* *
+* Description : Supprime les données dynamiques utilisées à la mise à jour. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_strings_panel_clean_data(GUpdatablePanel *panel, unsigned int uid, strings_update_data *data)
+{
+ if (data->filter != NULL)
+ {
+ regfree(data->filter);
+ free(data->filter);
+ }
+
+}