From cf3533ba9c26d5acb904031d92f10bb545cac4e1 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Mon, 17 May 2004 13:38:03 +0000 Subject: [PATCH] put the image popup menu into a dummy menubar to work around the silly 2004-05-17 Michael Natterer * menus/menus.xsl: put the image popup menu into a dummy menubar to work around the silly GtkUIManager restriction that popup menus can't have tearoff items. * app/menus/menus.c * app/menus/image-menu.c * app/display/gimpdisplayshell-callbacks.c * app/gui/gui-vtable.c * app/menus/plug-in-menus.c: changed accordingly. * app/gui/gui.c (gui_restore_after_callback): connect to "notify::tearoff-menus" of GimpGuiConfig and reconfigure the global image UI manager accordingly. * app/config/gimpguiconfig.c: removed GIMP_PARAM_RESTART from the "tearoff-menus" property because GtkUIManager can change this on the fly. * app/display/gimpdisplayshell.[ch]: added the menubar to the GimpDisplayShell struct. Some cleanup in gimp_display_shell_new(). * app/display/gimpdisplayshell-appearance.c (gimp_display_shell_set_show_menubar): use shell->menubar instead of asking the UI manager. * app/widgets/gimpuimanager.[ch]: changed gimp_ui_manager_ui_get() to transparently load the XML files even if a sub-widget was requested. Reordered parameters of gimp_ui_manager_ui_popup(). Lots of internal cleanups. * app/widgets/gimpdockable.c * app/widgets/gimptooloptionseditor.c: simplified accordingly. * app/widgets/gimpeditor.[ch]: added new function gimp_editor_popup_menu() which takes a GimpMenuPositionFunc and updates/shows the editor's menu. * app/widgets/gimpcolormapeditor.c * app/widgets/gimpcomponenteditor.c * app/widgets/gimpcontainereditor.c * app/widgets/gimpcontainergridview.c * app/widgets/gimpcontainertreeview.c * app/widgets/gimperrorconsole.c * app/widgets/gimpgradienteditor.c * app/widgets/gimpitemtreeview.c * app/widgets/gimppaletteeditor.c: use gimp_editor_popup_menu(). * app/widgets/gimptoolbox.c: moved all code from gimp_toolbox_new() to GObject::constructor(). --- ChangeLog | 52 +++ app/config/gimpguiconfig.c | 2 +- app/display/gimpdisplayshell-appearance.c | 9 +- app/display/gimpdisplayshell-callbacks.c | 14 +- app/display/gimpdisplayshell.c | 36 +- app/display/gimpdisplayshell.h | 1 + app/gui/gui-vtable.c | 12 +- app/gui/gui.c | 36 +- app/menus/image-menu.c | 5 + app/menus/menus.c | 2 +- app/menus/plug-in-menus.c | 2 +- app/widgets/gimpcolormapeditor.c | 10 +- app/widgets/gimpcomponenteditor.c | 9 +- app/widgets/gimpcontainereditor.c | 14 +- app/widgets/gimpcontainergridview.c | 17 +- app/widgets/gimpcontainertreeview.c | 18 +- app/widgets/gimpdockable.c | 9 +- app/widgets/gimpeditor.c | 20 ++ app/widgets/gimpeditor.h | 47 +-- app/widgets/gimperrorconsole.c | 15 +- app/widgets/gimpgradienteditor.c | 23 +- app/widgets/gimpitemtreeview.c | 13 +- app/widgets/gimppaletteeditor.c | 13 +- app/widgets/gimptoolbox.c | 158 +++++---- app/widgets/gimptooloptionseditor.c | 21 +- app/widgets/gimpuimanager.c | 390 +++++++++++++--------- app/widgets/gimpuimanager.h | 4 +- menus/menus.xsl | 10 +- 28 files changed, 513 insertions(+), 449 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a40f3a537..3eaa531680 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +2004-05-17 Michael Natterer + + * menus/menus.xsl: put the image popup menu into a dummy menubar + to work around the silly GtkUIManager restriction that popup menus + can't have tearoff items. + + * app/menus/menus.c + * app/menus/image-menu.c + * app/display/gimpdisplayshell-callbacks.c + * app/gui/gui-vtable.c + * app/menus/plug-in-menus.c: changed accordingly. + + * app/gui/gui.c (gui_restore_after_callback): connect to + "notify::tearoff-menus" of GimpGuiConfig and reconfigure the + global image UI manager accordingly. + + * app/config/gimpguiconfig.c: removed GIMP_PARAM_RESTART from the + "tearoff-menus" property because GtkUIManager can change this on + the fly. + + * app/display/gimpdisplayshell.[ch]: added the menubar to the + GimpDisplayShell struct. Some cleanup in gimp_display_shell_new(). + + * app/display/gimpdisplayshell-appearance.c + (gimp_display_shell_set_show_menubar): use shell->menubar instead + of asking the UI manager. + + * app/widgets/gimpuimanager.[ch]: changed gimp_ui_manager_ui_get() + to transparently load the XML files even if a sub-widget was + requested. Reordered parameters of gimp_ui_manager_ui_popup(). + Lots of internal cleanups. + + * app/widgets/gimpdockable.c + * app/widgets/gimptooloptionseditor.c: simplified accordingly. + + * app/widgets/gimpeditor.[ch]: added new function + gimp_editor_popup_menu() which takes a GimpMenuPositionFunc and + updates/shows the editor's menu. + + * app/widgets/gimpcolormapeditor.c + * app/widgets/gimpcomponenteditor.c + * app/widgets/gimpcontainereditor.c + * app/widgets/gimpcontainergridview.c + * app/widgets/gimpcontainertreeview.c + * app/widgets/gimperrorconsole.c + * app/widgets/gimpgradienteditor.c + * app/widgets/gimpitemtreeview.c + * app/widgets/gimppaletteeditor.c: use gimp_editor_popup_menu(). + + * app/widgets/gimptoolbox.c: moved all code from + gimp_toolbox_new() to GObject::constructor(). + 2004-05-17 Michael Natterer * app/actions/tool-options-actions.c: added icons to the Save, diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c index ebfb3238da..5de9b7a85a 100644 --- a/app/config/gimpguiconfig.c +++ b/app/config/gimpguiconfig.c @@ -184,7 +184,7 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass) GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_TEAROFF_MENUS, "tearoff-menus", TEAROFF_MENUS_BLURB, TRUE, - GIMP_PARAM_RESTART); + 0); GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_CAN_CHANGE_ACCELS, "can-change-accels", CAN_CHANGE_ACCELS_BLURB, FALSE, diff --git a/app/display/gimpdisplayshell-appearance.c b/app/display/gimpdisplayshell-appearance.c index 4a12007b42..d729c9f9b4 100644 --- a/app/display/gimpdisplayshell-appearance.c +++ b/app/display/gimpdisplayshell-appearance.c @@ -86,7 +86,6 @@ gimp_display_shell_set_show_menubar (GimpDisplayShell *shell, gboolean show) { GimpDisplayOptions *options; - GtkWidget *menubar; GtkContainer *vbox; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); @@ -95,14 +94,12 @@ gimp_display_shell_set_show_menubar (GimpDisplayShell *shell, g_object_set (options, "show-menubar", show, NULL); - menubar = gtk_ui_manager_get_widget (GTK_UI_MANAGER (shell->menubar_manager), - "/image-menubar"); - vbox = GTK_CONTAINER (shell->qmask->parent->parent); + vbox = GTK_CONTAINER (shell->qmask->parent->parent); if (show) - gtk_widget_show (menubar); + gtk_widget_show (shell->menubar); else - gtk_widget_hide (menubar); + gtk_widget_hide (shell->menubar); if (options->show_menubar || options->show_statusbar) gtk_container_set_border_width (vbox, 2); diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c index e7d99faa42..d6366351e4 100644 --- a/app/display/gimpdisplayshell-callbacks.c +++ b/app/display/gimpdisplayshell-callbacks.c @@ -422,12 +422,11 @@ gimp_display_shell_popup_menu (GtkWidget *widget) gimp_context_set_display (gimp_get_user_context (shell->gdisp->gimage->gimp), shell->gdisp); - gimp_ui_manager_ui_popup (shell->popup_manager, "/image-popup", - shell->gdisp, + gimp_ui_manager_ui_popup (shell->popup_manager, "/dummy-menubar/image-popup", GTK_WIDGET (shell), gimp_display_shell_origin_menu_position, shell->origin, - NULL); + NULL, NULL); return TRUE; } @@ -733,10 +732,10 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, case 3: state |= GDK_BUTTON3_MASK; - gimp_ui_manager_ui_popup (shell->popup_manager, "/image-popup", - gdisp, + gimp_ui_manager_ui_popup (shell->popup_manager, + "/dummy-menubar/image-popup", GTK_WIDGET (shell), - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); return_val = TRUE; break; @@ -1512,9 +1511,8 @@ gimp_display_shell_qmask_button_press (GtkWidget *widget, if ((bevent->type == GDK_BUTTON_PRESS) && (bevent->button == 3)) { gimp_ui_manager_ui_popup (shell->menubar_manager, "/qmask-popup", - shell, GTK_WIDGET (shell), - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); return TRUE; } diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 9488ac6abd..a7be6f59bc 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -486,7 +486,8 @@ gimp_display_shell_new (GimpDisplay *gdisp, GimpUIManager *popup_manager) { GimpDisplayShell *shell; - GimpDisplayConfig *config; + GimpDisplayConfig *display_config; + GimpGuiConfig *gui_config; GtkWidget *main_vbox; GtkWidget *disp_vbox; GtkWidget *upper_hbox; @@ -494,7 +495,6 @@ gimp_display_shell_new (GimpDisplay *gdisp, GtkWidget *lower_hbox; GtkWidget *inner_table; GtkWidget *image; - GtkWidget *menubar; GdkScreen *screen; gint image_width, image_height; gint n_width, n_height; @@ -514,13 +514,14 @@ gimp_display_shell_new (GimpDisplay *gdisp, image_width = gdisp->gimage->width; image_height = gdisp->gimage->height; - config = GIMP_DISPLAY_CONFIG (gdisp->gimage->gimp->config); + display_config = GIMP_DISPLAY_CONFIG (gdisp->gimage->gimp->config); + gui_config = GIMP_GUI_CONFIG (display_config); - shell->dot_for_dot = config->default_dot_for_dot; + shell->dot_for_dot = display_config->default_dot_for_dot; - gimp_config_sync (GIMP_CONFIG (config->default_view), + gimp_config_sync (GIMP_CONFIG (display_config->default_view), GIMP_CONFIG (shell->options), 0); - gimp_config_sync (GIMP_CONFIG (config->default_fullscreen_view), + gimp_config_sync (GIMP_CONFIG (display_config->default_fullscreen_view), GIMP_CONFIG (shell->fullscreen_options), 0); /* adjust the initial scale -- so that window fits on screen the 75% @@ -529,15 +530,15 @@ gimp_display_shell_new (GimpDisplay *gdisp, */ screen = gtk_widget_get_screen (GTK_WIDGET (shell)); - if (GIMP_DISPLAY_CONFIG (config)->monitor_res_from_gdk) + if (display_config->monitor_res_from_gdk) { gimp_get_screen_resolution (screen, &shell->monitor_xres, &shell->monitor_yres); } else { - shell->monitor_xres = GIMP_DISPLAY_CONFIG (config)->monitor_xres; - shell->monitor_yres = GIMP_DISPLAY_CONFIG (config)->monitor_yres; + shell->monitor_xres = display_config->monitor_xres; + shell->monitor_yres = display_config->monitor_yres; } s_width = gdk_screen_get_width (screen) * 0.75; @@ -546,7 +547,7 @@ gimp_display_shell_new (GimpDisplay *gdisp, n_width = SCALEX (shell, image_width); n_height = SCALEY (shell, image_height); - if (config->initial_zoom_to_fit) + if (display_config->initial_zoom_to_fit) { /* Limit to the size of the screen... */ if (n_width > s_width || n_height > s_height) @@ -636,27 +637,28 @@ gimp_display_shell_new (GimpDisplay *gdisp, main_vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (shell), main_vbox); - menubar = gimp_ui_manager_ui_get (shell->menubar_manager, "/image-menubar"); - gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0); + shell->menubar = gimp_ui_manager_ui_get (shell->menubar_manager, + "/image-menubar"); + gtk_box_pack_start (GTK_BOX (main_vbox), shell->menubar, FALSE, FALSE, 0); if (shell->options->show_menubar) - gtk_widget_show (menubar); + gtk_widget_show (shell->menubar); /* make sure we can activate accels even if the menubar is invisible * (see http://bugzilla.gnome.org/show_bug.cgi?id=137151) */ - g_signal_connect (menubar, "can-activate-accel", + g_signal_connect (shell->menubar, "can-activate-accel", G_CALLBACK (gtk_true), NULL); /* active display callback */ - g_signal_connect (menubar, "button_press_event", + g_signal_connect (shell->menubar, "button_press_event", G_CALLBACK (gimp_display_shell_events), shell); - g_signal_connect (menubar, "button_release_event", + g_signal_connect (shell->menubar, "button_release_event", G_CALLBACK (gimp_display_shell_events), shell); - g_signal_connect (menubar, "key_press_event", + g_signal_connect (shell->menubar, "key_press_event", G_CALLBACK (gimp_display_shell_events), shell); diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index 3512b6722c..bca5532ad3 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -107,6 +107,7 @@ struct _GimpDisplayShell GtkWidget *vrule; GtkWidget *origin; /* origin button */ + GtkWidget *menubar; /* menubar */ GtkWidget *statusbar; /* statusbar */ guchar *render_buf; /* buffer for rendering the image */ diff --git a/app/gui/gui-vtable.c b/app/gui/gui-vtable.c index f812460503..a0a6eedd6d 100644 --- a/app/gui/gui-vtable.c +++ b/app/gui/gui-vtable.c @@ -245,15 +245,15 @@ gui_menus_create_entry (Gimp *gimp, { if (! strncmp (path->data, "", 9)) { - plug_in_menus_add_proc (list->data, "/toolbox-menubar", proc_def, - path->data); + plug_in_menus_add_proc (list->data, "/toolbox-menubar", + proc_def, path->data); } else if (! strncmp (path->data, "", 7)) { - plug_in_menus_add_proc (list->data, "/image-menubar", proc_def, - path->data); - plug_in_menus_add_proc (list->data, "/image-popup", proc_def, - path->data); + plug_in_menus_add_proc (list->data, "/image-menubar", + proc_def, path->data); + plug_in_menus_add_proc (list->data, "/dummy-menubar/image-popup", + proc_def, path->data); } } } diff --git a/app/gui/gui.c b/app/gui/gui.c index 1bc01b22e8..971c53bf4c 100644 --- a/app/gui/gui.c +++ b/app/gui/gui.c @@ -94,9 +94,12 @@ static void gui_really_quit_callback (GtkWidget *button, gboolean quit, gpointer data); -static void gui_show_tooltips_notify (GObject *config, - GParamSpec *param_spec, +static void gui_show_tooltips_notify (GimpGuiConfig *gui_config, + GParamSpec *pspec, Gimp *gimp); +static void gui_tearoff_menus_notify (GimpGuiConfig *gui_config, + GParamSpec *pspec, + GtkUIManager *manager); static void gui_device_change_notify (Gimp *gimp); static void gui_display_changed (GimpContext *context, @@ -343,7 +346,12 @@ gui_restore_after_callback (Gimp *gimp, image_ui_manager = gimp_menu_factory_manager_new (global_menu_factory, "", - gimp, TRUE); + gimp, + gui_config->tearoff_menus); + + g_signal_connect_object (gui_config, "notify::tearoff-menus", + G_CALLBACK (gui_tearoff_menus_notify), + image_ui_manager, 0); gimp_devices_restore (gimp); @@ -475,22 +483,24 @@ gui_really_quit_callback (GtkWidget *button, } static void -gui_show_tooltips_notify (GObject *config, - GParamSpec *param_spec, - Gimp *gimp) +gui_show_tooltips_notify (GimpGuiConfig *gui_config, + GParamSpec *param_spec, + Gimp *gimp) { - gboolean show_tool_tips; - - g_object_get (config, - "show-tool-tips", &show_tool_tips, - NULL); - - if (show_tool_tips) + if (gui_config->show_tool_tips) gimp_help_enable_tooltips (); else gimp_help_disable_tooltips (); } +static void +gui_tearoff_menus_notify (GimpGuiConfig *gui_config, + GParamSpec *pspec, + GtkUIManager *manager) +{ + gtk_ui_manager_set_add_tearoffs (manager, gui_config->tearoff_menus); +} + static void gui_device_change_notify (Gimp *gimp) { diff --git a/app/menus/image-menu.c b/app/menus/image-menu.c index 9025beeae1..28bcbcc8f0 100644 --- a/app/menus/image-menu.c +++ b/app/menus/image-menu.c @@ -18,6 +18,8 @@ #include "config.h" +#include + #include #include "menus-types.h" @@ -31,6 +33,9 @@ void image_menu_setup (GimpUIManager *manager, const gchar *ui_path) { + if (! strcmp (ui_path, "/dummy-menubar")) + ui_path = "/dummy-menubar/image-popup"; + file_menu_setup (manager, ui_path); plug_in_menus_setup (manager, ui_path); } diff --git a/app/menus/menus.c b/app/menus/menus.c index 3f5e728a00..529c7c79ca 100644 --- a/app/menus/menus.c +++ b/app/menus/menus.c @@ -96,7 +96,7 @@ menus_init (Gimp *gimp) "toolbox-menu.xml", toolbox_menu_setup, "/image-menubar", "image-menu.xml", image_menu_setup, - "/image-popup", + "/dummy-menubar", "image-menu.xml", image_menu_setup, "/qmask-popup", "qmask-menu.xml", NULL, diff --git a/app/menus/plug-in-menus.c b/app/menus/plug-in-menus.c index e5327b98e9..a5565bf02a 100644 --- a/app/menus/plug-in-menus.c +++ b/app/menus/plug-in-menus.c @@ -145,7 +145,7 @@ plug_in_menus_setup (GimpUIManager *manager, ! strcmp (ui_path, "/toolbox-menubar")) || (! strncmp (path->data, "", 7) && (! strcmp (ui_path, "/image-menubar") || - ! strcmp (ui_path, "/image-popup")))) + ! strcmp (ui_path, "/dummy-menubar/image-popup")))) { PlugInMenuEntry *entry = g_new0 (PlugInMenuEntry, 1); const gchar *progname; diff --git a/app/widgets/gimpcolormapeditor.c b/app/widgets/gimpcolormapeditor.c index 3996ccc56b..0d45cc01e9 100644 --- a/app/widgets/gimpcolormapeditor.c +++ b/app/widgets/gimpcolormapeditor.c @@ -55,7 +55,6 @@ #include "gimpdialogfactory.h" #include "gimphelp-ids.h" #include "gimpmenufactory.h" -#include "gimpuimanager.h" #include "gimpwidgets-utils.h" #include "gui/color-notebook.h" @@ -766,14 +765,7 @@ gimp_colormap_preview_button_press (GtkWidget *widget, case 3: gimp_colormap_editor_set_index (editor, col); - - gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager, - GIMP_EDITOR (editor)->popup_data); - gimp_ui_manager_ui_popup (GIMP_EDITOR (editor)->ui_manager, - GIMP_EDITOR (editor)->ui_path, - GIMP_EDITOR (editor)->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); + gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); return TRUE; default: diff --git a/app/widgets/gimpcomponenteditor.c b/app/widgets/gimpcomponenteditor.c index e190eab539..cea2c4fec1 100644 --- a/app/widgets/gimpcomponenteditor.c +++ b/app/widgets/gimpcomponenteditor.c @@ -35,7 +35,6 @@ #include "gimpcomponenteditor.h" #include "gimpmenufactory.h" #include "gimppreviewrendererimage.h" -#include "gimpuimanager.h" #include "gimpwidgets-utils.h" #include "gimp-intl.h" @@ -520,13 +519,7 @@ gimp_component_editor_button_press (GtkWidget *widget, break; case 3: - gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager, - GIMP_EDITOR (editor)->popup_data); - gimp_ui_manager_ui_popup (GIMP_EDITOR (editor)->ui_manager, - GIMP_EDITOR (editor)->ui_path, - GIMP_EDITOR (editor)->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); + gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); break; default: diff --git a/app/widgets/gimpcontainereditor.c b/app/widgets/gimpcontainereditor.c index a0d9b0faea..4d4fa80ae5 100644 --- a/app/widgets/gimpcontainereditor.c +++ b/app/widgets/gimpcontainereditor.c @@ -257,19 +257,7 @@ gimp_container_editor_real_context_item (GimpContainerEditor *editor, if (viewable && gimp_container_have (container, GIMP_OBJECT (viewable))) { - GimpEditor *gimp_editor = GIMP_EDITOR (editor->view); - - if (gimp_editor->ui_manager) - { - gimp_ui_manager_update (gimp_editor->ui_manager, - gimp_editor->popup_data); - gimp_ui_manager_ui_popup (gimp_editor->ui_manager, - gimp_editor->ui_path, - gimp_editor->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); - return; - } + gimp_editor_popup_menu (GIMP_EDITOR (editor->view), NULL, NULL); } } diff --git a/app/widgets/gimpcontainergridview.c b/app/widgets/gimpcontainergridview.c index 45ea6c5ff1..16b3437d84 100644 --- a/app/widgets/gimpcontainergridview.c +++ b/app/widgets/gimpcontainergridview.c @@ -37,7 +37,6 @@ #include "gimpcontainerview.h" #include "gimppreview.h" #include "gimppreviewrenderer.h" -#include "gimpuimanager.h" #include "gimpwidgets-utils.h" #include "gtkhwrapbox.h" @@ -402,20 +401,12 @@ static gboolean gimp_container_grid_view_popup_menu (GtkWidget *widget) { GimpContainerGridView *grid_view = GIMP_CONTAINER_GRID_VIEW (widget); - GimpEditor *editor = GIMP_EDITOR (widget); - if (grid_view->selected_item && editor->ui_manager) + if (grid_view->selected_item) { - gimp_ui_manager_update (editor->ui_manager, - editor->popup_data); - gimp_ui_manager_ui_popup (editor->ui_manager, - editor->ui_path, - editor->popup_data, - GTK_WIDGET (editor), - gimp_container_grid_view_menu_position, - grid_view->selected_item, - NULL); - return TRUE; + return gimp_editor_popup_menu (GIMP_EDITOR (grid_view), + gimp_container_grid_view_menu_position, + grid_view->selected_item); } return FALSE; diff --git a/app/widgets/gimpcontainertreeview.c b/app/widgets/gimpcontainertreeview.c index febdbef351..f88ef904ff 100644 --- a/app/widgets/gimpcontainertreeview.c +++ b/app/widgets/gimpcontainertreeview.c @@ -40,7 +40,6 @@ #include "gimpcontainerview.h" #include "gimpdnd.h" #include "gimppreviewrenderer.h" -#include "gimpuimanager.h" #include "gimpwidgets-utils.h" @@ -362,21 +361,12 @@ static gboolean gimp_container_tree_view_popup_menu (GtkWidget *widget) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (widget); - GimpEditor *editor = GIMP_EDITOR (widget); - if (gtk_tree_selection_get_selected (tree_view->selection, NULL, NULL) && - editor->ui_manager) + if (gtk_tree_selection_get_selected (tree_view->selection, NULL, NULL)) { - gimp_ui_manager_update (editor->ui_manager, - editor->popup_data); - gimp_ui_manager_ui_popup (editor->ui_manager, - editor->ui_path, - editor->popup_data, - GTK_WIDGET (editor), - gimp_container_tree_view_menu_position, - editor, - NULL); - return TRUE; + return gimp_editor_popup_menu (GIMP_EDITOR (tree_view), + gimp_container_tree_view_menu_position, + tree_view); } return FALSE; diff --git a/app/widgets/gimpdockable.c b/app/widgets/gimpdockable.c index 332c38e84d..1cdff1b254 100644 --- a/app/widgets/gimpdockable.c +++ b/app/widgets/gimpdockable.c @@ -936,8 +936,6 @@ gimp_dockable_show_menu (GimpDockable *dockable) if (! dockbook_ui_manager) return FALSE; - gimp_ui_manager_ui_get (dockbook_ui_manager, "/dockable-popup"); - dialog_ui_manager = gimp_dockable_get_menu (dockable, &dialog_ui_path, &dialog_popup_data); @@ -958,8 +956,8 @@ gimp_dockable_show_menu (GimpDockable *dockable) dialog_ui_path); parent_menu_widget = - gtk_ui_manager_get_widget (GTK_UI_MANAGER (dockbook_ui_manager), - "/dockable-popup/dockable-menu"); + gimp_ui_manager_ui_get (dockbook_ui_manager, + "/dockable-popup/dockable-menu"); parent_menu_action = gtk_ui_manager_get_action (GTK_UI_MANAGER (dockbook_ui_manager), @@ -1019,10 +1017,9 @@ gimp_dockable_show_menu (GimpDockable *dockable) gimp_ui_manager_update (dockbook_ui_manager, dockable); gimp_ui_manager_ui_popup (dockbook_ui_manager, "/dockable-popup", - dockable, GTK_WIDGET (dockable), gimp_dockable_menu_position, dockable, - (GtkDestroyNotify) gimp_dockable_menu_end); + (GtkDestroyNotify) gimp_dockable_menu_end, dockable); return TRUE; } diff --git a/app/widgets/gimpeditor.c b/app/widgets/gimpeditor.c index 49cba950d7..cd13697497 100644 --- a/app/widgets/gimpeditor.c +++ b/app/widgets/gimpeditor.c @@ -390,6 +390,26 @@ gimp_editor_create_menu (GimpEditor *editor, editor->popup_data = popup_data; } +gboolean +gimp_editor_popup_menu (GimpEditor *editor, + GimpMenuPositionFunc position_func, + gpointer position_data) +{ + g_return_val_if_fail (GIMP_IS_EDITOR (editor), FALSE); + + if (editor->ui_manager && editor->ui_path) + { + gimp_ui_manager_update (editor->ui_manager, editor->popup_data); + gimp_ui_manager_ui_popup (editor->ui_manager, editor->ui_path, + GTK_WIDGET (editor), + position_func, position_data, + NULL, NULL); + return TRUE; + } + + return FALSE; +} + GtkWidget * gimp_editor_add_button (GimpEditor *editor, const gchar *stock_id, diff --git a/app/widgets/gimpeditor.h b/app/widgets/gimpeditor.h index 23e5b772e9..cc2f87abc9 100644 --- a/app/widgets/gimpeditor.h +++ b/app/widgets/gimpeditor.h @@ -59,32 +59,35 @@ GType gimp_editor_get_type (void) G_GNUC_CONST; GtkWidget * gimp_editor_new (void); -void gimp_editor_create_menu (GimpEditor *editor, - GimpMenuFactory *menu_factory, - const gchar *menu_identifier, - const gchar *ui_path, - gpointer popup_data); +void gimp_editor_create_menu (GimpEditor *editor, + GimpMenuFactory *menu_factory, + const gchar *menu_identifier, + const gchar *ui_path, + gpointer popup_data); +gboolean gimp_editor_popup_menu (GimpEditor *editor, + GimpMenuPositionFunc position_func, + gpointer position_data); -GtkWidget * gimp_editor_add_button (GimpEditor *editor, - const gchar *stock_id, - const gchar *tooltip, - const gchar *help_id, - GCallback callback, - GCallback extended_callback, - gpointer callback_data); -GtkWidget * gimp_editor_add_stock_box (GimpEditor *editor, - GType enum_type, - const gchar *stock_prefix, - GCallback callback, - gpointer callback_data); +GtkWidget * gimp_editor_add_button (GimpEditor *editor, + const gchar *stock_id, + const gchar *tooltip, + const gchar *help_id, + GCallback callback, + GCallback extended_callback, + gpointer callback_data); +GtkWidget * gimp_editor_add_stock_box (GimpEditor *editor, + GType enum_type, + const gchar *stock_prefix, + GCallback callback, + gpointer callback_data); -GtkWidget * gimp_editor_add_action_button (GimpEditor *editor, - const gchar *group_name, - const gchar *action_name, +GtkWidget * gimp_editor_add_action_button (GimpEditor *editor, + const gchar *group_name, + const gchar *action_name, ...); -void gimp_editor_set_box_style (GimpEditor *editor, - GtkBox *box); +void gimp_editor_set_box_style (GimpEditor *editor, + GtkBox *box); #endif /* __GIMP_EDITOR_H__ */ diff --git a/app/widgets/gimperrorconsole.c b/app/widgets/gimperrorconsole.c index bc67ff86d6..758a270531 100644 --- a/app/widgets/gimperrorconsole.c +++ b/app/widgets/gimperrorconsole.c @@ -59,7 +59,6 @@ #include "gimperrorconsole.h" #include "gimphelp-ids.h" #include "gimpmenufactory.h" -#include "gimpuimanager.h" #include "gimpwidgets-utils.h" #include "gimp-intl.h" @@ -300,19 +299,9 @@ gimp_error_console_button_press (GtkWidget *widget, GdkEventButton *bevent, GimpErrorConsole *console) { - if (bevent->button == 3) + if (bevent->button == 3 && bevent->type == GDK_BUTTON_PRESS) { - GimpEditor *editor = GIMP_EDITOR (console); - - gimp_ui_manager_update (editor->ui_manager, - editor->popup_data); - gimp_ui_manager_ui_popup (editor->ui_manager, - editor->ui_path, - editor->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); - - return TRUE; + return gimp_editor_popup_menu (GIMP_EDITOR (console), NULL, NULL); } return FALSE; diff --git a/app/widgets/gimpgradienteditor.c b/app/widgets/gimpgradienteditor.c index 1b24e2503e..6e3366c44e 100644 --- a/app/widgets/gimpgradienteditor.c +++ b/app/widgets/gimpgradienteditor.c @@ -71,7 +71,6 @@ #include "gimphelp-ids.h" #include "gimppreview.h" #include "gimppreviewrenderergradient.h" -#include "gimpuimanager.h" #include "gimpwidgets-utils.h" #include "gui/color-notebook.h" @@ -704,17 +703,7 @@ preview_events (GtkWidget *widget, case 3: if (GIMP_DATA_EDITOR (editor)->data_editable) - { - GimpEditor *gimp_editor = GIMP_EDITOR (editor); - - gimp_ui_manager_update (gimp_editor->ui_manager, - gimp_editor->popup_data); - gimp_ui_manager_ui_popup (gimp_editor->ui_manager, - gimp_editor->ui_path, - gimp_editor->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); - } + gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); break; default: @@ -1148,15 +1137,7 @@ control_button_press (GimpGradientEditor *editor, if (button == 3) { - GimpEditor *gimp_editor = GIMP_EDITOR (editor); - - gimp_ui_manager_update (gimp_editor->ui_manager, - gimp_editor->popup_data); - gimp_ui_manager_ui_popup (gimp_editor->ui_manager, - gimp_editor->ui_path, - gimp_editor->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); + gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); return; } diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c index 7f4a378d8b..0d7e19bba0 100644 --- a/app/widgets/gimpitemtreeview.c +++ b/app/widgets/gimpitemtreeview.c @@ -882,21 +882,10 @@ gimp_item_tree_view_context_item (GimpContainerView *view, GimpViewable *item, gpointer insert_data) { - GimpEditor *editor = GIMP_EDITOR (view); - if (parent_view_iface->context_item) parent_view_iface->context_item (view, item, insert_data); - if (editor->ui_manager) - { - gimp_ui_manager_update (editor->ui_manager, - editor->popup_data); - gimp_ui_manager_ui_popup (editor->ui_manager, - editor->ui_path, - editor->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); - } + gimp_editor_popup_menu (GIMP_EDITOR (view), NULL, NULL); } static gboolean diff --git a/app/widgets/gimppaletteeditor.c b/app/widgets/gimppaletteeditor.c index 34bde8328b..c64f091348 100644 --- a/app/widgets/gimppaletteeditor.c +++ b/app/widgets/gimppaletteeditor.c @@ -46,7 +46,6 @@ #include "gimppaletteeditor.h" #include "gimppreview.h" #include "gimpsessioninfo.h" -#include "gimpuimanager.h" #include "gimpwidgets-utils.h" #include "gui/color-notebook.h" @@ -581,17 +580,9 @@ palette_editor_eventbox_button_press (GtkWidget *widget, GdkEventButton *bevent, GimpPaletteEditor *editor) { - if (bevent->button == 3) + if (bevent->button == 3 && bevent->type == GDK_BUTTON_PRESS) { - GimpEditor *gimp_editor = GIMP_EDITOR (editor); - - gimp_ui_manager_update (gimp_editor->ui_manager, - gimp_editor->popup_data); - gimp_ui_manager_ui_popup (gimp_editor->ui_manager, - gimp_editor->ui_path, - gimp_editor->popup_data, - GTK_WIDGET (editor), - NULL, NULL, NULL); + return gimp_editor_popup_menu (GIMP_EDITOR (editor), NULL, NULL); } return TRUE; diff --git a/app/widgets/gimptoolbox.c b/app/widgets/gimptoolbox.c index 842123a27a..c32c396ed3 100644 --- a/app/widgets/gimptoolbox.c +++ b/app/widgets/gimptoolbox.c @@ -60,6 +60,10 @@ static void gimp_toolbox_class_init (GimpToolboxClass *klass); static void gimp_toolbox_init (GimpToolbox *toolbox); +static GObject * gimp_toolbox_constructor (GType type, + guint n_params, + GObjectConstructParam *params); + static gboolean gimp_toolbox_delete_event (GtkWidget *widget, GdkEventAny *event); static void gimp_toolbox_size_allocate (GtkWidget *widget, @@ -138,14 +142,14 @@ gimp_toolbox_get_type (void) static void gimp_toolbox_class_init (GimpToolboxClass *klass) { - GtkWidgetClass *widget_class; - GimpDockClass *dock_class; - - widget_class = GTK_WIDGET_CLASS (klass); - dock_class = GIMP_DOCK_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GimpDockClass *dock_class = GIMP_DOCK_CLASS (klass); parent_class = g_type_class_peek_parent (klass); + object_class->constructor = gimp_toolbox_constructor; + widget_class->delete_event = gimp_toolbox_delete_event; widget_class->size_allocate = gimp_toolbox_size_allocate; widget_class->style_set = gimp_toolbox_style_set; @@ -154,30 +158,52 @@ gimp_toolbox_class_init (GimpToolboxClass *klass) dock_class->book_removed = gimp_toolbox_book_removed; gtk_widget_class_install_style_property - (widget_class, - g_param_spec_enum ("tool_icon_size", - NULL, NULL, - GTK_TYPE_ICON_SIZE, - DEFAULT_TOOL_ICON_SIZE, - G_PARAM_READABLE)); + (widget_class, g_param_spec_enum ("tool_icon_size", + NULL, NULL, + GTK_TYPE_ICON_SIZE, + DEFAULT_TOOL_ICON_SIZE, + G_PARAM_READABLE)); gtk_widget_class_install_style_property - (widget_class, - g_param_spec_enum ("button_relief", - NULL, NULL, - GTK_TYPE_RELIEF_STYLE, - DEFAULT_BUTTON_RELIEF, - G_PARAM_READABLE)); + (widget_class, g_param_spec_enum ("button_relief", + NULL, NULL, + GTK_TYPE_RELIEF_STYLE, + DEFAULT_BUTTON_RELIEF, + G_PARAM_READABLE)); } static void gimp_toolbox_init (GimpToolbox *toolbox) { + gtk_window_set_role (GTK_WINDOW (toolbox), "gimp-toolbox"); + + gimp_help_connect (GTK_WIDGET (toolbox), gimp_standard_help_func, + GIMP_HELP_TOOLBOX, NULL); +} + +static GObject * +gimp_toolbox_constructor (GType type, + guint n_params, + GObjectConstructParam *params) +{ + GObject *object; + GimpToolbox *toolbox; + GimpContext *context; + GimpGuiConfig *config; GimpUIManager *manager; GtkWidget *main_vbox; GtkWidget *vbox; + GdkDisplay *display; + GList *list; - gtk_window_set_role (GTK_WINDOW (toolbox), "gimp-toolbox"); + object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params); + + toolbox = GIMP_TOOLBOX (object); + + context = GIMP_DOCK (toolbox)->context; + config = GIMP_GUI_CONFIG (context->gimp->config); + + gimp_window_set_hint (GTK_WINDOW (toolbox), config->toolbox_window_hint); main_vbox = GIMP_DOCK (toolbox)->main_vbox; @@ -203,6 +229,46 @@ gimp_toolbox_init (GimpToolbox *toolbox) gtk_box_pack_start (GTK_BOX (vbox), toolbox->wbox, FALSE, FALSE, 0); gtk_widget_show (toolbox->wbox); + + /* We need to know when the current device changes, so we can update + * the correct tool - to do this we connect to motion events. + * We can't just use EXTENSION_EVENTS_CURSOR though, since that + * would get us extension events for the mouse pointer, and our + * device would change to that and not change back. So we check + * manually that all devices have a cursor, before establishing the check. + */ + display = gtk_widget_get_display (GTK_WIDGET (toolbox)); + for (list = gdk_display_list_devices (display); list; list = list->next) + { + if (! ((GdkDevice *) (list->data))->has_cursor) + break; + } + + if (! list) /* all devices have cursor */ + { + g_signal_connect (toolbox, "motion_notify_event", + G_CALLBACK (toolbox_check_device), + context->gimp); + + gtk_widget_add_events (GTK_WIDGET (toolbox), GDK_POINTER_MOTION_MASK); + gtk_widget_set_extension_events (GTK_WIDGET (toolbox), + GDK_EXTENSION_EVENTS_CURSOR); + } + + toolbox_create_tools (toolbox, context); + toolbox_create_color_area (toolbox, context); + toolbox_create_indicator_area (toolbox, context); + + g_signal_connect_object (context, "tool_changed", + G_CALLBACK (toolbox_tool_changed), + toolbox->wbox, + 0); + + gimp_toolbox_dnd_init (GIMP_TOOLBOX (toolbox)); + + gimp_toolbox_style_set (GTK_WIDGET (toolbox), GTK_WIDGET (toolbox)->style); + + return object; } static gboolean @@ -422,68 +488,17 @@ GtkWidget * gimp_toolbox_new (GimpDialogFactory *dialog_factory, Gimp *gimp) { - GimpContext *context; - GimpToolbox *toolbox; - GimpGuiConfig *config; - GdkDisplay *display; - GList *list; + GimpToolbox *toolbox; g_return_val_if_fail (GIMP_IS_DIALOG_FACTORY (dialog_factory), NULL); g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); - context = gimp_get_user_context (gimp); - toolbox = g_object_new (GIMP_TYPE_TOOLBOX, "title", _("The GIMP"), - "context", context, + "context", gimp_get_user_context (gimp), "dialog-factory", dialog_factory, NULL); - gimp_help_connect (GTK_WIDGET (toolbox), gimp_standard_help_func, - GIMP_HELP_TOOLBOX, NULL); - - config = GIMP_GUI_CONFIG (gimp->config); - - gimp_window_set_hint (GTK_WINDOW (toolbox), config->toolbox_window_hint); - - /* We need to know when the current device changes, so we can update - * the correct tool - to do this we connect to motion events. - * We can't just use EXTENSION_EVENTS_CURSOR though, since that - * would get us extension events for the mouse pointer, and our - * device would change to that and not change back. So we check - * manually that all devices have a cursor, before establishing the check. - */ - display = gtk_widget_get_display (GTK_WIDGET (toolbox)); - for (list = gdk_display_list_devices (display); list; list = list->next) - { - if (! ((GdkDevice *) (list->data))->has_cursor) - break; - } - - if (! list) /* all devices have cursor */ - { - g_signal_connect (toolbox, "motion_notify_event", - G_CALLBACK (toolbox_check_device), - gimp); - - gtk_widget_add_events (GTK_WIDGET (toolbox), GDK_POINTER_MOTION_MASK); - gtk_widget_set_extension_events (GTK_WIDGET (toolbox), - GDK_EXTENSION_EVENTS_CURSOR); - } - - toolbox_create_tools (toolbox, context); - toolbox_create_color_area (toolbox, context); - toolbox_create_indicator_area (toolbox, context); - - g_signal_connect_object (context, "tool_changed", - G_CALLBACK (toolbox_tool_changed), - toolbox->wbox, - 0); - - gimp_toolbox_dnd_init (GIMP_TOOLBOX (toolbox)); - - gimp_toolbox_style_set (GTK_WIDGET (toolbox), GTK_WIDGET (toolbox)->style); - return GTK_WIDGET (toolbox); } @@ -611,7 +626,6 @@ toolbox_create_tools (GimpToolbox *toolbox, GSList *group = NULL; ui_manager = gimp_ui_managers_from_name ("")->data; - gimp_ui_manager_ui_get (ui_manager, "/image-popup"); active_tool = gimp_context_get_tool (context); diff --git a/app/widgets/gimptooloptionseditor.c b/app/widgets/gimptooloptionseditor.c index f90e578333..04ba26af43 100644 --- a/app/widgets/gimptooloptionseditor.c +++ b/app/widgets/gimptooloptionseditor.c @@ -326,10 +326,9 @@ static void gimp_tool_options_editor_menu_pos (GtkMenu *menu, gint *x, gint *y, - gboolean *push_in, - gpointer func_data) + gpointer data) { - gimp_button_menu_position (GTK_WIDGET (func_data), menu, GTK_POS_RIGHT, x, y); + gimp_button_menu_position (GTK_WIDGET (data), menu, GTK_POS_RIGHT, x, y); } static void @@ -338,22 +337,14 @@ gimp_tool_options_editor_menu_popup (GimpToolOptionsEditor *editor, const gchar *path) { GimpEditor *gimp_editor = GIMP_EDITOR (editor); - GtkWidget *menu_item; gimp_ui_manager_ui_get (gimp_editor->ui_manager, gimp_editor->ui_path); gimp_ui_manager_update (gimp_editor->ui_manager, gimp_editor->popup_data); - menu_item = - gtk_ui_manager_get_widget (GTK_UI_MANAGER (gimp_editor->ui_manager), path); - - if (GTK_IS_MENU_ITEM (menu_item)) - { - GtkWidget *menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item)); - - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, - gimp_tool_options_editor_menu_pos, button, - 0, GDK_CURRENT_TIME); - } + gimp_ui_manager_ui_popup (gimp_editor->ui_manager, path, + button, + gimp_tool_options_editor_menu_pos, button, + NULL, NULL); } static void diff --git a/app/widgets/gimpuimanager.c b/app/widgets/gimpuimanager.c index b9a6eb519d..c2a700a597 100644 --- a/app/widgets/gimpuimanager.c +++ b/app/widgets/gimpuimanager.c @@ -54,35 +54,50 @@ enum }; -static void gimp_ui_manager_init (GimpUIManager *manager); -static void gimp_ui_manager_class_init (GimpUIManagerClass *klass); +static void gimp_ui_manager_init (GimpUIManager *manager); +static void gimp_ui_manager_class_init (GimpUIManagerClass *klass); -static GObject * gimp_ui_manager_constructor (GType type, - guint n_params, - GObjectConstructParam *params); -static void gimp_ui_manager_dispose (GObject *object); -static void gimp_ui_manager_finalize (GObject *object); -static void gimp_ui_manager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_ui_manager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gimp_ui_manager_connect_proxy (GtkUIManager *manager, - GtkAction *action, - GtkWidget *proxy); -static void gimp_ui_manager_real_update (GimpUIManager *manager, - gpointer update_data); - -/* help support */ - -static void gimp_ui_manager_item_realize (GtkWidget *widget, - GimpUIManager *manager); -static gboolean gimp_ui_manager_item_key_press (GtkWidget *widget, - GdkEventKey *kevent, - GimpUIManager *manager); +static GObject * gimp_ui_manager_constructor (GType type, + guint n_params, + GObjectConstructParam *params); +static void gimp_ui_manager_dispose (GObject *object); +static void gimp_ui_manager_finalize (GObject *object); +static void gimp_ui_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_ui_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gimp_ui_manager_connect_proxy (GtkUIManager *manager, + GtkAction *action, + GtkWidget *proxy); +static void gimp_ui_manager_real_update (GimpUIManager *manager, + gpointer update_data); +static GimpUIManagerUIEntry * + gimp_ui_manager_entry_get (GimpUIManager *manager, + const gchar *ui_path); +static gboolean gimp_ui_manager_entry_load (GimpUIManager *manager, + GimpUIManagerUIEntry *entry, + GError **error); +static void gimp_ui_manager_menu_position (GtkMenu *menu, + gint *x, + gint *y, + gpointer data); +static void gimp_ui_manager_menu_pos (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer data); +static void + gimp_ui_manager_delete_popdown_data (GtkObject *object, + GimpUIManager *manager); +static void gimp_ui_manager_item_realize (GtkWidget *widget, + GimpUIManager *manager); +static gboolean gimp_ui_manager_item_key_press (GtkWidget *widget, + GdkEventKey *kevent, + GimpUIManager *manager); static guint manager_signals[LAST_SIGNAL] = { 0 }; @@ -430,6 +445,7 @@ gimp_ui_manager_ui_register (GimpUIManager *manager, g_return_if_fail (GIMP_IS_UI_MANAGER (manager)); g_return_if_fail (ui_path != NULL); g_return_if_fail (basename != NULL); + g_return_if_fail (gimp_ui_manager_entry_get (manager, ui_path) == NULL); entry = g_new0 (GimpUIManagerUIEntry, 1); @@ -446,70 +462,204 @@ GtkWidget * gimp_ui_manager_ui_get (GimpUIManager *manager, const gchar *ui_path) { - GList *list; + GimpUIManagerUIEntry *entry; g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL); g_return_val_if_fail (ui_path != NULL, NULL); + entry = gimp_ui_manager_entry_get (manager, ui_path); + + if (! entry) + { + g_warning ("%s: no entry registered for \"%s\"", G_STRFUNC, ui_path); + return NULL; + } + + if (! entry->merge_id) + { + GError *error = NULL; + + if (! gimp_ui_manager_entry_load (manager, entry, &error)) + { + g_message (error->message); + g_clear_error (&error); + return NULL; + } + } + + if (! entry->widget) + { + entry->widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), + entry->ui_path); + + if (entry->widget) + { + g_object_ref (entry->widget); + + /* take ownership of popup menus */ + if (GTK_IS_MENU (entry->widget)) + gtk_object_sink (GTK_OBJECT (entry->widget)); + + if (entry->setup_func) + entry->setup_func (manager, entry->ui_path); + } + else + { + g_warning ("%s: \"%s\" does not contain registered toplevel " + "widget \"%s\"", + G_STRFUNC, entry->basename, entry->ui_path); + return NULL; + } + } + + if (! strcmp (entry->ui_path, ui_path)) + return entry->widget; + + return gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), ui_path); +} + +typedef struct +{ + guint x; + guint y; +} MenuPos; + +void +gimp_ui_manager_ui_popup (GimpUIManager *manager, + const gchar *ui_path, + GtkWidget *parent, + GimpMenuPositionFunc position_func, + gpointer position_data, + GtkDestroyNotify popdown_func, + gpointer popdown_data) +{ + GtkWidget *widget; + GdkEvent *current_event; + gint x, y; + guint button; + guint32 activate_time; + MenuPos *menu_pos; + + g_return_if_fail (GIMP_IS_UI_MANAGER (manager)); + g_return_if_fail (ui_path != NULL); + g_return_if_fail (parent == NULL || GTK_IS_WIDGET (parent)); + + widget = gimp_ui_manager_ui_get (manager, ui_path); + + if (GTK_IS_MENU_ITEM (widget)) + widget = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); + + g_return_if_fail (GTK_IS_MENU (widget)); + + if (! position_func) + { + position_func = gimp_ui_manager_menu_position; + position_data = parent; + } + + (* position_func) (GTK_MENU (widget), &x, &y, position_data); + + current_event = gtk_get_current_event (); + + if (current_event && current_event->type == GDK_BUTTON_PRESS) + { + GdkEventButton *bevent = (GdkEventButton *) current_event; + + button = bevent->button; + activate_time = bevent->time; + } + else + { + button = 0; + activate_time = 0; + } + + menu_pos = g_object_get_data (G_OBJECT (widget), "menu-pos"); + + if (! menu_pos) + { + menu_pos = g_new0 (MenuPos, 1); + g_object_set_data_full (G_OBJECT (widget), "menu-pos", menu_pos, g_free); + } + + menu_pos->x = x; + menu_pos->y = y; + + if (popdown_func && popdown_data) + { + g_object_set_data_full (G_OBJECT (manager), "popdown-data", + popdown_data, popdown_func); + g_signal_connect (widget, "selection-done", + G_CALLBACK (gimp_ui_manager_delete_popdown_data), + manager); + } + + gtk_menu_popup (GTK_MENU (widget), + NULL, NULL, + gimp_ui_manager_menu_pos, menu_pos, + button, activate_time); +} + + +/* private functions */ + +static GimpUIManagerUIEntry * +gimp_ui_manager_entry_get (GimpUIManager *manager, + const gchar *ui_path) +{ + GList *list; + gchar *path; + + path = g_strdup (ui_path); + + if (strlen (path) > 1) + { + gchar *p = strchr (path + 1, '/'); + + if (p) + *p = '\0'; + } + for (list = manager->registered_uis; list; list = g_list_next (list)) { GimpUIManagerUIEntry *entry = list->data; - if (! strcmp (entry->ui_path, ui_path)) + if (! strcmp (entry->ui_path, path)) { - if (! entry->merge_id) - { - gchar *filename; - GError *error = NULL; + g_free (path); - filename = g_build_filename (gimp_data_directory (), "menus", - entry->basename, NULL); - - g_print ("loading menu: %s for %s\n", filename, - entry->ui_path); - - entry->merge_id = - gtk_ui_manager_add_ui_from_file (GTK_UI_MANAGER (manager), - filename, &error); - - g_free (filename); - - if (! entry->merge_id) - { - g_message (error->message); - g_clear_error (&error); - - return NULL; - } - } - - if (! entry->widget) - { - gtk_ui_manager_ensure_update (GTK_UI_MANAGER (manager)); - - entry->widget = - gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), - entry->ui_path); - - if (entry->widget) - { - g_object_ref (entry->widget); - - if (entry->setup_func) - entry->setup_func (manager, entry->ui_path); - } - } - - return entry->widget; + return entry; } } - g_warning ("%s: no entry registered for \"%s\"", - G_STRFUNC, ui_path); + g_free (path); return NULL; } +static gboolean +gimp_ui_manager_entry_load (GimpUIManager *manager, + GimpUIManagerUIEntry *entry, + GError **error) +{ + gchar *filename; + + filename = g_build_filename (gimp_data_directory (), "menus", + entry->basename, NULL); + + g_print ("loading menu: %s for %s\n", filename, entry->ui_path); + + entry->merge_id = gtk_ui_manager_add_ui_from_file (GTK_UI_MANAGER (manager), + filename, error); + + g_free (filename); + + if (! entry->merge_id) + return FALSE; + + return TRUE; +} + static void gimp_ui_manager_menu_position (GtkMenu *menu, gint *x, @@ -562,12 +712,6 @@ gimp_ui_manager_menu_position (GtkMenu *menu, if (*y < rect.y) *y = rect.y; } -typedef struct -{ - guint x; - guint y; -} MenuPos; - static void gimp_ui_manager_menu_pos (GtkMenu *menu, gint *x, @@ -582,91 +726,15 @@ gimp_ui_manager_menu_pos (GtkMenu *menu, } static void -gimp_ui_manager_delete_popup_data (GtkObject *object, - GimpUIManager *manager) +gimp_ui_manager_delete_popdown_data (GtkObject *object, + GimpUIManager *manager) { g_signal_handlers_disconnect_by_func (object, - gimp_ui_manager_delete_popup_data, + gimp_ui_manager_delete_popdown_data, manager); - g_object_set_data (G_OBJECT (manager), "popup-data", NULL); + g_object_set_data (G_OBJECT (manager), "popdown-data", NULL); } -void -gimp_ui_manager_ui_popup (GimpUIManager *manager, - const gchar *ui_path, - gpointer popup_data, - GtkWidget *parent, - GimpMenuPositionFunc position_func, - gpointer position_data, - GtkDestroyNotify popdown_func) -{ - GtkWidget *widget; - GdkEvent *current_event; - gint x, y; - guint button; - guint32 activate_time; - MenuPos *menu_pos; - - g_return_if_fail (GIMP_IS_UI_MANAGER (manager)); - g_return_if_fail (ui_path != NULL); - g_return_if_fail (parent == NULL || GTK_IS_WIDGET (parent)); - - widget = gimp_ui_manager_ui_get (manager, ui_path); - - g_return_if_fail (GTK_IS_MENU (widget)); - - if (! position_func) - { - position_func = gimp_ui_manager_menu_position; - position_data = parent; - } - - (* position_func) (GTK_MENU (widget), &x, &y, position_data); - - current_event = gtk_get_current_event (); - - if (current_event && current_event->type == GDK_BUTTON_PRESS) - { - GdkEventButton *bevent = (GdkEventButton *) current_event; - - button = bevent->button; - activate_time = bevent->time; - } - else - { - button = 0; - activate_time = 0; - } - - menu_pos = g_object_get_data (G_OBJECT (widget), "menu-pos"); - - if (! menu_pos) - { - menu_pos = g_new0 (MenuPos, 1); - g_object_set_data_full (G_OBJECT (widget), "menu-pos", menu_pos, g_free); - } - - menu_pos->x = x; - menu_pos->y = y; - - if (popup_data != NULL) - { - g_object_set_data_full (G_OBJECT (manager), "popup-data", - popup_data, popdown_func); - g_signal_connect (widget, "selection-done", - G_CALLBACK (gimp_ui_manager_delete_popup_data), - manager); - } - - gtk_menu_popup (GTK_MENU (widget), - NULL, NULL, - gimp_ui_manager_menu_pos, menu_pos, - button, activate_time); -} - - -/* private functions */ - static void gimp_ui_manager_item_realize (GtkWidget *widget, GimpUIManager *manager) diff --git a/app/widgets/gimpuimanager.h b/app/widgets/gimpuimanager.h index d52e6de4eb..d25754e212 100644 --- a/app/widgets/gimpuimanager.h +++ b/app/widgets/gimpuimanager.h @@ -87,11 +87,11 @@ GtkWidget * gimp_ui_manager_ui_get (GimpUIManager *manager, void gimp_ui_manager_ui_popup (GimpUIManager *manager, const gchar *ui_path, - gpointer popup_data, GtkWidget *parent, GimpMenuPositionFunc position_func, gpointer position_data, - GtkDestroyNotify popdown_func); + GtkDestroyNotify popdown_func, + gpointer popdown_data); #endif /* __GIMP_UI_MANAGER_H__ */ diff --git a/menus/menus.xsl b/menus/menus.xsl index ef1ae6d8b5..ae533ba512 100644 --- a/menus/menus.xsl +++ b/menus/menus.xsl @@ -25,10 +25,12 @@ -menubar - - -popup - - + + + -popup + + +