summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Soriano <carlos.sorian89@gmail.com>2015-01-20 11:38:47 +0100
committerCarlos Soriano <csoriano@gnome.org>2015-01-21 14:19:29 +0100
commit660829389d8ff92a6b13c5a3eab44b62e328b7c1 (patch)
tree30f41965fb884771700f75bc0ba596a4f809bc4d
parent00295cd54555e8cef519c70c1066c732de191afa (diff)
downloadnautilus-660829389d8ff92a6b13c5a3eab44b62e328b7c1.tar.gz
general: Implement extensions for GAction
The last commit rework the menus and ported to GAction. Update the extension mechanism to that. The changes are very little. Now menu items in extensions lost the property 'priority' since gmenu doesn't have one, and gain two properties, menu_name, which is in which menu do you want the extension to add a menu item, it can be background or selection, and menu_section, which indicates in which section of the menu do you want to add the items of the extension.
-rw-r--r--src/nautilus-view-context-menus.xml6
-rw-r--r--src/nautilus-view.c285
2 files changed, 291 insertions, 0 deletions
diff --git a/src/nautilus-view-context-menus.xml b/src/nautilus-view-context-menus.xml
index 6aa89a31d..10b821217 100644
--- a/src/nautilus-view-context-menus.xml
+++ b/src/nautilus-view-context-menus.xml
@@ -48,6 +48,9 @@
<attribute name="hidden-when">action-disabled</attribute>
</item>
</section>
+ <section>
+ <attribute name="id">extensions</attribute>
+ </section>
</menu>
<menu id="selection-menu">
<section>
@@ -199,6 +202,9 @@
</item>
</section>
<section>
+ <attribute name="id">extensions</attribute>
+ </section>
+ <section>
<item>
<attribute name="label" translatable="yes">P_roperties</attribute>
<attribute name="action">view.properties</attribute>
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index b502644d5..7847b47fe 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -3780,6 +3780,289 @@ get_menu_icon_for_file (NautilusFile *file,
return pixbuf;
}
+static GList *
+get_extension_selection_menu_items (NautilusView *view)
+{
+ NautilusWindow *window;
+ GList *items;
+ GList *providers;
+ GList *l;
+ GList *selection;
+
+ window = nautilus_view_get_window (view);
+ selection = nautilus_view_get_selection (view);
+ providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
+ items = NULL;
+
+ for (l = providers; l != NULL; l = l->next) {
+ NautilusMenuProvider *provider;
+ GList *file_items;
+
+ provider = NAUTILUS_MENU_PROVIDER (l->data);
+ file_items = nautilus_menu_provider_get_file_items (provider,
+ GTK_WIDGET (window),
+ selection);
+ items = g_list_concat (items, file_items);
+ }
+
+ nautilus_module_extension_list_free (providers);
+
+ return items;
+}
+
+static GList *
+get_extension_background_menu_items (NautilusView *view)
+{
+ NautilusWindow *window;
+ NautilusFile *file;
+ GList *items;
+ GList *providers;
+ GList *l;
+
+ window = nautilus_view_get_window (view);
+ providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
+ file = nautilus_window_slot_get_file (view->details->slot);
+ items = NULL;
+
+ for (l = providers; l != NULL; l = l->next) {
+ NautilusMenuProvider *provider;
+ GList *file_items;
+
+ provider = NAUTILUS_MENU_PROVIDER (l->data);
+ file_items = nautilus_menu_provider_get_background_items (provider,
+ GTK_WIDGET (window),
+ file);
+ items = g_list_concat (items, file_items);
+ }
+
+ nautilus_module_extension_list_free (providers);
+
+ return items;
+}
+
+typedef struct
+{
+ NautilusMenuItem *item;
+ NautilusView *view;
+ GList *selection;
+ GAction *action;
+} ExtensionActionCallbackData;
+
+
+static void
+extension_action_callback_data_free (ExtensionActionCallbackData *data)
+{
+ g_object_unref (data->item);
+ nautilus_file_list_free (data->selection);
+
+ g_free (data);
+}
+
+static gboolean
+search_in_menu_items (GList * items,
+ const char *item_name)
+{
+ GList* list;
+
+ for (list = items; list != NULL; list = list->next) {
+ NautilusMenu* menu;
+ char *name;
+
+ g_object_get (list->data, "name", &name, NULL);
+ if (strcmp (name, item_name) == 0) {
+ g_free (name);
+ return TRUE;
+ }
+ g_free (name);
+
+ menu = NULL;
+ g_object_get (list->data, "menu", &menu, NULL);
+ if (menu != NULL) {
+ gboolean ret;
+ GList* submenus;
+
+ submenus = nautilus_menu_get_items (menu);
+ ret = search_in_menu_items (submenus, item_name);
+ nautilus_menu_item_list_free (submenus);
+ g_object_unref (menu);
+ if (ret) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+static void
+extension_action_callback (GSimpleAction *action,
+ GVariant *state,
+ gpointer user_data)
+{
+ ExtensionActionCallbackData *data;
+ char *item_name;
+ gboolean is_valid;
+ GList *l;
+ GList *selection_items, *background_items;
+
+ data = user_data;
+
+ /* Make sure the selected menu item is valid for the final sniffed
+ * mime type */
+ g_object_get (data->item, "name", &item_name, NULL);
+ selection_items = get_extension_selection_menu_items (data->view);
+ background_items = get_extension_background_menu_items (data->view);
+
+ is_valid = search_in_menu_items (selection_items, item_name);
+ if (!is_valid)
+ is_valid = search_in_menu_items (background_items, item_name);
+
+ for (l = selection_items; l != NULL; l = l->next) {
+ g_object_unref (l->data);
+ }
+ for (l = background_items; l != NULL; l = l->next) {
+ g_object_unref (l->data);
+ }
+
+ g_list_free (selection_items);
+ g_list_free (background_items);
+
+ g_free (item_name);
+
+ if (is_valid) {
+ nautilus_menu_item_activate (data->item);
+ }
+}
+
+static void
+add_extension_action (NautilusView *view,
+ NautilusMenuItem *item)
+{
+ char *name, *label, *parsed_name;
+ gboolean sensitive;
+ GAction *action;
+ ExtensionActionCallbackData *data;
+
+ g_object_get (G_OBJECT (item),
+ "name", &name, "label", &label,
+ "sensitive", &sensitive,
+ NULL);
+
+ parsed_name = nautilus_escape_action_name (name, "extension_");
+ action = G_ACTION (g_simple_action_new (parsed_name, NULL));
+
+ data = g_new0 (ExtensionActionCallbackData, 1);
+ data->item = g_object_ref (item);
+ data->view = view;
+ data->action = action;
+
+ g_signal_connect_data (action, "activate",
+ G_CALLBACK (extension_action_callback),
+ data,
+ (GClosureNotify)extension_action_callback_data_free, 0);
+
+ g_action_map_add_action (G_ACTION_MAP (view->details->view_action_group),
+ action);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), sensitive);
+ g_object_unref (action);
+
+ g_free (name);
+ g_free (parsed_name);
+ g_free (label);
+}
+
+static GMenu *
+add_extension_menu_items (NautilusView *view,
+ GList *menu_items,
+ GMenu *insertion_menu,
+ GMenuItem *submenu_parent)
+{
+ GList *l;
+ GMenuItem *menu_item;
+ GMenu *gmenu, *children_menu;
+ char *name, *parsed_name, *label, *detailed_action_name;
+ gboolean sensitive;
+ GdkPixbuf *pixbuf;
+
+ gmenu = g_menu_new ();
+
+ for (l = menu_items; l; l = l->next) {
+ NautilusMenuItem *item;
+ NautilusMenu *menu;
+
+ item = NAUTILUS_MENU_ITEM (l->data);
+
+ g_object_get (item, "menu", &menu, NULL);
+
+ g_object_get (G_OBJECT (item),
+ "name", &name, "label", &label,
+ "sensitive", &sensitive,
+ NULL);
+
+ add_extension_action (view, item);
+ parsed_name = nautilus_escape_action_name (name, "extension_");
+ detailed_action_name = g_strconcat ("view.", parsed_name, NULL);
+ menu_item = g_menu_item_new (label, detailed_action_name);
+ if (menu != NULL) {
+ GList *children;
+
+ children = nautilus_menu_get_items (menu);
+
+ children_menu = add_extension_menu_items (view,
+ children,
+ insertion_menu,
+ menu_item);
+
+ nautilus_menu_item_list_free (children);
+ g_menu_item_set_submenu (menu_item, G_MENU_MODEL (children_menu));
+ }
+
+ g_menu_append_item (gmenu, menu_item);
+ }
+
+ if (submenu_parent) {
+ g_menu_item_set_submenu (submenu_parent, G_MENU_MODEL (gmenu));
+ } else {
+ nautilus_gmenu_merge (insertion_menu,
+ gmenu,
+ "extensions",
+ FALSE);
+ }
+
+ g_free (name);
+ g_free (parsed_name);
+ g_free (label);
+
+ return gmenu;
+}
+
+static void
+update_extensions_menus (NautilusView *view)
+{
+ GList *selection_items, *background_items;
+
+ selection_items = get_extension_selection_menu_items (view);
+ background_items = get_extension_background_menu_items (view);
+ if (selection_items != NULL) {
+ add_extension_menu_items (view,
+ selection_items,
+ view->details->selection_menu,
+ NULL);
+
+ g_list_foreach (selection_items, (GFunc) g_object_unref, NULL);
+ g_list_free (selection_items);
+ }
+
+ if (background_items != NULL) {
+ add_extension_menu_items (view,
+ background_items,
+ view->details->selection_menu,
+ NULL);
+
+ g_list_foreach (background_items, (GFunc) g_object_unref, NULL);
+ g_list_free (background_items);
+ }
+}
+
static char *
change_to_view_directory (NautilusView *view)
{
@@ -6245,6 +6528,8 @@ real_update_context_menus (NautilusView *view)
update_selection_menu (view);
update_background_menu (view);
+ update_extensions_menus (view);
+
nautilus_view_update_actions_state (view);
}