summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-01-17 13:45:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-01-17 19:06:08 (GMT)
commitd13bccd74759cd1c63a2036c279f04d9f052ecf3 (patch)
treeadbd0b9d915748a2b46070282c07b3f16033d89e /src/gui
parent52ac5b1b340335f56ceb599dba63164a26f10b10 (diff)
Updated access to the Edition menu based on the current selection.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/editem-int.h5
-rw-r--r--src/gui/editem.c63
-rw-r--r--src/gui/editem.h2
-rw-r--r--src/gui/menus/edition.c129
-rw-r--r--src/gui/menus/edition.h4
-rw-r--r--src/gui/menus/menubar.c29
-rw-r--r--src/gui/status.c58
7 files changed, 203 insertions, 87 deletions
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 */