From d13bccd74759cd1c63a2036c279f04d9f052ecf3 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 17 Jan 2016 14:45:49 +0100 Subject: Updated access to the Edition menu based on the current selection. --- ChangeLog | 18 +++++++ src/gtkext/gtkviewpanel.c | 3 ++ src/gui/editem-int.h | 5 ++ src/gui/editem.c | 63 +++++++++++++++++++++- src/gui/editem.h | 2 +- src/gui/menus/edition.c | 129 ++++++++++++++++++++++++++++++++++------------ src/gui/menus/edition.h | 4 ++ src/gui/menus/menubar.c | 29 +++++++++++ src/gui/status.c | 58 ++------------------- 9 files changed, 224 insertions(+), 87 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2f3e291..98a2406 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +16-01-17 Cyrille Bagard + + * src/gtkext/gtkviewpanel.c: + Reset output arguments in gtk_view_panel_get_position() in all cases. + + * src/gui/editem-int.h: + * src/gui/editem.c: + * src/gui/editem.h: + Give a way to all editor items to react on selection changes. + + * src/gui/menus/edition.c: + * src/gui/menus/edition.h: + Update access to the Edition menu based on the current selection. + + * src/gui/menus/menubar.c: + * src/gui/status.c: + Update code. + 16-01-16 Cyrille Bagard * src/analysis/db/collection.c: diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index 091482b..861b46f 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -903,6 +903,9 @@ bool gtk_view_panel_get_position(const GtkViewPanel *panel, GBufferLine **line, { bool result; /* Bilan de l'opération */ + *line = NULL; + if (segment != NULL) *segment = NULL; + if (GTK_VIEW_PANEL_GET_CLASS(panel)->get_position == NULL) return false; diff --git a/src/gui/editem-int.h b/src/gui/editem-int.h index b76769f..fa62dc6 100644 --- a/src/gui/editem-int.h +++ b/src/gui/editem-int.h @@ -33,6 +33,7 @@ #include "../common/dllist.h" +#include "../gtkext/gtkbufferview.h" @@ -45,6 +46,9 @@ typedef void (* manage_item_view_fc) (GEditorItem *, GtkViewPanel *, bool); /* Réagit à un changement d'affichage principal de contenu. */ typedef void (* update_item_view_fc) (GEditorItem *, GtkViewPanel *); +/* Suit les changements de position dans du code d'assembleur. */ +typedef void (* track_caret_in_view_fc) (GEditorItem *, GtkBufferView *, const vmpa2t *); + /* Concentre l'attention de l'ensemble sur une adresse donnée. */ typedef void (* focus_addr_fc) (GEditorItem *, GLoadedBinary *, const vmpa2t *); @@ -75,6 +79,7 @@ struct _GEditorItemClass update_item_binary_fc update_binary; /* Changement de binaire */ manage_item_view_fc manage_view; /* Gestion des vues manipulées */ update_item_view_fc update_view; /* Rechargement dû à une vue */ + track_caret_in_view_fc track_caret; /* Suivi des positions */ update_item_view_fc update_content; /* Rechargement dû à un contenu*/ focus_addr_fc focus_addr; /* Prête attention à une addr. */ update_project_fc update_project; /* Actualisation des binaires */ diff --git a/src/gui/editem.c b/src/gui/editem.c index e4c74a9..9f10bec 100644 --- a/src/gui/editem.c +++ b/src/gui/editem.c @@ -26,6 +26,7 @@ #include "editem-int.h" +#include "../gtkext/gtkblockview.h" @@ -43,9 +44,16 @@ static void g_editor_item_init(GEditorItem *); /* ---------------------------- MANIPULATION D'ENSEMBLES ---------------------------- */ -/* liste des éléments enregistrés */ +/* Liste des éléments enregistrés */ static GEditorItem *_editem_list = NULL; +/* Suivi des changements de position */ +static GObject *_caret_instance = NULL; + + +/* Suit les changements de position dans du code d'assembleur. */ +static void track_caret_address_on_buffer_views(GtkBufferView *, const vmpa2t *, void *); + /* ---------------------------------------------------------------------------------- */ @@ -252,6 +260,36 @@ void manage_editor_items_view(GtkViewPanel *view, bool created) if (klass->manage_view != NULL) klass->manage_view(iter, view, created); + } + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant d'affichage parcouru. * +* addr = nouvelle adresse du curseur courant. * +* data = adresse non utilisée ici. * +* * +* Description : Suit les changements de position dans du code d'assembleur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2t *addr, void *data) +{ + GEditorItem *iter; /* Boucle de parcours */ + GEditorItemClass *klass; /* Classe correspondante */ + + editem_list_for_each(iter, _editem_list) + { + klass = G_EDITOR_ITEM_GET_CLASS(iter); + + if (klass->track_caret != NULL) + klass->track_caret(iter, view, addr); } @@ -285,6 +323,29 @@ void change_editor_items_current_view(GObject *ref, GtkViewPanel *view) if (klass->update_view != NULL) klass->update_view(iter, view); + } + + if (_caret_instance != NULL) + { + g_signal_handlers_disconnect_by_func(_caret_instance, + G_CALLBACK(track_caret_address_on_buffer_views), + NULL); + g_object_unref(_caret_instance); + _caret_instance = NULL; + } + + if (view != NULL) + { + if (GTK_IS_BLOCK_VIEW(view)) + { + g_signal_connect(view, "caret-moved", + G_CALLBACK(track_caret_address_on_buffer_views), + NULL); + + _caret_instance = G_OBJECT(view); + g_object_ref(_caret_instance); + + } } diff --git a/src/gui/editem.h b/src/gui/editem.h index c716337..67bc402 100644 --- a/src/gui/editem.h +++ b/src/gui/editem.h @@ -80,7 +80,7 @@ void register_editor_item(GEditorItem *); void change_editor_items_current_binary(GObject *, GLoadedBinary *); /* Lance une actualisation liée à une modification du cheptel. */ -void manage_editor_items_view(GtkViewPanel *, bool); +void manage_editor_items_view(GtkViewPanel *, bool) __attribute__ ((deprecated));; /* Lance une actualisation du fait d'un changement de vue. */ void change_editor_items_current_view(GObject *, GtkViewPanel *); diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c index c524891..b77f864 100644 --- a/src/gui/menus/edition.c +++ b/src/gui/menus/edition.c @@ -100,25 +100,25 @@ GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b deepmenubar = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenuitem), deepmenubar); - deepmenuitem = qck_create_menu_item(NULL, NULL, _("Hexadecimal"), + deepmenuitem = qck_create_menu_item(ref, "mnu_edit_switch_hex", _("Hexadecimal"), G_CALLBACK(mcb_edition_switch_numeric_operand), bar); add_accelerator_to_menu_item(deepmenuitem, "H", accgroup); g_object_set_data(G_OBJECT(deepmenuitem), "kind_of_switch", GUINT_TO_POINTER(IOD_HEX)); gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - deepmenuitem = qck_create_menu_item(NULL, NULL, _("Decimal"), + deepmenuitem = qck_create_menu_item(ref, "mnu_edit_switch_dec", _("Decimal"), G_CALLBACK(mcb_edition_switch_numeric_operand), bar); add_accelerator_to_menu_item(deepmenuitem, "D", accgroup); g_object_set_data(G_OBJECT(deepmenuitem), "kind_of_switch", GUINT_TO_POINTER(IOD_DEC)); gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - deepmenuitem = qck_create_menu_item(NULL, NULL, _("Octal"), + deepmenuitem = qck_create_menu_item(ref, "mnu_edit_switch_oct", _("Octal"), G_CALLBACK(mcb_edition_switch_numeric_operand), bar); add_accelerator_to_menu_item(deepmenuitem, "O", accgroup); g_object_set_data(G_OBJECT(deepmenuitem), "kind_of_switch", GUINT_TO_POINTER(IOD_OCT)); gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - deepmenuitem = qck_create_menu_item(NULL, NULL, _("Binary"), + deepmenuitem = qck_create_menu_item(ref, "mnu_edit_switch_bin", _("Binary"), G_CALLBACK(mcb_edition_switch_numeric_operand), bar); add_accelerator_to_menu_item(deepmenuitem, "B", accgroup); g_object_set_data(G_OBJECT(deepmenuitem), "kind_of_switch", GUINT_TO_POINTER(IOD_BIN)); @@ -127,7 +127,7 @@ GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b deepmenuitem = qck_create_menu_separator(); gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - deepmenuitem = qck_create_menu_item(NULL, NULL, _("Default"), + deepmenuitem = qck_create_menu_item(ref, "mnu_edit_switch_def", _("Default"), G_CALLBACK(mcb_edition_switch_numeric_operand), bar); g_object_set_data(G_OBJECT(deepmenuitem), "kind_of_switch", GUINT_TO_POINTER(IOD_COUNT)); gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); @@ -166,6 +166,77 @@ GtkWidget *build_menu_edition(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *b /****************************************************************************** * * +* Paramètres : bar = barre de menus à actualiser. * +* addr = nouvelle adresse du curseur courant. * +* info = barre de statut présentant les informations. * +* * +* Description : Met à jour les accès du menu "Edition" selon une position. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_access_in_menu_edition(GObject *ref, GtkBufferView *view, const vmpa2t *addr) +{ + bool state; /* Etat principal à considérer */ + gboolean access; /* Accès à déterminer */ + GBufferLine *line; /* Ligne de position courante */ + GBufferSegment *segment; /* Segment actif s'il existe */ + GObject *creator; /* Créateur à l'orgine du seg. */ + GtkWidget *item; /* Elément de menu à traiter */ + + /* Préliminaire */ + + if (view == NULL) + state = false; + else + state = gtk_view_panel_get_position(GTK_VIEW_PANEL(view), &line, &segment); + + if (state) + creator = g_buffer_segment_get_creator(segment); + else + creator = NULL; + + /* Bascule des opérandes numériques */ + + access = (state && G_IS_IMM_OPERAND(creator)); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_switch_hex")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_switch_dec")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_switch_oct")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_switch_bin")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_switch_def")); + gtk_widget_set_sensitive(item, access); + + /* Suivi de cibles */ + + access = (state && (G_IS_TARGET_OPERAND(creator) || G_IS_IMM_OPERAND(creator))); + + item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_follow_ref")); + gtk_widget_set_sensitive(item, access); + + /* Nettoyage et sortie finale */ + + if (creator != NULL) g_object_unref(G_OBJECT(creator)); + + if (segment != NULL) g_object_unref(G_OBJECT(segment)); + if (line != NULL) g_object_unref(G_OBJECT(line)); + +} + + +/****************************************************************************** +* * * Paramètres : menuitem = élément de menu sélectionné. * * bar = barre de menu parente. * * * @@ -292,40 +363,34 @@ static void mcb_edition_follow_ref(GtkMenuItem *menuitem, GMenuBar *bar) if (gtk_view_panel_get_position(vpanel, &line, &segment)) { - if (segment != NULL) - creator = g_buffer_segment_get_creator(segment); - else - creator = NULL; - - if (creator != NULL) - { - /** - * On fait le pari de reposer uniquement sur des adresses virtuelles ! - * A changer dans un futur ? - */ - - virt = VMPA_NO_VIRTUAL; + creator = g_buffer_segment_get_creator(segment); + assert(creator != NULL); - if (G_IS_TARGET_OPERAND(creator)) - virt = g_target_operand_get_addr(G_TARGET_OPERAND(creator)); + /** + * On fait le pari de reposer uniquement sur des adresses virtuelles ! + * A changer dans un futur ? + */ - else if (G_IS_IMM_OPERAND(creator)) - { - if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt)) - virt = VMPA_NO_VIRTUAL; - } + virt = VMPA_NO_VIRTUAL; - if (virt != VMPA_NO_VIRTUAL) - { - init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); - gtk_view_panel_scroll_to_address(vpanel, &addr, SPT_CENTER); - } + if (G_IS_TARGET_OPERAND(creator)) + virt = g_target_operand_get_addr(G_TARGET_OPERAND(creator)); - g_object_unref(creator); + else if (G_IS_IMM_OPERAND(creator)) + { + if (!g_imm_operand_to_virt_t(G_IMM_OPERAND(creator), &virt)) + virt = VMPA_NO_VIRTUAL; + } + if (virt != VMPA_NO_VIRTUAL) + { + init_vmpa(&addr, VMPA_NO_PHYSICAL, virt); + gtk_view_panel_scroll_to_address(vpanel, &addr, SPT_CENTER); } - if (segment != NULL) g_object_unref(G_OBJECT(segment)); + g_object_unref(creator); + + g_object_unref(G_OBJECT(segment)); g_object_unref(G_OBJECT(line)); } diff --git a/src/gui/menus/edition.h b/src/gui/menus/edition.h index b430a8b..82a48bd 100644 --- a/src/gui/menus/edition.h +++ b/src/gui/menus/edition.h @@ -30,12 +30,16 @@ #include "menubar.h" +#include "../../gtkext/gtkbufferview.h" /* Construit le menu "Edition". */ GtkWidget *build_menu_edition(GObject *, GtkAccelGroup *, GMenuBar *); +/* Met à jour les accès du menu "Edition" selon une position. */ +void update_access_in_menu_edition(GObject *, GtkBufferView *, const vmpa2t *); + #endif /* _GUI_MENUS_EDITION_H */ diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c index 1fc1b6f..cbb6ae2 100644 --- a/src/gui/menus/menubar.c +++ b/src/gui/menus/menubar.c @@ -80,6 +80,9 @@ static void manage_view_in_menu_bar(GMenuBar *, GtkViewPanel *, bool); /* Lance une actualisation du fait d'un changement de vue. */ static void update_menu_bar_for_view(GMenuBar *, GtkViewPanel *); +/* Met à jour les accès aux menus en fonction de la position. */ +static void track_caret_address_for_menu_bar(GMenuBar *, GtkBufferView *, const vmpa2t *); + /* Lance une actualisation relative à l'étendue du projet. */ static void update_menu_bar_for_project(GMenuBar *, GStudyProject *); @@ -115,6 +118,7 @@ static void g_menu_bar_class_init(GMenuBarClass *klass) editem->manage_view = (manage_item_view_fc)manage_view_in_menu_bar; editem->update_view = (update_item_view_fc)update_menu_bar_for_view; + editem->track_caret = (track_caret_in_view_fc)track_caret_address_for_menu_bar; editem->update_project = (update_project_fc)update_menu_bar_for_project; } @@ -345,6 +349,31 @@ static void update_menu_bar_for_view(GMenuBar *bar, GtkViewPanel *view) /****************************************************************************** * * +* Paramètres : bar = barre de menus à actualiser. * +* addr = nouvelle adresse du curseur courant. * +* info = barre de statut présentant les informations. * +* * +* Description : Met à jour les accès aux menus en fonction de la position. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void track_caret_address_for_menu_bar(GMenuBar *bar, GtkBufferView *view, const vmpa2t *addr) +{ + GEditorItem *item; /* Autre version de l'élément */ + + item = G_EDITOR_ITEM(bar); + + update_access_in_menu_edition(item->ref, view, addr); + +} + + +/****************************************************************************** +* * * Paramètres : bar = barre de menus à actualiser. * * project = projet visé par la procédure. * * * diff --git a/src/gui/status.c b/src/gui/status.c index de80049..8db4f3a 100644 --- a/src/gui/status.c +++ b/src/gui/status.c @@ -46,9 +46,6 @@ struct _GStatusInfo { GEditorItem parent; /* A laisser en premier */ - GObject *caret_instance; /* Dernier émetteur de signaux */ - bstatus_id_t msg_id; /* Identifiant du dernier msg. */ - }; @@ -72,11 +69,8 @@ static void g_status_info_dispose(GStatusInfo *); /* Procède à la libération totale de la mémoire. */ static void g_status_info_finalize(GStatusInfo *); -/* Lance une actualisation du fait d'un changement de vue. */ -static void update_status_info_for_view(GStatusInfo *, GtkViewPanel *); - /* Imprime la position du parcours courant dans le statut. */ -static void track_caret_address_on_buffer_views(GtkBufferView *, const vmpa2t *, GStatusInfo *); +static void track_caret_address_for_status_info(GStatusInfo *, GtkBufferView *, const vmpa2t *); /* Concentre l'attention de l'ensemble sur une adresse donnée. */ static void focus_address_in_status_info(GStatusInfo *, GLoadedBinary *, const vmpa2t *); @@ -111,7 +105,7 @@ static void g_status_info_class_init(GStatusInfoClass *klass) editem = G_EDITOR_ITEM_CLASS(klass); - editem->update_view = (update_item_view_fc)update_status_info_for_view; + editem->track_caret = (track_caret_in_view_fc)track_caret_address_for_status_info; editem->focus_addr = (focus_addr_fc)focus_address_in_status_info; } @@ -157,14 +151,6 @@ static void g_status_info_init(GStatusInfo *bar) static void g_status_info_dispose(GStatusInfo *info) { - if (info->caret_instance != NULL) - { - g_signal_handlers_disconnect_by_func(info->caret_instance, - G_CALLBACK(track_caret_address_on_buffer_views), - info); - g_object_unref(info->caret_instance); - } - G_OBJECT_CLASS(g_status_info_parent_class)->dispose(G_OBJECT(info)); } @@ -222,43 +208,9 @@ GEditorItem *g_status_info_new(GObject *ref) /****************************************************************************** * * -* Paramètres : info = barre de statut à actualiser. * -* view = nouveau panneau d'affichage actif. * -* * -* Description : Lance une actualisation du fait d'un changement de vue. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void update_status_info_for_view(GStatusInfo *info, GtkViewPanel *view) -{ - if (info->caret_instance != NULL) - { - g_signal_handlers_disconnect_by_func(info->caret_instance, - G_CALLBACK(track_caret_address_on_buffer_views), - info); - g_object_unref(info->caret_instance); - } - - if (GTK_IS_BLOCK_VIEW(view)) - g_signal_connect(view, "caret-moved", - G_CALLBACK(track_caret_address_on_buffer_views), - info); - - info->caret_instance = G_OBJECT(view); - g_object_ref(info->caret_instance); - -} - - -/****************************************************************************** -* * -* Paramètres : view = composant d'affichage parcouru. * +* Paramètres : info = barre de statut présentant les informations. * +* view = composant d'affichage parcouru. * * addr = nouvelle adresse du curseur courant. * -* info = barre de statut présentant les informations. * * * * Description : Imprime la position du parcours courant dans le statut. * * * @@ -268,7 +220,7 @@ static void update_status_info_for_view(GStatusInfo *info, GtkViewPanel *view) * * ******************************************************************************/ -static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2t *addr, GStatusInfo *info) +static void track_caret_address_for_status_info(GStatusInfo *info, GtkBufferView *view, const vmpa2t *addr) { GEditorItem *item; /* Autre version de l'élément */ GLoadedBinary *binary; /* Binaire courant */ -- cgit v0.11.2-87-g4458