summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libnautilus-extension/nautilus-menu-item.c51
-rw-r--r--libnautilus-extension/nautilus-menu.h4
-rw-r--r--nautilus-sendto-extension/nautilus-nste.c23
-rw-r--r--src/nautilus-view-context-menus.xml7
-rw-r--r--src/nautilus-view.c258
5 files changed, 318 insertions, 25 deletions
diff --git a/libnautilus-extension/nautilus-menu-item.c b/libnautilus-extension/nautilus-menu-item.c
index dfe3e2712..a76e9ca4c 100644
--- a/libnautilus-extension/nautilus-menu-item.c
+++ b/libnautilus-extension/nautilus-menu-item.c
@@ -37,7 +37,8 @@ enum {
PROP_TIP,
PROP_ICON,
PROP_SENSITIVE,
- PROP_PRIORITY,
+ PROP_MENU_NAME,
+ PROP_SECTION_NAME,
PROP_MENU,
LAST_PROP
};
@@ -47,6 +48,8 @@ struct _NautilusMenuItemDetails {
char *label;
char *tip;
char *icon;
+ char *menu_name;
+ char *section_name;
NautilusMenu *menu;
gboolean sensitive;
gboolean priority;
@@ -71,7 +74,9 @@ NautilusMenuItem *
nautilus_menu_item_new (const char *name,
const char *label,
const char *tip,
- const char *icon)
+ const char *icon,
+ const char *menu_name,
+ const char *section_name)
{
NautilusMenuItem *item;
@@ -84,6 +89,8 @@ nautilus_menu_item_new (const char *name,
"label", label,
"tip", tip,
"icon", icon,
+ "menu_name", menu_name,
+ "section_name", section_name,
NULL);
return item;
@@ -140,8 +147,11 @@ nautilus_menu_item_get_property (GObject *object,
case PROP_SENSITIVE :
g_value_set_boolean (value, item->details->sensitive);
break;
- case PROP_PRIORITY :
- g_value_set_boolean (value, item->details->priority);
+ case PROP_MENU_NAME :
+ g_value_set_string (value, item->details->menu_name);
+ break;
+ case PROP_SECTION_NAME :
+ g_value_set_string (value, item->details->section_name);
break;
case PROP_MENU :
g_value_set_object (value, item->details->menu);
@@ -187,9 +197,15 @@ nautilus_menu_item_set_property (GObject *object,
item->details->sensitive = g_value_get_boolean (value);
g_object_notify (object, "sensitive");
break;
- case PROP_PRIORITY :
- item->details->priority = g_value_get_boolean (value);
- g_object_notify (object, "priority");
+ case PROP_MENU_NAME :
+ g_free (item->details->menu_name);
+ item->details->menu_name = g_strdup (g_value_get_string (value));
+ g_object_notify (object, "menu_name");
+ break;
+ case PROP_SECTION_NAME :
+ g_free (item->details->section_name);
+ item->details->section_name = g_strdup (g_value_get_string (value));
+ g_object_notify (object, "section_name");
break;
case PROP_MENU :
if (item->details->menu) {
@@ -215,6 +231,8 @@ nautilus_menu_item_finalize (GObject *object)
g_free (item->details->label);
g_free (item->details->tip);
g_free (item->details->icon);
+ g_free (item->details->section_name);
+ g_free (item->details->menu_name);
if (item->details->menu) {
g_object_unref (item->details->menu);
}
@@ -288,12 +306,19 @@ nautilus_menu_item_class_init (NautilusMenuItemClass *class)
TRUE,
G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (class),
- PROP_PRIORITY,
- g_param_spec_boolean ("priority",
- "Priority",
- "Show priority text in toolbars",
- TRUE,
- G_PARAM_READWRITE));
+ PROP_MENU_NAME,
+ g_param_spec_string ("menu_name",
+ "Menu name",
+ "The name of the menu to for inserting the item. It can be 'background' or 'selection'",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (G_OBJECT_CLASS (class),
+ PROP_SECTION_NAME,
+ g_param_spec_string ("section_name",
+ "Section name",
+ "The name of the section to be the insertion point for the item",
+ NULL,
+ G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (class),
PROP_MENU,
g_param_spec_object ("menu",
diff --git a/libnautilus-extension/nautilus-menu.h b/libnautilus-extension/nautilus-menu.h
index fd132be4e..2f9623dc2 100644
--- a/libnautilus-extension/nautilus-menu.h
+++ b/libnautilus-extension/nautilus-menu.h
@@ -95,7 +95,9 @@ GType nautilus_menu_item_get_type (void);
NautilusMenuItem *nautilus_menu_item_new (const char *name,
const char *label,
const char *tip,
- const char *icon);
+ const char *icon,
+ const char *menu_name,
+ const char *section_name);
void nautilus_menu_item_activate (NautilusMenuItem *item);
void nautilus_menu_item_set_submenu (NautilusMenuItem *item,
diff --git a/nautilus-sendto-extension/nautilus-nste.c b/nautilus-sendto-extension/nautilus-nste.c
index 92f347e0a..9859d61b4 100644
--- a/nautilus-sendto-extension/nautilus-nste.c
+++ b/nautilus-sendto-extension/nautilus-nste.c
@@ -78,6 +78,7 @@ nautilus_nste_get_file_items (NautilusMenuProvider *provider,
gboolean one_item;
NautilusMenuItem *item;
NautilusNste *nste;
+ char *tip;
nste = NAUTILUS_NSTE (provider);
if (!nste->nst_present)
@@ -91,17 +92,17 @@ nautilus_nste_get_file_items (NautilusMenuProvider *provider,
one_item = (files != NULL) && (files->next == NULL);
if (one_item &&
- !nautilus_file_info_is_directory ((NautilusFileInfo *)files->data)) {
- item = nautilus_menu_item_new ("NautilusNste::sendto",
- _("Email…"),
- _("Send file by mail…"),
- "document-send");
- } else {
- item = nautilus_menu_item_new ("NautilusNste::sendto",
- _("Email…"),
- _("Send files by mail…"),
- "document-send");
- }
+ !nautilus_file_info_is_directory ((NautilusFileInfo *)files->data))
+ tip = _("Send file by mail…");
+ else
+ tip = _("Send files by mail…");
+
+ item = nautilus_menu_item_new ("nautilus-nste-send-to",
+ _("Email…"),
+ tip,
+ "document-send",
+ "selection",
+ "file-actions-section");
g_signal_connect (item,
"activate",
G_CALLBACK (sendto_callback),
diff --git a/src/nautilus-view-context-menus.xml b/src/nautilus-view-context-menus.xml
index ffda16e6b..96f45184b 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>
@@ -139,6 +142,7 @@
</item>
</section>
<section>
+ <attribute name="id">file-actions-section</attribute>
<item>
<attribute name="label" translatable="yes">Move to…</attribute>
<attribute name="action">view.move-to</attribute>
@@ -189,6 +193,9 @@
<attribute name="action">view.properties</attribute>
</item>
</section>
+ <section>
+ <attribute name="id">extensions</attribute>
+ </section>
</menu>
<menu id="pathbar-menu">
<section>
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 38424f3ad..65699e2b5 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -3662,6 +3662,262 @@ get_menu_icon_for_file (NautilusFile *file,
return pixbuf;
}
+static GList *
+get_all_extension_menu_items (GtkWidget *window,
+ GList *selection)
+{
+ GList *items;
+ GList *providers;
+ GList *l;
+
+ 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,
+ window,
+ selection);
+ 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 *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);
+ items = get_all_extension_menu_items (gtk_widget_get_toplevel (GTK_WIDGET (data->view)),
+ data->selection);
+
+ is_valid = search_in_menu_items (items, item_name);
+
+ for (l = items; l != NULL; l = l->next) {
+ g_object_unref (l->data);
+ }
+ g_list_free (items);
+
+ g_free (item_name);
+
+ if (is_valid) {
+ nautilus_menu_item_activate (data->item);
+ }
+}
+
+static void
+add_extension_action_for_files (NautilusView *view,
+ NautilusMenuItem *item,
+ GList *files)
+{
+ char *name, *label, *tip, *icon;
+ gboolean sensitive;
+ GAction *action;
+ ExtensionActionCallbackData *data;
+
+ g_object_get (G_OBJECT (item),
+ "name", &name, "label", &label,
+ "tip", &tip, "icon", &icon,
+ "sensitive", &sensitive,
+ NULL);
+
+ action = G_ACTION (g_simple_action_new (name, NULL));
+
+ data = g_new0 (ExtensionActionCallbackData, 1);
+ data->item = g_object_ref (item);
+ data->view = view;
+ data->selection = nautilus_file_list_copy (files);
+ 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 (label);
+ g_free (tip);
+ g_free (icon);
+}
+
+static GMenu *
+add_extension_menu_items (NautilusView *view,
+ GList *files,
+ GList *menu_items,
+ GMenuItem *parent)
+{
+ GList *l;
+ GMenuItem *menu_item;
+ GMenu *gmenu, *target, *children_menu;
+ char *name, *label, *tip, *icon, *menu_name, *section_name, *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,
+ "tip", &tip, "icon", &icon,
+ "sensitive", &sensitive,
+ "menu_name", &menu_name,
+ "section_name", &section_name,
+ NULL);
+
+ add_extension_action_for_files (view, item, files);
+ detailed_action_name = g_strconcat ("view.", 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,
+ files,
+ children,
+ menu_item);
+
+ nautilus_menu_item_list_free (children);
+ g_menu_item_set_submenu (menu_item, G_MENU_MODEL (children_menu));
+ }
+
+ if (icon != NULL) {
+ pixbuf = nautilus_ui_get_menu_icon (icon, GTK_WIDGET (view));
+ if (pixbuf != NULL) {
+ g_menu_item_set_icon (menu_item, pixbuf);
+ g_object_unref (pixbuf);
+ }
+ }
+
+ g_menu_append_item (gmenu, menu_item);
+ }
+
+ if (g_strcmp0(menu_name, "background") == 0)
+ target = view->details->background_menu;
+ else if (g_strcmp0(menu_name, "selection") == 0)
+ target = view->details->selection_menu;
+ else
+ goto clean_up;
+
+ if (parent) {
+ g_menu_item_set_submenu (parent, G_MENU_MODEL (gmenu));
+ } else {
+ nautilus_gmenu_merge (target,
+ gmenu,
+ section_name,
+ FALSE);
+ }
+clean_up:
+ g_free (name);
+ g_free (label);
+ g_free (tip);
+ g_free (icon);
+ g_free (menu_name);
+ g_free (section_name);
+
+ return gmenu;
+}
+
+static void
+update_extensions_menus (NautilusView *view)
+{
+ GList *items;
+ GList *selection;
+
+ selection = nautilus_view_get_selection (view);
+
+ items = get_all_extension_menu_items (gtk_widget_get_toplevel (GTK_WIDGET (view)),
+ selection);
+ if (items != NULL) {
+ add_extension_menu_items (view, selection, items, NULL);
+
+ g_list_foreach (items, (GFunc) g_object_unref, NULL);
+ g_list_free (items);
+ }
+}
+
static char *
change_to_view_directory (NautilusView *view)
{
@@ -5812,6 +6068,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);
}