summaryrefslogtreecommitdiff
path: root/libnautilus-private/nautilus-ui-utilities.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnautilus-private/nautilus-ui-utilities.c')
-rw-r--r--libnautilus-private/nautilus-ui-utilities.c210
1 files changed, 143 insertions, 67 deletions
diff --git a/libnautilus-private/nautilus-ui-utilities.c b/libnautilus-private/nautilus-ui-utilities.c
index 6fcc3a419..b6bb4035f 100644
--- a/libnautilus-private/nautilus-ui-utilities.c
+++ b/libnautilus-private/nautilus-ui-utilities.c
@@ -29,87 +29,154 @@
#include <gio/gio.h>
#include <gtk/gtk.h>
+#include <string.h>
-void
-nautilus_ui_unmerge_ui (GtkUIManager *ui_manager,
- guint *merge_id,
- GtkActionGroup **action_group)
+static GMenuModel *
+find_gmenu_model (GMenuModel *model,
+ const gchar *insertion_id)
{
- if (*merge_id != 0) {
- gtk_ui_manager_remove_ui (ui_manager,
- *merge_id);
- *merge_id = 0;
- }
- if (*action_group != NULL) {
- gtk_ui_manager_remove_action_group (ui_manager,
- *action_group);
- *action_group = NULL;
+ gint i, n_items;
+ GMenuModel *insertion_model = NULL;
+
+ n_items = g_menu_model_get_n_items (model);
+
+ for (i = 0; i < n_items && !insertion_model; i++)
+ {
+ gchar *id = NULL;
+ if (g_menu_model_get_item_attribute (model, i, "id", "s", &id) &&
+ strcmp (id, insertion_id) == 0)
+ {
+ insertion_model = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
+ if (!insertion_model)
+ {
+ insertion_model = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
+ }
+ }
+ else
+ {
+ GMenuModel *submodel;
+ GMenuModel *submenu;
+ gint j, j_items;
+
+ submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION);
+
+ if (!submodel)
+ {
+ submodel = g_menu_model_get_item_link (model, i, G_MENU_LINK_SUBMENU);
+ if (!submodel)
+ continue;
+ }
+
+ j_items = g_menu_model_get_n_items (submodel);
+ for (j = 0; j < j_items && !insertion_model; j++)
+ {
+ submenu = g_menu_model_get_item_link (submodel, j, G_MENU_LINK_SUBMENU);
+ if (submenu)
+ {
+ insertion_model = find_gmenu_model (submenu, insertion_id);
+ }
+ }
+ }
+
+ g_free (id);
}
+
+ return insertion_model;
}
-
+
+/*
+ * The original GMenu is modified adding to the section @section_name
+ * the items in @gmenu_to_merge.
+ * @gmenu_to_merge should be a list of menu items.
+ */
void
-nautilus_ui_prepare_merge_ui (GtkUIManager *ui_manager,
- const char *name,
- guint *merge_id,
- GtkActionGroup **action_group)
+nautilus_gmenu_merge (GMenu *original,
+ GMenu *gmenu_to_merge,
+ const gchar *section_name)
{
- *merge_id = gtk_ui_manager_new_merge_id (ui_manager);
- *action_group = gtk_action_group_new (name);
- gtk_action_group_set_translation_domain (*action_group, GETTEXT_PACKAGE);
- gtk_ui_manager_insert_action_group (ui_manager, *action_group, 0);
- g_object_unref (*action_group); /* owned by ui manager */
-}
+ gint i, n_items;
+ GMenuModel *section;
+ GMenuItem *item;
-static void
-extension_action_callback (GtkAction *action,
- gpointer callback_data)
-{
- nautilus_menu_item_activate (NAUTILUS_MENU_ITEM (callback_data));
-}
+ g_return_if_fail (G_IS_MENU (original));
+ g_return_if_fail (G_IS_MENU (gmenu_to_merge));
-GtkAction *
-nautilus_action_from_menu_item (NautilusMenuItem *item,
- GtkWidget *parent_widget)
-{
- char *name, *label, *tip, *icon_name;
- gboolean sensitive, priority;
- GtkAction *action;
- GdkPixbuf *pixbuf;
+ section = find_gmenu_model (G_MENU_MODEL (original), section_name);
- g_object_get (G_OBJECT (item),
- "name", &name, "label", &label,
- "tip", &tip, "icon", &icon_name,
- "sensitive", &sensitive,
- "priority", &priority,
- NULL);
-
- action = gtk_action_new (name,
- label,
- tip,
- NULL);
-
- if (icon_name != NULL) {
- pixbuf = nautilus_ui_get_menu_icon (icon_name, parent_widget);
- if (pixbuf != NULL) {
- gtk_action_set_gicon (action, G_ICON (pixbuf));
- g_object_unref (pixbuf);
- }
+ g_return_if_fail (section != NULL);
+
+ n_items = g_menu_model_get_n_items (G_MENU_MODEL (gmenu_to_merge));
+
+ for (i = 0; i < n_items; i++)
+ {
+ item = g_menu_item_new_from_model (G_MENU_MODEL (gmenu_to_merge), i);
+ g_menu_append_item (G_MENU (section), item);
+ g_object_unref (item);
}
+}
+
+/*
+ * The GMenu @menu is modified adding to the section @section_name
+ * the item @item.
+ */
+void
+nautilus_gmenu_add_item_in_submodel (GMenu *menu,
+ GMenuItem *item,
+ const gchar *submodel_name,
+ gboolean prepend)
+{
+ GMenuModel *submodel;
- gtk_action_set_sensitive (action, sensitive);
- g_object_set (action, "is-important", priority, NULL);
+ g_return_if_fail (G_IS_MENU (menu));
+ g_return_if_fail (G_IS_MENU_ITEM (item));
- g_signal_connect_data (action, "activate",
- G_CALLBACK (extension_action_callback),
- g_object_ref (item),
- (GClosureNotify)g_object_unref, 0);
+ submodel = find_gmenu_model (G_MENU_MODEL (menu), submodel_name);
- g_free (name);
- g_free (label);
- g_free (tip);
- g_free (icon_name);
+ g_return_if_fail (submodel != NULL);
+ if (prepend) {
+ g_menu_prepend_item (G_MENU (submodel), item);
+ } else {
+ g_menu_append_item (G_MENU (submodel), item);
+ }
+}
- return action;
+void
+pop_up_context_menu (GtkWidget *parent,
+ GMenu *menu,
+ GdkEventButton *event)
+{
+ GtkWidget *gtk_menu;
+
+ int button;
+
+ g_return_if_fail (G_IS_MENU (menu));
+ g_return_if_fail (GTK_IS_WIDGET (parent));
+
+ gtk_menu = gtk_menu_new_from_model (G_MENU_MODEL (menu));
+ gtk_menu_attach_to_widget (GTK_MENU (gtk_menu), parent, NULL);
+ /* The event button needs to be 0 if we're popping up this menu from
+ * a button release, else a 2nd click outside the menu with any button
+ * other than the one that invoked the menu will be ignored (instead
+ * of dismissing the menu). This is a subtle fragility of the GTK menu code.
+ */
+ if (event) {
+ button = event->type == GDK_BUTTON_RELEASE
+ ? 0
+ : event->button;
+ } else {
+ button = 0;
+ }
+
+ gtk_menu_popup (GTK_MENU (gtk_menu), /* menu */
+ NULL, /* parent_menu_shell */
+ NULL, /* parent_menu_item */
+ NULL, /* popup_position_func */
+ NULL, /* popup_position_data */
+ button, /* button */
+ event ? event->time : gtk_get_current_event_time ()); /* activate_time */
+
+ g_object_ref_sink (gtk_menu);
+ g_object_unref (gtk_menu);
}
GdkPixbuf *
@@ -161,6 +228,15 @@ nautilus_escape_action_name (const char *action_name,
case '"':
g_string_append (s, "\\q");
break;
+ case ' ':
+ g_string_append (s, "+");
+ break;
+ case '(':
+ g_string_append (s, "#");
+ break;
+ case ')':
+ g_string_append (s, "^");
+ break;
default:
g_string_append_c (s, *action_name);
}