diff options
Diffstat (limited to 'src/gui/menus')
-rw-r--r-- | src/gui/menus/menubar.c | 5 | ||||
-rw-r--r-- | src/gui/menus/view.c | 312 | ||||
-rw-r--r-- | src/gui/menus/view.h | 7 |
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 *); |