/* Chrysalide - Outil d'analyse de fichiers binaires * view.c - gestion du menu 'Affichage' * * Copyright (C) 2012-2017 Cyrille Bagard * * This view 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 "view.h" #include #include #include #include #include "../agroup.h" #include "../editem-int.h" #include "../core/global.h" #include "../core/items.h" #include "../core/panels.h" #include "../../analysis/loaded.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdisplaypanel.h" #include "../../gtkext/gtkgraphdisplay.h" /* 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 *); /* Réagit avec le menu "Affichage -> Vue xxx". */ 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 *); /* Réagit avec le menu "Affichage -> Basculer vers le précédent". */ static void mcb_view_switch_to_prev_support(GtkRadioMenuItem *, GObject *); /* Accompagne la première allocation d'un panneau d'affichage. */ static void handle_loaded_panel_first_allocation(GtkWidget *, GdkRectangle *, GLineCursor *); /* Effectue la bascule d'un panneau de chargement à un autre. */ static void change_current_view_support(unsigned int); /* Réagit avec le menu "Affichage -> Zoom *". */ static void mcb_view_zoom(GtkCheckMenuItem *, gpointer ); /* Réagit avec le menu "Affichage -> (colonne xxx)". */ 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); /****************************************************************************** * * * Paramètres : ref = espace de référencement global. * * bar = barre de menu parente. * * * * Description : Construit le menu "Affichage". * * * * Retour : Panneau de menus mis en place. * * * * Remarques : - * * * ******************************************************************************/ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar) { GtkWidget *result; /* Support à retourner */ GtkWidget *menubar; /* Support pour éléments */ GtkWidget *submenuitem; /* Sous-élément de menu */ result = gtk_menu_item_new_with_mnemonic(_("_View")); gtk_widget_show(result); menubar = qck_create_menu(GTK_MENU_ITEM(result)); /* 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 */ 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); /* 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 */ submenuitem = qck_create_menu_separator(); g_object_set_data(ref, "mnu_view_start_options", submenuitem); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); /* 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; } /****************************************************************************** * * * Paramètres : widget = menu principal à actualiser. * * ref = espace de référencement global. * * new = nouveau contenu chargé à analyser. * * * * Description : Réagit à un changement d'affichage principal de contenu. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void rebuild_menu_view_for_content(GtkWidget *widget, GObject *ref, GLoadedContent *new) { 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 */ /* Retrait d'éventuels anciens menus */ menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); for (i = 0; ; i++) { asprintf(&key, "mnu_view_panel_%u", i); submenuitem = g_object_get_data(ref, key); free(key); if (submenuitem == NULL) break; else gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(submenuitem)); } if (new != NULL) { /* Insertion des différentes vues */ marker = g_object_get_data(ref, "mnu_view_start_panels"); list = gtk_container_get_children(GTK_CONTAINER(menubar)); position = 0; for (iter = list; iter != NULL; iter = g_list_next(iter)) { position++; if (marker == iter->data) break; } g_list_free(list); count = g_loaded_content_count_views(new); rgroup = NULL; for (i = 0; i < count; i++) { asprintf(&key, "mnu_view_panel_%u", i); submenuitem = qck_create_radio_menu_item(ref, key, rgroup, g_loaded_content_get_view_name(new, i), G_CALLBACK(mcb_view_change_support), NULL); g_object_set_data(G_OBJECT(submenuitem), "kind_of_view", GUINT_TO_POINTER(i)); free(key); asprintf(&key, "F%u", 3 + i); add_accelerator_to_widget(submenuitem, key); free(key); if (rgroup == NULL) rgroup = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(submenuitem)); gtk_menu_shell_insert(GTK_MENU_SHELL(menubar), submenuitem, position + i); } } } /****************************************************************************** * * * Paramètres : widget = menu principal à actualiser. * * 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 rebuild_menu_view_for_view(GtkWidget *widget, GObject *ref, GLoadedPanel *new) { 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 */ content = get_current_content(); assert((content == NULL && new == NULL) || (content != NULL && new != NULL)); /* Retrait d'éventuels anciens menus */ menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); 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); free(key); if (submenuitem == NULL) break; else gtk_container_remove(GTK_CONTAINER(menubar), GTK_WIDGET(submenuitem)); } if (content != NULL) { 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")); radios = gtk_radio_menu_item_get_group(item); void disconnect_display_radio(GtkWidget *wgt, gpointer unused) { g_signal_handlers_disconnect_by_func(wgt, G_CALLBACK(mcb_view_change_support), NULL); } 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); void reconnect_display_radio(GtkWidget *wgt, gpointer unused) { g_signal_connect(wgt, "toggled", G_CALLBACK(mcb_view_change_support), NULL); } g_slist_foreach(radios, (GFunc)reconnect_display_radio, NULL); /* Insertion des options de rendu */ list = gtk_container_get_children(GTK_CONTAINER(menubar)); position = 0; for (iter = list; iter != NULL; iter = g_list_next(iter)) { position++; if (marker == iter->data) break; } g_list_free(list); options = g_loaded_content_get_display_options(content, index); 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); /** * 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 ! */ status = g_display_options_get(options, i); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(submenuitem), status); } g_object_unref(G_OBJECT(options)); g_object_unref(G_OBJECT(content)); } else count = 0; /* Utilité de la séparation ? */ gtk_widget_set_visible(GTK_WIDGET(marker), count > 0); } /****************************************************************************** * * * Paramètres : ref = espace de référencement global. * * new = nouvelle vue du contenu chargé analysé. * * * * Description : Met à jour les accès du menu "Affichage" selon le contenu. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void update_access_for_view_in_menu_view(GObject *ref, GLoadedPanel *new) { 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); item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_out")); gtk_widget_set_sensitive(item, access); item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_zoom_reset")); gtk_widget_set_sensitive(item, access); } /****************************************************************************** * * * Paramètres : ref = espace de référencement global. * * * * Description : Met à jour les accès du menu "Affichage -> Basculer...". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void update_switch_access_in_menu_view(GObject *ref) { 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 */ panel = get_current_view(); if (panel == NULL) content = NULL; else { 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)); } access = (panel != NULL && (index + 1) < count); item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_to_next_support")); gtk_widget_set_sensitive(item, access); access = (panel != NULL && index > 0); item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_to_prev_support")); gtk_widget_set_sensitive(item, access); if (panel != NULL) { g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(panel)); } } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * bar = barre de menu parente. * * * * Description : Réagit avec le menu "Affichage -> Panneaux latéraux". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) { 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); } gtk_container_foreach(GTK_CONTAINER(menubar), (GtkCallback)remove_panel_menu_item, menubar); /* Ajout des panneaux uniques */ bool add_side_panel_to_list(GPanelItem *panel, panels_loading_filter *filter) { const char *name; /* 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 */ name = g_editor_item_get_name(G_EDITOR_ITEM(panel)); submenuitem = qck_create_check_menu_item(NULL, NULL, name, G_CALLBACK(mcb_view_change_panel_docking), panel); bindings = gtk_panel_item_get_key_bindings(panel); if (bindings != NULL) add_accelerator_to_widget(submenuitem, bindings); gtk_container_add(filter->support, submenuitem); /* Statut de la coche */ 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); } aptl_exit: return true; } pfilter.support = GTK_CONTAINER(menubar); 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 : menuitem = élément de menu ayant basculé. * * bar = barre de menu parente. * * * * Description : Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void mcb_view_change_panel_docking(GtkCheckMenuItem *menuitem, GPanelItem *item) { 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. */ active = !g_panel_item_is_docked(item); if (active) g_panel_item_dock(item); else g_panel_item_undock(item); } /****************************************************************************** * * * 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 : - * * * ******************************************************************************/ 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 */ /* 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); for (iter = group; iter != NULL; iter = g_slist_next(iter)) { if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(iter->data))) continue; wanted = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view")); change_current_view_support(wanted); } } /****************************************************************************** * * * 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 : - * * * ******************************************************************************/ 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 panel = get_current_view(); content = g_loaded_panel_get_content(panel); index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); #ifndef NDEBUG count = g_loaded_content_count_views(content); assert((index + 1) < count); #endif change_current_view_support(index + 1); g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(panel)); update_switch_access_in_menu_view(ref); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu ayant basculé. * * ref = espace de référencement global. * * * * Description : Réagit avec le menu "Affichage -> Basculer ... précédent". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void mcb_view_switch_to_prev_support(GtkRadioMenuItem *menuitem, GObject *ref) { GLoadedPanel *panel; /* Afficheur effectif de code */ GLoadedContent *content; /* Contenu représenté */ unsigned int index; /* Indice de la vue courante */ panel = get_current_view(); content = g_loaded_panel_get_content(panel); index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); assert(index > 0); change_current_view_support(index - 1); g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(panel)); update_switch_access_in_menu_view(ref); } /****************************************************************************** * * * 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 : - * * * ******************************************************************************/ 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); g_object_unref(G_OBJECT(cursor)); } /****************************************************************************** * * * Paramètres : wanted = indice de la vue désirée. * * * * Description : Effectue la bascule d'un panneau de chargement à un autre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ 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 */ panel = get_current_view(); station = get_dock_station_for_view_panel(GTK_WIDGET(panel)); content = g_loaded_panel_get_content(panel); support = g_loaded_content_build_view(content, wanted); g_object_unref(G_OBJECT(content)); gtk_dock_panel_change_active_widget(station, support); new = G_LOADED_PANEL(get_loaded_panel_from_built_view(support)); cursor = g_loaded_panel_get_cursor(panel); change_editor_items_current_view(new); 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. */ 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é. * * data = données indiquant la nature du zoom. * * * * Description : Réagit avec le menu "Affichage -> Zoom *". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void mcb_view_zoom(GtkCheckMenuItem *menuitem, gpointer data) { GtkDisplayPanel *panel; /* Afficheur effectif de code */ double scale; /* Echelle à appliquer */ panel = GTK_DISPLAY_PANEL(get_current_view()); scale = gtk_display_panel_get_scale(panel); switch (GPOINTER_TO_INT(data)) { case 0: scale /= 1.25; break; case 1: scale *= 1.25; break; case 2: scale = 1.0; break; } gtk_display_panel_set_scale(panel, scale); } /****************************************************************************** * * * 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 */ option = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_opt")); active = gtk_check_menu_item_get_active(menuitem); panel = get_current_view(); content = g_loaded_panel_get_content(panel); index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); options = g_loaded_content_get_display_options(content, index); g_display_options_set(options, option, active); g_object_unref(G_OBJECT(options)); g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(panel)); } /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * * unused = adresse non utilisée ici. * * * * Description : Réagit avec le menu "Affichage -> Plein écran". * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ 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 */ editor = get_editor_window(); active = gtk_check_menu_item_get_active(menuitem); if (active) gtk_window_fullscreen(editor); else gtk_window_unfullscreen(editor); g_object_unref(G_OBJECT(editor)); }