From fb32b8e48e49224ef94675c1a3b84c3d6f1c3cbe Mon Sep 17 00:00:00 2001 From: Andre Miranda <andreldm@xfce.org> Date: Sun, 19 Nov 2017 15:02:23 -0300 Subject: [PATCH] Introduce ThunarxMenu Also refactoring some menu related code into thunar-menu-util.c --- docs/reference/thunarx/thunarx-docs.xml | 2 + docs/reference/thunarx/thunarx-sections.txt | 22 +++ docs/reference/thunarx/thunarx.types | 1 + thunar/Makefile.am | 2 + thunar/thunar-dnd.c | 17 +- thunar/thunar-menu-util.c | 164 ++++++++++++++++++++ thunar/thunar-menu-util.h | 39 +++++ thunar/thunar-renamer-dialog.c | 24 +-- thunar/thunar-shortcuts-view.c | 16 +- thunar/thunar-standard-view.c | 48 ++---- thunar/thunar-tree-view.c | 16 +- thunar/thunar-util.c | 53 ------- thunar/thunar-util.h | 2 - thunar/thunar-window.c | 58 ++----- thunarx/Makefile.am | 2 + thunarx/thunarx-menu-item.c | 71 ++++++++- thunarx/thunarx-menu-item.h | 42 +---- thunarx/thunarx-menu.c | 144 +++++++++++++++++ thunarx/thunarx-menu.h | 115 ++++++++++++++ thunarx/thunarx.h | 2 +- thunarx/thunarx.symbols | 8 + 21 files changed, 602 insertions(+), 246 deletions(-) create mode 100644 thunar/thunar-menu-util.c create mode 100644 thunar/thunar-menu-util.h create mode 100644 thunarx/thunarx-menu.c create mode 100644 thunarx/thunarx-menu.h diff --git a/docs/reference/thunarx/thunarx-docs.xml b/docs/reference/thunarx/thunarx-docs.xml index 663379549..12127dc9d 100644 --- a/docs/reference/thunarx/thunarx-docs.xml +++ b/docs/reference/thunarx/thunarx-docs.xml @@ -3,6 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ <!ENTITY ThunarxFileInfo SYSTEM "xml/thunarx-file-info.xml"> +<!ENTITY ThunarxMenu SYSTEM "xml/thunarx-menu.xml"> <!ENTITY ThunarxMenuItem SYSTEM "xml/thunarx-menu-item.xml"> <!ENTITY ThunarxMenuProvider SYSTEM "xml/thunarx-menu-provider.xml"> <!ENTITY ThunarxPreferencesProvider SYSTEM "xml/thunarx-preferences-provider.xml"> @@ -451,6 +452,7 @@ thunar_extension_initialize (ThunarxProviderPlugin *plugin) </para> &ThunarxFileInfo; + &ThunarxMenu; &ThunarxMenuItem; &ThunarxPropertyPage; &ThunarxProviderPlugin; diff --git a/docs/reference/thunarx/thunarx-sections.txt b/docs/reference/thunarx/thunarx-sections.txt index 7eceb0ce1..d057ceb6e 100644 --- a/docs/reference/thunarx/thunarx-sections.txt +++ b/docs/reference/thunarx/thunarx-sections.txt @@ -30,6 +30,26 @@ thunarx_file_info_get_type thunarx_file_info_list_get_type </SECTION> +<SECTION> +<FILE>thunarx-menu</FILE> +<TITLE>ThunarxMenu</TITLE> +ThunarxMenu +thunarx_menu_new +thunarx_menu_append_item +thunarx_menu_get_items +<SUBSECTION Standard> +ThunarxMenuClass +THUNARX_TYPE_MENU +THUNARX_MENU +THUNARX_MENU_CLASS +THUNARX_IS_MENU +THUNARX_IS_MENU_CLASS +THUNARX_MENU_GET_CLASS +<SUBSECTION Private> +ThunarxMenuPrivate +thunarx_menu_get_type +</SECTION> + <SECTION> <FILE>thunarx-menu-item</FILE> <TITLE>ThunarxMenuItem</TITLE> @@ -38,6 +58,8 @@ thunarx_menu_item_new thunarx_menu_item_activate thunarx_menu_item_get_sensitive thunarx_menu_item_set_sensitive +thunarx_menu_item_set_menu +thunarx_menu_item_list_free <SUBSECTION Standard> ThunarxMenuItemClass THUNARX_TYPE_MENU_ITEM diff --git a/docs/reference/thunarx/thunarx.types b/docs/reference/thunarx/thunarx.types index 81cbc41c7..7af7f57e7 100644 --- a/docs/reference/thunarx/thunarx.types +++ b/docs/reference/thunarx/thunarx.types @@ -1,6 +1,7 @@ #include <thunarx/thunarx.h> thunarx_file_info_get_type +thunarx_menu_get_type thunarx_menu_item_get_type thunarx_menu_provider_get_type thunarx_preferences_provider_get_type diff --git a/thunar/Makefile.am b/thunar/Makefile.am index dc8284e69..1ae0d3e34 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -139,6 +139,8 @@ thunar_SOURCES = \ thunar-location-buttons.h \ thunar-location-entry.c \ thunar-location-entry.h \ + thunar-menu-util.c \ + thunar-menu-util.h \ thunar-misc-jobs.c \ thunar-misc-jobs.h \ thunar-notify.c \ diff --git a/thunar/thunar-dnd.c b/thunar/thunar-dnd.c index 9bf1b8684..a8b54d0a1 100644 --- a/thunar/thunar-dnd.c +++ b/thunar/thunar-dnd.c @@ -29,8 +29,8 @@ #include <thunar/thunar-dialogs.h> #include <thunar/thunar-dnd.h> #include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-menu-util.h> #include <thunar/thunar-private.h> -#include <thunar/thunar-util.h> @@ -85,7 +85,6 @@ thunar_dnd_ask (GtkWidget *widget, GList *items = NULL; GList *lp; guint n; - GtkAction *action; _thunar_return_val_if_fail (thunar_file_is_directory (folder), 0); _thunar_return_val_if_fail (GTK_IS_WIDGET (widget), 0); @@ -153,19 +152,7 @@ thunar_dnd_ask (GtkWidget *widget, if (G_UNLIKELY (items != NULL)) { /* add menu items for all items */ - for (lp = items; lp != NULL; lp = lp->next) - { - action = thunar_util_action_from_menu_item (G_OBJECT (lp->data)); - - /* add a menu item for the action */ - item = gtk_action_create_menu_item (action); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* release the reference on the menu item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); - } + thunar_menu_util_add_items_to_menu (menu, items); g_list_free (items); /* append another separator */ diff --git a/thunar/thunar-menu-util.c b/thunar/thunar-menu-util.c new file mode 100644 index 000000000..921830504 --- /dev/null +++ b/thunar/thunar-menu-util.c @@ -0,0 +1,164 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2017 Andre Miranda <andreldm@xfce.org> + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <thunar/thunar-menu-util.h> + +#include <thunarx/thunarx.h> + + + +static void +extension_action_callback (GtkAction *action, + gpointer callback_data) +{ + thunarx_menu_item_activate (THUNARX_MENU_ITEM (callback_data)); +} + + + +static GtkAction * +action_from_menu_item (GObject *item) +{ + gchar *name, *label, *tooltip, *icon_name; + gboolean sensitive, priority; + GtkAction *action; + + g_return_val_if_fail (THUNARX_IS_MENU_ITEM (item), NULL); + + g_object_get (G_OBJECT (item), + "name", &name, + "label", &label, + "tooltip", &tooltip, + "icon", &icon_name, + "sensitive", &sensitive, + "priority", &priority, + NULL); + + action = gtk_action_new (name, label, tooltip, NULL); + + if (icon_name != NULL) + { + gtk_action_set_icon_name (action, icon_name); + } + + gtk_action_set_sensitive (action, sensitive); + g_object_set (action, "is-important", priority, NULL); + + g_signal_connect_data (action, "activate", + G_CALLBACK (extension_action_callback), + g_object_ref (item), + (GClosureNotify) g_object_unref, 0); + + g_free (name); + g_free (label); + g_free (tooltip); + g_free (icon_name); + + return action; +} + + + +void +thunar_menu_util_add_items_to_ui_manager (GtkUIManager *ui_manager, + GtkActionGroup *action_group, + gint merge_id, + const gchar *path, + GList *items) +{ + GList *lp; + GtkAction *action; + ThunarxMenu *menu; + char *subpath; + GList *children; + + /* add the menu items to the UI manager */ + for (lp = items; lp != NULL; lp = lp->next) + { + action = action_from_menu_item (G_OBJECT (lp->data)); + g_object_get (G_OBJECT (lp->data), "menu", &menu, NULL); + + /* add the action to the action group */ + gtk_action_group_add_action (action_group, action); + + /* add the action to the UI manager */ + gtk_ui_manager_add_ui (ui_manager, merge_id, path, + gtk_action_get_name (GTK_ACTION (action)), + gtk_action_get_name (GTK_ACTION (action)), + (menu != NULL) ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM, FALSE); + + /* add submenu items if any */ + if (menu != NULL) { + children = thunarx_menu_get_items (menu); + subpath = g_build_path ("/", path, gtk_action_get_name (action), NULL); + + thunar_menu_util_add_items_to_ui_manager (ui_manager, action_group, merge_id, + subpath, children); + + thunarx_menu_item_list_free (children); + g_free (subpath); + } + + /* release the reference on item and action */ + g_object_unref (G_OBJECT (lp->data)); + g_object_unref (G_OBJECT (action)); + } +} + + + +void +thunar_menu_util_add_items_to_menu (GtkWidget *menu, + GList *items) +{ + GList *lp; + GtkAction *action; + GtkWidget *item; + GtkWidget *submenu; + ThunarxMenu *thunarx_menu; + GList *children; + + /* add the menu items to the UI manager */ + for (lp = items; lp != NULL; lp = lp->next) + { + action = action_from_menu_item (G_OBJECT (lp->data)); + + item = gtk_action_create_menu_item (action); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + + /* add submenu items if any */ + g_object_get (G_OBJECT (lp->data), "menu", &thunarx_menu, NULL); + if (thunarx_menu != NULL) { + children = thunarx_menu_get_items (thunarx_menu); + + submenu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + + thunar_menu_util_add_items_to_menu (submenu, children); + + thunarx_menu_item_list_free (children); + } + + /* release the reference on item and action */ + g_object_unref (G_OBJECT (lp->data)); + g_object_unref (G_OBJECT (action)); + } +} diff --git a/thunar/thunar-menu-util.h b/thunar/thunar-menu-util.h new file mode 100644 index 000000000..68efe81b0 --- /dev/null +++ b/thunar/thunar-menu-util.h @@ -0,0 +1,39 @@ +/* vi:set et ai sw=2 sts=2 ts=2: */ +/*- + * Copyright (c) 2017 Andre Miranda <andreldm@xfce.org> + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __THUNAR_MENU_UTIL_H__ +#define __THUNAR_MENU_UTIL_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +void thunar_menu_util_add_items_to_ui_manager (GtkUIManager *ui_manager, + GtkActionGroup *action_group, + gint merge_id, + const gchar *path, + GList *items); + +void thunar_menu_util_add_items_to_menu (GtkWidget *menu, + GList *items); + +G_END_DECLS + +#endif /* !__THUNAR_MENU_UTIL_H__ */ diff --git a/thunar/thunar-renamer-dialog.c b/thunar/thunar-renamer-dialog.c index 5cbffe777..e72889f3d 100644 --- a/thunar/thunar-renamer-dialog.c +++ b/thunar/thunar-renamer-dialog.c @@ -37,13 +37,13 @@ #include <thunar/thunar-icon-factory.h> #include <thunar/thunar-icon-renderer.h> #include <thunar/thunar-launcher.h> +#include <thunar/thunar-menu-util.h> #include <thunar/thunar-private.h> #include <thunar/thunar-properties-dialog.h> #include <thunar/thunar-renamer-dialog.h> #include <thunar/thunar-renamer-dialog-ui.h> #include <thunar/thunar-renamer-model.h> #include <thunar/thunar-renamer-progress.h> -#include <thunar/thunar-util.h> @@ -849,9 +849,7 @@ thunar_renamer_dialog_context_menu (ThunarRenamerDialog *renamer_dialog, ThunarxRenamer *renamer; GtkWidget *menu; GList *items = NULL; - GList *lp; gint renamer_merge_id = 0; - GtkAction *action; _thunar_return_if_fail (THUNAR_IS_RENAMER_DIALOG (renamer_dialog)); @@ -875,24 +873,8 @@ thunar_renamer_dialog_context_menu (ThunarRenamerDialog *renamer_dialog, gtk_ui_manager_insert_action_group (renamer_dialog->ui_manager, renamer_actions, -1); /* add the items to the UI manager */ - for (lp = items; lp != NULL; lp = lp->next) - { - action = thunar_util_action_from_menu_item (G_OBJECT (lp->data)); - - /* add the action to the action group */ - gtk_action_group_add_action (renamer_actions, action); - - /* add the action to the UI manager */ - gtk_ui_manager_add_ui (renamer_dialog->ui_manager, renamer_merge_id, - "/file-context-menu/placeholder-renamer-actions", - gtk_action_get_name (action), - gtk_action_get_name (action), - GTK_UI_MANAGER_MENUITEM, FALSE); - - /* release the reference on the menu item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); - } + thunar_menu_util_add_items_to_ui_manager (renamer_dialog->ui_manager, renamer_actions, renamer_merge_id, + "/file-context-menu/placeholder-renamer-actions", items); /* be sure to update the UI manager to avoid flickering */ gtk_ui_manager_ensure_update (renamer_dialog->ui_manager); diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c index 0685246a5..e45742306 100644 --- a/thunar/thunar-shortcuts-view.c +++ b/thunar/thunar-shortcuts-view.c @@ -40,13 +40,13 @@ #include <thunar/thunar-dnd.h> #include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gtk-extensions.h> +#include <thunar/thunar-menu-util.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-shortcuts-icon-renderer.h> #include <thunar/thunar-shortcuts-model.h> #include <thunar/thunar-shortcuts-view.h> #include <thunar/thunar-stock.h> -#include <thunar/thunar-util.h> @@ -1072,7 +1072,6 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, gboolean can_mount; gboolean can_unmount; gboolean can_eject; - GtkAction *action; /* check if this is an item menu or a header menu */ gtk_tree_model_get (model, iter, THUNAR_SHORTCUTS_MODEL_COLUMN_IS_HEADER, &is_header, -1); @@ -1242,18 +1241,7 @@ thunar_shortcuts_view_context_menu (ThunarShortcutsView *view, } /* add the menu items to the menu */ - for (lp = items; lp != NULL; lp = lp->next) - { - action = thunar_util_action_from_menu_item (G_OBJECT (lp->data)); - - item = gtk_action_create_menu_item (action); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* release the reference on the menu item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); - } + thunar_menu_util_add_items_to_menu (menu, items); /* cleanup */ g_list_free (items); diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c index 165507be4..5ae8ab20d 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -43,6 +43,7 @@ #include <thunar/thunar-history.h> #include <thunar/thunar-icon-renderer.h> #include <thunar/thunar-marshal.h> +#include <thunar/thunar-menu-util.h> #include <thunar/thunar-private.h> #include <thunar/thunar-properties-dialog.h> #include <thunar/thunar-renamer-dialog.h> @@ -2002,7 +2003,7 @@ thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view, GList *files = NULL; GList *tmp; GList *lp; - GtkAction *action; + gchar *path; /* we cannot add anything if we aren't connected to any UI manager */ if (G_UNLIKELY (standard_view->ui_manager == NULL)) @@ -2075,40 +2076,21 @@ thunar_standard_view_merge_custom_actions (ThunarStandardView *standard_view, standard_view->priv->custom_merge_id = gtk_ui_manager_new_merge_id (standard_view->ui_manager); gtk_ui_manager_insert_action_group (standard_view->ui_manager, standard_view->priv->custom_actions, -1); - /* add the menu items to the UI manager */ - for (lp = items; lp != NULL; lp = lp->next) + if (G_LIKELY (selected_items != NULL)) { - action = thunar_util_action_from_menu_item (G_OBJECT (lp->data)); - - /* add the action to the action group */ - gtk_action_group_add_action (standard_view->priv->custom_actions, action); - - /* add the action to the UI manager */ - if (G_LIKELY (selected_items != NULL)) - { - /* add to the file context menu */ - gtk_ui_manager_add_ui (standard_view->ui_manager, - standard_view->priv->custom_merge_id, - "/file-context-menu/placeholder-custom-actions", - gtk_action_get_name (GTK_ACTION (action)), - gtk_action_get_name (GTK_ACTION (action)), - GTK_UI_MANAGER_MENUITEM, FALSE); - } - else - { - /* add to the folder context menu */ - gtk_ui_manager_add_ui (standard_view->ui_manager, - standard_view->priv->custom_merge_id, - "/folder-context-menu/placeholder-custom-actions", - gtk_action_get_name (GTK_ACTION (action)), - gtk_action_get_name (GTK_ACTION (action)), - GTK_UI_MANAGER_MENUITEM, FALSE); - } - - /* release the reference on item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); + /* add to the file context menu */ + path = "/file-context-menu/placeholder-custom-actions"; } + else + { + /* add to the folder context menu */ + path = "/folder-context-menu/placeholder-custom-actions"; + } + + thunar_menu_util_add_items_to_ui_manager (standard_view->ui_manager, + standard_view->priv->custom_actions, + standard_view->priv->custom_merge_id, + path, items); /* be sure to update the UI manager to avoid flickering */ gtk_ui_manager_ensure_update (standard_view->ui_manager); diff --git a/thunar/thunar-tree-view.c b/thunar/thunar-tree-view.c index 17954bb62..7711b925b 100644 --- a/thunar/thunar-tree-view.c +++ b/thunar/thunar-tree-view.c @@ -35,6 +35,7 @@ #include <thunar/thunar-gtk-extensions.h> #include <thunar/thunar-job.h> #include <thunar/thunar-marshal.h> +#include <thunar/thunar-menu-util.h> #include <thunar/thunar-preferences.h> #include <thunar/thunar-private.h> #include <thunar/thunar-stock.h> @@ -43,7 +44,6 @@ #include <thunar/thunar-simple-job.h> #include <thunar/thunar-tree-model.h> #include <thunar/thunar-tree-view.h> -#include <thunar/thunar-util.h> @@ -1266,7 +1266,6 @@ thunar_tree_view_context_menu (ThunarTreeView *view, GIcon *icon; GList *providers, *lp; GList *items = NULL, *tmp; - GtkAction *action; /* verify that we're connected to the clipboard manager */ if (G_UNLIKELY (view->clipboard == NULL)) @@ -1516,18 +1515,7 @@ thunar_tree_view_context_menu (ThunarTreeView *view, g_list_free (providers); /* add the menu items to the menu */ - for (lp = items; lp != NULL; lp = lp->next) - { - action = thunar_util_action_from_menu_item (G_OBJECT (lp->data)); - - item = gtk_action_create_menu_item (action); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - - /* release the reference on the menu item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); - } + thunar_menu_util_add_items_to_menu (menu, items); /* add a separator to the end of the menu */ if (G_LIKELY (lp != items)) diff --git a/thunar/thunar-util.c b/thunar/thunar-util.c index e4a291d44..c61a73b91 100644 --- a/thunar/thunar-util.c +++ b/thunar/thunar-util.c @@ -56,7 +56,6 @@ #include <thunar/thunar-private.h> #include <thunar/thunar-util.h> -#include <thunarx/thunarx.h> #include <glib.h> #include <glib/gstdio.h> @@ -610,55 +609,3 @@ thunar_setup_display_cb (gpointer data) { g_setenv ("DISPLAY", (char *) data, TRUE); } - - - -static void -extension_action_callback (GtkAction *action, - gpointer callback_data) -{ - thunarx_menu_item_activate (THUNARX_MENU_ITEM (callback_data)); -} - - - -GtkAction * -thunar_util_action_from_menu_item (GObject *item) -{ - gchar *name, *label, *tooltip, *icon_name; - gboolean sensitive, priority; - GtkAction *action; - - g_return_val_if_fail (THUNARX_IS_MENU_ITEM (item), NULL); - - g_object_get (G_OBJECT (item), - "name", &name, - "label", &label, - "tooltip", &tooltip, - "icon", &icon_name, - "sensitive", &sensitive, - "priority", &priority, - NULL); - - action = gtk_action_new (name, label, tooltip, NULL); - - if (icon_name != NULL) - { - gtk_action_set_icon_name (action, icon_name); - } - - gtk_action_set_sensitive (action, sensitive); - g_object_set (action, "is-important", priority, NULL); - - g_signal_connect_data (action, "activate", - G_CALLBACK (extension_action_callback), - g_object_ref (item), - (GClosureNotify) g_object_unref, 0); - - g_free (name); - g_free (label); - g_free (tooltip); - g_free (icon_name); - - return action; -} diff --git a/thunar/thunar-util.h b/thunar/thunar-util.h index adf058583..5449f0c3d 100644 --- a/thunar/thunar-util.h +++ b/thunar/thunar-util.h @@ -55,8 +55,6 @@ gchar *thunar_util_change_working_directory (const gchar *new_directory) void thunar_setup_display_cb (gpointer data); -GtkAction *thunar_util_action_from_menu_item (GObject *item) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - G_END_DECLS; #endif /* !__THUNAR_UTIL_H__ */ diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 462ecebd6..9d846e95c 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -49,6 +49,7 @@ #include <thunar/thunar-location-buttons.h> #include <thunar/thunar-location-entry.h> #include <thunar/thunar-marshal.h> +#include <thunar/thunar-menu-util.h> #include <thunar/thunar-pango-extensions.h> #include <thunar/thunar-preferences-dialog.h> #include <thunar/thunar-preferences.h> @@ -1946,8 +1947,7 @@ thunar_window_merge_custom_preferences (ThunarWindow *window) { GList *providers; GList *items; - GList *ap, *pp; - GtkAction *action; + GList *pp; _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); _thunar_return_if_fail (window->custom_preferences_merge_id == 0); @@ -1964,24 +1964,12 @@ thunar_window_merge_custom_preferences (ThunarWindow *window) { /* determine the available menu items for the provider */ items = thunarx_preferences_provider_get_menu_items (THUNARX_PREFERENCES_PROVIDER (pp->data), GTK_WIDGET (window)); - for (ap = items; ap != NULL; ap = ap->next) - { - /* add the action to the action group */ - action = thunar_util_action_from_menu_item (G_OBJECT (ap->data)); - gtk_action_group_add_action (window->action_group, action); - - /* add the action to the UI manager */ - gtk_ui_manager_add_ui (window->ui_manager, - window->custom_preferences_merge_id, - "/main-menu/edit-menu/placeholder-custom-preferences", - gtk_action_get_name (GTK_ACTION (action)), - gtk_action_get_name (GTK_ACTION (action)), - GTK_UI_MANAGER_MENUITEM, FALSE); - - /* release the references on menu item and action */ - g_object_unref (G_OBJECT (ap->data)); - g_object_unref (G_OBJECT (action)); - } + + thunar_menu_util_add_items_to_ui_manager (window->ui_manager, + window->action_group, + window->custom_preferences_merge_id, + "/main-menu/edit-menu/placeholder-custom-preferences", + items); /* release the reference on the provider */ g_object_unref (G_OBJECT (pp->data)); @@ -3361,7 +3349,6 @@ thunar_window_update_custom_actions (ThunarView *view, GList *lp; GList *providers; GList *tmp; - GtkAction *action; _thunar_return_if_fail (THUNAR_IS_VIEW (view)); _thunar_return_if_fail (THUNAR_IS_WINDOW (window)); @@ -3436,30 +3423,11 @@ thunar_window_update_custom_actions (ThunarView *view, gtk_ui_manager_ensure_update (window->ui_manager); /* add the menu items to the UI manager */ - for (lp = items; lp != NULL; lp = lp->next) - { - if (G_UNLIKELY (lp->data == NULL)) - continue; - - action = thunar_util_action_from_menu_item (G_OBJECT (lp->data)); - - /* add the action to the action group */ - gtk_action_group_add_action_with_accel (window->custom_actions, - action, - NULL); - - /* add to the file context menu */ - gtk_ui_manager_add_ui (window->ui_manager, - window->custom_merge_id, - "/main-menu/file-menu/placeholder-custom-actions", - gtk_action_get_name (GTK_ACTION (action)), - gtk_action_get_name (GTK_ACTION (action)), - GTK_UI_MANAGER_MENUITEM, FALSE); - - /* release the references on menu item and action */ - g_object_unref (G_OBJECT (lp->data)); - g_object_unref (G_OBJECT (action)); - } + thunar_menu_util_add_items_to_ui_manager (window->ui_manager, + window->custom_actions, + window->custom_merge_id, + "/main-menu/file-menu/placeholder-custom-actions", + items); /* cleanup */ g_list_free (items); diff --git a/thunarx/Makefile.am b/thunarx/Makefile.am index abea8793f..82161ec8f 100644 --- a/thunarx/Makefile.am +++ b/thunarx/Makefile.am @@ -9,6 +9,7 @@ libthunarx_headers = \ thunarx.h \ thunarx-config.h \ thunarx-file-info.h \ + thunarx-menu.h \ thunarx-menu-item.h \ thunarx-menu-provider.h \ thunarx-preferences-provider.h \ @@ -32,6 +33,7 @@ libthunarx_3_la_SOURCES = \ $(libthunarx_headers) \ thunarx-config.c \ thunarx-file-info.c \ + thunarx-menu.c \ thunarx-menu-item.c \ thunarx-menu-provider.c \ thunarx-preferences-provider.c \ diff --git a/thunarx/thunarx-menu-item.c b/thunarx/thunarx-menu-item.c index 3a48d6fe4..9f4f608dd 100644 --- a/thunarx/thunarx-menu-item.c +++ b/thunarx/thunarx-menu-item.c @@ -23,6 +23,7 @@ #include <thunarx/thunarx-private.h> #include <thunarx/thunarx-menu-item.h> +#include <thunarx/thunarx-menu.h> @@ -77,12 +78,13 @@ static void thunarx_menu_item_finalize (GObject *object); struct _ThunarxMenuItemPrivate { - gchar *name; - gchar *label; - gchar *tooltip; - gchar *icon; - gboolean sensitive; - gboolean priority; + gchar *name; + gchar *label; + gchar *tooltip; + gchar *icon; + gboolean sensitive; + gboolean priority; + ThunarxMenu *menu; }; @@ -146,7 +148,6 @@ thunarx_menu_item_class_init (ThunarxMenuItemClass *klass) "Name of the icon to display in the menu item", NULL, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, PROP_SENSITIVE, g_param_spec_boolean ("sensitive", @@ -161,6 +162,13 @@ thunarx_menu_item_class_init (ThunarxMenuItemClass *klass) "Show priority text in toolbars", TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_MENU, + g_param_spec_object ("menu", + "Menu", + "The menu belonging to this item. May be null.", + THUNARX_TYPE_MENU, + G_PARAM_READWRITE)); } @@ -171,6 +179,7 @@ thunarx_menu_item_init (ThunarxMenuItem *item) item->priv = THUNARX_MENU_ITEM_GET_PRIVATE (item); item->priv->sensitive = TRUE; item->priv->priority = FALSE; + item->priv->menu = NULL; } @@ -209,6 +218,10 @@ thunarx_menu_item_get_property (GObject *object, g_value_set_boolean (value, item->priv->priority); break; + case PROP_MENU: + g_value_set_object (value, item->priv->menu); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -261,6 +274,13 @@ thunarx_menu_item_set_property (GObject *object, g_object_notify (object, "priority"); break; + case PROP_MENU: + if (item->priv->menu) + g_object_unref (item->priv->menu); + item->priv->menu = g_object_ref (g_value_get_object (value)); + g_object_notify (object, "menu"); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -279,6 +299,9 @@ thunarx_menu_item_finalize (GObject *object) g_free (item->priv->tooltip); g_free (item->priv->icon); + if (item->priv->menu) + g_object_unref (item->priv->menu); + (*G_OBJECT_CLASS (thunarx_menu_item_parent_class)->finalize) (object); } @@ -357,3 +380,37 @@ thunarx_menu_item_set_sensitive (ThunarxMenuItem *item, g_return_if_fail (THUNARX_IS_MENU_ITEM (item)); item->priv->sensitive = sensitive; } + + + +/** + * thunarx_menu_item_set_menu: + * @item: pointer to a #ThunarxMenuItem instance + * @menu: pointer to a #ThunarxMenu instance + * + * Attaches @menu to menu item. + */ +void +thunarx_menu_item_set_menu (ThunarxMenuItem *item, + ThunarxMenu *menu) +{ + g_return_if_fail (THUNARX_IS_MENU_ITEM (item)); + g_return_if_fail (THUNARX_IS_MENU (menu)); + + g_object_set (item, "menu", THUNARX_MENU (menu), NULL); +} + + + +/** + * thunarx_menu_item_list_free: + * @items: (element-type ThunarxMenuItem): a list of #ThunarxMenuItem + */ +void +thunarx_menu_item_list_free (GList *items) +{ + g_return_if_fail (items != NULL); + + g_list_foreach (items, (GFunc)g_object_unref, NULL); + g_list_free (items); +} diff --git a/thunarx/thunarx-menu-item.h b/thunarx/thunarx-menu-item.h index 3eaed6b44..005509062 100644 --- a/thunarx/thunarx-menu-item.h +++ b/thunarx/thunarx-menu-item.h @@ -23,46 +23,6 @@ #ifndef __THUNARX_MENU_ITEM_H__ #define __THUNARX_MENU_ITEM_H__ -#include <glib-object.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarxMenuItemPrivate ThunarxMenuItemPrivate; -typedef struct _ThunarxMenuItemClass ThunarxMenuItemClass; -typedef struct _ThunarxMenuItem ThunarxMenuItem; - -#define THUNARX_TYPE_MENU_ITEM (thunarx_menu_item_get_type ()) -#define THUNARX_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNARX_TYPE_MENU_ITEM, ThunarxMenuItem)) -#define THUNARX_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNARX_TYPE_MENU_ITEM, ThunarxMenuItemClass)) -#define THUNARX_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNARX_TYPE_MENU_ITEM)) -#define THUNARX_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), THUNARX_TYPE_MENU_ITEM)) -#define THUNARX_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), THUNARX_TYPE_MENU_ITEM)) - -struct _ThunarxMenuItemClass { - GObjectClass __parent__; - void (*activate) (ThunarxMenuItem *item); -}; - -struct _ThunarxMenuItem { - GObject __parent__; - - /*< private >*/ - ThunarxMenuItemPrivate *priv; -}; - -GType thunarx_menu_item_get_type (void) G_GNUC_CONST; - -ThunarxMenuItem *thunarx_menu_item_new (const gchar *name, - const gchar *label, - const gchar *tip, - const gchar *icon) G_GNUC_MALLOC; - -void thunarx_menu_item_activate (ThunarxMenuItem *item); - -gboolean thunarx_menu_item_get_sensitive (ThunarxMenuItem *item); -void thunarx_menu_item_set_sensitive (ThunarxMenuItem *item, - gboolean sensitive); - -G_END_DECLS; +#include "thunarx-menu.h" #endif /* !__THUNARX_MENU_ITEM_H__ */ diff --git a/thunarx/thunarx-menu.c b/thunarx/thunarx-menu.c new file mode 100644 index 000000000..97961b592 --- /dev/null +++ b/thunarx/thunarx-menu.c @@ -0,0 +1,144 @@ +/*- + * Copyright (c) 2017 Andre Miranda <andreldm@xfce.org> + * + * This program 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 2 of the License, or (at your option) + * any later version. + * + * This program 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 + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib/gi18n-lib.h> + +#include <thunarx/thunarx-private.h> +#include <thunarx/thunarx-menu-item.h> +#include <thunarx/thunarx-menu.h> + + + +#define THUNARX_MENU_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNARX_TYPE_MENU, ThunarxMenuPrivate)) + +/** + * SECTION: thunarx-menu + * @short_description: The base class for submenus added to the context menus + * @title: ThunarxMenu + * @include: thunarx/thunarx.h + * + * The class for submenus that can be added to Thunar's context menus. Extensions + * can provide ThunarxMenu objects by attaching them to ThunarxMenuItem objects, + * using thunarx_menu_item_set_menu(). + */ + + + +static void thunarx_menu_finalize (GObject *object); + + + +struct _ThunarxMenuPrivate +{ + GList *items; +}; + + + +G_DEFINE_TYPE (ThunarxMenu, thunarx_menu, G_TYPE_OBJECT) + + + +static void +thunarx_menu_class_init (ThunarxMenuClass *klass) +{ + GObjectClass *gobject_class; + + /* add our private data to the class type */ + g_type_class_add_private (klass, sizeof (ThunarxMenuPrivate)); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunarx_menu_finalize; +} + + + +static void +thunarx_menu_init (ThunarxMenu *menu) +{ + menu->priv = THUNARX_MENU_GET_PRIVATE (menu); + menu->priv->items = NULL; +} + + + +static void +thunarx_menu_finalize (GObject *object) +{ + ThunarxMenu *menu = THUNARX_MENU (object); + + if (menu->priv->items) + g_list_free (menu->priv->items); + + (*G_OBJECT_CLASS (thunarx_menu_parent_class)->finalize) (object); +} + + + +/** + * thunarx_menu_new: + * + * Creates a new menu that can be added to the toolbar or to a contextual menu. + * + * Returns: a newly created #ThunarxMenu + */ +ThunarxMenu * +thunarx_menu_new (void) +{ + return g_object_new (THUNARX_TYPE_MENU, NULL); +} + + + +/** + * thunarx_menu_append_item: + * @menu: a #ThunarxMenu + * @item: a #ThunarxMenuItem + */ +void +thunarx_menu_append_item (ThunarxMenu *menu, ThunarxMenuItem *item) +{ + g_return_if_fail (menu != NULL); + g_return_if_fail (item != NULL); + + menu->priv->items = g_list_append (menu->priv->items, g_object_ref (item)); +} + + + +/** + * thunarx_menu_get_items: + * @menu: a #ThunarxMenu + * + * Returns: (element-type ThunarxMenuItem) (transfer full): the provided #ThunarxMenuItem list + */ +GList * +thunarx_menu_get_items (ThunarxMenu *menu) +{ + GList *items; + + g_return_val_if_fail (menu != NULL, NULL); + + items = g_list_copy (menu->priv->items); + g_list_foreach (items, (GFunc) g_object_ref, NULL); + + return items; +} diff --git a/thunarx/thunarx-menu.h b/thunarx/thunarx-menu.h new file mode 100644 index 000000000..1f43f6e50 --- /dev/null +++ b/thunarx/thunarx-menu.h @@ -0,0 +1,115 @@ +/*- + * Copyright (c) 2017 Andre Miranda <andreldm@xfce.org> + * + * This program 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 2 of the License, or (at your option) + * any later version. + * + * This program 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 + */ + +#if !defined(THUNARX_INSIDE_THUNARX_H) && !defined(THUNARX_COMPILATION) +#error "Only <thunarx/thunarx.h> can be included directly, this file may disappear or change contents" +#endif + +#ifndef __THUNARX_MENU_H__ +#define __THUNARX_MENU_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS; + +/* ThunarxMenu types */ +typedef struct _ThunarxMenuPrivate ThunarxMenuPrivate; +typedef struct _ThunarxMenuClass ThunarxMenuClass; +typedef struct _ThunarxMenu ThunarxMenu; + +/* ThunarxMenuItem types */ +typedef struct _ThunarxMenuItemPrivate ThunarxMenuItemPrivate; +typedef struct _ThunarxMenuItemClass ThunarxMenuItemClass; +typedef struct _ThunarxMenuItem ThunarxMenuItem; + + + + +/* ThunarxMenu defines */ +#define THUNARX_TYPE_MENU (thunarx_menu_get_type ()) +#define THUNARX_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNARX_TYPE_MENU, ThunarxMenu)) +#define THUNARX_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNARX_TYPE_MENU, ThunarxMenuClass)) +#define THUNARX_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNARX_TYPE_MENU)) +#define THUNARX_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), THUNARX_TYPE_MENU)) +#define THUNARX_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), THUNARX_TYPE_MENU)) + +/* ThunarxMenuItem defines */ +#define THUNARX_TYPE_MENU_ITEM (thunarx_menu_item_get_type ()) +#define THUNARX_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNARX_TYPE_MENU_ITEM, ThunarxMenuItem)) +#define THUNARX_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNARX_TYPE_MENU_ITEM, ThunarxMenuItemClass)) +#define THUNARX_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNARX_TYPE_MENU_ITEM)) +#define THUNARX_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), THUNARX_TYPE_MENU_ITEM)) +#define THUNARX_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), THUNARX_TYPE_MENU_ITEM)) + + + +/* ThunarxMenu structs */ +struct _ThunarxMenuClass { + GObjectClass __parent__; +}; + +struct _ThunarxMenu { + GObject __parent__; + ThunarxMenuPrivate *priv; +}; + +/* ThunarxMenuItem structs */ +struct _ThunarxMenuItemClass { + GObjectClass __parent__; + void (*activate) (ThunarxMenuItem *item); +}; + +struct _ThunarxMenuItem { + GObject __parent__; + ThunarxMenuItemPrivate *priv; +}; + + + +/* ThunarxMenu methods */ +GType thunarx_menu_get_type (void) G_GNUC_CONST; + +ThunarxMenu *thunarx_menu_new (void) G_GNUC_MALLOC; + +void thunarx_menu_append_item (ThunarxMenu *menu, + ThunarxMenuItem *item); + +GList* thunarx_menu_get_items (ThunarxMenu *menu); + +/* ThunarxMenuItem methods */ +GType thunarx_menu_item_get_type (void) G_GNUC_CONST; + +ThunarxMenuItem *thunarx_menu_item_new (const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *icon) G_GNUC_MALLOC; + +void thunarx_menu_item_activate (ThunarxMenuItem *item); + +gboolean thunarx_menu_item_get_sensitive (ThunarxMenuItem *item); +void thunarx_menu_item_set_sensitive (ThunarxMenuItem *item, + gboolean sensitive); + +void thunarx_menu_item_list_free (GList *items); + +void thunarx_menu_item_set_menu (ThunarxMenuItem *item, + ThunarxMenu *menu); + +G_END_DECLS; + +#endif /* !__THUNARX_MENU_H__ */ diff --git a/thunarx/thunarx.h b/thunarx/thunarx.h index d6de6913a..192bf9a7b 100644 --- a/thunarx/thunarx.h +++ b/thunarx/thunarx.h @@ -25,7 +25,7 @@ #include <thunarx/thunarx-config.h> #include <thunarx/thunarx-file-info.h> -#include <thunarx/thunarx-menu-item.h> +#include <thunarx/thunarx-menu.h> #include <thunarx/thunarx-menu-provider.h> #include <thunarx/thunarx-preferences-provider.h> #include <thunarx/thunarx-property-page.h> diff --git a/thunarx/thunarx.symbols b/thunarx/thunarx.symbols index a53ed091a..750d55fe3 100644 --- a/thunarx/thunarx.symbols +++ b/thunarx/thunarx.symbols @@ -46,12 +46,20 @@ thunarx_file_info_list_get_type thunarx_file_info_list_copy thunarx_file_info_list_free +/* ThunarxMenu methods */ +thunarx_menu_get_type G_GNUC_CONST +thunarx_menu_new G_GNUC_MALLOC +thunarx_menu_append_item +thunarx_menu_get_items + /* ThunarxMenuItem methods */ thunarx_menu_item_get_type G_GNUC_CONST thunarx_menu_item_new G_GNUC_MALLOC thunarx_menu_item_activate thunarx_menu_item_get_sensitive thunarx_menu_item_set_sensitive +thunarx_menu_item_set_menu +thunarx_menu_item_list_free /* ThunarxMenuProvider methods */ thunarx_menu_provider_get_type G_GNUC_CONST -- GitLab