diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c index 48f69035db..8c17e7f9e6 100644 --- a/app/display/gimpdisplayshell-callbacks.c +++ b/app/display/gimpdisplayshell-callbacks.c @@ -353,6 +353,7 @@ gimp_display_shell_quick_mask_button_press (GtkWidget *widget, gimp_ui_manager_ui_popup_at_widget (manager, "/quick-mask-popup", + NULL, NULL, widget, GDK_GRAVITY_EAST, GDK_GRAVITY_SOUTH_WEST, diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 138f0107c5..3bb7f3dbd2 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -989,6 +989,7 @@ gimp_display_shell_popup_menu (GtkWidget *widget) gimp_ui_manager_ui_popup_at_widget (shell->popup_manager, "/image-menubar", + NULL, NULL, shell->origin, GDK_GRAVITY_EAST, GDK_GRAVITY_NORTH_WEST, diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c index c4d3b5372a..8df831feae 100644 --- a/app/widgets/gimpdockbook.c +++ b/app/widgets/gimpdockbook.c @@ -551,8 +551,6 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook) GimpUIManager *dialog_ui_manager; const gchar *dialog_ui_path; gpointer dialog_popup_data; - GtkWidget *parent_menu_widget; - GimpAction *parent_menu_action; GimpDockable *dockable; gint page_num; @@ -561,16 +559,6 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook) if (! dockbook_ui_manager) return FALSE; - parent_menu_widget = - gimp_ui_manager_get_widget (dockbook_ui_manager, - "/dockable-popup/dockable-menu"); - parent_menu_action = - gimp_ui_manager_get_action (dockbook_ui_manager, - "/dockable-popup/dockable-menu"); - - if (! parent_menu_widget || ! parent_menu_action) - return FALSE; - page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook)); dockable = GIMP_DOCKABLE (gtk_notebook_get_nth_page (GTK_NOTEBOOK (dockbook), page_num)); @@ -582,69 +570,6 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook) &dialog_ui_path, &dialog_popup_data); - if (dialog_ui_manager && dialog_ui_path) - { - GtkWidget *child_menu_widget; - GimpAction *child_menu_action; - gchar *label; - - child_menu_widget = - gimp_ui_manager_get_widget (dialog_ui_manager, dialog_ui_path); - - if (! child_menu_widget) - { - g_warning ("%s: UI manager '%s' has no widget at path '%s'", - G_STRFUNC, dialog_ui_manager->name, dialog_ui_path); - return FALSE; - } - - child_menu_action = - gimp_ui_manager_get_action (dialog_ui_manager, - dialog_ui_path); - - if (! child_menu_action) - { - g_warning ("%s: UI manager '%s' has no action at path '%s'", - G_STRFUNC, dialog_ui_manager->name, dialog_ui_path); - return FALSE; - } - - g_object_get (child_menu_action, - "label", &label, - NULL); - - g_object_set (parent_menu_action, - "label", label, - "icon-name", gimp_dockable_get_icon_name (dockable), - "visible", TRUE, - NULL); - - g_free (label); - - if (! GTK_IS_MENU (child_menu_widget)) - { - g_warning ("%s: child_menu_widget (%p) is not a GtkMenu", - G_STRFUNC, child_menu_widget); - return FALSE; - } - - { - GtkWidget *image = gimp_dockable_get_icon (dockable, - GTK_ICON_SIZE_MENU); - gimp_menu_item_set_image (GTK_MENU_ITEM (parent_menu_widget), image, NULL); - gtk_widget_show (image); - } - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (parent_menu_widget), - child_menu_widget); - - gimp_ui_manager_update (dialog_ui_manager, dialog_popup_data); - } - else - { - g_object_set (parent_menu_action, "visible", FALSE, NULL); - } - /* an action callback may destroy both dockable and dockbook, so * reference them for gimp_dockbook_menu_end() */ @@ -653,10 +578,10 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook) g_object_ref (dockbook), g_object_unref); - gimp_ui_manager_update (dockbook_ui_manager, dockable); - gimp_ui_manager_ui_popup_at_widget (dockbook_ui_manager, "/dockable-popup", + dialog_ui_manager, + dialog_ui_path, dockbook->p->menu_button, GDK_GRAVITY_WEST, GDK_GRAVITY_NORTH_EAST, @@ -670,23 +595,6 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook) static void gimp_dockbook_menu_end (GimpDockable *dockable) { - GimpUIManager *dialog_ui_manager; - const gchar *dialog_ui_path; - gpointer dialog_popup_data; - - dialog_ui_manager = gimp_dockable_get_menu (dockable, - &dialog_ui_path, - &dialog_popup_data); - - if (dialog_ui_manager && dialog_ui_path) - { - GtkWidget *child_menu_widget = - gimp_ui_manager_get_widget (dialog_ui_manager, dialog_ui_path); - - if (child_menu_widget) - gtk_menu_detach (GTK_MENU (child_menu_widget)); - } - /* release gimp_dockbook_show_menu()'s references */ g_object_set_data (G_OBJECT (dockable), GIMP_DOCKABLE_DETACH_REF_KEY, NULL); g_object_unref (dockable); diff --git a/app/widgets/gimpmenushell.c b/app/widgets/gimpmenushell.c index cde476e75c..7116a91c03 100644 --- a/app/widgets/gimpmenushell.c +++ b/app/widgets/gimpmenushell.c @@ -157,6 +157,33 @@ gimp_menu_shell_fill (GimpMenuShell *shell, } } +void +gimp_menu_shell_merge (GimpMenuShell *shell, + GimpMenuShell *shell2, + gboolean top) +{ + GList *children; + GList *iter; + + children = gtk_container_get_children (GTK_CONTAINER (shell2)); + iter = top ? g_list_last (children) : children; + for (; iter; iter = top ? iter->prev : iter->next) + { + GtkWidget *item = iter->data; + + g_object_ref (item); + gtk_container_remove (GTK_CONTAINER (shell2), item); + if (top) + gtk_menu_shell_prepend (GTK_MENU_SHELL (shell), item); + else + gtk_menu_shell_append (GTK_MENU_SHELL (shell), item); + g_object_unref (item); + } + + g_list_free (children); + gtk_widget_destroy (GTK_WIDGET (shell2)); +} + /* Protected functions. */ diff --git a/app/widgets/gimpmenushell.h b/app/widgets/gimpmenushell.h index 419df138cb..3983432828 100644 --- a/app/widgets/gimpmenushell.h +++ b/app/widgets/gimpmenushell.h @@ -49,6 +49,9 @@ GType gimp_menu_shell_get_type (void) G_GNUC_CONST; void gimp_menu_shell_fill (GimpMenuShell *shell, GMenuModel *model, const gchar *update_signal); +void gimp_menu_shell_merge (GimpMenuShell *shell, + GimpMenuShell *shell2, + gboolean top); /* Protected functions. */ diff --git a/app/widgets/gimptooloptionseditor.c b/app/widgets/gimptooloptionseditor.c index d04e7fb045..16558333f6 100644 --- a/app/widgets/gimptooloptionseditor.c +++ b/app/widgets/gimptooloptionseditor.c @@ -383,7 +383,7 @@ gimp_tool_options_editor_menu_popup (GimpToolOptionsEditor *editor, gimp_editor_get_popup_data (gimp_editor)); gimp_ui_manager_ui_popup_at_widget (gimp_editor_get_ui_manager (gimp_editor), - path, + path, NULL, NULL, button, GDK_GRAVITY_WEST, GDK_GRAVITY_NORTH_EAST, diff --git a/app/widgets/gimpuimanager.c b/app/widgets/gimpuimanager.c index 1669a01eb6..4854adfc39 100644 --- a/app/widgets/gimpuimanager.c +++ b/app/widgets/gimpuimanager.c @@ -723,6 +723,8 @@ gimp_ui_manager_ui_register (GimpUIManager *manager, void gimp_ui_manager_ui_popup_at_widget (GimpUIManager *manager, const gchar *ui_path, + GimpUIManager *child_ui_manager, + const gchar *child_ui_path, GtkWidget *widget, GdkGravity widget_anchor, GdkGravity menu_anchor, @@ -745,6 +747,19 @@ gimp_ui_manager_ui_popup_at_widget (GimpUIManager *manager, if (! menu) return; + if (child_ui_manager != NULL && child_ui_path != NULL) + { + GMenuModel *child_model; + GtkWidget *child_menu; + + /* TODO GMenu: the "icon" attribute set in the .ui file should be visible. */ + child_model = gimp_ui_manager_get_model (child_ui_manager, child_ui_path); + child_menu = gimp_menu_new (child_ui_manager); + gimp_menu_shell_fill (GIMP_MENU_SHELL (child_menu), child_model, NULL); + + gimp_menu_shell_merge (GIMP_MENU_SHELL (menu), GIMP_MENU_SHELL (child_menu), TRUE); + } + if (popdown_func && popdown_data) { g_object_set_data_full (G_OBJECT (manager), "popdown-data", diff --git a/app/widgets/gimpuimanager.h b/app/widgets/gimpuimanager.h index 9cb0cd2e70..e38a9e0904 100644 --- a/app/widgets/gimpuimanager.h +++ b/app/widgets/gimpuimanager.h @@ -155,6 +155,8 @@ void gimp_ui_manager_ui_register (GimpUIManager *manager, void gimp_ui_manager_ui_popup_at_widget (GimpUIManager *manager, const gchar *ui_path, + GimpUIManager *child_ui_manager, + const gchar *child_ui_path, GtkWidget *widget, GdkGravity widget_anchor, GdkGravity menu_anchor, diff --git a/menus/meson.build b/menus/meson.build index 54f1349f1f..e8283c1e23 100644 --- a/menus/meson.build +++ b/menus/meson.build @@ -56,6 +56,7 @@ ui_menus_files = files( 'patterns-menu.ui', 'quick-mask-menu.ui', 'templates-menu.ui', + 'undo-menu.ui', 'vectors-menu.ui', ) diff --git a/menus/undo-menu.ui b/menus/undo-menu.ui new file mode 100644 index 0000000000..4c2bb78e58 --- /dev/null +++ b/menus/undo-menu.ui @@ -0,0 +1,13 @@ + + + + + + Undo History Menu + edit-undo + app.edit-undo + app.edit-redo + app.edit-undo-clear + + +