summaryrefslogtreecommitdiff
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
parent5093663eb4e4aa17edd97cbd864ccb4a3d48a803 (diff)
Included dynamic items in the view menu.
-rw-r--r--src/analysis/binary.c46
-rw-r--r--src/analysis/loaded-int.h4
-rw-r--r--src/analysis/loaded.c29
-rw-r--r--src/analysis/loaded.h3
-rw-r--r--src/glibext/gdisplayoptions.c30
-rw-r--r--src/glibext/gdisplayoptions.h3
-rw-r--r--src/gtkext/gtkdisplaypanel.c60
-rw-r--r--src/gui/editor.c4
-rw-r--r--src/gui/menus/menubar.c5
-rw-r--r--src/gui/menus/view.c312
-rw-r--r--src/gui/menus/view.h7
11 files changed, 351 insertions, 152 deletions
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 89370b2..44dfe6c 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -165,6 +165,9 @@ static const char *g_loaded_binary_describe(const GLoadedBinary *, bool);
/* Détermine le nombre de vues disponibles pour un contenu. */
static unsigned int g_loaded_binary_count_views(const GLoadedBinary *);
+/* Fournit le nom d'une vue donnée d'un contenu chargé. */
+static const char *g_loaded_binary_get_view_name(const GLoadedBinary *, unsigned int);
+
/* Met en place la vue demandée pour un contenu binaire. */
static GtkWidget *g_loaded_binary_build_view(GLoadedBinary *, unsigned int);
@@ -278,6 +281,7 @@ static void g_loaded_binary_interface_init(GLoadedContentInterface *iface)
iface->describe = (describe_loaded_fc)g_loaded_binary_describe;
iface->count_views = (count_loaded_views_fc)g_loaded_binary_count_views;
+ iface->get_view_name = (get_loaded_view_name_fc)g_loaded_binary_get_view_name;
iface->build_view = (build_loaded_view_fc)g_loaded_binary_build_view;
iface->get_view_index = (get_loaded_view_index_fc)g_loaded_binary_get_view_index;
@@ -1641,6 +1645,44 @@ static unsigned int g_loaded_binary_count_views(const GLoadedBinary *binary)
* Paramètres : binary = contenu chargé à consulter. *
* index = indice de la vue ciblée. *
* *
+* Description : Fournit le nom d'une vue donnée d'un contenu chargé. *
+* *
+* Retour : Désignation humainement lisible. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static const char *g_loaded_binary_get_view_name(const GLoadedBinary *binary, unsigned int index)
+{
+ const char *result; /* Désignation à retourner */
+
+ switch (index)
+ {
+ case BVW_BLOCK:
+ result = _("Text view");
+ break;
+
+ case BVW_GRAPH:
+ result = _("Graph view");
+ break;
+
+ default:
+ assert(false);
+ result = NULL;
+ break;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : binary = contenu chargé à consulter. *
+* index = indice de la vue ciblée. *
+* *
* Description : Met en place la vue demandée pour un contenu binaire. *
* *
* Retour : Composant graphique nouveau. *
@@ -1654,8 +1696,6 @@ static GtkWidget *g_loaded_binary_build_view(GLoadedBinary *binary, unsigned int
GtkWidget *result; /* Support à retourner */
GtkWidget *display; /* Composant d'affichage */
- assert(index < g_loaded_binary_count_views(binary));
-
switch (index)
{
case BVW_BLOCK:
@@ -1735,8 +1775,6 @@ static GDisplayOptions *g_loaded_binary_get_display_options(const GLoadedBinary
{
GDisplayOptions *result; /* Instance à renvoyer */
- assert(index < BVW_COUNT);
-
if (index < BVW_COUNT)
result = binary->options[index];
else
diff --git a/src/analysis/loaded-int.h b/src/analysis/loaded-int.h
index 044dad7..ed7d84a 100644
--- a/src/analysis/loaded-int.h
+++ b/src/analysis/loaded-int.h
@@ -51,6 +51,9 @@ typedef const char * (* describe_loaded_fc) (const GLoadedContent *, bool);
/* Détermine le nombre de vues disponibles pour un contenu. */
typedef unsigned int (* count_loaded_views_fc) (const GLoadedContent *);
+/* Fournit le nom d'une vue donnée d'un contenu chargé. */
+typedef const char * (* get_loaded_view_name_fc) (const GLoadedContent *, unsigned int);
+
/* Met en place la vue demandée pour un contenu chargé. */
typedef GtkWidget * (* build_loaded_view_fc) (GLoadedContent *, unsigned int);
@@ -79,6 +82,7 @@ struct _GLoadedContentIface
describe_loaded_fc describe; /* Description de contenu */
count_loaded_views_fc count_views; /* Compteur de vues */
+ get_loaded_view_name_fc get_view_name; /* Désignation d'une vue donnée*/
build_loaded_view_fc build_view; /* Mise en place de vues */
get_loaded_view_index_fc get_view_index;/* Récupération d'indice de vue*/
diff --git a/src/analysis/loaded.c b/src/analysis/loaded.c
index 28aea43..4f8cfea 100644
--- a/src/analysis/loaded.c
+++ b/src/analysis/loaded.c
@@ -403,6 +403,35 @@ unsigned int g_loaded_content_count_views(const GLoadedContent *content)
* Paramètres : content = contenu chargé à consulter. *
* index = indice de la vue ciblée. *
* *
+* Description : Fournit le nom d'une vue donnée d'un contenu chargé. *
+* *
+* Retour : Désignation humainement lisible. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *g_loaded_content_get_view_name(const GLoadedContent *content, unsigned int index)
+{
+ const char *result; /* Désignation à retourner */
+ GLoadedContentIface *iface; /* Interface utilisée */
+
+ iface = G_LOADED_CONTENT_GET_IFACE(content);
+
+ assert(index <= g_loaded_content_count_views(content));
+
+ result = iface->get_view_name(content, index);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu chargé à consulter. *
+* index = indice de la vue ciblée. *
+* *
* Description : Met en place la vue demandée pour un contenu chargé. *
* *
* Retour : Composant graphique nouveau. *
diff --git a/src/analysis/loaded.h b/src/analysis/loaded.h
index 66d448a..71e1ff6 100644
--- a/src/analysis/loaded.h
+++ b/src/analysis/loaded.h
@@ -87,6 +87,9 @@ const char *g_loaded_content_describe(const GLoadedContent *, bool);
/* Détermine le nombre de vues disponibles pour un contenu. */
unsigned int g_loaded_content_count_views(const GLoadedContent *);
+/* Fournit le nom d'une vue donnée d'un contenu chargé. */
+const char *g_loaded_content_get_view_name(const GLoadedContent *, unsigned int);
+
/* Met en place la vue demandée pour un contenu chargé. */
GtkWidget *g_loaded_content_build_view(GLoadedContent *, unsigned int);
diff --git a/src/glibext/gdisplayoptions.c b/src/glibext/gdisplayoptions.c
index 8641f59..9ab2063 100644
--- a/src/glibext/gdisplayoptions.c
+++ b/src/glibext/gdisplayoptions.c
@@ -263,6 +263,36 @@ void g_display_options_add(GDisplayOptions *options, const char *name, bool valu
* Paramètres : options = options à consulter. *
* index = indice de l'option concernée. *
* *
+* Description : Fournit la désignation d'une option donnée. *
+* *
+* Retour : Nom humainement lisible. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *g_display_options_get_name(const GDisplayOptions *options, size_t index)
+{
+ char *result; /* Désignation à retourner */
+
+ assert(index < options->count);
+
+ if (index < options->count)
+ result = options->names[index];
+
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : options = options à consulter. *
+* index = indice de l'option concernée. *
+* *
* Description : Fournit la valeur d'une option donnée. *
* *
* Retour : Valeur attribuée. *
diff --git a/src/glibext/gdisplayoptions.h b/src/glibext/gdisplayoptions.h
index 5697385..7549897 100644
--- a/src/glibext/gdisplayoptions.h
+++ b/src/glibext/gdisplayoptions.h
@@ -57,6 +57,9 @@ size_t g_display_options_count(const GDisplayOptions *);
/* Ajoute une nouvelle option à l'ensemble. */
void g_display_options_add(GDisplayOptions *, const char *, bool);
+/* Fournit la désignation d'une option donnée. */
+const char *g_display_options_get_name(const GDisplayOptions *, size_t);
+
/* Fournit la valeur d'une option donnée. */
bool g_display_options_get(const GDisplayOptions *, size_t);
diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c
index 706e8f7..97a4276 100644
--- a/src/gtkext/gtkdisplaypanel.c
+++ b/src/gtkext/gtkdisplaypanel.c
@@ -91,14 +91,14 @@ static void gtk_display_panel_update_adjustment(GtkDisplayPanel *, GtkOrientatio
/* Réagit à un défilement chez une barre associée au composant.*/
static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDisplayPanel *);
-/* Réagit à un changement des règles d'affichage. */
-static void on_view_panel_binary_option_change(GLoadedBinary *, BinaryView, BufferLineColumn, GtkDisplayPanel *);
-
/* ----------------------- INTERFACE DE PANNEAU DE CHARGEMENT ----------------------- */
+/* Réagit à un changement des règles d'affichage. */
+static void on_display_panel_option_change(GDisplayOptions *, size_t, bool, GtkDisplayPanel *);
+
/* Associe à un panneau d'affichage un binaire chargé. */
static void gtk_display_panel_set_content(GtkDisplayPanel *, GLoadedContent *);
@@ -860,34 +860,6 @@ void gtk_display_panel_draw_border(GtkDisplayPanel *panel, cairo_t *cr)
/******************************************************************************
* *
-* Paramètres : binary = bianire dont les consignes d'affichage ont évolué. *
-* view = type d'affichage à considérer. *
-* col = colonne dont le statut a changé. *
-* panel = composant GTK à consulter. *
-* *
-* Description : Réagit à un changement des règles d'affichage. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void on_view_panel_binary_option_change(GLoadedBinary *binary, BinaryView view, BufferLineColumn col, GtkDisplayPanel *panel)
-{
- if (panel->view_index == view)
- {
- gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel)));
- gtk_widget_queue_resize(GTK_WIDGET(panel));
- gtk_widget_queue_draw(GTK_WIDGET(panel));
-
- }
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : panel = composant GTK à consulter. *
* *
* Description : Indique la position courante du curseur. *
@@ -1047,6 +1019,30 @@ void gtk_display_panel_compute_relative_coords(GtkDisplayPanel *panel, gint *x,
/******************************************************************************
* *
+* Paramètres : options = options à mettre à jour. *
+* index = indice de l'option concernée. *
+* value = nouvelle valeur à intégrer. *
+* panel = composant GTK à consulter. *
+* *
+* Description : Réagit à un changement des règles d'affichage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_display_panel_option_change(GDisplayOptions *options, size_t index, bool value, GtkDisplayPanel *panel)
+{
+ gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel)));
+ gtk_widget_queue_resize(GTK_WIDGET(panel));
+ gtk_widget_queue_draw(GTK_WIDGET(panel));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : panel = composant GTK à mettre à jour. *
* content = binaire associé à intégrer. *
* *
@@ -1069,7 +1065,7 @@ static void gtk_display_panel_set_content(GtkDisplayPanel *panel, GLoadedContent
if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach != NULL) /* REMME */
GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach(panel, panel->binary);
- g_signal_connect(content, "value-changed", G_CALLBACK(on_view_panel_binary_option_change), panel);
+ g_signal_connect(panel->options, "value-changed", G_CALLBACK(on_display_panel_option_change), panel);
}
diff --git a/src/gui/editor.c b/src/gui/editor.c
index 5034104..9fffde8 100644
--- a/src/gui/editor.c
+++ b/src/gui/editor.c
@@ -1391,10 +1391,10 @@ static void on_dock_item_switch(GtkDockStation *station, GtkWidget *widget, gpoi
GLoadedPanel *panel; /* Vue du contenu chargé */
GLoadedContent *content; /* Contenu en cours d'édition */
- if (GTK_IS_SCROLLED_WINDOW(widget))
+ if (!G_IS_LOADED_PANEL(widget) && GTK_IS_SCROLLED_WINDOW(widget))
widget = gtk_bin_get_child(GTK_BIN(widget));
- if (GTK_IS_VIEWPORT(widget))
+ if (!G_IS_LOADED_PANEL(widget) && GTK_IS_VIEWPORT(widget))
widget = gtk_bin_get_child(GTK_BIN(widget));
if (G_IS_LOADED_PANEL(widget))
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 *);