From ab4d9d3afa6185275323a40729193102c99ea5c6 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 15 Aug 2020 14:52:38 +0200 Subject: Rebuilt the main interface using Glade. --- plugins/pychrysalide/gui/core/global.c | 43 ++ plugins/pychrysalide/gui/menubar.c | 323 +--------- plugins/ropgadgets/plugin.c | 27 +- src/gui/Makefile.am | 18 + src/gui/agroup.c | 37 +- src/gui/agroup.h | 5 +- src/gui/core/core.c | 14 +- src/gui/core/global.c | 53 ++ src/gui/core/global.h | 6 + src/gui/editor.c | 215 ++++--- src/gui/editor.ui | 883 +++++++++++++++++++++++++ src/gui/gresource.xml | 6 + src/gui/menubar.c | 297 +-------- src/gui/menubar.h | 27 +- src/gui/menus/Makefile.am | 1 - src/gui/menus/binary.c | 190 +++--- src/gui/menus/binary.h | 10 +- src/gui/menus/debug.c | 92 +-- src/gui/menus/debug.h | 4 +- src/gui/menus/edition.c | 493 ++++++-------- src/gui/menus/edition.h | 9 +- src/gui/menus/file.c | 59 +- src/gui/menus/file.h | 4 +- src/gui/menus/help.c | 39 +- src/gui/menus/help.h | 4 +- src/gui/menus/options.c | 31 +- src/gui/menus/options.h | 7 +- src/gui/menus/plugins.c | 63 -- src/gui/menus/plugins.h | 38 -- src/gui/menus/project.c | 173 +++-- src/gui/menus/project.h | 7 +- src/gui/menus/view.c | 1099 ++++++++++++++++---------------- src/gui/menus/view.h | 16 +- 33 files changed, 2229 insertions(+), 2064 deletions(-) create mode 100644 src/gui/editor.ui create mode 100644 src/gui/gresource.xml delete mode 100644 src/gui/menus/plugins.c delete mode 100644 src/gui/menus/plugins.h diff --git a/plugins/pychrysalide/gui/core/global.c b/plugins/pychrysalide/gui/core/global.c index 26d51cb..a3b62ee 100644 --- a/plugins/pychrysalide/gui/core/global.c +++ b/plugins/pychrysalide/gui/core/global.c @@ -25,6 +25,7 @@ #include "global.h" +#include #include @@ -36,6 +37,9 @@ +/* Fournit l'adresse du constructeur principal de l'éditeur. */ +static PyObject *py_global_get_editor_builder(PyObject *, PyObject *); + /* Fournit l'adresse de la fenêtre principale de l'éditeur. */ static PyObject *py_global_get_editor_window(PyObject *, PyObject *); @@ -49,6 +53,44 @@ static PyObject *py_global_get_current_content(PyObject *, PyObject *); * Paramètres : self = objet Python concerné par l'appel. * * args = non utilisé ici. * * * +* Description : Fournit l'adresse du constructeur principal de l'éditeur. * +* * +* Retour : Constructeur principal référencé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_global_get_editor_builder(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance Python à retourner */ + GtkBuilder *builder; /* Constructeur principal */ + +#define GLOBAL_GET_EDITOR_BUILDER_METHOD PYTHON_METHOD_DEF \ +( \ + get_editor_builder, "", \ + METH_NOARGS, py_global, \ + "Provide access to the Chrysalide main window builder.\n" \ + "\n" \ + "The result should be an instance of Gtk.Builder, never None." \ +) + + builder = get_editor_builder(); + assert(builder != NULL); + + result = pygobject_new(G_OBJECT(builder)); + g_object_unref(G_OBJECT(builder)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* args = non utilisé ici. * +* * * Description : Fournit l'adresse de la fenêtre principale de l'éditeur. * * * * Retour : Fenêtre principale référencée. * @@ -150,6 +192,7 @@ bool populate_gui_core_module_with_global(void) PyObject *module; /* Module à recompléter */ static PyMethodDef py_global_methods[] = { + GLOBAL_GET_EDITOR_BUILDER_METHOD, GLOBAL_GET_EDITOR_WINDOW_METHOD, GLOBAL_GET_CURRENT_CONTENT_METHOD, { NULL } diff --git a/plugins/pychrysalide/gui/menubar.c b/plugins/pychrysalide/gui/menubar.c index 0234fba..5c6270e 100644 --- a/plugins/pychrysalide/gui/menubar.c +++ b/plugins/pychrysalide/gui/menubar.c @@ -47,296 +47,9 @@ " 'menubar' as key." -/* Fournit le composant GTK associé au menu "Fichier". */ -static PyObject *py_menu_bar_get_file_menu(PyObject *, void *); +/* Fournit le constructeur associé à la barre de menus. */ +static PyObject *py_menu_bar_get_builder(PyObject *self, void *); -/* Fournit le composant GTK associé au menu "Edition". */ -static PyObject *py_menu_bar_get_edition_menu(PyObject *, void *); - -/* Fournit le composant GTK associé au menu "Affichage". */ -static PyObject *py_menu_bar_get_view_menu(PyObject *, void *); - -/* Fournit le composant GTK associé au menu "Projet". */ -static PyObject *py_menu_bar_get_project_menu(PyObject *, void *); - -/* Fournit le composant GTK associé au menu "Binaire". */ -static PyObject *py_menu_bar_get_binary_menu(PyObject *, void *); - -/* Fournit le composant GTK associé au menu "Débogage". */ -static PyObject *py_menu_bar_get_debug_menu(PyObject *, void *); - -/* Fournit le composant GTK associé au menu "Options". */ -static PyObject *py_menu_bar_get_options_menu(PyObject *, void *); - -/* Fournit le composant GTK associé au menu "Aide". */ -static PyObject *py_menu_bar_get_help_menu(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le composant GTK associé au menu "Fichier". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_menu_bar_get_file_menu(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ - -#define MENU_BAR_FILE_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - file_menu, py_menu_bar, \ - "File menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ -) - - bar = G_MENU_BAR(pygobject_get(self)); - - menu = g_menu_bar_get_file_menu(bar); - - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le composant GTK associé au menu "Edition". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_menu_bar_get_edition_menu(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ - -#define MENU_BAR_EDITION_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - edition_menu, py_menu_bar, \ - "Edition menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ -) - - bar = G_MENU_BAR(pygobject_get(self)); - - menu = g_menu_bar_get_edition_menu(bar); - - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le composant GTK associé au menu "Affichage". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_menu_bar_get_view_menu(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ - -#define MENU_BAR_VIEW_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - view_menu, py_menu_bar, \ - "View menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ -) - - bar = G_MENU_BAR(pygobject_get(self)); - - menu = g_menu_bar_get_view_menu(bar); - - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le composant GTK associé au menu "Projet". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_menu_bar_get_project_menu(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ - -#define MENU_BAR_PROJECT_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - project_menu, py_menu_bar, \ - "Project menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ -) - - bar = G_MENU_BAR(pygobject_get(self)); - - menu = g_menu_bar_get_project_menu(bar); - - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le composant GTK associé au menu "Binaire". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_menu_bar_get_binary_menu(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ - -#define MENU_BAR_BINARY_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - binary_menu, py_menu_bar, \ - "Binary menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ -) - - bar = G_MENU_BAR(pygobject_get(self)); - - menu = g_menu_bar_get_binary_menu(bar); - - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le composant GTK associé au menu "Débogage". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_menu_bar_get_debug_menu(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ - -#define MENU_BAR_DEBUG_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - debug_menu, py_menu_bar, \ - "Debug menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ -) - - bar = G_MENU_BAR(pygobject_get(self)); - - menu = g_menu_bar_get_debug_menu(bar); - - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le composant GTK associé au menu "Options". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_menu_bar_get_options_menu(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ - -#define MENU_BAR_OPTIONS_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - options_menu, py_menu_bar, \ - "Options menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ -) - - bar = G_MENU_BAR(pygobject_get(self)); - - menu = g_menu_bar_get_options_menu(bar); - - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); - - return result; - -} /****************************************************************************** @@ -344,33 +57,32 @@ static PyObject *py_menu_bar_get_options_menu(PyObject *self, void *closure) * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Fournit le composant GTK associé au menu "Aide". * +* Description : Fournit le constructeur associé à la barre de menus. * * * -* Retour : Instance de composant graphique correspondant au menu visé. * +* Retour : Instance du constructeur (principal) associé à la barre. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_menu_bar_get_help_menu(PyObject *self, void *closure) +static PyObject *py_menu_bar_get_builder(PyObject *self, void *closure) { PyObject *result; /* Valeur à retourner */ GMenuBar *bar; /* Elément à consulter */ - GtkWidget *menu; /* Composant GTK visé */ + GtkBuilder *builder; /* Instance GTK visée */ -#define MENU_BAR_HELP_MENU_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - help_menu, py_menu_bar, \ - "Help menu included in the main menubar, as a" \ - " Gtk.MenuItem instance." \ +#define MENU_BAR_BUILDER_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + builder, py_menu_bar, \ + "Builder linked to the main menubar, as a Gtk.Builder instance." \ ) bar = G_MENU_BAR(pygobject_get(self)); - menu = g_menu_bar_get_help_menu(bar); + builder = g_menu_bar_get_builder(bar); - result = pygobject_new(G_OBJECT(menu)); - g_object_unref(G_OBJECT(menu)); + result = pygobject_new(G_OBJECT(builder)); + g_object_unref(G_OBJECT(builder)); return result; @@ -396,14 +108,7 @@ PyTypeObject *get_python_menu_bar_type(void) }; static PyGetSetDef py_menu_bar_getseters[] = { - MENU_BAR_FILE_MENU_ATTRIB, - MENU_BAR_EDITION_MENU_ATTRIB, - MENU_BAR_VIEW_MENU_ATTRIB, - MENU_BAR_PROJECT_MENU_ATTRIB, - MENU_BAR_BINARY_MENU_ATTRIB, - MENU_BAR_DEBUG_MENU_ATTRIB, - MENU_BAR_OPTIONS_MENU_ATTRIB, - MENU_BAR_HELP_MENU_ATTRIB, + MENU_BAR_BUILDER_ATTRIB, { NULL } }; diff --git a/plugins/ropgadgets/plugin.c b/plugins/ropgadgets/plugin.c index c4c33dc..836717c 100644 --- a/plugins/ropgadgets/plugin.c +++ b/plugins/ropgadgets/plugin.c @@ -70,27 +70,34 @@ static void mcb_plugins_list_rop_gadgets(GtkMenuItem *, gpointer); G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) { bool result; /* Bilan à retourner */ - GObject *ref; /* Espace de référencements */ - GtkContainer *menubar; /* Support pour éléments */ + GtkBuilder *builder; /* Constructeur principal */ + GtkMenuItem *item; /* Menu à compléter */ + GtkContainer *menu; /* Support pour éléments */ GtkWidget *submenuitem; /* Sous-élément de menu */ result = false; - ref = G_OBJECT(get_editor_window()); - if (ref == NULL) goto no_editor; + builder = get_editor_builder(); + if (builder == NULL) + { + result = true; + goto no_editor; + } - menubar = GTK_CONTAINER(g_object_get_data(ref, "menubar_plugins")); - if (menubar == NULL) goto no_menubar; + item = GTK_MENU_ITEM(gtk_builder_get_object(builder, "binary")); + if (item == NULL) goto no_binary_menu; - submenuitem = qck_create_menu_item(ref, "mnu_plugins_ropgadgets", _("List ROP gadgets"), + menu = GTK_CONTAINER(gtk_menu_item_get_submenu(item)); + + submenuitem = qck_create_menu_item(G_OBJECT(item), "binary_ropgadgets", _("List ROP gadgets"), G_CALLBACK(mcb_plugins_list_rop_gadgets), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + gtk_container_add(GTK_CONTAINER(menu), submenuitem); result = true; - no_menubar: + no_binary_menu: - g_object_unref(ref); + g_object_unref(G_OBJECT(builder)); no_editor: diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 1bd4130..135e724 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,6 +1,11 @@ +BUILT_SOURCES = resources.h resources.c + noinst_LTLIBRARIES = libgui.la +UI_FILES = \ + editor.ui + libgui_la_SOURCES = \ agroup.h agroup.c \ editor.h editor.c \ @@ -9,6 +14,7 @@ libgui_la_SOURCES = \ menubar.h menubar.c \ panel-int.h \ panel.h panel.c \ + resources.h resources.c \ status.h status.c \ theme.h theme.c @@ -32,3 +38,15 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) SUBDIRS = core dialogs menus panels tb + + +resources.c: gresource.xml $(UI_FILES) + glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name gui gresource.xml + +resources.h: gresource.xml + glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name gui gresource.xml + + +CLEANFILES = resources.h resources.c + +EXTRA_DIST = gresource.xml $(UI_FILES) diff --git a/src/gui/agroup.c b/src/gui/agroup.c index 00dbaef..435f005 100644 --- a/src/gui/agroup.c +++ b/src/gui/agroup.c @@ -28,9 +28,6 @@ #include -#include "core/global.h" - - /* Détermine si un élément graphique peut être actionné. */ static gboolean enable_accel_all_the_time(GtkWidget *, guint, gpointer); @@ -39,7 +36,6 @@ static gboolean enable_accel_all_the_time(GtkWidget *, guint, gpointer); static gboolean enable_accel_with_care(GtkWidget *, guint, gpointer); - /* Suivi des autorisations suivant la zone active. */ static bool _entry_focused = false; @@ -47,6 +43,31 @@ static bool _entry_focused = false; /****************************************************************************** * * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* * +* Description : Précise l'accès aux menus avec raccourcis. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void setup_accel_group_callbacks(GtkBuilder *builder) +{ + +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) + + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(enable_accel_all_the_time), + DEFINE_CALLBACK(enable_accel_with_care), + NULL); + +} + + +/****************************************************************************** +* * * Paramètres : widget = composant graphique à analyser. * * signal_id = identifiant de signal. * * unused = adresse non utilisée ici. * @@ -97,9 +118,9 @@ static gboolean enable_accel_with_care(GtkWidget *widget, guint signal_id, gpoin /****************************************************************************** * * -* Paramètres : widget = composant GTK à traiter. * +* Paramètres : builder = constructeur associé à l'interface principale. * +* widget = composant GTK à traiter. * * accelerator = description sous forme de chaîne de caractères.* -* group = groupe d'appartenance du raccourci. * * * * Description : Ajoute un accélérateur à un composant graphique. * * * @@ -109,7 +130,7 @@ static gboolean enable_accel_with_care(GtkWidget *widget, guint signal_id, gpoin * * ******************************************************************************/ -void add_accelerator_to_widget(GtkWidget *widget, const char *accelerator) +void add_accelerator_to_widget(GtkBuilder *builder, GtkWidget *widget, const char *accelerator) { guint key; /* Touche concernée */ GdkModifierType mods; /* Eventuels modificateurs */ @@ -122,7 +143,7 @@ void add_accelerator_to_widget(GtkWidget *widget, const char *accelerator) else g_signal_connect(widget, "can-activate-accel", G_CALLBACK(enable_accel_all_the_time), NULL); - group = get_accel_group(); + group = GTK_ACCEL_GROUP(gtk_builder_get_object(builder, "accelgroup")); gtk_widget_add_accelerator(widget, "activate", group, key, mods, GTK_ACCEL_VISIBLE); diff --git a/src/gui/agroup.h b/src/gui/agroup.h index 30a63f9..3e0070a 100644 --- a/src/gui/agroup.h +++ b/src/gui/agroup.h @@ -30,8 +30,11 @@ +/* Précise l'accès aux menus avec raccourcis. */ +void setup_accel_group_callbacks(GtkBuilder *); + /* Ajoute un accélérateur à un composant graphique. */ -void add_accelerator_to_widget(GtkWidget *, const char *); +void add_accelerator_to_widget(GtkBuilder *, GtkWidget *, const char *); /* Prend note d'un changement de focus sur une zone de saisie. */ gboolean track_focus_change_in_text_area(GtkWidget *, GdkEventFocus *, gpointer); diff --git a/src/gui/core/core.c b/src/gui/core/core.c index 5cfa1ed..0c1e3f3 100644 --- a/src/gui/core/core.c +++ b/src/gui/core/core.c @@ -25,6 +25,7 @@ #include "global.h" +#include "items.h" #include "panels.h" #include "theme.h" #include "../menubar.h" @@ -51,8 +52,8 @@ bool load_all_gui_components(void) { bool result; /* Bilan à retourner */ - GObject *ref; /* Espace de référencements */ GMenuBar *bar; /* Gestion des menus */ + GtkBuilder *builder; /* Constructeur principal */ GtkMenuItem *submenuitem; /* Sous-élément de menu */ result = true; @@ -63,13 +64,18 @@ bool load_all_gui_components(void) * Charge une liste initiale pour activer les raccourcis clavier. */ - ref = get_global_ref(); + bar = G_MENU_BAR(find_editor_item_by_key("menubar")); - bar = G_MENU_BAR(g_object_get_data(ref, "menubar")); - submenuitem = GTK_MENU_ITEM(g_object_get_data(ref, "mnu_view_side_panels")); + builder = get_editor_builder(); + + submenuitem = GTK_MENU_ITEM(gtk_builder_get_object(builder, "view_side_panels")); mcb_view_update_side_panels_list(submenuitem, bar); + g_object_unref(G_OBJECT(builder)); + + g_object_unref(G_OBJECT(bar)); + return result; } diff --git a/src/gui/core/global.c b/src/gui/core/global.c index a9fd82f..c7e9a34 100644 --- a/src/gui/core/global.c +++ b/src/gui/core/global.c @@ -25,6 +25,9 @@ +/* Constructeur principal de l'éditeur */ +static GtkBuilder *_builder = NULL; + /* Fenêtre principale de l'éditeur */ static GtkWindow *_editor = NULL; @@ -53,6 +56,56 @@ G_LOCK_DEFINE_STATIC(_cv_mutex); * * * Paramètres : editor = fenêtre principale à référencer. * * * +* Description : Note l'adresse du constructeur principal de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_editor_builder(GtkBuilder *builder) +{ + g_clear_object(&_builder); + + _builder = builder; + + if (builder != NULL) + g_object_ref(G_OBJECT(builder)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit l'adresse du constructeur principal de l'éditeur. * +* * +* Retour : Constructeur principal référencé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkBuilder *get_editor_builder(void) +{ + GtkBuilder *result; /* Instance à retourner */ + + result = _builder; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : editor = fenêtre principale à référencer. * +* * * Description : Note l'adresse de la fenêtre principale de l'éditeur. * * * * Retour : - * diff --git a/src/gui/core/global.h b/src/gui/core/global.h index a624ab7..7d3e67b 100644 --- a/src/gui/core/global.h +++ b/src/gui/core/global.h @@ -32,6 +32,12 @@ +/* Note l'adresse du constructeur principal de l'éditeur. */ +void set_editor_builder(GtkBuilder *); + +/* Fournit l'adresse du constructeur principal de l'éditeur. */ +GtkBuilder *get_editor_builder(void); + /* Note l'adresse de la fenêtre principale de l'éditeur. */ void set_editor_window(GtkWindow *); diff --git a/src/gui/editor.c b/src/gui/editor.c index 01d7264..b444752 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -46,6 +46,7 @@ #include "tb/portions.h" #include "../common/extstr.h" #include "../core/global.h" +#include "../core/logs.h" #include "../core/params.h" #include "../glibext/chrysamarshal.h" #include "../glibext/named.h" @@ -70,15 +71,17 @@ static GtkBuilder *_load_dialog_builder = NULL; /* Met en place la liste des icônes de l'éditeur. */ static GList *build_editor_icons_list(void); - /* Construit la fenêtre de l'éditeur. */ GtkWidget *create_editor(void); +/* Applique tous les enregistrements de signaux. */ +static void connect_all_editor_signals(GtkBuilder *, GObject *, const gchar *, const gchar *, GObject *, GConnectFlags, gpointer); + /* Quitte le programme en sortie de la boucle de GTK. */ static gboolean on_delete_editor(GtkWidget *, GdkEvent *, gpointer); /* Quitte le programme en sortie de la boucle de GTK. */ -static void on_destroy_editor(GtkWidget *, GObject *); +static void on_destroy_editor(GtkWidget *, gpointer); @@ -86,10 +89,10 @@ static void on_destroy_editor(GtkWidget *, GObject *); /* Réagit à un changement d'état pour l'éditeur. */ -static gboolean on_window_state_changed(GtkWidget *, GdkEvent *, GObject *); +static gboolean on_window_state_changed(GtkWidget *, GdkEvent *, GtkBuilder *); /* Suit la frappe de touches sur la fenêtre principale. */ -static gboolean on_key_event(GtkWidget *, GdkEventKey *, GObject *); +static gboolean on_key_event(GtkWidget *, GdkEventKey *, GtkBuilder *); @@ -200,34 +203,23 @@ static GList *build_editor_icons_list(void) GtkWidget *create_editor(void) { GtkWidget *result; /* Fenêtre à renvoyer */ - - + GtkBuilder *builder; /* Constructeur principal */ bool hide; /* Cachette de la barre ? */ bool maximized; /* Affichage en plein écran ? */ GList *icons; /* Liste d'images dimensionnées*/ - GObject *ref; /* Version de référence */ - GtkAccelGroup *accgroup; /* Groupe de raccourcis clavier*/ + GtkBox *vbox; /* Rangements verticaux */ GEditorItem *editem; /* Menus réactifs principaux */ - GtkWidget *menuboard; /* Barre de menus principale */ - GtkWidget *toolbar; /* Barre d'outils */ GtkWidget *grid; /* Affichage en tuiles */ - - GtkWidget *vbox1; - - - GtkWidget *widget; /* Composant à intégrer */ + /* Mise en place des premières pierres */ + builder = gtk_builder_new_from_resource("/org/chrysalide/gui/editor.ui"); + set_editor_builder(builder); - result = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_position(GTK_WINDOW(result), GTK_WIN_POS_CENTER); - gtk_container_set_border_width(GTK_CONTAINER(result), 4); - gtk_window_set_title(GTK_WINDOW(result), _("Chrysalide")); - - g_object_ref_sink(G_OBJECT(result)); + result = GTK_WIDGET(gtk_builder_get_object(builder, "window")); set_editor_window(GTK_WINDOW(result)); @@ -241,45 +233,30 @@ GtkWidget *create_editor(void) gtk_window_set_icon_list(GTK_WINDOW(result), icons); g_list_free_full(icons, (GDestroyNotify)g_object_unref); - ref = G_OBJECT(result); - - g_signal_connect(ref, "delete-event", G_CALLBACK(on_delete_editor), NULL); - g_signal_connect(ref, "destroy", G_CALLBACK(on_destroy_editor), ref); - - g_signal_connect(ref, "window-state-event", G_CALLBACK(on_window_state_changed), ref); - g_signal_connect(ref, "key-press-event", G_CALLBACK(on_key_event), ref); - g_signal_connect(ref, "key-release-event", G_CALLBACK(on_key_event), ref); - - accgroup = gtk_accel_group_new(); - set_accel_group(accgroup); - - gtk_window_add_accel_group(GTK_WINDOW(result), accgroup); +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(on_delete_editor), + DEFINE_CALLBACK(on_destroy_editor), + DEFINE_CALLBACK(on_window_state_changed), + DEFINE_CALLBACK(on_key_event), + NULL); + setup_accel_group_callbacks(builder); - vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); - gtk_widget_show(vbox1); - gtk_container_add(GTK_CONTAINER(result), vbox1); + /* Constitution du corps */ + vbox = GTK_BOX(gtk_builder_get_object(builder, "vbox")); /* Intégration des menus */ - editem = g_menu_bar_new(ref); + editem = g_menu_bar_new(builder); register_editor_item(editem); - menuboard = g_editor_item_get_widget(editem); - gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); - g_object_unref(G_OBJECT(menuboard)); - - g_object_set_data(ref, "menubar", editem); - g_object_set_data(ref, "menuboard", menuboard); - - gtk_widget_hide(menuboard); - /* Barre d'outils */ - toolbar = build_editor_toolbar(ref); - gtk_box_pack_start(GTK_BOX(vbox1), toolbar, FALSE, FALSE, 0); + toolbar = build_editor_toolbar(G_OBJECT(result)); + gtk_box_pack_start(vbox, toolbar, FALSE, FALSE, 0); /* Coeur de la fenêtre principale */ @@ -290,7 +267,7 @@ GtkWidget *create_editor(void) g_signal_connect(grid, "station-created", G_CALLBACK(on_dock_station_created), NULL); - gtk_box_pack_start(GTK_BOX(vbox1), grid, TRUE, TRUE, 0); + gtk_box_pack_start(vbox, grid, TRUE, TRUE, 0); /* Barre de statut générale */ @@ -298,16 +275,12 @@ GtkWidget *create_editor(void) register_editor_item(editem); widget = g_editor_item_get_widget(editem); - gtk_box_pack_start(GTK_BOX(vbox1), widget, FALSE, FALSE, 0); - g_object_unref(G_OBJECT(widget)); - + gtk_box_pack_start(vbox, widget, FALSE, FALSE, 0); /* Autre */ /* ... = */prepare_drag_and_drop_window(); - - /* Actualisation des contenus */ register_project_change_notification(notify_editor_project_change); @@ -319,6 +292,10 @@ GtkWidget *create_editor(void) _load_dialog = create_loading_dialog(GTK_WINDOW(result), &_load_dialog_builder); + /* Connexions finales */ + + gtk_builder_connect_signals_full(builder, connect_all_editor_signals, NULL); + return result; } @@ -326,9 +303,88 @@ GtkWidget *create_editor(void) /****************************************************************************** * * +* Paramètres : builder = constructeur (principal) visé par l'opération. * +* obj = objet à traiter. * +* sig_name = désignation du signal à traiter. * +* hdl_name = désignation du gestionnaire à employer. * +* conn_obj = approche alternative si différent de NULL. * +* flags = indications à prendre en compte. * +* unused = adresse non utilisée ici. * +* * +* Description : Applique tous les enregistrements de signaux. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void connect_all_editor_signals(GtkBuilder *builder, GObject *obj, const gchar *sig_name, const gchar *hdl_name, GObject *conn_obj, GConnectFlags flags, gpointer unused) +{ + GCallback func; /* Gestionnaire effectif */ + GModule *module; /* Module courant en soutien */ + GMenuBar *bar; /* Gestion des menus */ + void *arg; /* Données utilisateur choisie */ + + /* Recherche de l'adresse de renvoi */ + + func = gtk_builder_lookup_callback_symbol(builder, hdl_name); + + if (!func) + { + if (g_module_supported()) + module = g_module_open(NULL, G_MODULE_BIND_LAZY); + + if (module == NULL) + { + log_simple_message(LMT_ERROR, _("A working GModule is required!")); + goto exit; + } + + if (!g_module_symbol(module, hdl_name, (gpointer)&func)) + { + log_variadic_message(LMT_ERROR, _("Could not find signal handler '%s'"), hdl_name); + g_module_close(module); + goto exit; + } + + g_module_close(module); + + } + + /* Connexion du signal à son gestionnaire */ + + if (conn_obj != NULL) + g_signal_connect_object(obj, sig_name, func, conn_obj, flags); + + else + { + if (strncmp(hdl_name, "mcb_", 4) == 0) + { + bar = G_MENU_BAR(find_editor_item_by_key("menubar")); + arg = bar; + g_object_unref(G_OBJECT(bar)); + } + + else + arg = builder; + + g_signal_connect_data(obj, sig_name, func, arg, NULL, flags); + + } + + exit: + + ; + +} + + +/****************************************************************************** +* * * Paramètres : widget = fenêtre de l'éditeur de préférences. * * event = informations liées à l'événement. * -* data = adresse non utilisée ici. * +* unused = adresse non utilisée ici. * * * * Description : Quitte le programme en sortie de la boucle de GTK. * * * @@ -338,7 +394,7 @@ GtkWidget *create_editor(void) * * ******************************************************************************/ -static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer data) +static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer unused) { gboolean result; /* Continuation à retourner */ bool skip; /* Saut de la vérification ? */ @@ -397,7 +453,7 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da /****************************************************************************** * * * Paramètres : widget = fenêtre de l'éditeur de préférences. * -* ref = espace de référencement global. * +* unused = adresse non utilisée ici. * * * * Description : Quitte le programme en sortie de la boucle de GTK. * * * @@ -407,7 +463,7 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da * * ******************************************************************************/ -static void on_destroy_editor(GtkWidget *widget, GObject *ref) +static void on_destroy_editor(GtkWidget *widget, gpointer unused) { /* Fermeture propre */ @@ -433,9 +489,9 @@ static void on_destroy_editor(GtkWidget *widget, GObject *ref) /****************************************************************************** * * -* Paramètres : widget = fenêtre principale de l'éditeur. * -* event = informations liées à l'événement. * -* ref = espace de référencement global. * +* Paramètres : widget = fenêtre principale de l'éditeur. * +* event = informations liées à l'événement. * +* builder = constructeur principal de l'interface. * * * * Description : Réagit à un changement d'état pour l'éditeur. * * * @@ -445,12 +501,12 @@ static void on_destroy_editor(GtkWidget *widget, GObject *ref) * * ******************************************************************************/ -static gboolean on_window_state_changed(GtkWidget *widget, GdkEvent *event, GObject *ref) +static gboolean on_window_state_changed(GtkWidget *widget, GdkEvent *event, GtkBuilder *builder) { gboolean result; /* Consommation à retourner */ GdkWindow *window; /* Fenêtre principale */ GdkWindowState state; /* Statut courant d'affichage */ - GtkWidget *menuboard; /* Planche de menu à traiter */ + GtkWidget *menubar; /* Planche de menu à traiter */ result = FALSE; @@ -460,10 +516,10 @@ static gboolean on_window_state_changed(GtkWidget *widget, GdkEvent *event, GObj if ((state & GDK_WINDOW_STATE_FOCUSED) == 0) { - menuboard = GTK_WIDGET(g_object_get_data(ref, "menuboard")); + menubar = GTK_WIDGET(gtk_builder_get_object(builder, "menubar")); - if (gtk_widget_get_visible(menuboard)) - gtk_widget_hide(menuboard); + if (gtk_widget_get_visible(menubar)) + gtk_widget_hide(menubar); } @@ -474,9 +530,9 @@ static gboolean on_window_state_changed(GtkWidget *widget, GdkEvent *event, GObj /****************************************************************************** * * -* Paramètres : widget = fenêtre principale de l'éditeur. * -* event = informations liées à l'événement. * -* ref = espace de référencement global. * +* Paramètres : widget = fenêtre principale de l'éditeur. * +* event = informations liées à l'événement. * +* builder = constructeur principal de l'interface. * * * * Description : Suit la frappe de touches sur la fenêtre principale. * * * @@ -486,27 +542,27 @@ static gboolean on_window_state_changed(GtkWidget *widget, GdkEvent *event, GObj * * ******************************************************************************/ -static gboolean on_key_event(GtkWidget *widget, GdkEventKey *event, GObject *ref) +static gboolean on_key_event(GtkWidget *widget, GdkEventKey *event, GtkBuilder *builder) { gboolean result; /* Consommation à retourner */ - GtkWidget *menuboard; /* Planche de menu à traiter */ + GtkWidget *menubar; /* Planche de menu à traiter */ result = FALSE; result = (event->keyval == GDK_KEY_Alt_L); - menuboard = GTK_WIDGET(g_object_get_data(ref, "menuboard")); + menubar = GTK_WIDGET(gtk_builder_get_object(builder, "menubar")); - if (gtk_widget_get_visible(menuboard)) + if (gtk_widget_get_visible(menubar)) { if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KEY_Alt_L) - gtk_widget_hide(menuboard); + gtk_widget_hide(menubar); } else { if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KEY_Alt_L) - gtk_widget_show(menuboard); + gtk_widget_show(menubar); } @@ -726,6 +782,7 @@ static bool add_side_panel_to_menu(GPanelItem *panel, GtkContainer *support) char *key; /* Désignation de l'entrée */ GtkWidget *submenuitem; /* Sous-élément de menu */ const char *bindings; /* Raccourcis clavier bruts */ + GtkBuilder *builder; /* Constructeur principal */ /* Profil qui ne cadre pas ? */ @@ -747,7 +804,11 @@ static bool add_side_panel_to_menu(GPanelItem *panel, GtkContainer *support) bindings = gtk_panel_item_get_key_bindings(panel); if (bindings != NULL) - add_accelerator_to_widget(submenuitem, bindings); + { + builder = get_editor_builder(); + add_accelerator_to_widget(builder, submenuitem, bindings); + g_object_unref(G_OBJECT(builder)); + } gtk_container_add(support, submenuitem); diff --git a/src/gui/editor.ui b/src/gui/editor.ui new file mode 100644 index 0000000..fa832de --- /dev/null +++ b/src/gui/editor.ui @@ -0,0 +1,883 @@ + + + + + + + + application/chrysalide.project + + + + False + 4 + Chrysalide + center + + + + + + + + + + + True + False + vertical + + + False + + + True + False + _File + True + + + True + False + + + True + False + New project + True + + + + + + + + True + False + + + + + True + False + Open project + True + + + + + + + + True + False + Recent projects... + True + + + True + False + recent_project_filter + 10 + + + + + + + True + False + + + + + True + False + Save project + True + + + + + + + + True + False + Save project as... + True + + + + + + True + False + + + + + True + False + Quit + True + + + + + + + + + + + + True + False + _Edition + True + + + True + False + + + True + False + Go to address... + True + + + + + + + + True + False + + + + + True + False + Numeric operand + True + + + True + False + + + True + False + Hexadecimal + True + + + + + + + + True + False + Decimal + True + + + + + + + + True + False + Octal + True + + + + + + + + True + False + Binary + True + + + + + + + + True + False + + + + + True + False + Default + True + + + + + + + + + + True + False + + + + + True + False + Go back + True + + + + + + + + True + False + Follow the reference + True + + + + + + + + True + False + List all references leading to... + True + + + + + + + + True + False + + + + + True + False + Bookmarks + True + + + True + False + + + True + False + Toggle at current location + True + + + + + + + + True + False + Delete all bookmarks + True + + + + + + + + + + True + False + Comment + True + + + True + False + + + True + False + Enter a comment... + True + + + + + + + + True + False + Enter a repeatable comment... + True + + + + + + + + True + False + Enter a comment in the previous line... + True + + + + + + + + True + False + Enter a comment in the next line... + True + + + + + + + + + + + + + + + + True + False + _View + True + + + True + False + + + True + False + Side panels + True + + + + + + True + False + + + + + True + False + Switch to next + True + + + + + + + + True + False + Switch to previous + True + + + + + + + + True + False + + + + + True + False + Zoom in + True + + + + + + + + True + False + Zoom out + True + + + + + + + + True + False + Reset zoom + True + + + + + + + + True + False + + + + + True + False + + + + + True + False + Full screen + True + + + + + + + + + + + + True + False + _Project + True + + + True + False + + + True + False + Add a binary... + True + + + True + False + + + True + False + File + True + + + + + + + + + + True + False + Remove a binary + Remove a binary + True + + + + + + + + + True + False + _Binary + True + + + True + False + + + True + False + Entry points + True + + + + + + + + True + False + + + + + True + False + Attach a debugger + True + + + + + + True + False + + + + + True + False + Storage + True + + + + + + True + False + Snapshots + True + + + + + + True + False + + + + + True + False + Export + True + + + True + False + + + True + False + Disassembly + True + + + + + + True + False + Graph view + True + + + + + + + + + + + + + + True + False + _Debug + True + + + True + False + + + True + False + _Continue + True + + + + + + + + True + False + Continue to selection + True + + + + + + + + True + False + _Pause + True + + + + + + + + True + False + _Restart + True + + + + + + True + False + Close + True + + + + + + True + False + + + + + True + False + Step into + True + + + + + + + + True + False + Step over + True + + + + + + + + True + False + Visit basic blocks into + True + + + + + + + + True + False + Visit basic blocks over + True + + + + + + + + True + False + Continue until return + True + + + + + + + + True + False + + + + + True + False + Debugging options... + True + + + + + + + + + + True + False + _Options + True + + + True + False + + + True + False + _Preferences + True + + + + + + True + False + _Identity + True + + + + + + + + + + True + False + _Help + True + + + True + False + + + True + False + _Website + True + + + + + + True + False + _Python API documentation + True + + + + + + True + False + _Bug report + True + + + + + + True + False + + + + + True + False + _About + True + + + + + + + + + + False + True + 0 + + + + + + + + + + + + + + + diff --git a/src/gui/gresource.xml b/src/gui/gresource.xml new file mode 100644 index 0000000..011281d --- /dev/null +++ b/src/gui/gresource.xml @@ -0,0 +1,6 @@ + + + + editor.ui + + diff --git a/src/gui/menubar.c b/src/gui/menubar.c index 55ff3fa..5630194 100644 --- a/src/gui/menubar.c +++ b/src/gui/menubar.c @@ -36,7 +36,6 @@ #include "menus/file.h" #include "menus/help.h" #include "menus/options.h" -#include "menus/plugins.h" #include "menus/project.h" #include "menus/view.h" @@ -47,17 +46,7 @@ struct _GMenuBar { GEditorItem parent; /* A laisser en premier */ - GtkWidget *support; /* Composant principal */ - - GtkWidget *file; /* Menu "Fichier" */ - GtkWidget *edition; /* Menu "Edition" */ - GtkWidget *view; /* Menu "Affichage" */ - GtkWidget *project; /* Menu "Projet" */ - GtkWidget *binary; /* Menu "Binaire" */ - GtkWidget *debug; /* Menu "Débogage" */ - GtkWidget *options; /* Menu "Options" */ - GtkWidget *plugins; /* Menu "Greffons" */ - GtkWidget *help; /* Menu "Aide" */ + GtkBuilder *builder; /* Constructeur des menus */ }; @@ -86,7 +75,7 @@ static void g_menu_bar_finalize(GMenuBar *); static char *g_menu_bar_get_key(const GMenuBar *); /* Fournit le composant GTK associé à l'élément réactif. */ -static GtkWidget *g_menu_bar_get_widget(const GMenuBar *); +static GtkWidget *g_menu_bar_get_widget(GMenuBar *); /* Réagit à un changement d'affichage principal de contenu. */ static void change_menubar_current_content(GMenuBar *, GLoadedContent *, GLoadedContent *); @@ -155,8 +144,7 @@ static void g_menu_bar_class_init(GMenuBarClass *klass) static void g_menu_bar_init(GMenuBar *bar) { - bar->support = gtk_menu_bar_new(); - gtk_widget_show(bar->support); + bar->builder = NULL; } @@ -175,6 +163,8 @@ static void g_menu_bar_init(GMenuBar *bar) static void g_menu_bar_dispose(GMenuBar *bar) { + g_clear_object(&bar->builder); + G_OBJECT_CLASS(g_menu_bar_parent_class)->dispose(G_OBJECT(bar)); } @@ -201,7 +191,7 @@ static void g_menu_bar_finalize(GMenuBar *bar) /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : builder = constructeur principal de l'éditeur. * * * * Description : Compose la barre de menus principale. * * * @@ -211,56 +201,23 @@ static void g_menu_bar_finalize(GMenuBar *bar) * * ******************************************************************************/ -GEditorItem *g_menu_bar_new(GObject *ref) +GEditorItem *g_menu_bar_new(GtkBuilder *builder) { GMenuBar *result; /* Structure à retourner */ result = g_object_new(G_TYPE_MENU_BAR, NULL); - /* Fichier */ - - result->file = build_menu_file(); - gtk_container_add(GTK_CONTAINER(result->support), result->file); - - /* Edition */ - - result->edition = build_menu_edition(ref, result); - gtk_container_add(GTK_CONTAINER(result->support), result->edition); - - /* Affichage */ - - result->view = build_menu_view(ref, result); - gtk_container_add(GTK_CONTAINER(result->support), result->view); - - /* Projet */ - - result->project = build_menu_project(ref, result); - gtk_container_add(GTK_CONTAINER(result->support), result->project); - - /* Binaire */ - - result->binary = build_menu_binary(ref, result); - gtk_container_add(GTK_CONTAINER(result->support), result->binary); + result->builder = builder; + g_object_ref(G_OBJECT(builder)); - /* Débogage */ - - result->debug = build_menu_debug(ref); - gtk_container_add(GTK_CONTAINER(result->support), result->debug); - - /* Options */ - - result->options = build_menu_options(ref, result); - gtk_container_add(GTK_CONTAINER(result->support), result->options); - - /* Greffons */ - - result->plugins = build_menu_plugins(ref); - gtk_container_add(GTK_CONTAINER(result->support), result->plugins); - - /* Aide */ - - result->help = build_menu_help(); - gtk_container_add(GTK_CONTAINER(result->support), result->help); + setup_menu_file_callbacks(builder); + setup_menu_edition_callbacks(builder); + setup_menu_view_callbacks(builder); + setup_menu_project_callbacks(builder); + setup_menu_binary_callbacks(builder); + setup_menu_debug_callbacks(builder); + setup_menu_options_callbacks(builder); + setup_menu_help_callbacks(builder); return G_EDITOR_ITEM(result); @@ -302,14 +259,13 @@ static char *g_menu_bar_get_key(const GMenuBar *bar) * * ******************************************************************************/ -static GtkWidget *g_menu_bar_get_widget(const GMenuBar *bar) +static GtkWidget *g_menu_bar_get_widget(GMenuBar *bar) { GtkWidget *result; /* Composant à retourner */ - result = bar->support; + result = GTK_WIDGET(gtk_builder_get_object(bar->builder, "menubar")); - if (result != NULL) - g_object_ref(G_OBJECT(result)); + g_object_ref(G_OBJECT(result)); return result; @@ -332,13 +288,9 @@ static GtkWidget *g_menu_bar_get_widget(const GMenuBar *bar) static void change_menubar_current_content(GMenuBar *bar, GLoadedContent *old, GLoadedContent *new) { - GObject *ref; /* Espace de référencements */ - - ref = get_global_ref(); - - rebuild_menu_view_for_content(bar->view, ref, new); + rebuild_menu_view_for_content(bar->builder, new); - update_access_for_content_in_menu_binary(ref, new); + update_access_for_content_in_menu_binary(bar->builder, new); } @@ -359,17 +311,13 @@ static void change_menubar_current_content(GMenuBar *bar, GLoadedContent *old, G static void change_menubar_current_view(GMenuBar *bar, GLoadedPanel *old, GLoadedPanel *new) { - GObject *ref; /* Espace de référencements */ + update_access_for_view_in_menu_edition(bar->builder, new); - ref = get_global_ref(); + rebuild_menu_view_for_view(bar->builder, new); - update_access_for_view_in_menu_edition(ref, new); + update_access_for_view_in_menu_view(bar->builder, new); - rebuild_menu_view_for_view(bar->view, ref, new); - - update_access_for_view_in_menu_view(ref, new); - - update_access_for_view_in_menu_binary(ref, new); + update_access_for_view_in_menu_binary(bar->builder, new); } @@ -390,11 +338,7 @@ static void change_menubar_current_view(GMenuBar *bar, GLoadedPanel *old, GLoade static void track_caret_address_for_menu_bar(GMenuBar *bar, GLoadedPanel *panel, const GLineCursor *cursor) { - GObject *ref; /* Espace de référencements */ - - ref = get_global_ref(); - - update_access_for_cursor_in_menu_edition(ref, panel, cursor); + update_access_for_cursor_in_menu_edition(bar->builder, panel, cursor); } @@ -414,182 +358,7 @@ static void track_caret_address_for_menu_bar(GMenuBar *bar, GLoadedPanel *panel, static void update_menu_bar_for_project(GMenuBar *bar, GStudyProject *project) { - update_menu_project_for_project(bar->project, project, bar); - -} - - -/****************************************************************************** -* * -* Paramètres : bar = instance à consulter. * -* * -* Description : Fournit le composant GTK associé au menu "Fichier". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_menu_bar_get_file_menu(const GMenuBar *bar) -{ - GtkWidget *result; /* Menu à renvoyer */ - - result = bar->file; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bar = instance à consulter. * -* * -* Description : Fournit le composant GTK associé au menu "Edition". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_menu_bar_get_edition_menu(const GMenuBar *bar) -{ - GtkWidget *result; /* Menu à renvoyer */ - - result = bar->edition; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bar = instance à consulter. * -* * -* Description : Fournit le composant GTK associé au menu "Affichage". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_menu_bar_get_view_menu(const GMenuBar *bar) -{ - GtkWidget *result; /* Menu à renvoyer */ - - result = bar->view; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bar = instance à consulter. * -* * -* Description : Fournit le composant GTK associé au menu "Projet". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_menu_bar_get_project_menu(const GMenuBar *bar) -{ - GtkWidget *result; /* Menu à renvoyer */ - - result = bar->project; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bar = instance à consulter. * -* * -* Description : Fournit le composant GTK associé au menu "Binaire". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_menu_bar_get_binary_menu(const GMenuBar *bar) -{ - GtkWidget *result; /* Menu à renvoyer */ - - result = bar->binary; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bar = instance à consulter. * -* * -* Description : Fournit le composant GTK associé au menu "Débogage". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_menu_bar_get_debug_menu(const GMenuBar *bar) -{ - GtkWidget *result; /* Menu à renvoyer */ - - result = bar->debug; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : bar = instance à consulter. * -* * -* Description : Fournit le composant GTK associé au menu "Options". * -* * -* Retour : Instance de composant graphique correspondant au menu visé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *g_menu_bar_get_options_menu(const GMenuBar *bar) -{ - GtkWidget *result; /* Menu à renvoyer */ - - result = bar->options; - - g_object_ref(G_OBJECT(result)); - - return result; + update_menu_project_for_project(bar->builder, project); } @@ -598,19 +367,19 @@ GtkWidget *g_menu_bar_get_options_menu(const GMenuBar *bar) * * * Paramètres : bar = instance à consulter. * * * -* Description : Fournit le composant GTK associé au menu "Aide". * +* Description : Fournit le constructeur associé à la barre de menus. * * * -* Retour : Instance de composant graphique correspondant au menu visé. * +* Retour : Instance du constructeur (principal) associé à la barre. * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *g_menu_bar_get_help_menu(const GMenuBar *bar) +GtkBuilder *g_menu_bar_get_builder(const GMenuBar *bar) { - GtkWidget *result; /* Menu à renvoyer */ + GtkBuilder *result; /* Constructeur à renvoyer */ - result = bar->help; + result = bar->builder; g_object_ref(G_OBJECT(result)); diff --git a/src/gui/menubar.h b/src/gui/menubar.h index 1a1b23c..73cc327 100644 --- a/src/gui/menubar.h +++ b/src/gui/menubar.h @@ -49,31 +49,10 @@ typedef struct _GMenuBarClass GMenuBarClass; GType g_menu_bar_get_type(void); /* Compose la barre de menus principale. */ -GEditorItem *g_menu_bar_new(GObject *); +GEditorItem *g_menu_bar_new(GtkBuilder *); -/* Fournit le composant GTK associé au menu "Fichier". */ -GtkWidget *g_menu_bar_get_file_menu(const GMenuBar *); - -/* Fournit le composant GTK associé au menu "Edition". */ -GtkWidget *g_menu_bar_get_edition_menu(const GMenuBar *); - -/* Fournit le composant GTK associé au menu "Affichage". */ -GtkWidget *g_menu_bar_get_view_menu(const GMenuBar *); - -/* Fournit le composant GTK associé au menu "Projet". */ -GtkWidget *g_menu_bar_get_project_menu(const GMenuBar *); - -/* Fournit le composant GTK associé au menu "Binaire". */ -GtkWidget *g_menu_bar_get_binary_menu(const GMenuBar *); - -/* Fournit le composant GTK associé au menu "Débogage". */ -GtkWidget *g_menu_bar_get_debug_menu(const GMenuBar *); - -/* Fournit le composant GTK associé au menu "Options". */ -GtkWidget *g_menu_bar_get_options_menu(const GMenuBar *); - -/* Fournit le composant GTK associé au menu "Aide". */ -GtkWidget *g_menu_bar_get_help_menu(const GMenuBar *); +/* Fournit le constructeur associé à la barre de menus. */ +GtkBuilder *g_menu_bar_get_builder(const GMenuBar *); diff --git a/src/gui/menus/Makefile.am b/src/gui/menus/Makefile.am index 4218374..02ed19f 100644 --- a/src/gui/menus/Makefile.am +++ b/src/gui/menus/Makefile.am @@ -8,7 +8,6 @@ libguimenus_la_SOURCES = \ file.h file.c \ help.h help.c \ options.h options.c \ - plugins.h plugins.c \ project.h project.c \ view.h view.c diff --git a/src/gui/menus/binary.c b/src/gui/menus/binary.c index 9e85520..98563a0 100644 --- a/src/gui/menus/binary.c +++ b/src/gui/menus/binary.c @@ -30,6 +30,7 @@ #include "../agroup.h" #include "../item-int.h" +#include "../menubar.h" #include "../core/global.h" #include "../dialogs/export_disass.h" #include "../dialogs/export_graph.h" @@ -64,88 +65,9 @@ static void mcb_binary_export_graph(GtkMenuItem *, gpointer); /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* bar = barre de menu parente. * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Binaire". * -* * -* Retour : Panneau de menus mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *build_menu_binary(GObject *ref, GMenuBar *bar) -{ - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments */ - GtkWidget *submenuitem; /* Sous-élément de menu #1 */ - GtkWidget *deepmenubar; /* Support pour éléments #2 */ - GtkWidget *deepmenuitem; /* Sous-élément de menu #2 */ - - result = gtk_menu_item_new_with_mnemonic(_("_Binary")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - - submenuitem = qck_create_menu_item(ref, "mnu_binary_epoints", _("Entry points"), - G_CALLBACK(mcb_binary_entry_points), bar); - add_accelerator_to_widget(submenuitem, "E"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_binary_attach_debugger", _("Attach a debugger"), - G_CALLBACK(mcb_binary_attach_debugger), bar); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Séparation */ - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Bases de données */ - - submenuitem = qck_create_menu_item(ref, "mnu_binary_storage", _("Storage"), - G_CALLBACK(mcb_binary_storage), bar); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_binary_snapshots", _("Snapshots"), - G_CALLBACK(mcb_binary_snapshots), bar); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Séparation */ - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Exportations */ - - submenuitem = qck_create_menu_item(NULL, NULL, _("Export"), NULL, NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - deepmenubar = qck_create_menu(GTK_MENU_ITEM(submenuitem)); - - deepmenuitem = qck_create_menu_item(ref, "mnu_binary_export_disass", _("Disassembly"), - G_CALLBACK(mcb_binary_export_disass), bar); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - deepmenuitem = qck_create_menu_item(ref, "mnu_binary_export_graph", _("Graph view"), - G_CALLBACK(mcb_binary_export_graph), NULL); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* new = nouveau contenu chargé à analyser. * -* * -* Description : Réagit à un changement d'affichage principal de contenu. * +* Description : Complète la définition du menu "Binaire". * * * * Retour : - * * * @@ -153,47 +75,19 @@ GtkWidget *build_menu_binary(GObject *ref, GMenuBar *bar) * * ******************************************************************************/ -void update_access_for_content_in_menu_binary(GObject *ref, GLoadedContent *new) +void setup_menu_binary_callbacks(GtkBuilder *builder) { - gboolean access; /* Accès à déterminer */ - GtkWidget *item; /* Elément de menu à traiter */ - access = G_IS_LOADED_BINARY(new); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_binary_epoints")); - gtk_widget_set_sensitive(item, access); +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) - item = GTK_WIDGET(g_object_get_data(ref, "mnu_binary_storage")); - gtk_widget_set_sensitive(item, access); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_binary_export_disass")); - gtk_widget_set_sensitive(item, access); - -} - - -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* new = nouvelle vue du contenu chargé analysé. * -* * -* Description : Lance une actualisation du fait d'un changement de support. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void update_access_for_view_in_menu_binary(GObject *ref, GLoadedPanel *new) -{ - gboolean access; /* Accès à déterminer */ - GtkWidget *item; /* Elément de menu à traiter */ - - access = GTK_IS_GRAPH_DISPLAY(new); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_binary_export_graph")); - gtk_widget_set_sensitive(item, access); + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_binary_entry_points), + DEFINE_CALLBACK(mcb_binary_attach_debugger), + DEFINE_CALLBACK(mcb_binary_storage), + DEFINE_CALLBACK(mcb_binary_snapshots), + DEFINE_CALLBACK(mcb_binary_export_disass), + DEFINE_CALLBACK(mcb_binary_export_graph), + NULL); } @@ -415,3 +309,61 @@ static void mcb_binary_export_graph(GtkMenuItem *menuitem, gpointer unused) g_object_unref(G_OBJECT(binary)); } + + +/****************************************************************************** +* * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* new = nouveau contenu chargé à analyser. * +* * +* Description : Réagit à un changement d'affichage principal de contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_access_for_content_in_menu_binary(GtkBuilder *builder, GLoadedContent *new) +{ + gboolean access; /* Accès à déterminer */ + GtkWidget *item; /* Elément de menu à traiter */ + + access = G_IS_LOADED_BINARY(new); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "binary_entry_points")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "binary_storage")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "binary_export_disass")); + gtk_widget_set_sensitive(item, access); + +} + + +/****************************************************************************** +* * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* new = nouvelle vue du contenu chargé analysé. * +* * +* Description : Lance une actualisation du fait d'un changement de support. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_access_for_view_in_menu_binary(GtkBuilder *builder, GLoadedPanel *new) +{ + gboolean access; /* Accès à déterminer */ + GtkWidget *item; /* Elément de menu à traiter */ + + access = GTK_IS_GRAPH_DISPLAY(new); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "binary_export_graph")); + gtk_widget_set_sensitive(item, access); + +} diff --git a/src/gui/menus/binary.h b/src/gui/menus/binary.h index 056b918..86a68ba 100644 --- a/src/gui/menus/binary.h +++ b/src/gui/menus/binary.h @@ -29,19 +29,19 @@ #include -#include "../menubar.h" #include "../../analysis/loaded.h" +#include "../../glibext/gloadedpanel.h" -/* Construit le menu "Binaire". */ -GtkWidget *build_menu_binary(GObject *, GMenuBar *); +/* Complète la définition du menu "Binaire". */ +void setup_menu_binary_callbacks(GtkBuilder *); /* Réagit à un changement d'affichage principal de contenu. */ -void update_access_for_content_in_menu_binary(GObject *, GLoadedContent *); +void update_access_for_content_in_menu_binary(GtkBuilder *, GLoadedContent *); /* Lance une actualisation du fait d'un changement de support. */ -void update_access_for_view_in_menu_binary(GObject *, GLoadedPanel *); +void update_access_for_view_in_menu_binary(GtkBuilder *, GLoadedPanel *); diff --git a/src/gui/menus/debug.c b/src/gui/menus/debug.c index 74844e2..bfa9229 100644 --- a/src/gui/menus/debug.c +++ b/src/gui/menus/debug.c @@ -73,86 +73,34 @@ static void mcb_debug_options(GtkMenuItem *, GObject *); /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Aide". * +* Description : Complète la définition du menu "Débogage". * * * -* Retour : Panneau de menus mis en place. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *build_menu_debug(GObject *ref) +void setup_menu_debug_callbacks(GtkBuilder *builder) { - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments */ - GtkWidget *submenuitem; /* Sous-élément de menu */ - - result = gtk_menu_item_new_with_mnemonic(_("_Debug")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_continue", _("Continue"), - G_CALLBACK(mcb_debug_continue), ref); - add_accelerator_to_widget(submenuitem, "F9"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_continue_to", _("Continue to selection"), - G_CALLBACK(mcb_debug_continue_to), ref); - add_accelerator_to_widget(submenuitem, "F9"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_pause", _("Pause"), - G_CALLBACK(mcb_debug_pause), ref); - add_accelerator_to_widget(submenuitem, "F10"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_restart", _("Restart"), - G_CALLBACK(mcb_debug_restart), ref); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_close", _("Close"), - G_CALLBACK(mcb_debug_close), ref); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_step_into", _("Step into"), - G_CALLBACK(mcb_debug_step_into), ref); - add_accelerator_to_widget(submenuitem, "F7"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_step_over", _("Step over"), - G_CALLBACK(mcb_debug_step_over), ref); - add_accelerator_to_widget(submenuitem, "F7"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_basic", _("Visit basic blocks into"), - G_CALLBACK(mcb_debug_visit_blocks_into), ref); - add_accelerator_to_widget(submenuitem, "F8"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_basic", _("Visit basic blocks over"), - G_CALLBACK(mcb_debug_visit_blocks_over), ref); - add_accelerator_to_widget(submenuitem, "F8"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_return", _("Continue until return"), - G_CALLBACK(mcb_debug_return), ref); - add_accelerator_to_widget(submenuitem, "F12"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_debug_options", _("Debugging options..."), - G_CALLBACK(mcb_debug_options), ref); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - return result; + +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) + + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_debug_continue), + DEFINE_CALLBACK(mcb_debug_continue_to), + DEFINE_CALLBACK(mcb_debug_pause), + DEFINE_CALLBACK(mcb_debug_restart), + DEFINE_CALLBACK(mcb_debug_close), + DEFINE_CALLBACK(mcb_debug_step_into), + DEFINE_CALLBACK(mcb_debug_step_over), + DEFINE_CALLBACK(mcb_debug_visit_blocks_into), + DEFINE_CALLBACK(mcb_debug_visit_blocks_over), + DEFINE_CALLBACK(mcb_debug_return), + DEFINE_CALLBACK(mcb_debug_options), + NULL); } diff --git a/src/gui/menus/debug.h b/src/gui/menus/debug.h index aac8da9..4107bc1 100644 --- a/src/gui/menus/debug.h +++ b/src/gui/menus/debug.h @@ -30,8 +30,8 @@ -/* Construit le menu "Aide". */ -GtkWidget *build_menu_debug(GObject *); +/* Complète la définition du menu "Débogage". */ +void setup_menu_debug_callbacks(GtkBuilder *); diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c index cebb733..f18e4e4 100644 --- a/src/gui/menus/edition.c +++ b/src/gui/menus/edition.c @@ -32,6 +32,7 @@ #include "../agroup.h" +#include "../menubar.h" #include "../core/global.h" #include "../dialogs/bookmark.h" #include "../dialogs/goto.h" @@ -85,162 +86,9 @@ static void mcb_edition_comment_enter_next(GtkMenuItem *, GMenuBar *); /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* bar = barre de menu parente. * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Edition". * -* * -* Retour : Panneau de menus mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *build_menu_edition(GObject *ref, GMenuBar *bar) -{ - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments */ - GtkWidget *submenuitem; /* Sous-élément de menu #1 */ - GtkWidget *deepmenubar; /* Support pour éléments #2 */ - GtkWidget *deepmenuitem; /* Sous-élément de menu #2 */ - - result = gtk_menu_item_new_with_mnemonic(_("_Edition")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - - /* Déplacements ciblés */ - - submenuitem = qck_create_menu_item(ref, "mnu_edit_goto", _("Go to address..."), - G_CALLBACK(mcb_edition_goto), bar); - add_accelerator_to_widget(submenuitem, "G"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Séparation */ - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Bascule des opérandes numériques */ - - submenuitem = qck_create_menu_item(NULL, NULL, _("Numeric operand"), NULL, NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - deepmenubar = qck_create_menu(GTK_MENU_ITEM(submenuitem)); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_switch_hex", _("Hexadecimal"), - G_CALLBACK(mcb_edition_switch_numeric_operand), NULL); - add_accelerator_to_widget(deepmenuitem, "H"); - 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(ref, "mnu_edit_switch_dec", _("Decimal"), - G_CALLBACK(mcb_edition_switch_numeric_operand), NULL); - add_accelerator_to_widget(deepmenuitem, "D"); - 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(ref, "mnu_edit_switch_oct", _("Octal"), - G_CALLBACK(mcb_edition_switch_numeric_operand), NULL); - add_accelerator_to_widget(deepmenuitem, "O"); - 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(ref, "mnu_edit_switch_bin", _("Binary"), - G_CALLBACK(mcb_edition_switch_numeric_operand), NULL); - add_accelerator_to_widget(deepmenuitem, "B"); - g_object_set_data(G_OBJECT(deepmenuitem), "kind_of_switch", GUINT_TO_POINTER(IOD_BIN)); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - deepmenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_switch_def", _("Default"), - G_CALLBACK(mcb_edition_switch_numeric_operand), NULL); - g_object_set_data(G_OBJECT(deepmenuitem), "kind_of_switch", GUINT_TO_POINTER(IOD_COUNT)); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - /* Séparation */ - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Suivi de cibles */ - - submenuitem = qck_create_menu_item(ref, "mnu_edit_go_back", _("Go back"), - G_CALLBACK(mcb_edition_go_back), bar); - add_accelerator_to_widget(submenuitem, "Escape"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_edit_follow_ref", _("Follow the reference"), - G_CALLBACK(mcb_edition_follow_ref), NULL); - add_accelerator_to_widget(submenuitem, "Return"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_edit_list_xrefs", _("List all references leading to..."), - G_CALLBACK(mcb_edition_list_xrefs), bar); - add_accelerator_to_widget(submenuitem, "X"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Séparation */ - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Signets */ - - submenuitem = qck_create_menu_item(NULL, NULL, _("Bookmarks"), NULL, NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - deepmenubar = qck_create_menu(GTK_MENU_ITEM(submenuitem)); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_toggle_bmark", _("Toggle at current location"), - G_CALLBACK(mcb_edition_bookmarks_toggle), bar); - add_accelerator_to_widget(deepmenuitem, "D"); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_delete_bmarks", _("Delete all bookmarks"), - G_CALLBACK(mcb_edition_bookmarks_delete_all), bar); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - /* Commentaires */ - - submenuitem = qck_create_menu_item(NULL, NULL, _("Comments"), NULL, NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - deepmenubar = qck_create_menu(GTK_MENU_ITEM(submenuitem)); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_enter_comment", _("Enter a comment..."), - G_CALLBACK(mcb_edition_comment_enter), bar); - add_accelerator_to_widget(deepmenuitem, "semicolon"); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_enter_rep_comment", _("Enter a repeatable comment..."), - G_CALLBACK(mcb_edition_comment_enter_repeatable), bar); - add_accelerator_to_widget(deepmenuitem, "colon"); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_enter_prev", _("Enter a comment in the previous line..."), - G_CALLBACK(mcb_edition_comment_enter_previous), bar); - add_accelerator_to_widget(deepmenuitem, "Insert"); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - deepmenuitem = qck_create_menu_item(ref, "mnu_edit_enter_next", _("Enter a comment in the next line..."), - G_CALLBACK(mcb_edition_comment_enter_next), bar); - add_accelerator_to_widget(deepmenuitem, "Insert"); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* new = nouvelle vue du contenu chargé analysé. * -* * -* Description : Lance une actualisation du fait d'un changement de support. * +* Description : Complète la définition du menu "Edition". * * * * Retour : - * * * @@ -248,155 +96,42 @@ GtkWidget *build_menu_edition(GObject *ref, GMenuBar *bar) * * ******************************************************************************/ -void update_access_for_view_in_menu_edition(GObject *ref, GLoadedPanel *new) +void setup_menu_edition_callbacks(GtkBuilder *builder) { - gboolean access; /* Accès à déterminer */ - GtkWidget *item; /* Elément de menu à traiter */ - - /* Déplacements ciblés */ - - access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_goto")); - gtk_widget_set_sensitive(item, access); + GObject *item; /* Elément à compléter */ + +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) + + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_edition_goto), + DEFINE_CALLBACK(mcb_edition_switch_numeric_operand), + DEFINE_CALLBACK(mcb_edition_go_back), + DEFINE_CALLBACK(mcb_edition_follow_ref), + DEFINE_CALLBACK(mcb_edition_list_xrefs), + DEFINE_CALLBACK(mcb_edition_bookmarks_toggle), + DEFINE_CALLBACK(mcb_edition_bookmarks_delete_all), + DEFINE_CALLBACK(mcb_edition_comment_enter), + DEFINE_CALLBACK(mcb_edition_comment_enter_repeatable), + DEFINE_CALLBACK(mcb_edition_comment_enter_previous), + DEFINE_CALLBACK(mcb_edition_comment_enter_next), + NULL); /* Bascule des opérandes numériques */ - access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); - - 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 = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_go_back")); - gtk_widget_set_sensitive(item, access); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_follow_ref")); - gtk_widget_set_sensitive(item, access); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_list_xrefs")); - gtk_widget_set_sensitive(item, access); - - /* Signets */ - - access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_toggle_bmark")); - gtk_widget_set_sensitive(item, access); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_delete_bmarks")); - gtk_widget_set_sensitive(item, access); + item = gtk_builder_get_object(builder, "edition_switch_hex"); + g_object_set_data(item, "kind_of_switch", GUINT_TO_POINTER(IOD_HEX)); - /* Commentaires */ + item = gtk_builder_get_object(builder, "edition_switch_dec"); + g_object_set_data(item, "kind_of_switch", GUINT_TO_POINTER(IOD_DEC)); - access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); + item = gtk_builder_get_object(builder, "edition_switch_oct"); + g_object_set_data(item, "kind_of_switch", GUINT_TO_POINTER(IOD_OCT)); - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_enter_comment")); - gtk_widget_set_sensitive(item, access); + item = gtk_builder_get_object(builder, "edition_switch_bin"); + g_object_set_data(item, "kind_of_switch", GUINT_TO_POINTER(IOD_BIN)); - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_enter_rep_comment")); - gtk_widget_set_sensitive(item, access); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_enter_prev")); - gtk_widget_set_sensitive(item, access); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_enter_next")); - gtk_widget_set_sensitive(item, access); - -} - - -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* panel = vue d'affichage active ou NULL si aucune. * -* cursor = suivi des positions à consulter. * -* * -* Description : Met à jour les accès du menu "Edition" selon une position. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void update_access_for_cursor_in_menu_edition(GObject *ref, GLoadedPanel *panel, const GLineCursor *cursor) -{ - GObject *creator; /* Créateur à l'orgine du seg. */ - gboolean access; /* Accès à déterminer */ - GtkWidget *item; /* Elément de menu à traiter */ - - /* Préliminaire */ - - /** - * Seuls les affichages de blocs (en graphique ou non) distribuent ce - * genre de curseur. Donc on valide dans le même temps la nature de la vue. - */ - - if (G_IS_BINARY_CURSOR(cursor)) - { - assert(GTK_IS_HEX_DISPLAY(panel) || GTK_IS_BLOCK_DISPLAY(panel) || GTK_IS_GRAPH_DISPLAY(panel)); - - if (g_line_cursor_is_valid(cursor)) - creator = gtk_display_panel_get_active_object(GTK_DISPLAY_PANEL(panel)); - else - creator = NULL; - - } - - else - creator = NULL; - - /* Bascule des opérandes numériques */ - - access = 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 = G_IS_TARGETABLE_OPERAND(creator); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_follow_ref")); - gtk_widget_set_sensitive(item, access); - - access = g_line_cursor_is_valid(cursor); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_edit_list_xrefs")); - gtk_widget_set_sensitive(item, access); - - /* Nettoyage et sortie finale */ - - if (creator != NULL) - g_object_unref(G_OBJECT(creator)); + item = gtk_builder_get_object(builder, "edition_switch_def"); + g_object_set_data(item, "kind_of_switch", GUINT_TO_POINTER(IOD_COUNT)); } @@ -851,3 +586,169 @@ static void mcb_edition_comment_enter_next(GtkMenuItem *menuitem, GMenuBar *bar) { } + + +/****************************************************************************** +* * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* new = nouvelle vue du contenu chargé analysé. * +* * +* Description : Lance une actualisation du fait d'un changement de support. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_access_for_view_in_menu_edition(GtkBuilder *builder, GLoadedPanel *new) +{ + gboolean access; /* Accès à déterminer */ + GtkWidget *item; /* Elément de menu à traiter */ + + /* Déplacements ciblés */ + + access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_goto")); + gtk_widget_set_sensitive(item, access); + + /* Bascule des opérandes numériques */ + + access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_hex")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_dec")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_oct")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_bin")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_def")); + gtk_widget_set_sensitive(item, access); + + /* Suivi de cibles */ + + access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_go_back")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_follow_ref")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_list_xrefs")); + gtk_widget_set_sensitive(item, access); + + /* Signets */ + + access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_bookmarks_toggle")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_bookmarks_delete_all")); + gtk_widget_set_sensitive(item, access); + + /* Commentaires */ + + access = GTK_IS_BLOCK_DISPLAY(new) || GTK_IS_GRAPH_DISPLAY(new); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_comment_enter")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_comment_enter_rep")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_comment_enter_prev")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_comment_enter_next")); + gtk_widget_set_sensitive(item, access); + +} + + +/****************************************************************************** +* * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* panel = vue d'affichage active ou NULL si aucune. * +* cursor = suivi des positions à consulter. * +* * +* Description : Met à jour les accès du menu "Edition" selon une position. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_access_for_cursor_in_menu_edition(GtkBuilder *builder, GLoadedPanel *panel, const GLineCursor *cursor) +{ + GObject *creator; /* Créateur à l'orgine du seg. */ + gboolean access; /* Accès à déterminer */ + GtkWidget *item; /* Elément de menu à traiter */ + + /* Préliminaire */ + + /** + * Seuls les affichages de blocs (en graphique ou non) distribuent ce + * genre de curseur. Donc on valide dans le même temps la nature de la vue. + */ + + if (G_IS_BINARY_CURSOR(cursor)) + { + assert(GTK_IS_HEX_DISPLAY(panel) || GTK_IS_BLOCK_DISPLAY(panel) || GTK_IS_GRAPH_DISPLAY(panel)); + + if (g_line_cursor_is_valid(cursor)) + creator = gtk_display_panel_get_active_object(GTK_DISPLAY_PANEL(panel)); + else + creator = NULL; + + } + + else + creator = NULL; + + /* Bascule des opérandes numériques */ + + access = G_IS_IMM_OPERAND(creator); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_hex")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_dec")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_oct")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_bin")); + gtk_widget_set_sensitive(item, access); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_switch_def")); + gtk_widget_set_sensitive(item, access); + + /* Suivi de cibles */ + + access = G_IS_TARGETABLE_OPERAND(creator); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_follow_ref")); + gtk_widget_set_sensitive(item, access); + + access = g_line_cursor_is_valid(cursor); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "edition_list_xrefs")); + gtk_widget_set_sensitive(item, access); + + /* Nettoyage et sortie finale */ + + if (creator != NULL) + g_object_unref(G_OBJECT(creator)); + +} diff --git a/src/gui/menus/edition.h b/src/gui/menus/edition.h index 909d5ec..d87bff6 100644 --- a/src/gui/menus/edition.h +++ b/src/gui/menus/edition.h @@ -29,19 +29,18 @@ #include -#include "../menubar.h" #include "../../glibext/gloadedpanel.h" -/* Construit le menu "Edition". */ -GtkWidget *build_menu_edition(GObject *, GMenuBar *); +/* Complète la définition du menu "Edition". */ +void setup_menu_edition_callbacks(GtkBuilder *); /* Lance une actualisation du fait d'un changement de support. */ -void update_access_for_view_in_menu_edition(GObject *, GLoadedPanel *); +void update_access_for_view_in_menu_edition(GtkBuilder *, GLoadedPanel *); /* Met à jour les accès du menu "Edition" selon une position. */ -void update_access_for_cursor_in_menu_edition(GObject *, GLoadedPanel *, const GLineCursor *); +void update_access_for_cursor_in_menu_edition(GtkBuilder *, GLoadedPanel *, const GLineCursor *); diff --git a/src/gui/menus/file.c b/src/gui/menus/file.c index 62b8381..b7c8dc8 100644 --- a/src/gui/menus/file.c +++ b/src/gui/menus/file.c @@ -52,41 +52,37 @@ static void mcb_file_quit(GtkMenuItem *, gpointer); /****************************************************************************** * * -* Paramètres : - * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Fichier". * +* Description : Complète la définition du menu "Fichier". * * * -* Retour : Panneau de menus mis en place. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *build_menu_file(void) +void setup_menu_file_callbacks(GtkBuilder *builder) { + +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) + + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_file_new_project), + DEFINE_CALLBACK(mcb_file_open_project), + DEFINE_CALLBACK(mcb_file_save_project), + DEFINE_CALLBACK(mcb_file_save_project_as), + DEFINE_CALLBACK(mcb_file_quit), + NULL); + + +#if 0 GtkWidget *result; /* Support à retourner */ GtkWidget *menubar; /* Support pour éléments */ GtkWidget *submenuitem; /* Sous-élément de menu #1 */ GtkWidget *deepmenuitem; /* Sous-élément de menu #2 */ GtkRecentFilter *filter; /* Filtre gardant les projets */ - result = gtk_menu_item_new_with_mnemonic(_("_File")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - - submenuitem = qck_create_menu_item(NULL, NULL, _("New project"), - G_CALLBACK(mcb_file_new_project), NULL); - add_accelerator_to_widget(submenuitem, "N"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Open project"), - G_CALLBACK(mcb_file_open_project), NULL); - add_accelerator_to_widget(submenuitem, "O"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_menu_item(NULL, NULL, _("Recent projects..."), NULL, NULL); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); @@ -100,27 +96,8 @@ GtkWidget *build_menu_file(void) filter = gtk_recent_filter_new(); gtk_recent_filter_add_mime_type(filter, "application/chrysalide.project"); gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(deepmenuitem), filter); +#endif - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Save project"), - G_CALLBACK(mcb_file_save_project), NULL); - add_accelerator_to_widget(submenuitem, "S"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Save project as..."), - G_CALLBACK(mcb_file_save_project_as), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Quit"), G_CALLBACK(mcb_file_quit), NULL); - add_accelerator_to_widget(submenuitem, "Q"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - return result; } diff --git a/src/gui/menus/file.h b/src/gui/menus/file.h index 7b98a93..c939067 100644 --- a/src/gui/menus/file.h +++ b/src/gui/menus/file.h @@ -30,8 +30,8 @@ -/* Construit le menu "Fichier". */ -GtkWidget *build_menu_file(void); +/* Complète la définition du menu "Fichier". */ +void setup_menu_file_callbacks(GtkBuilder *); /* Réagit au menu "Fichier -> Enregistrer le projet". */ void mcb_file_save_project(GtkMenuItem *, gpointer); diff --git a/src/gui/menus/help.c b/src/gui/menus/help.c index c265703..655c68e 100644 --- a/src/gui/menus/help.c +++ b/src/gui/menus/help.c @@ -50,44 +50,27 @@ static void mcb_help_about(GtkMenuItem *, gpointer); /****************************************************************************** * * -* Paramètres : - * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Aide". * +* Description : Complète la définition du menu "Aide". * * * -* Retour : Panneau de menus mis en place. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *build_menu_help(void) +void setup_menu_help_callbacks(GtkBuilder *builder) { - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments */ - GtkWidget *submenuitem; /* Sous-élément de menu */ - - result = gtk_menu_item_new_with_mnemonic(_("_Help")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Website"), G_CALLBACK(mcb_help_website), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Python API documentation"), - G_CALLBACK(mcb_help_python_api_documentation), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Bug report"), G_CALLBACK(mcb_help_bug_report), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - submenuitem = qck_create_menu_item(NULL, NULL, _("About"), G_CALLBACK(mcb_help_about), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) - return result; + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_help_website), + DEFINE_CALLBACK(mcb_help_python_api_documentation), + DEFINE_CALLBACK(mcb_help_bug_report), + DEFINE_CALLBACK(mcb_help_about), + NULL); } diff --git a/src/gui/menus/help.h b/src/gui/menus/help.h index 1deeb5a..b8816a4 100644 --- a/src/gui/menus/help.h +++ b/src/gui/menus/help.h @@ -30,8 +30,8 @@ -/* Construit le menu "Aide". */ -GtkWidget *build_menu_help(void); +/* Complète la définition du menu "Aide". */ +void setup_menu_help_callbacks(GtkBuilder *); diff --git a/src/gui/menus/options.c b/src/gui/menus/options.c index 62f58f5..03f5259 100644 --- a/src/gui/menus/options.c +++ b/src/gui/menus/options.c @@ -29,6 +29,7 @@ #include "../item-int.h" +#include "../menubar.h" #include "../core/global.h" #include "../dialogs/identity.h" #include "../dialogs/preferences.h" @@ -46,37 +47,25 @@ static void mcb_options_identity(GtkMenuItem *, gpointer); /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* bar = barre de menu parente. * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Options". * +* Description : Complète la définition du menu "Options". * * * -* Retour : Panneau de menus mis en place. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *build_menu_options(GObject *ref, GMenuBar *bar) +void setup_menu_options_callbacks(GtkBuilder *builder) { - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments */ - GtkWidget *submenuitem; /* Sous-élément de menu */ - - result = gtk_menu_item_new_with_mnemonic(_("_Options")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - - submenuitem = qck_create_menu_item(ref, "mnu_options_preferences", _("Preferences"), - G_CALLBACK(mcb_options_preferences), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - submenuitem = qck_create_menu_item(ref, "mnu_options_identity", _("Identity"), - G_CALLBACK(mcb_options_identity), NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) - return result; + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_options_preferences), + DEFINE_CALLBACK(mcb_options_identity), + NULL); } diff --git a/src/gui/menus/options.h b/src/gui/menus/options.h index 7176a09..0818fac 100644 --- a/src/gui/menus/options.h +++ b/src/gui/menus/options.h @@ -29,12 +29,9 @@ #include -#include "../menubar.h" - - -/* Construit le menu "Options". */ -GtkWidget *build_menu_options(GObject *, GMenuBar *); +/* Complète la définition du menu "Options". */ +void setup_menu_options_callbacks(GtkBuilder *); diff --git a/src/gui/menus/plugins.c b/src/gui/menus/plugins.c deleted file mode 100644 index dfe3caa..0000000 --- a/src/gui/menus/plugins.c +++ /dev/null @@ -1,63 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * plugins.c - gestion du menu 'Greffons' - * - * Copyright (C) 2015-2018 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "plugins.h" - - -#include - - -#include - - -#include "../../gtkext/easygtk.h" - - - -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Construit le menu "Aide". * -* * -* Retour : Panneau de menus mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *build_menu_plugins(GObject *ref) -{ - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments */ - - result = gtk_menu_item_new_with_mnemonic(_("_Plugins")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - g_object_set_data(ref, "menubar_plugins", G_OBJECT(menubar)); - - return result; - -} diff --git a/src/gui/menus/plugins.h b/src/gui/menus/plugins.h deleted file mode 100644 index 43cc4ee..0000000 --- a/src/gui/menus/plugins.h +++ /dev/null @@ -1,38 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * plugins.h - prototypes pour la gestion du menu 'Greffons' - * - * Copyright (C) 2015-2018 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _GUI_MENUS_PLUGINS_H -#define _GUI_MENUS_PLUGINS_H - - -#include - - - -/* Construit le menu "Aide". */ -GtkWidget *build_menu_plugins(GObject *); - - - -#endif /* _GUI_MENUS_PLUGINS_H */ diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c index e472419..e9e690c 100644 --- a/src/gui/menus/project.c +++ b/src/gui/menus/project.c @@ -32,6 +32,7 @@ #include "../item-int.h" +#include "../menubar.h" #include "../core/global.h" #include "../../analysis/loading.h" #include "../../analysis/contents/file.h" @@ -50,57 +51,9 @@ static void mcb_project_remove_content(GtkMenuItem *, GStudyProject *); /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* bar = barre de menu parente. * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Projet". * -* * -* Retour : Panneau de menus mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *build_menu_project(GObject *ref, GMenuBar *bar) -{ - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments #1 */ - GtkWidget *submenuitem; /* Sous-élément de menu #1 */ - GtkWidget *deepmenubar; /* Support pour éléments #2 */ - GtkWidget *deepmenuitem; /* Sous-élément de menu #2 */ - - result = gtk_menu_item_new_with_mnemonic(_("_Project")); - gtk_widget_show(result); - - menubar = qck_create_menu(GTK_MENU_ITEM(result)); - - submenuitem = qck_create_menu_item(NULL, NULL, _("Add a binary..."), NULL, NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - deepmenubar = qck_create_menu(GTK_MENU_ITEM(submenuitem)); - - deepmenuitem = qck_create_menu_item(ref, "mnu_project_add_binary", _("File"), - G_CALLBACK(mcb_project_add_binary_file), bar); - gtk_container_add(GTK_CONTAINER(deepmenubar), deepmenuitem); - - submenuitem = qck_create_menu_item(G_OBJECT(result), "menu_prj_remove_bin", _("Remove a binary"), - NULL, NULL); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - deepmenubar = qck_create_menu(GTK_MENU_ITEM(submenuitem)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : widget = menu principal à actualiser. * -* project = projet visé par la procédure. * -* bar = barre de menu parente. * -* * -* Description : Lance une actualisation relative à l'étendue du projet. * +* Description : Complète la définition du menu "Projet". * * * * Retour : - * * * @@ -108,56 +61,21 @@ GtkWidget *build_menu_project(GObject *ref, GMenuBar *bar) * * ******************************************************************************/ -void update_menu_project_for_project(GtkWidget *widget, GStudyProject *project, GMenuBar *bar) +void setup_menu_project_callbacks(GtkBuilder *builder) { - GtkWidget *menuitem; /* Menu principal à compléter */ - GtkWidget *menubar; /* Support pour éléments */ - GList *list; /* Liste des éléments en place */ - GList *iter; /* Boucle de parcours #1 */ - size_t count; /* Nombre de contenus attachés */ - GLoadedContent **contents; /* Liste de ces contenus */ - size_t i; /* Boucle de parcours #2 */ - char *desc; /* Description à afficher */ - GtkWidget *submenuitem; /* Sous-menu à ajouter */ - - menuitem = GTK_WIDGET(g_object_get_data(G_OBJECT(widget), "menu_prj_remove_bin")); - menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)); - - /* Remise à zéro */ - - list = gtk_container_get_children(GTK_CONTAINER(menubar)); - - for (iter = list; iter != NULL; iter = g_list_next(iter)) - gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(iter->data)); - - g_list_free(list); - - /* Ajout des entrées */ - - contents = g_study_project_get_contents(project, &count); - - for (i = 0; i < count; i++) - { - desc = g_loaded_content_describe(contents[i], true); + GObject *item; /* Elément à compléter */ - submenuitem = qck_create_menu_item(NULL, NULL, desc, - G_CALLBACK(mcb_project_remove_content), project); - g_object_set_data_full(G_OBJECT(submenuitem), "content", contents[i], g_object_unref); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) - free(desc); + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_project_add_binary_file), + NULL); - /** - * Note : l'appel à g_object_unref() est réalisé lorsque la référence - * est retirée du menu. - */ + /* Projet -> Retirer un binaire */ - } - - if (contents != NULL) - free(contents); + item = gtk_builder_get_object(builder, "project_remove"); - gtk_widget_set_sensitive(menuitem, count > 0); + qck_create_menu(GTK_MENU_ITEM(item)); } @@ -255,3 +173,70 @@ static void mcb_project_remove_content(GtkMenuItem *menuitem, GStudyProject *pro g_object_set_data(ref, "content", NULL); } + + +/****************************************************************************** +* * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* project = projet visé par la procédure. * +* * +* Description : Lance une actualisation relative à l'étendue du projet. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void update_menu_project_for_project(GtkBuilder *builder, GStudyProject *project) +{ + GtkWidget *menuitem; /* Menu principal à compléter */ + GtkWidget *submenu; /* Support pour éléments */ + GList *list; /* Liste des éléments en place */ + GList *iter; /* Boucle de parcours #1 */ + size_t count; /* Nombre de contenus attachés */ + GLoadedContent **contents; /* Liste de ces contenus */ + size_t i; /* Boucle de parcours #2 */ + char *desc; /* Description à afficher */ + GtkWidget *submenuitem; /* Sous-menu à ajouter */ + + menuitem = GTK_WIDGET(gtk_builder_get_object(builder, "project_remove")); + submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)); + + /* Remise à zéro */ + + list = gtk_container_get_children(GTK_CONTAINER(submenu)); + + for (iter = list; iter != NULL; iter = g_list_next(iter)) + gtk_container_remove(GTK_CONTAINER(submenu), GTK_WIDGET(iter->data)); + + g_list_free(list); + + /* Ajout des entrées */ + + contents = g_study_project_get_contents(project, &count); + + for (i = 0; i < count; i++) + { + desc = g_loaded_content_describe(contents[i], true); + + submenuitem = qck_create_menu_item(NULL, NULL, desc, + G_CALLBACK(mcb_project_remove_content), project); + g_object_set_data_full(G_OBJECT(submenuitem), "content", contents[i], g_object_unref); + gtk_container_add(GTK_CONTAINER(submenu), submenuitem); + + free(desc); + + /** + * Note : l'appel à g_object_unref() est réalisé lorsque la référence + * est retirée du menu. + */ + + } + + if (contents != NULL) + free(contents); + + gtk_widget_set_sensitive(menuitem, count > 0); + +} diff --git a/src/gui/menus/project.h b/src/gui/menus/project.h index 6fddf74..78370a0 100644 --- a/src/gui/menus/project.h +++ b/src/gui/menus/project.h @@ -29,16 +29,15 @@ #include -#include "../menubar.h" #include "../../analysis/project.h" -/* Construit le menu "Projet". */ -GtkWidget *build_menu_project(GObject *, GMenuBar *); +/* Complète la définition du menu "Projet". */ +void setup_menu_project_callbacks(GtkBuilder *); /* Lance une actualisation relative à l'étendue du projet. */ -void update_menu_project_for_project(GtkWidget *, GStudyProject *, GMenuBar *); +void update_menu_project_for_project(GtkBuilder *, GStudyProject *); diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index c2f3f28..b778f8c 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -45,9 +45,6 @@ -/* Met à jour les accès du menu "Affichage -> Basculer...". */ -static void update_switch_access_in_menu_view(GObject *); - /* Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". */ static void mcb_view_change_panel_docking(GtkCheckMenuItem *, GPanelItem *); @@ -55,10 +52,10 @@ static void mcb_view_change_panel_docking(GtkCheckMenuItem *, GPanelItem *); static void mcb_view_change_support(GtkRadioMenuItem *, gpointer); /* Réagit avec le menu "Affichage -> Basculer vers le suivant". */ -static void mcb_view_switch_to_next_support(GtkRadioMenuItem *, GObject *); +static void mcb_view_switch_to_next_support(GtkRadioMenuItem *, GMenuBar *); /* Réagit avec le menu "Affichage -> Basculer vers le précédent". */ -static void mcb_view_switch_to_prev_support(GtkRadioMenuItem *, GObject *); +static void mcb_view_switch_to_prev_support(GtkRadioMenuItem *, GMenuBar *); /* Accompagne la première allocation d'un panneau d'affichage. */ static void handle_loaded_panel_first_allocation(GtkWidget *, GdkRectangle *, GLineCursor *); @@ -75,110 +72,63 @@ static void mcb_view_display_column(GtkCheckMenuItem *, gpointer); /* Réagit avec le menu "Affichage -> Plein écran". */ static void mcb_view_show_full_screen(GtkCheckMenuItem *, gpointer); +/* Met à jour les accès du menu "Affichage -> Basculer...". */ +static void update_switch_access_in_menu_view(GtkBuilder *); + /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* bar = barre de menu parente. * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Construit le menu "Affichage". * +* Description : Complète la définition du menu "Affichage". * * * -* Retour : Panneau de menus mis en place. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar) +void setup_menu_view_callbacks(GtkBuilder *builder) { - GtkWidget *result; /* Support à retourner */ - GtkWidget *menubar; /* Support pour éléments */ - GtkWidget *submenuitem; /* Sous-élément de menu */ + GObject *item; /* Elément à compléter */ - result = gtk_menu_item_new_with_mnemonic(_("_View")); - gtk_widget_show(result); +#define DEFINE_CALLBACK(cb) #cb, G_CALLBACK(cb) - menubar = qck_create_menu(GTK_MENU_ITEM(result)); + gtk_builder_add_callback_symbols(builder, + DEFINE_CALLBACK(mcb_view_update_side_panels_list), + DEFINE_CALLBACK(mcb_view_switch_to_next_support), + DEFINE_CALLBACK(mcb_view_switch_to_prev_support), + DEFINE_CALLBACK(mcb_view_zoom), + DEFINE_CALLBACK(mcb_view_show_full_screen), + NULL); /* Affichage -> Panneaux latéraux */ - submenuitem = qck_create_menu_item(ref, "mnu_view_side_panels", _("Side panels"), NULL, NULL); - g_signal_connect(submenuitem, "select", G_CALLBACK(mcb_view_update_side_panels_list), bar); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - qck_create_menu(GTK_MENU_ITEM(submenuitem)); - - /* Séparation */ + item = gtk_builder_get_object(builder, "view_side_panels"); - 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_menu_item(ref, "mnu_view_switch_to_next_support", _("Switch to next"), - G_CALLBACK(mcb_view_switch_to_next_support), ref); - add_accelerator_to_widget(submenuitem, "Tab"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_view_switch_to_prev_support", _("Switch to previous"), - G_CALLBACK(mcb_view_switch_to_prev_support), ref); - add_accelerator_to_widget(submenuitem, "Tab"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Séparation */ - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + qck_create_menu(GTK_MENU_ITEM(item)); /* Zooms */ - submenuitem = qck_create_menu_item(ref, "mnu_view_zoom_in", _("Zoom in"), - G_CALLBACK(mcb_view_zoom), GINT_TO_POINTER(0)); - add_accelerator_to_widget(submenuitem, "plus"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_view_zoom_out", _("Zoom out"), - G_CALLBACK(mcb_view_zoom), GINT_TO_POINTER(1)); - add_accelerator_to_widget(submenuitem, "minus"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - submenuitem = qck_create_menu_item(ref, "mnu_view_zoom_reset", _("Reset zoom"), - G_CALLBACK(mcb_view_zoom), GINT_TO_POINTER(2)); - add_accelerator_to_widget(submenuitem, "0"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Séparation */ + item = gtk_builder_get_object(builder, "view_zoom_in"); + g_object_set_data(item, "kind_of_zoom", GINT_TO_POINTER(0)); - submenuitem = qck_create_menu_separator(); - g_object_set_data(ref, "mnu_view_start_options", submenuitem); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + item = gtk_builder_get_object(builder, "view_zoom_out"); + g_object_set_data(item, "kind_of_zoom", GINT_TO_POINTER(1)); - /* Séparation */ - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - /* Affichage -> Plein écran */ - - submenuitem = qck_create_check_menu_item(NULL, NULL, _("Full screen"), - G_CALLBACK(mcb_view_show_full_screen), NULL); - add_accelerator_to_widget(submenuitem, "F11"); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - return result; + item = gtk_builder_get_object(builder, "view_zoom_reset"); + g_object_set_data(item, "kind_of_zoom", GINT_TO_POINTER(2)); } /****************************************************************************** * * -* Paramètres : widget = menu principal à actualiser. * -* ref = espace de référencement global. * -* new = nouveau contenu chargé à analyser. * +* Paramètres : menuitem = élément de menu sélectionné. * +* bar = barre de menu parente. * * * -* Description : Réagit à un changement d'affichage principal de contenu. * +* Description : Réagit avec le menu "Affichage -> Panneaux latéraux". * * * * Retour : - * * * @@ -186,101 +136,115 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar) * * ******************************************************************************/ -void rebuild_menu_view_for_content(GtkWidget *widget, GObject *ref, GLoadedContent *new) +void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) { - 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 */ - 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 */ - char *caption; /* Etiquette pour un menu */ + GtkWidget *menu; /* Support pour éléments */ + GtkBuilder *builder; /* Constructeur principal */ - /* Retrait d'éventuels anciens menus */ + typedef struct _panels_loading_filter + { + GtkContainer *support; /* Support pour éléments */ - menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); + PanelItemPersonality personality; /* Nature des éléments attendus*/ + bool first; /* Premier ajout ? */ - for (i = 0; ; i++) - { - asprintf(&key, "mnu_view_panel_%u", i); + } panels_loading_filter; - submenuitem = g_object_get_data(ref, key); + panels_loading_filter pfilter; /* Mécanismes de filtrage */ - free(key); + menu = gtk_menu_item_get_submenu(menuitem); - if (submenuitem == NULL) - break; - else - gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(submenuitem)); + /* Réinitialisation */ + + void remove_panel_menu_item(GtkWidget *widget, GtkContainer *container) + { + gtk_container_remove(container, widget); } - if (new != NULL) - { - /* Insertion des différentes vues */ + gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)remove_panel_menu_item, menu); - marker = g_object_get_data(ref, "mnu_view_start_panels"); + /* Ajout des panneaux uniques */ - list = gtk_container_get_children(GTK_CONTAINER(menubar)); + bool add_side_panel_to_list(GPanelItem *panel, panels_loading_filter *filter) + { + char *key; /* Désignation de l'entrée */ + GtkWidget *submenuitem; /* Sous-élément de menu */ + const char *bindings; /* Raccourcis clavier bruts */ - position = 0; + if (gtk_panel_item_get_personality(panel) != filter->personality) + goto aptl_exit; - for (iter = list; iter != NULL; iter = g_list_next(iter)) + /* Séparation */ + + if (filter->first) { - position++; + filter->first = false; - if (marker == iter->data) - break; + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(menu), submenuitem); } - g_list_free(list); + /* Elément de menu */ - count = g_loaded_content_count_views(new); + key = g_editor_item_get_key(G_EDITOR_ITEM(panel)); - rgroup = NULL; + submenuitem = qck_create_check_menu_item(NULL, NULL, key, + G_CALLBACK(mcb_view_change_panel_docking), panel); - for (i = 0; i < count; i++) - { - asprintf(&key, "mnu_view_panel_%u", i); - caption = g_loaded_content_get_view_name(new, i); + free(key); - submenuitem = qck_create_radio_menu_item(ref, key, rgroup, caption, - G_CALLBACK(mcb_view_change_support), NULL); - g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(i)); + bindings = gtk_panel_item_get_key_bindings(panel); - free(caption); - free(key); + if (bindings != NULL) + { + builder = g_menu_bar_get_builder(bar); + add_accelerator_to_widget(builder, submenuitem, bindings); + g_object_unref(G_OBJECT(builder)); + } - asprintf(&key, "F%u", 3 + i); + gtk_container_add(filter->support, submenuitem); - add_accelerator_to_widget(submenuitem, key); + /* Statut de la coche */ - free(key); + if (g_panel_item_is_docked(panel)) + { + g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_change_panel_docking), panel); - if (rgroup == NULL) - rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem)); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), TRUE); - gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), submenuitem, position + i); + g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_change_panel_docking), panel); } + aptl_exit: + + return true; + } + pfilter.support = GTK_CONTAINER(menu); + + pfilter.personality = PIP_SINGLETON; + pfilter.first = false; + + browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter); + + pfilter.personality = PIP_OTHER; + pfilter.first = true; + + browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter); + } /****************************************************************************** * * -* Paramètres : widget = menu principal à actualiser. * -* ref = espace de référencement global. * -* new = nouvelle vue du contenu chargé analysé. * +* Paramètres : menuitem = élément de menu ayant basculé. * +* bar = barre de menu parente. * * * -* Description : Lance une actualisation du fait d'un changement de support. * +* Description : Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". * * * * Retour : - * * * @@ -288,145 +252,167 @@ void rebuild_menu_view_for_content(GtkWidget *widget, GObject *ref, GLoadedConte * * ******************************************************************************/ -void rebuild_menu_view_for_view(GtkWidget *widget, GObject *ref, GLoadedPanel *new) +static void mcb_view_change_panel_docking(GtkCheckMenuItem *menuitem, GPanelItem *item) { - 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 */ + gboolean active; /* Etat de sélection du menu */ - content = get_current_content(); - assert((content == NULL && new == NULL) || (content != NULL && new != NULL)); + /** + * Comme l'accrochage et le décrochage d'un panneau peuvent se réaliser + * sans l'aide de ce menu (via les menus des stations d'accueil par exemple), + * on ne peut se baser sur l'état de ce menu, mis à jour uniquement à + * l'affichage, pour basculer lors de l'activation dudit menu via les raccourcis. + * + * L'appel suivant peut donc conduire à des erreurs, ie on réaccroche un + * panneau déjà accroché ou l'inverse : + * + * active = gtk_check_menu_item_get_active(menuitem); + * + * On préfèrera donc se baser sur l'état courant du panneau. + */ - /* Retrait d'éventuels anciens menus */ + active = !g_panel_item_is_docked(item); - menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); + if (active) + g_panel_item_dock(item); + else + g_panel_item_undock(item); - marker = g_object_get_data(ref, "mnu_view_start_options"); +} - for (i = 0; ; i++) - { - asprintf(&key, "mnu_view_display_option_%zu", i); - submenuitem = g_object_get_data(ref, key); +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* unused = adresse non utilisée ici. * +* * +* Description : Réagit avec le menu "Affichage -> Vue xxx". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - free(key); +static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused) +{ + GSList *group; /* Liste de menus radio */ + GSList *iter; /* Boucle de parcours */ + unsigned int wanted; /* Nouvelle vue à présenter */ - if (submenuitem == NULL) - break; - else - gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(submenuitem)); + /* On ne traite qu'une seule fois ! */ + if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return; - } + group = gtk_radio_menu_item_get_group(menuitem); - if (content != NULL) + for (iter = group; iter != NULL; iter = g_slist_next(iter)) { - index = g_loaded_content_get_view_index(content, GTK_WIDGET(new)); - - /* Mise à jour du choix de la vue */ - - item = GTK_RADIO_MENU_ITEM(g_object_get_data(ref, "mnu_view_panel_0")); + if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(iter->data))) continue; - radios = gtk_radio_menu_item_get_group(item); + wanted = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view")); - void disconnect_display_radio(GtkWidget *wgt, gpointer unused) - { - g_signal_handlers_disconnect_by_func(wgt, G_CALLBACK(mcb_view_change_support), NULL); - } + change_current_view_support(wanted); - 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); +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* bar = barre de menu parente. * +* * +* Description : Réagit avec le menu "Affichage -> Basculer vers le suivant". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - void reconnect_display_radio(GtkWidget *wgt, gpointer unused) - { - g_signal_connect(wgt, "toggled", G_CALLBACK(mcb_view_change_support), NULL); - } +static void mcb_view_switch_to_next_support(GtkRadioMenuItem *menuitem, GMenuBar *bar) +{ + GLoadedPanel *panel; /* Afficheur effectif de code */ + GLoadedContent *content; /* Contenu représenté */ + unsigned int index; /* Indice de la vue courante */ +#ifndef NDEBUG + unsigned int count; /* Nombre de vues possibles */ +#endif + GtkBuilder *builder; /* Constructeur lié au menu */ - g_slist_foreach(radios, (GFunc)reconnect_display_radio, NULL); + panel = get_current_view(); + content = g_loaded_panel_get_content(panel); - /* Insertion des options de rendu */ + index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); - list = gtk_container_get_children(GTK_CONTAINER(menubar)); +#ifndef NDEBUG + count = g_loaded_content_count_views(content); - position = 0; + assert((index + 1) < count); +#endif - for (iter = list; iter != NULL; iter = g_list_next(iter)) - { - position++; + change_current_view_support(index + 1); - if (marker == iter->data) - break; + g_object_unref(G_OBJECT(content)); + g_object_unref(G_OBJECT(panel)); - } + builder = g_menu_bar_get_builder(bar); - g_list_free(list); + update_switch_access_in_menu_view(builder); - options = g_loaded_content_get_display_options(content, index); + g_object_unref(G_OBJECT(builder)); - count = g_display_options_count(options); +} - for (i = 0; i < count; i++) - { - asprintf(&key, "mnu_view_display_option_%zu", i); - 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)); - - gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), submenuitem, position + i); - - free(key); +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* bar = barre de menu parente. * +* * +* Description : Réagit avec le menu "Affichage -> Basculer ... précédent". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - /** - * 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 ! - */ +static void mcb_view_switch_to_prev_support(GtkRadioMenuItem *menuitem, GMenuBar *bar) +{ + GLoadedPanel *panel; /* Afficheur effectif de code */ + GLoadedContent *content; /* Contenu représenté */ + unsigned int index; /* Indice de la vue courante */ + GtkBuilder *builder; /* Constructeur lié au menu */ - status = g_display_options_get(options, i); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), status); + panel = get_current_view(); + content = g_loaded_panel_get_content(panel); - } + index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); - g_object_unref(G_OBJECT(options)); + assert(index > 0); - g_object_unref(G_OBJECT(content)); + change_current_view_support(index - 1); - } + g_object_unref(G_OBJECT(content)); + g_object_unref(G_OBJECT(panel)); - else - count = 0; + builder = g_menu_bar_get_builder(bar); - /* Utilité de la séparation ? */ + update_switch_access_in_menu_view(builder); - gtk_widget_set_visible(GTK_WIDGET(marker), count > 0); + g_object_unref(G_OBJECT(builder)); } /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * -* new = nouvelle vue du contenu chargé analysé. * +* Paramètres : widget = composant graphique visé par la procédure. * +* alloc = emplacement accordé à ce composant. * +* cursor = emplacement transmis à présenter en premier lieu. * * * -* Description : Met à jour les accès du menu "Affichage" selon le contenu. * +* Description : Accompagne la première allocation d'un panneau d'affichage. * * * * Retour : - * * * @@ -434,36 +420,23 @@ void rebuild_menu_view_for_view(GtkWidget *widget, GObject *ref, GLoadedPanel *n * * ******************************************************************************/ -void update_access_for_view_in_menu_view(GObject *ref, GLoadedPanel *new) +static void handle_loaded_panel_first_allocation(GtkWidget *widget, GdkRectangle *alloc, GLineCursor *cursor) { - gboolean access; /* Accès à déterminer */ - GtkWidget *item; /* Elément de menu à traiter */ - - /* Bascules */ - - update_switch_access_in_menu_view(ref); - - /* Zooms */ - - access = GTK_IS_GRAPH_DISPLAY(new); - - item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_in")); - gtk_widget_set_sensitive(item, access); + /* On ne réagit que la première fois */ + g_signal_handlers_disconnect_by_func(widget, G_CALLBACK(handle_loaded_panel_first_allocation), cursor); - item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_out")); - gtk_widget_set_sensitive(item, access); + g_loaded_panel_scroll_to_cursor(G_LOADED_PANEL(widget), cursor, SPT_TOP, true); - item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_reset")); - gtk_widget_set_sensitive(item, access); + g_object_unref(G_OBJECT(cursor)); } /****************************************************************************** * * -* Paramètres : ref = espace de référencement global. * +* Paramètres : wanted = indice de la vue désirée. * * * -* Description : Met à jour les accès du menu "Affichage -> Basculer...". * +* Description : Effectue la bascule d'un panneau de chargement à un autre. * * * * Retour : - * * * @@ -471,54 +444,72 @@ void update_access_for_view_in_menu_view(GObject *ref, GLoadedPanel *new) * * ******************************************************************************/ -static void update_switch_access_in_menu_view(GObject *ref) +static void change_current_view_support(unsigned int wanted) { GLoadedPanel *panel; /* Afficheur effectif de code */ + GtkDockStation *station; /* Base du remplacement */ GLoadedContent *content; /* Contenu représenté */ - unsigned int count; /* Nombre de vues possibles */ - unsigned int index; /* Indice de la vue courante */ - gboolean access; /* Accès à déterminer */ - GtkWidget *item; /* Elément de menu à traiter */ + GtkWidget *support; /* Nouvel afficheur généraliste*/ + GLoadedPanel *new; /* Panneau encapsulé */ + GLineCursor *cursor; /* Position à transmettre */ panel = get_current_view(); - if (panel == NULL) - content = NULL; + station = get_dock_station_for_view_panel(GTK_WIDGET(panel)); - else - { - content = g_loaded_panel_get_content(panel); + content = g_loaded_panel_get_content(panel); - count = g_loaded_content_count_views(content); - index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); + support = g_loaded_content_build_view(content, wanted); - } + g_object_unref(G_OBJECT(content)); - access = (panel != NULL && (index + 1) < count); + gtk_dock_panel_change_active_widget(station, support); - item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_to_next_support")); - gtk_widget_set_sensitive(item, access); + new = G_LOADED_PANEL(get_loaded_panel_from_built_view(support)); - access = (panel != NULL && index > 0); + cursor = g_loaded_panel_get_cursor(panel); - item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_to_prev_support")); - gtk_widget_set_sensitive(item, access); + change_editor_items_current_view(new); - if (panel != NULL) + if (cursor != NULL) { - g_object_unref(G_OBJECT(content)); - g_object_unref(G_OBJECT(panel)); + /** + * A ce stade, le nouveau composant d'affichage n'a pas encore connu son + * premier gtk_widget_size_allocate(). Cela viendra avec un événement ultérieur + * à celui déclenché pour ce menu. + * + * Dans les faits, cette situation est notable pour la vue en graphique : + * tous les blocs basiques chargés et intégrés dedans ont une position + * égale à -1 et une dimension d'un pixel. + * + * La recherche du bloc présent à une position donnée échoue donc dans la + * fonction gtk_graph_display_move_caret_to(), appelée in fine par + * g_loaded_panel_scroll_to_cursor(). + * + * Et au final, le curseur d'origine n'est pas transmis, et donc pas + * transmissible non plus par la suite. + * + * On se doit ainsi d'attendre l'attribution des emplacements avant de déplacer + * le curseur et de terminer de cet fait les opérations. + */ + + g_signal_connect(new, "size-allocate", G_CALLBACK(handle_loaded_panel_first_allocation), cursor); + } + g_object_unref(G_OBJECT(new)); + + g_object_unref(G_OBJECT(panel)); + } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * -* bar = barre de menu parente. * +* unused = adresse non utilisée ici. * * * -* Description : Réagit avec le menu "Affichage -> Panneaux latéraux". * +* Description : Réagit avec le menu "Affichage -> Zoom *". * * * * Retour : - * * * @@ -526,111 +517,93 @@ static void update_switch_access_in_menu_view(GObject *ref) * * ******************************************************************************/ -void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) +static void mcb_view_zoom(GtkCheckMenuItem *menuitem, gpointer unused) { - GtkWidget *menubar; /* Support pour éléments */ - - typedef struct _panels_loading_filter - { - GtkContainer *support; /* Support pour éléments */ - - PanelItemPersonality personality; /* Nature des éléments attendus*/ - bool first; /* Premier ajout ? */ - - } panels_loading_filter; - - panels_loading_filter pfilter; - - - menubar = gtk_menu_item_get_submenu(menuitem); - - /* Réinitialisation */ - - void remove_panel_menu_item(GtkWidget *widget, GtkContainer *container) - { - gtk_container_remove(container, widget); + GtkDisplayPanel *panel; /* Afficheur effectif de code */ + double scale; /* Echelle à appliquer */ + int zoom_kind; /* Type de zoom à appliquer */ - } + panel = GTK_DISPLAY_PANEL(get_current_view()); - gtk_container_foreach(GTK_CONTAINER(menubar), (GtkCallback)remove_panel_menu_item, menubar); + scale = gtk_display_panel_get_scale(panel); - /* Ajout des panneaux uniques */ + zoom_kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menuitem), "kind_of_zoom")); - bool add_side_panel_to_list(GPanelItem *panel, panels_loading_filter *filter) + switch (zoom_kind) { - char *key; /* Désignation de l'entrée */ - GtkWidget *submenuitem; /* Sous-élément de menu */ - const char *bindings; /* Raccourcis clavier bruts */ - - if (gtk_panel_item_get_personality(panel) != filter->personality) - goto aptl_exit; - - /* Séparation */ - - if (filter->first) - { - filter->first = false; - - submenuitem = qck_create_menu_separator(); - gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - - } - - /* Elément de menu */ - - key = g_editor_item_get_key(G_EDITOR_ITEM(panel)); - - submenuitem = qck_create_check_menu_item(NULL, NULL, key, - G_CALLBACK(mcb_view_change_panel_docking), panel); + case 0: + scale /= 1.25; + break; - free(key); + case 1: + scale *= 1.25; + break; - bindings = gtk_panel_item_get_key_bindings(panel); + case 2: + scale = 1.0; + break; - if (bindings != NULL) - add_accelerator_to_widget(submenuitem, bindings); + default: + assert(false); + scale = 1.0; + break; - gtk_container_add(filter->support, submenuitem); + } - /* Statut de la coche */ + gtk_display_panel_set_scale(panel, scale); - if (g_panel_item_is_docked(panel)) - { - g_signal_handlers_disconnect_by_func(submenuitem, G_CALLBACK(mcb_view_change_panel_docking), panel); +} - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), TRUE); - g_signal_connect(submenuitem, "toggled", G_CALLBACK(mcb_view_change_panel_docking), panel); +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu ayant basculé. * +* unused = adresse non utilisée ici. * +* * +* Description : Réagit avec le menu "Affichage -> (colonne xxx)". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - } +static void mcb_view_display_column(GtkCheckMenuItem *menuitem, gpointer unused) +{ + unsigned int option; /* Paramètre à traiter */ + gboolean active; /* Etat de sélection du menu */ + GLoadedPanel *panel; /* Afficheur effectif de code */ + GLoadedContent *content; /* Contenu représenté */ + unsigned int index; /* Indice de la vue courante */ + GDisplayOptions *options; /* Ensemble à mettre à jour */ - aptl_exit: + option = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_opt")); - return true; + active = gtk_check_menu_item_get_active(menuitem); - } + panel = get_current_view(); + content = g_loaded_panel_get_content(panel); - pfilter.support = GTK_CONTAINER(menubar); + index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); - pfilter.personality = PIP_SINGLETON; - pfilter.first = false; + options = g_loaded_content_get_display_options(content, index); - browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter); + g_display_options_set(options, option, active); - pfilter.personality = PIP_OTHER; - pfilter.first = true; + g_object_unref(G_OBJECT(options)); - browse_all_item_panels((handle_panel_item_fc)add_side_panel_to_list, &pfilter); + g_object_unref(G_OBJECT(content)); + g_object_unref(G_OBJECT(panel)); } /****************************************************************************** * * -* Paramètres : menuitem = élément de menu ayant basculé. * -* bar = barre de menu parente. * +* Paramètres : menuitem = élément de menu sélectionné. * +* unused = adresse non utilisée ici. * * * -* Description : Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". * +* Description : Réagit avec le menu "Affichage -> Plein écran". * * * * Retour : - * * * @@ -638,40 +611,31 @@ void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) * * ******************************************************************************/ -static void mcb_view_change_panel_docking(GtkCheckMenuItem *menuitem, GPanelItem *item) +static void mcb_view_show_full_screen(GtkCheckMenuItem *menuitem, gpointer unused) { + GtkWindow *editor; /* Fenêtre graphique principale*/ gboolean active; /* Etat de sélection du menu */ - /** - * Comme l'accrochage et le décrochage d'un panneau peuvent se réaliser - * sans l'aide de ce menu (via les menus des stations d'accueil par exemple), - * on ne peut se baser sur l'état de ce menu, mis à jour uniquement à - * l'affichage, pour basculer lors de l'activation dudit menu via les raccourcis. - * - * L'appel suivant peut donc conduire à des erreurs, ie on réaccroche un - * panneau déjà accroché ou l'inverse : - * - * active = gtk_check_menu_item_get_active(menuitem); - * - * On préfèrera donc se baser sur l'état courant du panneau. - */ + editor = get_editor_window(); - active = !g_panel_item_is_docked(item); + active = gtk_check_menu_item_get_active(menuitem); if (active) - g_panel_item_dock(item); + gtk_window_fullscreen(editor); else - g_panel_item_undock(item); + gtk_window_unfullscreen(editor); + + g_object_unref(G_OBJECT(editor)); } /****************************************************************************** * * -* Paramètres : menuitem = élément de menu ayant basculé. * -* unused = adresse non utilisée ici. * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* new = nouveau contenu chargé à analyser. * * * -* Description : Réagit avec le menu "Affichage -> Vue xxx". * +* Description : Réagit à un changement d'affichage principal de contenu. * * * * Retour : - * * * @@ -679,79 +643,103 @@ static void mcb_view_change_panel_docking(GtkCheckMenuItem *menuitem, GPanelItem * * ******************************************************************************/ -static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused) +void rebuild_menu_view_for_content(GtkBuilder *builder, GLoadedContent *new) { - GSList *group; /* Liste de menus radio */ - GSList *iter; /* Boucle de parcours */ - unsigned int wanted; /* Nouvelle vue à présenter */ + GObject *menuitem; /* Menu d'affichage */ + GtkWidget *menu; /* 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 */ + 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 */ + char *caption; /* Etiquette pour un menu */ - /* On ne traite qu'une seule fois ! */ - if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return; + /* Retrait d'éventuels anciens menus */ - group = gtk_radio_menu_item_get_group(menuitem); + menuitem = gtk_builder_get_object(builder, "view"); - for (iter = group; iter != NULL; iter = g_slist_next(iter)) + menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)); + + for (i = 0; ; i++) { - if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(iter->data))) continue; + asprintf(&key, "view_panel_%u", i); - wanted = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view")); + submenuitem = g_object_get_data(menuitem, key); - change_current_view_support(wanted); + free(key); + + if (submenuitem == NULL) + break; + else + gtk_container_remove(GTK_CONTAINER(menu), GTK_WIDGET(submenuitem)); } -} + if (new != NULL) + { + /* Insertion des différentes vues */ + marker = gtk_builder_get_object(builder, "view_sep_0"); -/****************************************************************************** -* * -* Paramètres : menuitem = élément de menu ayant basculé. * -* ref = espace de référencement global. * -* * -* Description : Réagit avec le menu "Affichage -> Basculer vers le suivant". * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + list = gtk_container_get_children(GTK_CONTAINER(menu)); -static void mcb_view_switch_to_next_support(GtkRadioMenuItem *menuitem, GObject *ref) -{ - GLoadedPanel *panel; /* Afficheur effectif de code */ - GLoadedContent *content; /* Contenu représenté */ - unsigned int index; /* Indice de la vue courante */ -#ifndef NDEBUG - unsigned int count; /* Nombre de vues possibles */ -#endif + position = 0; - panel = get_current_view(); - content = g_loaded_panel_get_content(panel); + for (iter = list; iter != NULL; iter = g_list_next(iter)) + { + position++; - index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); + if (marker == iter->data) + break; -#ifndef NDEBUG - count = g_loaded_content_count_views(content); + } - assert((index + 1) < count); -#endif + g_list_free(list); - change_current_view_support(index + 1); + count = g_loaded_content_count_views(new); - g_object_unref(G_OBJECT(content)); - g_object_unref(G_OBJECT(panel)); + rgroup = NULL; - update_switch_access_in_menu_view(ref); + for (i = 0; i < count; i++) + { + asprintf(&key, "view_panel_%u", i); + caption = g_loaded_content_get_view_name(new, i); + + submenuitem = qck_create_radio_menu_item(menuitem, key, rgroup, caption, + G_CALLBACK(mcb_view_change_support), NULL); + g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(i)); + + free(caption); + free(key); + + asprintf(&key, "F%u", 3 + i); + + add_accelerator_to_widget(builder, submenuitem, key); + + free(key); + + if (rgroup == NULL) + rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem)); + + gtk_menu_shell_insert(GTK_MENU_SHELL(menu), submenuitem, position + i); + + } + + } } /****************************************************************************** * * -* Paramètres : menuitem = élément de menu ayant basculé. * -* ref = espace de référencement global. * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* new = nouvelle vue du contenu chargé analysé. * * * -* Description : Réagit avec le menu "Affichage -> Basculer ... précédent". * +* Description : Lance une actualisation du fait d'un changement de support. * * * * Retour : - * * * @@ -759,176 +747,148 @@ static void mcb_view_switch_to_next_support(GtkRadioMenuItem *menuitem, GObject * * ******************************************************************************/ -static void mcb_view_switch_to_prev_support(GtkRadioMenuItem *menuitem, GObject *ref) +void rebuild_menu_view_for_view(GtkBuilder *builder, GLoadedPanel *new) { - GLoadedPanel *panel; /* Afficheur effectif de code */ - GLoadedContent *content; /* Contenu représenté */ - unsigned int index; /* Indice de la vue courante */ + GObject *menuitem; /* Menu d'affichage */ + GLoadedContent *content; /* Contenu en cours d'analyse */ + unsigned int index; /* Indice de la vue */ + GtkWidget *menu; /* 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 */ - panel = get_current_view(); - content = g_loaded_panel_get_content(panel); + menuitem = gtk_builder_get_object(builder, "view"); - index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); + content = get_current_content(); + assert((content == NULL && new == NULL) || (content != NULL && new != NULL)); - assert(index > 0); + /* Retrait d'éventuels anciens menus */ - change_current_view_support(index - 1); + menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)); - g_object_unref(G_OBJECT(content)); - g_object_unref(G_OBJECT(panel)); + marker = gtk_builder_get_object(builder, "view_sep_2"); - update_switch_access_in_menu_view(ref); + for (i = 0; ; i++) + { + asprintf(&key, "view_display_option_%zu", i); -} + submenuitem = g_object_get_data(menuitem, key); + free(key); -/****************************************************************************** -* * -* Paramètres : widget = composant graphique visé par la procédure. * -* alloc = emplacement accordé à ce composant. * -* cursor = emplacement transmis à présenter en premier lieu. * -* * -* Description : Accompagne la première allocation d'un panneau d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + if (submenuitem == NULL) + break; + else + gtk_container_remove(GTK_CONTAINER(menu), GTK_WIDGET(submenuitem)); -static void handle_loaded_panel_first_allocation(GtkWidget *widget, GdkRectangle *alloc, GLineCursor *cursor) -{ - /* On ne réagit que la première fois */ - g_signal_handlers_disconnect_by_func(widget, G_CALLBACK(handle_loaded_panel_first_allocation), cursor); + } - g_loaded_panel_scroll_to_cursor(G_LOADED_PANEL(widget), cursor, SPT_TOP, true); + if (content != NULL) + { + index = g_loaded_content_get_view_index(content, GTK_WIDGET(new)); - g_object_unref(G_OBJECT(cursor)); + /* Mise à jour du choix de la vue */ -} + item = GTK_RADIO_MENU_ITEM(g_object_get_data(menuitem, "view_panel_0")); + radios = gtk_radio_menu_item_get_group(item); -/****************************************************************************** -* * -* Paramètres : wanted = indice de la vue désirée. * -* * -* Description : Effectue la bascule d'un panneau de chargement à un autre. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + void disconnect_display_radio(GtkWidget *wgt, gpointer unused) + { + g_signal_handlers_disconnect_by_func(wgt, G_CALLBACK(mcb_view_change_support), NULL); + } -static void change_current_view_support(unsigned int wanted) -{ - GLoadedPanel *panel; /* Afficheur effectif de code */ - GtkDockStation *station; /* Base du remplacement */ - GLoadedContent *content; /* Contenu représenté */ - GtkWidget *support; /* Nouvel afficheur généraliste*/ - GLoadedPanel *new; /* Panneau encapsulé */ - GLineCursor *cursor; /* Position à transmettre */ + g_slist_foreach(radios, (GFunc)disconnect_display_radio, NULL); - panel = get_current_view(); + asprintf(&key, "view_panel_%u", index); - station = get_dock_station_for_view_panel(GTK_WIDGET(panel)); + item = GTK_RADIO_MENU_ITEM(g_object_get_data(menuitem, key)); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); - content = g_loaded_panel_get_content(panel); + free(key); - support = g_loaded_content_build_view(content, wanted); + void reconnect_display_radio(GtkWidget *wgt, gpointer unused) + { + g_signal_connect(wgt, "toggled", G_CALLBACK(mcb_view_change_support), NULL); + } - g_object_unref(G_OBJECT(content)); + g_slist_foreach(radios, (GFunc)reconnect_display_radio, NULL); - gtk_dock_panel_change_active_widget(station, support); + /* Insertion des options de rendu */ - new = G_LOADED_PANEL(get_loaded_panel_from_built_view(support)); + list = gtk_container_get_children(GTK_CONTAINER(menu)); - cursor = g_loaded_panel_get_cursor(panel); + position = 0; - change_editor_items_current_view(new); + for (iter = list; iter != NULL; iter = g_list_next(iter)) + { + position++; - if (cursor != NULL) - { - /** - * A ce stade, le nouveau composant d'affichage n'a pas encore connu son - * premier gtk_widget_size_allocate(). Cela viendra avec un événement ultérieur - * à celui déclenché pour ce menu. - * - * Dans les faits, cette situation est notable pour la vue en graphique : - * tous les blocs basiques chargés et intégrés dedans ont une position - * égale à -1 et une dimension d'un pixel. - * - * La recherche du bloc présent à une position donnée échoue donc dans la - * fonction gtk_graph_display_move_caret_to(), appelée in fine par - * g_loaded_panel_scroll_to_cursor(). - * - * Et au final, le curseur d'origine n'est pas transmis, et donc pas - * transmissible non plus par la suite. - * - * On se doit ainsi d'attendre l'attribution des emplacements avant de déplacer - * le curseur et de terminer de cet fait les opérations. - */ + if (marker == iter->data) + break; - g_signal_connect(new, "size-allocate", G_CALLBACK(handle_loaded_panel_first_allocation), cursor); + } - } + g_list_free(list); - g_object_unref(G_OBJECT(new)); + options = g_loaded_content_get_display_options(content, index); - g_object_unref(G_OBJECT(panel)); + count = g_display_options_count(options); -} + for (i = 0; i < count; i++) + { + asprintf(&key, "view_display_option_%zu", i); + submenuitem = qck_create_check_menu_item(menuitem, 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)); -/****************************************************************************** -* * -* Paramètres : menuitem = élément de menu sélectionné. * -* data = données indiquant la nature du zoom. * -* * -* Description : Réagit avec le menu "Affichage -> Zoom *". * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + gtk_menu_shell_insert(GTK_MENU_SHELL(menu), submenuitem, position + i); -static void mcb_view_zoom(GtkCheckMenuItem *menuitem, gpointer data) -{ - GtkDisplayPanel *panel; /* Afficheur effectif de code */ - double scale; /* Echelle à appliquer */ + free(key); - panel = GTK_DISPLAY_PANEL(get_current_view()); + /** + * 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 ! + */ - scale = gtk_display_panel_get_scale(panel); + status = g_display_options_get(options, i); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), status); - switch (GPOINTER_TO_INT(data)) - { - case 0: - scale /= 1.25; - break; + } - case 1: - scale *= 1.25; - break; + g_object_unref(G_OBJECT(options)); - case 2: - scale = 1.0; - break; + g_object_unref(G_OBJECT(content)); } - gtk_display_panel_set_scale(panel, scale); + else + count = 0; + + /* Utilité de la séparation ? */ + + gtk_widget_set_visible(GTK_WIDGET(marker), count > 0); } /****************************************************************************** * * -* Paramètres : menuitem = élément de menu ayant basculé. * -* unused = adresse non utilisée ici. * +* Paramètres : builder = constructeur avec l'ensemble des références. * +* new = nouvelle vue du contenu chargé analysé. * * * -* Description : Réagit avec le menu "Affichage -> (colonne xxx)". * +* Description : Met à jour les accès du menu "Affichage" selon le contenu. * * * * Retour : - * * * @@ -936,42 +896,36 @@ static void mcb_view_zoom(GtkCheckMenuItem *menuitem, gpointer data) * * ******************************************************************************/ -static void mcb_view_display_column(GtkCheckMenuItem *menuitem, gpointer unused) +void update_access_for_view_in_menu_view(GtkBuilder *builder, GLoadedPanel *new) { - unsigned int option; /* Paramètre à traiter */ - gboolean active; /* Etat de sélection du menu */ - GLoadedPanel *panel; /* Afficheur effectif de code */ - GLoadedContent *content; /* Contenu représenté */ - unsigned int index; /* Indice de la vue courante */ - GDisplayOptions *options; /* Ensemble à mettre à jour */ - - option = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_opt")); + gboolean access; /* Accès à déterminer */ + GtkWidget *item; /* Elément de menu à traiter */ - active = gtk_check_menu_item_get_active(menuitem); + /* Bascules */ - panel = get_current_view(); - content = g_loaded_panel_get_content(panel); + update_switch_access_in_menu_view(builder); - index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); + /* Zooms */ - options = g_loaded_content_get_display_options(content, index); + access = GTK_IS_GRAPH_DISPLAY(new); - g_display_options_set(options, option, active); + item = GTK_WIDGET(gtk_builder_get_object(builder, "view_zoom_in")); + gtk_widget_set_sensitive(item, access); - g_object_unref(G_OBJECT(options)); + item = GTK_WIDGET(gtk_builder_get_object(builder, "view_zoom_out")); + gtk_widget_set_sensitive(item, access); - g_object_unref(G_OBJECT(content)); - g_object_unref(G_OBJECT(panel)); + item = GTK_WIDGET(gtk_builder_get_object(builder, "view_zoom_reset")); + gtk_widget_set_sensitive(item, access); } /****************************************************************************** * * -* Paramètres : menuitem = élément de menu sélectionné. * -* unused = adresse non utilisée ici. * +* Paramètres : builder = constructeur avec l'ensemble des références. * * * -* Description : Réagit avec le menu "Affichage -> Plein écran". * +* Description : Met à jour les accès du menu "Affichage -> Basculer...". * * * * Retour : - * * * @@ -979,20 +933,43 @@ static void mcb_view_display_column(GtkCheckMenuItem *menuitem, gpointer unused) * * ******************************************************************************/ -static void mcb_view_show_full_screen(GtkCheckMenuItem *menuitem, gpointer unused) +static void update_switch_access_in_menu_view(GtkBuilder *builder) { - GtkWindow *editor; /* Fenêtre graphique principale*/ - gboolean active; /* Etat de sélection du menu */ + GLoadedPanel *panel; /* Afficheur effectif de code */ + GLoadedContent *content; /* Contenu représenté */ + unsigned int count; /* Nombre de vues possibles */ + unsigned int index; /* Indice de la vue courante */ + gboolean access; /* Accès à déterminer */ + GtkWidget *item; /* Elément de menu à traiter */ - editor = get_editor_window(); + panel = get_current_view(); - active = gtk_check_menu_item_get_active(menuitem); + if (panel == NULL) + content = NULL; - if (active) - gtk_window_fullscreen(editor); else - gtk_window_unfullscreen(editor); + { + content = g_loaded_panel_get_content(panel); - g_object_unref(G_OBJECT(editor)); + count = g_loaded_content_count_views(content); + index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); + + } + + access = (panel != NULL && (index + 1) < count); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "view_switch_to_next")); + gtk_widget_set_sensitive(item, access); + + access = (panel != NULL && index > 0); + + item = GTK_WIDGET(gtk_builder_get_object(builder, "view_switch_to_prev")); + gtk_widget_set_sensitive(item, access); + + if (panel != NULL) + { + g_object_unref(G_OBJECT(content)); + g_object_unref(G_OBJECT(panel)); + } } diff --git a/src/gui/menus/view.h b/src/gui/menus/view.h index 3d4b69f..963f3fd 100644 --- a/src/gui/menus/view.h +++ b/src/gui/menus/view.h @@ -34,20 +34,20 @@ -/* Construit le menu "Affichage". */ -GtkWidget *build_menu_view(GObject *, GMenuBar *); +/* Complète la définition du menu "Affichage". */ +void setup_menu_view_callbacks(GtkBuilder *); + +/* Réagit avec le menu "Affichage -> Panneaux latéraux". */ +void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *); /* Réagit à un changement d'affichage principal de contenu. */ -void rebuild_menu_view_for_content(GtkWidget *, GObject *, GLoadedContent *); +void rebuild_menu_view_for_content(GtkBuilder *, GLoadedContent *); /* Lance une actualisation du fait d'un changement de support. */ -void rebuild_menu_view_for_view(GtkWidget *, GObject *, GLoadedPanel *); +void rebuild_menu_view_for_view(GtkBuilder *, GLoadedPanel *); /* Met à jour les accès du menu "Affichage" selon le contenu. */ -void update_access_for_view_in_menu_view(GObject *, GLoadedPanel *); - -/* Réagit avec le menu "Affichage -> Panneaux latéraux". */ -void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *); +void update_access_for_view_in_menu_view(GtkBuilder *, GLoadedPanel *); -- cgit v0.11.2-87-g4458