summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--src/gui/panels/history.c178
2 files changed, 140 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 140dc62..25a9176 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+15-08-05 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/gui/panels/history.c:
+ Properly handle the history selection and update the history on changes.
+
15-08-04 Cyrille Bagard <nocbos@gmail.com>
* src/analysis/db/collection.c:
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index 1e86880..7d0cdd5 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* history.c - panneau de la liste des évolutions d'utilisateur(s)
*
- * Copyright (C) 2008-2013 Cyrille Bagard
+ * Copyright (C) 2015 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -94,8 +94,8 @@ static void on_history_changed(GDbCollection *, DBAction, GDbItem *, GHistoryPan
/* Compare deux lignes entre elles pour le tri des évolutions. */
static gint sort_history_lines(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer);
-/* Réagit à une validation d'une ligne affichée. */
-static void on_history_row_activated(GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *, GHistoryPanel *);
+/* Réagit au changement de sélection des éléments d'historique. */
+static void on_history_selection_change(GtkTreeSelection *, GHistoryPanel *);
/* Annule l'élément d'évolution courant. */
static void do_history_undo(GtkButton *, GHistoryPanel *);
@@ -163,6 +163,7 @@ static void g_history_panel_init(GHistoryPanel *panel)
GtkTreeViewColumn *column; /* Colonne de la liste */
GtkWidget *box; /* Séparation horizontale */
GtkWidget *button; /* Bouton de cette même barre */
+ GtkTreeSelection *select; /* Sélection dans la liste */
base = G_EDITOR_ITEM(panel);
@@ -170,8 +171,7 @@ static void g_history_panel_init(GHistoryPanel *panel)
gtk_container_set_border_width(GTK_CONTAINER(base->widget), 8);
gtk_widget_show(base->widget);
- ref = G_OBJECT(base->widget);
- g_object_set_data(ref, "panel", panel);
+ ref = G_OBJECT(panel);
/* Liste des éléments d'évolution */
@@ -194,8 +194,6 @@ static void g_history_panel_init(GHistoryPanel *panel)
gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(panel->store), sort_history_lines, NULL, NULL);
- g_signal_connect(treeview, "row-activated", G_CALLBACK(on_history_row_activated), panel);
-
gtk_widget_show(treeview);
gtk_container_add(GTK_CONTAINER(scrollwnd), treeview);
@@ -226,11 +224,11 @@ static void g_history_panel_init(GHistoryPanel *panel)
gtk_widget_show(box);
gtk_box_pack_start(GTK_BOX(base->widget), box, FALSE, TRUE, 0);
- button = qck_create_button_with_css_img(NULL, NULL, "img-undo", _("Undo"),
+ button = qck_create_button_with_css_img(ref, "undo", "img-undo", _("Undo"),
G_CALLBACK(do_history_undo), panel);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
- button = qck_create_button_with_css_img(NULL, NULL, "img-redo", _("Redo"),
+ button = qck_create_button_with_css_img(ref, "redo", "img-redo", _("Redo"),
G_CALLBACK(do_history_redo), panel);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
@@ -238,6 +236,12 @@ static void g_history_panel_init(GHistoryPanel *panel)
G_CALLBACK(do_history_clean), panel);
gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
+ /* 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_BROWSE);
+ g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(on_history_selection_change), panel);
+
}
@@ -349,27 +353,39 @@ GPanelItem *create_history_panel(GObject *ref)
static void change_history_panel_current_binary(GHistoryPanel *panel, GLoadedBinary *binary)
{
-
-
- GtkTreeStore *store; /* Modèle de gestion */
GList *collections; /* Ensemble de collections */
GList *c; /* Boucle de parcours #1 */
GDbCollection *collec; /* Collection visée manipulée */
+ GtkTreeStore *store; /* Modèle de gestion */
GList *items; /* Liste des éléments groupés */
GList *i; /* Boucle de parcours #2 */
GDbItem *item; /* Elément à intégrer */
GtkTreeIter iter; /* Point d'insertion */
-
/* Basculement du binaire utilisé */
+ if (panel->binary != NULL)
+ {
+ collections = g_loaded_binary_get_all_collections(panel->binary);
+ rlock_collections(collections);
- panel->binary = binary;
+ for (c = g_list_first(collections); c != NULL; c = g_list_next(c))
+ {
+ collec = G_DB_COLLECTION(c->data);
+ g_signal_handlers_disconnect_by_func(collec, G_CALLBACK(on_history_changed), panel);
+ }
+ runlock_collections(collections);
+ g_object_unref(G_OBJECT(panel->binary));
+ }
+ panel->binary = binary;
+
+ if (panel->binary != NULL)
+ g_object_ref(G_OBJECT(binary));
store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview));
gtk_tree_store_clear(store);
@@ -410,6 +426,9 @@ static void change_history_panel_current_binary(GHistoryPanel *panel, GLoadedBin
runlock_collections(collections);
+ /* Force une sélection initiale */
+ on_history_changed(NULL, DBA_COUNT, NULL, panel);
+
}
@@ -432,34 +451,102 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem *
{
GtkTreeModel *model; /* Modèle de gestion courant */
GtkTreeIter iter; /* Boucle de parcours */
- GDbItem *displayed; /* Elément de collection */
+ GtkTreeSelection *selection; /* Nouvelle sélection à établir*/
model = GTK_TREE_MODEL(panel->store);
- switch (action)
+ /* Mise à jour de la liste affichée */
+
+ bool find_changed_item(GtkTreeModel *_model, GDbItem *target, GtkTreeIter *_found)
{
- case DBA_CHANGE_STATE:
+ bool status;
+ GtkTreeIter candidate;
+ GDbItem *displayed;
+
+ status = false;
+
+ if (gtk_tree_model_get_iter_first(_model, &candidate))
+ do
+ {
+ gtk_tree_model_get(_model, &candidate, HTC_ITEM, &displayed, -1);
- if (gtk_tree_model_get_iter_first(model, &iter))
- do
+ if (target == displayed)
{
- gtk_tree_model_get(model, &iter, HTC_ITEM, &displayed, -1);
+ *_found = candidate;
+ status = true;
+ }
- if (item == displayed)
- {
- gtk_tree_store_set(panel->store, &iter,
- HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey",
- -1);
- break;
- }
+ g_object_unref(G_OBJECT(displayed));
- g_object_unref(G_OBJECT(displayed));
+ }
+ while (!status && gtk_tree_model_iter_next(_model, &candidate));
- }
- while (gtk_tree_model_iter_next(model, &iter));
+ return status;
+
+ }
+
+ switch (action)
+ {
+ case DBA_ADD_ITEM:
+
+ gtk_tree_store_append(panel->store, &iter, NULL);
+ gtk_tree_store_set(panel->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),
+ -1);
break;
+ case DBA_REM_ITEM:
+
+ if (find_changed_item(model, item, &iter))
+ gtk_tree_store_remove(panel->store, &iter);
+
+ break;
+
+ case DBA_CHANGE_STATE:
+
+ if (find_changed_item(model, item, &iter))
+ gtk_tree_store_set(panel->store, &iter,
+ HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey",
+ -1);
+ break;
+
+ case DBA_COUNT:
+ /* Actualisation artificielle de la sélection */
+ break;
+
+ }
+
+ /* Redéfinition de la sélection */
+
+ if (gtk_tree_model_get_iter_first(model, &iter))
+ {
+ gboolean find_last_active(GtkTreeModel *_model, GtkTreePath *_path, GtkTreeIter *_iter, GtkTreeIter *last)
+ {
+ GDbItem *item;
+ gboolean active;
+
+ gtk_tree_model_get(_model, _iter, HTC_ITEM, &item, -1);
+
+ active = g_db_item_is_active(item);
+
+ g_object_unref(G_OBJECT(item));
+
+ if (active)
+ *last = *_iter;
+
+ return !active;
+
+ }
+
+ gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)find_last_active, &iter);
+
+ selection = gtk_tree_view_get_selection(panel->treeview);
+ gtk_tree_selection_select_iter(selection, &iter);
+
}
}
@@ -501,12 +588,10 @@ static gint sort_history_lines(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter
/******************************************************************************
* *
-* Paramètres : treeview = composant graphique manipulé par l'utilisateur. *
-* path = chemin d'accès à la ligne activée. *
-* column = colonne impactée par l'action. *
-* panel = panneau d'historique concerné par la procédure. *
+* Paramètres : selection = sélection modifiée. *
+* panel = structure contenant les informations maîtresses. *
* *
-* Description : Réagit à une validation d'une ligne affichée. *
+* Description : Réagit au changement de sélection des éléments d'historique. *
* *
* Retour : - *
* *
@@ -514,20 +599,30 @@ static gint sort_history_lines(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter
* *
******************************************************************************/
-static void on_history_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, GHistoryPanel *panel)
+static void on_history_selection_change(GtkTreeSelection *selection, GHistoryPanel *panel)
{
+ GtkTreeIter iter; /* Point de sélection */
+ GtkTreeModel *model; /* Modèle de gestion */
+ GDbItem *item; /* Elément de collection */
+ GtkWidget *button; /* Bouton de barre de contrôle */
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ gtk_tree_model_get(model, &iter, HTC_ITEM, &item, -1);
+ button = GTK_WIDGET(g_object_get_data(G_OBJECT(panel), "undo"));
+ gtk_widget_set_sensitive(button, g_db_item_is_active(item));
+ button = GTK_WIDGET(g_object_get_data(G_OBJECT(panel), "redo"));
+ gtk_widget_set_sensitive(button, !g_db_item_is_active(item));
+ g_object_unref(G_OBJECT(item));
+ }
}
-
-
-
/******************************************************************************
* *
* Paramètres : button = bouton d'édition de l'historique d'évolution. *
@@ -622,9 +717,6 @@ static void do_history_redo(GtkButton *button, GHistoryPanel *panel)
static void do_history_clean(GtkButton *button, GHistoryPanel *panel)
{
-
-
-
-
+ /* TODO */
}