summaryrefslogtreecommitdiff
path: root/src/gui/menus
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-07-20 16:43:23 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-07-20 16:43:23 (GMT)
commita809d3517eb928d5d7a03d96a85f8af96daa1047 (patch)
tree451decffd5fc20d1a5237b2aa814a62aaba99316 /src/gui/menus
parent5093663eb4e4aa17edd97cbd864ccb4a3d48a803 (diff)
Included dynamic items in the view menu.
Diffstat (limited to 'src/gui/menus')
-rw-r--r--src/gui/menus/menubar.c5
-rw-r--r--src/gui/menus/view.c312
-rw-r--r--src/gui/menus/view.h7
3 files changed, 210 insertions, 114 deletions
diff --git a/src/gui/menus/menubar.c b/src/gui/menus/menubar.c
index bc5a045..863ac54 100644
--- a/src/gui/menus/menubar.c
+++ b/src/gui/menus/menubar.c
@@ -282,6 +282,8 @@ GEditorItem *g_menu_bar_new(GObject *ref)
static void change_menubar_current_content(GMenuBar *bar, GLoadedContent *old, GLoadedContent *new)
{
+ rebuild_menu_view_for_content(bar->view, new);
+
update_access_for_content_in_menu_binary(new);
}
@@ -305,7 +307,8 @@ static void change_menubar_current_view(GMenuBar *bar, GLoadedPanel *old, GLoade
{
update_access_for_view_in_menu_edition(new);
- rebuild_menu_view(bar->view, new, bar);
+ rebuild_menu_view_for_view(bar->view, new);
+
update_access_for_view_in_menu_view(G_EDITOR_ITEM(bar)->ref, new);
}
diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c
index 31726c7..8c34950 100644
--- a/src/gui/menus/view.c
+++ b/src/gui/menus/view.c
@@ -26,6 +26,8 @@
#include <assert.h>
+#include <malloc.h>
+#include <stdio.h>
#include <i18n.h>
@@ -38,8 +40,6 @@
#include "../core/panels.h"
#include "../../analysis/loaded.h"
#include "../../gtkext/easygtk.h"
-#include "../../gtkext/gtkblockdisplay.h"
-#include "../../gtkext/gtkgraphdisplay.h"
@@ -90,7 +90,6 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar)
GtkWidget *result; /* Support à retourner */
GtkWidget *menubar; /* Support pour éléments */
GtkWidget *submenuitem; /* Sous-élément de menu */
- GSList *rgroup; /* Groupe des boutons radio */
result = gtk_menu_item_new_with_mnemonic(_("_View"));
gtk_widget_show(result);
@@ -108,26 +107,11 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar)
/* Séparation */
submenuitem = qck_create_menu_separator();
+ g_object_set_data(ref, "mnu_view_start_panels", submenuitem);
gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
/* Types de panneau de code */
- submenuitem = qck_create_radio_menu_item(ref, "mnu_view_switch_textview", NULL, _("Text view"),
- G_CALLBACK(mcb_view_change_support), NULL);
- add_accelerator_to_widget(submenuitem, "F3");
- g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_BLOCK));
- g_object_set_data(G_OBJECT(submenuitem), "kind_of_display", GSIZE_TO_POINTER(GTK_TYPE_BLOCK_DISPLAY));
- gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
- rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem));
-
- submenuitem = qck_create_radio_menu_item(ref, "mnu_view_switch_graphview", rgroup, _("Graph view"),
- G_CALLBACK(mcb_view_change_support), NULL);
- add_accelerator_to_widget(submenuitem, "F4");
- g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(BVW_GRAPH));
- g_object_set_data(G_OBJECT(submenuitem), "kind_of_display", GSIZE_TO_POINTER(GTK_TYPE_GRAPH_DISPLAY));
- gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
submenuitem = qck_create_menu_item(ref, "mcb_view_switch_to_next_support", _("Switch to next"),
G_CALLBACK(mcb_view_switch_to_next_support), NULL);
add_accelerator_to_widget(submenuitem, "Tab");
@@ -141,23 +125,7 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar)
/* Séparation */
submenuitem = qck_create_menu_separator();
- gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
- /* Affichage des données */
-
- submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_off", _("Physical offset"),
- G_CALLBACK(mcb_view_display_column), NULL);
- g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_PHYSICAL));
- gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
- submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_addr", _("Virtual address"),
- G_CALLBACK(mcb_view_display_column), NULL);
- g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_VIRTUAL));
- gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
-
- submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_code", _("Binary code"),
- G_CALLBACK(mcb_view_display_column), NULL);
- g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_BINARY));
+ g_object_set_data(ref, "mnu_view_start_options", submenuitem);
gtk_container_add(GTK_CONTAINER(menubar), submenuitem);
/* Séparation */
@@ -180,10 +148,9 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar)
/******************************************************************************
* *
* Paramètres : widget = menu principal à actualiser. *
-* panel = nouveau panneau d'affichage actif. *
-* bar = barre de menu parente. *
+* new = nouveau contenu chargé à analyser. *
* *
-* Description : Lance une actualisation du fait d'un changement de vue. *
+* Description : Réagit à un changement d'affichage principal de contenu. *
* *
* Retour : - *
* *
@@ -191,105 +158,246 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar)
* *
******************************************************************************/
-void rebuild_menu_view(GtkWidget *widget, GLoadedPanel *panel, GMenuBar *bar)
+void rebuild_menu_view_for_content(GtkWidget *widget, GLoadedContent *new)
{
- GObject *ref; /* Espace de référencements */
- GtkRadioMenuItem *item; /* Elément de menu arbitraire */
- GSList *radios; /* Liste des menus d'affichage */
- GSList *found; /* Elément de menu à activer */
- GLoadedContent *content; /* Contenu global représenté */
- unsigned int view_index; /* Indice de représentation */
- GDisplayOptions *options; /* Règles d'affichage courantes*/
+ GObject *ref; /* Espace de références */
+ GtkWidget *menubar; /* Support pour éléments */
+ unsigned int i; /* Boucle de parcours */
+ char *key; /* Clef pour accès ultérieurs */
GtkWidget *submenuitem; /* Sous-élément de menu */
- bool status; /* Consigne d'affichage */
-
- ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar));
+ void *marker; /* Menu de référence */
+ GList *list; /* Liste des éléments en place */
+ gint position; /* Point d'insertion */
+ GList *iter; /* Boucle de parcours */
+ unsigned int count; /* Nombre d'itérations à mener */
+ GSList *rgroup; /* Groupe des boutons radio */
- /* Types de panneau de code */
+ ref = get_global_ref();
- item = GTK_RADIO_MENU_ITEM(g_object_get_data(ref, "mnu_view_switch_graphview"));
+ /* Retrait d'éventuels anciens menus */
- radios = gtk_radio_menu_item_get_group(item);
+ menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget));
- void disconnect_display_radio(GtkWidget *wgt, gpointer unused)
+ for (i = 0; ; i++)
{
- g_signal_handlers_disconnect_by_func(wgt, G_CALLBACK(mcb_view_change_support), NULL);
+ asprintf(&key, "mnu_view_panel_%u", i);
- }
+ submenuitem = g_object_get_data(ref, key);
- g_slist_foreach(radios, (GFunc)disconnect_display_radio, NULL);
+ free(key);
- gint find_suitable_display_radio(GObject *rdo, GObject *pnl)
+ if (submenuitem == NULL)
+ break;
+ else
+ gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(submenuitem));
+
+ }
+
+ if (new != NULL)
{
- GType rdo_type; /* Type d'affichage supporté */
- GType pnl_type; /* Type du panneau affiché */
+ /* Insertion des différentes vues */
+
+ marker = g_object_get_data(ref, "mnu_view_start_panels");
+
+ list = gtk_container_get_children(GTK_CONTAINER(menubar));
- rdo_type = GPOINTER_TO_SIZE(g_object_get_data(rdo, "kind_of_display"));
+ position = 0;
- pnl_type = G_OBJECT_TYPE(pnl);
+ for (iter = list; iter != NULL; iter = g_list_next(iter))
+ {
+ position++;
+
+ if (marker == iter->data)
+ break;
+
+ }
+
+ g_list_free(list);
+
+ count = g_loaded_content_count_views(new);
+
+ rgroup = NULL;
+
+ for (i = 0; i < count; i++)
+ {
+ asprintf(&key, "mnu_view_panel_%u", i);
+
+ submenuitem = qck_create_radio_menu_item(ref, key, rgroup,
+ g_loaded_content_get_view_name(new, i),
+ G_CALLBACK(mcb_view_change_support), NULL);
+ g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(i));
+
+ free(key);
+
+ asprintf(&key, "F%u", 3 + i);
+
+ add_accelerator_to_widget(submenuitem, key);
+
+ free(key);
+
+ if (rgroup == NULL)
+ rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem));
- return (rdo_type == pnl_type ? 0 : -1);
+ gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), submenuitem, position + i);
+
+ }
}
- found = g_slist_find_custom(radios, G_OBJECT(panel), (GCompareFunc)find_suitable_display_radio);
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = menu principal à actualiser. *
+* new = nouvelle vue du contenu chargé analysé. *
+* *
+* Description : Lance une actualisation du fait d'un changement de support. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void rebuild_menu_view_for_view(GtkWidget *widget, GLoadedPanel *new)
+{
+ GObject *ref; /* Espace de références */
+ GLoadedContent *content; /* Contenu en cours d'analyse */
+ unsigned int index; /* Indice de la vue */
+
+ GtkWidget *menubar; /* Support pour éléments */
+ void *marker; /* Menu de référence */
+ size_t i; /* Boucle de parcours */
+ char *key; /* Clef pour accès ultérieurs */
+ GtkWidget *submenuitem; /* Sous-élément de menu */
+
+
+
+ GtkRadioMenuItem *item; /* Elément de menu arbitraire */
+ GSList *radios; /* Liste des menus d'affichage */
+
+ GList *list; /* Liste des éléments en place */
+ gint position; /* Point d'insertion */
+ GList *iter; /* Boucle de parcours */
+
+ GDisplayOptions *options; /* Paramètres de rendus */
+ size_t count; /* Nombre d'itérations à mener */
+ bool status; /* Consigne d'affichage */
+
+ ref = get_global_ref();
+
+ content = get_current_content();
+ assert((content == NULL && new == NULL) || (content != NULL && new != NULL));
- assert(found != NULL);
+ /* Retrait d'éventuels anciens menus */
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(found->data), TRUE);
+ menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget));
- void reconnect_display_radio(GtkWidget *wgt, gpointer unused)
+ marker = g_object_get_data(ref, "mnu_view_start_options");
+
+ for (i = 0; ; i++)
{
- g_signal_connect(wgt, "toggled", G_CALLBACK(mcb_view_change_support), NULL);
+ asprintf(&key, "mnu_view_display_option_%zu", i);
+
+ submenuitem = g_object_get_data(ref, key);
+
+ free(key);
+
+ if (submenuitem == NULL)
+ break;
+ else
+ gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(submenuitem));
}
- g_slist_foreach(radios, (GFunc)reconnect_display_radio, NULL);
+ if (content != NULL)
+ {
+ index = g_loaded_content_get_view_index(content, GTK_WIDGET(new));
- /* Séparation */
+ /* Mise à jour du choix de la vue */
- content = g_loaded_panel_get_content(panel);
+ item = GTK_RADIO_MENU_ITEM(g_object_get_data(ref, "mnu_view_panel_0"));
- view_index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel));
+ radios = gtk_radio_menu_item_get_group(item);
- options = g_loaded_content_get_display_options(content, view_index);
+ void disconnect_display_radio(GtkWidget *wgt, gpointer unused)
+ {
+ g_signal_handlers_disconnect_by_func(wgt, G_CALLBACK(mcb_view_change_support), NULL);
+ }
- g_object_unref(G_OBJECT(content));
+ g_slist_foreach(radios, (GFunc)disconnect_display_radio, NULL);
+
+ asprintf(&key, "mnu_view_panel_%u", index);
+
+ item = GTK_RADIO_MENU_ITEM(g_object_get_data(ref, key));
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
+
+ free(key);
- /* Positions physiques */
+ void reconnect_display_radio(GtkWidget *wgt, gpointer unused)
+ {
+ g_signal_connect(wgt, "toggled", G_CALLBACK(mcb_view_change_support), NULL);
+ }
+
+ g_slist_foreach(radios, (GFunc)reconnect_display_radio, NULL);
+
+ /* Insertion des options de rendu */
- submenuitem = g_object_get_data(ref, "mnu_view_display_off");
+ list = gtk_container_get_children(GTK_CONTAINER(menubar));
- g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_display_column), NULL);
+ position = 0;
- status = g_display_options_get(options, BLC_PHYSICAL);
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), status);
+ for (iter = list; iter != NULL; iter = g_list_next(iter))
+ {
+ position++;
- g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_display_column), NULL);
+ if (marker == iter->data)
+ break;
- /* Adresses virtuelles */
+ }
- submenuitem = g_object_get_data(ref, "mnu_view_display_addr");
+ g_list_free(list);
- g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_display_column), NULL);
+ options = g_loaded_content_get_display_options(content, index);
- status = g_display_options_get(options, BLC_VIRTUAL);
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), status);
+ count = g_display_options_count(options);
- g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_display_column), NULL);
+ for (i = 0; i < count; i++)
+ {
+ asprintf(&key, "mnu_view_display_option_%zu", i);
- /* Code binaire */
+ submenuitem = qck_create_check_menu_item(ref, key,
+ g_display_options_get_name(options, i),
+ G_CALLBACK(mcb_view_display_column), NULL);
+ g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(i));
- submenuitem = g_object_get_data(ref, "mnu_view_display_code");
+ gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), submenuitem, position + i);
- g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_display_column), NULL);
+ free(key);
- status = g_display_options_get(options, BLC_BINARY);
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), status);
+ /**
+ * Un signal va être émis pour le menu, mais il n'ira pas très loin :
+ * l'ensemble des options ne notifie un changement que si changement il y a !
+ */
- g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_display_column), NULL);
+ status = g_display_options_get(options, i);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), status);
- g_object_unref(G_OBJECT(options));
+ }
+
+ g_object_unref(G_OBJECT(options));
+
+ g_object_unref(G_OBJECT(content));
+
+ }
+
+ else
+ count = 0;
+
+ /* Utilité de la séparation ? */
+
+ gtk_widget_set_visible(GTK_WIDGET(marker), count > 0);
}
@@ -309,28 +417,10 @@ void rebuild_menu_view(GtkWidget *widget, GLoadedPanel *panel, GMenuBar *bar)
void update_access_for_view_in_menu_view(GObject *ref, GLoadedPanel *panel)
{
- gboolean access; /* Accès à déterminer */
- GtkWidget *item; /* Elément de menu à traiter */
-
- /* Préliminaire */
-
- access = (panel != NULL);
-
/* Bascules */
update_switch_access_in_menu_view();
- /* Affichage des données */
-
- item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_display_off"));
- gtk_widget_set_sensitive(item, access);
-
- item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_display_addr"));
- gtk_widget_set_sensitive(item, access);
-
- item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_display_code"));
- gtk_widget_set_sensitive(item, access);
-
}
diff --git a/src/gui/menus/view.h b/src/gui/menus/view.h
index fadf881..a6491bd 100644
--- a/src/gui/menus/view.h
+++ b/src/gui/menus/view.h
@@ -37,8 +37,11 @@
/* Construit le menu "Affichage". */
GtkWidget *build_menu_view(GObject *, GMenuBar *);
-/* Lance une actualisation du fait d'un changement de vue. */
-void rebuild_menu_view(GtkWidget *, GLoadedPanel *, GMenuBar *);
+/* Réagit à un changement d'affichage principal de contenu. */
+void rebuild_menu_view_for_content(GtkWidget *, GLoadedContent *);
+
+/* Lance une actualisation du fait d'un changement de support. */
+void rebuild_menu_view_for_view(GtkWidget *, GLoadedPanel *);
/* Met à jour les accès du menu "Affichage" selon le contenu. */
void update_access_for_view_in_menu_view(GObject *, GLoadedPanel *);