[PATCH] add location button context menu



This is the second version of a patch I've submitted about 2.5 months
ago to nautilus-list [1]. There were no direct followups, but I was now
asked to update the patch, though, so it looks like people are
interested in it.
The new version only has the Cut, Copy, Paste, Trash + Delete and
Properties items in the context menu, but - in contrast to the last
version - doesn't make nautilus spit out g_warnings. Also, I've added a
context menu to the navigation view "Location:" label.
Comments, suggestions?

[1]
http://mail.gnome.org/archives/nautilus-list/2005-February/msg00040.html

-- 
Christian Neumair <chris gnome-de org>
Index: src/nautilus-location-bar.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-location-bar.c,v
retrieving revision 1.104
diff -u -r1.104 nautilus-location-bar.c
--- src/nautilus-location-bar.c	25 Mar 2005 14:02:02 -0000	1.104
+++ src/nautilus-location-bar.c	29 Apr 2005 19:57:51 -0000
@@ -258,6 +258,40 @@
 	gtk_widget_set_size_request (widget, width, -1);
 }
 
+static gboolean
+label_button_pressed_callback (GtkWidget             *widget,
+			       GdkEventButton        *event)
+{
+	GtkUIManager             *ui_manager;
+	NautilusNavigationWindow *window;
+	GtkWidget                *menu;
+	GtkWidget                *label;
+
+	if (event->button != 3)
+		return FALSE;
+
+	/* only pop-up if the URI in the entry matches the displayed location */
+	label = GTK_BIN (widget)->child;
+	if (g_utf8_collate (gtk_label_get_text (GTK_LABEL (label)), LOCATION_LABEL))
+		return FALSE;
+
+	window = nautilus_location_bar_get_window (widget->parent);
+	ui_manager = nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window));
+	menu = gtk_ui_manager_get_widget (ui_manager, "/location");
+
+	g_return_val_if_fail (menu, FALSE);
+	g_return_val_if_fail (GTK_IS_MENU (menu), FALSE);
+
+	gtk_menu_popup (GTK_MENU (menu),
+		       	NULL, widget,
+			NULL, NULL,
+			event->button,
+			gdk_event_get_time ((GdkEvent *)event));
+
+	return TRUE;
+}
+
+
 static int
 get_editable_number_of_chars (GtkEditable *editable)
 {
@@ -401,6 +435,11 @@
 	eel_accessibility_set_up_label_widget_relation (label, entry);
 
 	gtk_container_add (GTK_CONTAINER (bar), hbox);
+
+
+	/* Label context menu */
+	g_signal_connect (event_box, "button-press-event",
+			  G_CALLBACK (label_button_pressed_callback), NULL);
 
 	/* Drag source */
 	gtk_drag_source_set (GTK_WIDGET (event_box), 
Index: src/nautilus-spatial-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-spatial-window.c,v
retrieving revision 1.439
diff -u -r1.439 nautilus-spatial-window.c
--- src/nautilus-spatial-window.c	17 Apr 2005 16:55:23 -0000	1.439
+++ src/nautilus-spatial-window.c	29 Apr 2005 19:57:52 -0000
@@ -488,6 +488,33 @@
 	*push_in = TRUE;
 }
 
+static gboolean
+location_button_pressed_callback (GtkWidget             *widget,
+				  GdkEventButton        *event,
+				  NautilusSpatialWindow *window)
+{
+	GtkUIManager *ui_manager;
+	GtkWidget    *menu;
+
+	if (event->button != 3)
+		return FALSE;
+
+	ui_manager = nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window));
+	menu = gtk_ui_manager_get_widget (ui_manager, "/location");
+
+	g_return_val_if_fail (menu, FALSE);
+	g_return_val_if_fail (GTK_IS_MENU (menu), FALSE);
+
+	gtk_menu_popup (GTK_MENU (menu),
+		       	NULL, widget,
+			NULL, NULL,
+			event->button,
+			gdk_event_get_time ((GdkEvent *)event));
+
+	return TRUE;
+}
+
+
 static void
 location_button_clicked_callback (GtkWidget *widget, NautilusSpatialWindow *window)
 {
@@ -697,6 +724,10 @@
 	gtk_widget_show (window->details->content_box);
 
 	window->details->location_button = gtk_button_new ();
+	g_signal_connect (window->details->location_button,
+			  "button-press-event",
+			  G_CALLBACK (location_button_pressed_callback),
+			  window);
 	gtk_button_set_relief (GTK_BUTTON (window->details->location_button),
 			       GTK_RELIEF_NORMAL);
 	rc_style = gtk_widget_get_modifier_style (window->details->location_button);
@@ -706,7 +737,6 @@
 				 rc_style);
 
 	gtk_widget_show (window->details->location_button);
-
 	hbox = gtk_hbox_new (FALSE, 3);
 	gtk_container_add (GTK_CONTAINER (window->details->location_button), 
 			   hbox);
Index: src/file-manager/fm-actions.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-actions.h,v
retrieving revision 1.5
diff -u -r1.5 fm-actions.h
--- src/file-manager/fm-actions.h	12 Mar 2005 11:18:32 -0000	1.5
+++ src/file-manager/fm-actions.h	29 Apr 2005 19:57:52 -0000
@@ -38,6 +38,7 @@
 #define FM_ACTION_COPY "Copy"
 #define FM_ACTION_PASTE "Paste"
 #define FM_ACTION_PASTE_FILES_INTO "Paste Files Into"
+#define FM_ACTION_LOCATION_PASTE "LocationPaste"
 #define FM_ACTION_NEW_LAUNCHER "New Launcher"
 #define FM_ACTION_RENAME "Rename"
 #define FM_ACTION_DUPLICATE "Duplicate"
@@ -45,7 +46,9 @@
 #define FM_ACTION_SELECT_ALL "Select All"
 #define FM_ACTION_SELECT_PATTERN "Select Pattern"
 #define FM_ACTION_TRASH "Trash"
+#define FM_ACTION_LOCATION_TRASH "LocationTrash"
 #define FM_ACTION_DELETE "Delete"
+#define FM_ACTION_LOCATION_DELETE "LocationDelete"
 #define FM_ACTION_SHOW_HIDDEN_FILES "Show Hidden Files"
 #define FM_ACTION_CONNECT_TO_SERVER_LINK "Connect To Server Link"
 #define FM_ACTION_MOUNT_VOLUME "Mount Volume"
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.668
diff -u -r1.668 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	11 Apr 2005 21:42:03 -0000	1.668
+++ src/file-manager/fm-directory-view.c	29 Apr 2005 19:57:56 -0000
@@ -123,6 +123,13 @@
 #define FM_DIRECTORY_VIEW_POPUP_PATH_BACKGROUND_SCRIPTS_PLACEHOLDER	"/background/Before Zoom Items/New Object Items/Scripts/Scripts Placeholder"
 #define FM_DIRECTORY_VIEW_POPUP_PATH_BACKGROUND_NEW_DOCUMENTS_PLACEHOLDER "/background/Before Zoom Items/New Object Items/New Documents/New Documents Placeholder"
 
+#define FM_DIRECTORY_VIEW_POPUP_PATH_LOCATION				"/location"
+
+gchar *paste_actions[] = {
+	FM_ACTION_PASTE,
+	FM_ACTION_LOCATION_PASTE
+};
+
 #define MAX_MENU_LEVELS 5
 
 enum {
@@ -360,6 +367,23 @@
 static void action_unmount_volume_callback         (GtkAction *action,
 						    gpointer   data);
 
+/* location popup-related actions */
+static void action_location_cut_callback        (GtkAction *action,
+						 gpointer   callback_data);
+static void action_location_copy_callback       (GtkAction *action,
+						 gpointer   callback_data);
+/* paste is handled by action_paste_files_callback */
+
+static void action_location_trash_callback      (GtkAction *action,
+						 gpointer   callback_data);
+static void action_location_delete_callback      (GtkAction *action,
+						  gpointer   callback_data);
+
+static void action_location_properties_callback (GtkAction *action,
+						 gpointer   callback_data);
+
+
+
 EEL_CLASS_BOILERPLATE (FMDirectoryView, fm_directory_view, GTK_TYPE_SCROLLED_WINDOW)
 
 EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, add_file)
@@ -5187,15 +5211,13 @@
 	
 static void
 copy_or_cut_files (FMDirectoryView *view,
-		   gboolean cut)
+		   GList           *clipboard_contents,
+		   gboolean         cut)
 {
 	int count;
 	char *status_string, *name;
-	GList *clipboard_contents;
 	ClipboardInfo *info;
 	
-	clipboard_contents = fm_directory_view_get_selection (view);
-
 	info = g_new0 (ClipboardInfo, 1);
 	info->file_uris = convert_file_list_to_uri_list (clipboard_contents);
 	info->cut = cut;
@@ -5249,14 +5271,22 @@
 action_copy_files_callback (GtkAction *action,
 			    gpointer callback_data)
 {
-	copy_or_cut_files (callback_data, FALSE);
+	FMDirectoryView *view = FM_DIRECTORY_VIEW (callback_data);
+
+	copy_or_cut_files (callback_data,
+			   fm_directory_view_get_selection (view),
+			   FALSE);
 }
 
 static void
 action_cut_files_callback (GtkAction *action,
 			   gpointer callback_data)
 {
-	copy_or_cut_files (callback_data, TRUE);
+	FMDirectoryView *view = FM_DIRECTORY_VIEW (callback_data);
+
+	copy_or_cut_files (callback_data,
+			   fm_directory_view_get_selection (view),
+			   TRUE);
 }
 
 static GList *
@@ -5687,6 +5717,75 @@
 	g_free (name);
 }
 
+
+static void
+action_location_cut_callback (GtkAction *action,
+			      gpointer   callback_data)
+{
+	FMDirectoryView *view = FM_DIRECTORY_VIEW (callback_data);
+	NautilusFile *file = fm_directory_view_get_directory_as_file (view);
+	GList *files = g_list_append (NULL, file);
+
+	copy_or_cut_files (view, files, TRUE);
+
+	g_list_free (files);
+}
+
+static void
+action_location_copy_callback (GtkAction *action,
+			       gpointer   callback_data)
+{
+	FMDirectoryView *view = FM_DIRECTORY_VIEW (callback_data);
+	NautilusFile *file = fm_directory_view_get_directory_as_file (view);
+	GList *files = g_list_append (NULL, file);
+
+	copy_or_cut_files (view, files, FALSE);
+
+	g_list_free (files);
+}
+
+static void
+action_location_trash_callback (GtkAction *action,
+				gpointer   callback_data)
+{
+	FMDirectoryView *view = FM_DIRECTORY_VIEW (callback_data);
+	NautilusFile *file = fm_directory_view_get_directory_as_file (view);
+	GList *files = g_list_append (NULL, file);
+
+	trash_or_delete_files (view, files);
+
+	g_list_free (files);
+}
+
+static void
+action_location_delete_callback (GtkAction *action,
+				 gpointer   callback_data)
+{
+	FMDirectoryView *view = FM_DIRECTORY_VIEW (callback_data);
+	NautilusFile *file = fm_directory_view_get_directory_as_file (view);
+	char *file_uri = nautilus_file_get_uri (file);
+	GList *files = g_list_append (NULL, file_uri);
+
+	nautilus_file_operations_delete (files, GTK_WIDGET (view));
+
+	g_free (file_uri);
+	g_list_free (files);
+}
+
+static void
+action_location_properties_callback (GtkAction *action,
+				     gpointer   callback_data)
+{
+	FMDirectoryView *view = FM_DIRECTORY_VIEW (callback_data);
+	NautilusFile *file = fm_directory_view_get_directory_as_file (view);
+	GList *files = g_list_append (NULL, file);
+
+	fm_properties_window_present (files, GTK_WIDGET (view));
+
+	g_list_free (files);
+}
+
+
 static void
 fm_directory_view_init_show_hidden_files (FMDirectoryView *view)
 {
@@ -5855,6 +5954,36 @@
     N_("Open File and Close window"), "<alt><shift>Down",                /* label, accelerator */
     NULL,                   /* tooltip */ 
     G_CALLBACK (action_open_close_parent_callback) },
+
+  /* Location-specific actions */
+  { "LocationCut", GTK_STOCK_CUT,                  /* name, stock id */
+    NULL, "",                /* label, accelerator */
+    N_("Prepare the open folder to be moved with a Paste Files command"),                   /* tooltip */ 
+    G_CALLBACK (action_location_cut_callback) },
+  { "LocationCopy", GTK_STOCK_COPY,                  /* name, stock id */
+    NULL, "",                /* label, accelerator */
+    N_("Prepare the open folder to be copied with a Paste Files command"),                   /* tooltip */ 
+    G_CALLBACK (action_location_copy_callback) },
+  /* We make accelerator "" instead of null here to not inherit the stock
+     accelerator for paste */
+  { "LocationPaste", GTK_STOCK_PASTE,                  /* name, stock id */
+    NULL, "",                /* label, accelerator */
+    N_("Move or copy files previously selected by a Cut Files or Copy Files command into the open folder"),                   /* tooltip */ 
+    G_CALLBACK (action_paste_files_callback) },
+
+  { "LocationTrash", GTK_STOCK_DELETE,                  /* name, stock id */
+    N_("Mo_ve to Trash"), "",                /* label, accelerator */
+    N_("Move the open folder to the Trash"),                   /* tooltip */ 
+    G_CALLBACK (action_location_trash_callback) },
+  { "LocationDelete", GTK_STOCK_DELETE,                  /* name, stock id */
+    N_("_Delete"), "",                /* label, accelerator */
+    N_("Delete the open folder, without moving to the Trash"),                   /* tooltip */ 
+    G_CALLBACK (action_location_delete_callback) },
+
+  { "LocationProperties", GTK_STOCK_PROPERTIES,                  /* name, stock id */
+    N_("_Properties"), "",                /* label, accelerator */
+    N_("View or modify the properties of the open folder"),                   /* tooltip */ 
+    G_CALLBACK (action_location_properties_callback) },
 };
 
 static GtkToggleActionEntry directory_view_toggle_entries[] = {
@@ -5946,11 +6075,13 @@
 	
 	selection = fm_directory_view_get_selection (view);
 	count = g_list_length (selection);
-	
-	action = gtk_action_group_get_action (view->details->dir_action_group,
-					      FM_ACTION_PASTE);
-	gtk_action_set_sensitive (action,
-				  can_paste && !fm_directory_view_is_read_only (view));
+
+	for (i = 0; i < G_N_ELEMENTS (paste_actions); i++) {
+		action = gtk_action_group_get_action (view->details->dir_action_group,
+						      paste_actions[i]);
+		gtk_action_set_sensitive (action,
+					  can_paste && !fm_directory_view_is_read_only (view));
+	}
 
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_PASTE_FILES_INTO);
@@ -6118,6 +6249,8 @@
 	gboolean is_read_only;
 	GtkAction *action;
 
+	int i;
+
 	selection_is_read_only = selection_count == 1
 		&& !nautilus_file_can_write (NAUTILUS_FILE (selection->data));
 	
@@ -6126,9 +6259,11 @@
 	can_paste_files_into = selection_count == 1 && 
 		nautilus_file_is_directory (NAUTILUS_FILE (selection->data));
 
-	action = gtk_action_group_get_action (view->details->dir_action_group,
-					      FM_ACTION_PASTE);
-	gtk_action_set_sensitive (action, !is_read_only);
+	for (i = 0; i < G_N_ELEMENTS (paste_actions); i++) {
+		action = gtk_action_group_get_action (view->details->dir_action_group,
+						      paste_actions[i]);
+		gtk_action_set_sensitive (action, !is_read_only);
+	}
 	
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_PASTE_FILES_INTO);
@@ -6281,6 +6416,7 @@
 	reset_open_with_menu (view, selection);
 	reset_extension_actions_menu (view, selection);
 
+	/* Delete action */
 	if (all_selected_items_in_trash (view)) {
 		label = _("_Delete from Trash");
 		tip = _("Delete all selected items permanently");
@@ -6303,13 +6439,35 @@
 					      FM_ACTION_DELETE);
 	gtk_action_set_visible (action, show_separate_delete_command);
 	
-	if (show_separate_delete_command) {
-		g_object_set (action,
-			      "label", _("_Delete"),
-			      NULL);
+	if (show_separate_delete_command)
 		gtk_action_set_sensitive (action, can_delete_files);
+
+	/* LocationDelete action */
+	if (nautilus_file_is_in_trash (view->details->directory_as_file)) {
+		label = _("_Delete from Trash");
+		tip = _("Delete the open folder permanently");
+		show_separate_delete_command = FALSE;
+	} else {
+		label = _("Mo_ve to Trash");
+		tip = _("Move the open folder to the Trash");
+		show_separate_delete_command = show_delete_command_auto_value;
 	}
+
+	action = gtk_action_group_get_action (view->details->dir_action_group,
+					      FM_ACTION_LOCATION_TRASH);
+	g_object_set (action,
+		      "label", label,
+		      "tooltip", tip,
+		      NULL);
+	gtk_action_set_sensitive (action, !fm_directory_view_is_read_only (view));
+
+	action = gtk_action_group_get_action (view->details->dir_action_group,
+					      FM_ACTION_LOCATION_DELETE);
+	gtk_action_set_visible (action, show_separate_delete_command);
 	
+	if (show_separate_delete_command)
+		gtk_action_set_sensitive (action, fm_directory_view_is_read_only (view));
+
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_DUPLICATE);
 	gtk_action_set_sensitive (action, can_duplicate_files);
@@ -6446,6 +6604,34 @@
 				      EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
 				      event);
 }
+
+
+/**
+ * fm_directory_view_pop_up_location_context_menu
+ *
+ * Pop up a context menu appropriate to the view globally.
+ * @view: FMDirectoryView of interest.
+ * @event: GdkEventButton triggering the popup.
+ *
+ **/
+void 
+fm_directory_view_pop_up_location_context_menu (FMDirectoryView *view, 
+						GdkEventButton *event)
+{
+	g_assert (FM_IS_DIRECTORY_VIEW (view));
+
+	/* Make the context menu items not flash as they update to proper disabled,
+	 * etc. states by forcing menus to update now.
+	 */
+	update_menus_if_pending (view);
+
+	eel_pop_up_context_menu (create_popup_menu 
+				      (view, FM_DIRECTORY_VIEW_POPUP_PATH_LOCATION),
+				      EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
+				      EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
+				      event);
+}
+
 
 static void
 schedule_update_menus (FMDirectoryView *view) 
Index: src/file-manager/fm-directory-view.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.h,v
retrieving revision 1.135
diff -u -r1.135 fm-directory-view.h
--- src/file-manager/fm-directory-view.h	13 Jan 2005 13:27:51 -0000	1.135
+++ src/file-manager/fm-directory-view.h	29 Apr 2005 19:57:56 -0000
@@ -362,6 +362,8 @@
 EelBackground *     fm_directory_view_get_background                   (FMDirectoryView  *view);
 void                fm_directory_view_pop_up_background_context_menu   (FMDirectoryView  *view,
 									GdkEventButton   *event);
+void                fm_directory_view_pop_up_location_context_menu     (FMDirectoryView *view, 
+									GdkEventButton *event);
 void                fm_directory_view_pop_up_selection_context_menu    (FMDirectoryView  *view,
 									GdkEventButton   *event); 
 void                fm_directory_view_send_selection_change            (FMDirectoryView *view);
Index: src/file-manager/nautilus-directory-view-ui.xml
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/nautilus-directory-view-ui.xml,v
retrieving revision 1.72
diff -u -r1.72 nautilus-directory-view-ui.xml
--- src/file-manager/nautilus-directory-view-ui.xml	23 Jan 2005 19:03:56 -0000	1.72
+++ src/file-manager/nautilus-directory-view-ui.xml	29 Apr 2005 19:57:57 -0000
@@ -144,4 +144,18 @@
         </placeholder>
         <menuitem name="Connect To Server Link" action="Connect To Server Link"/>
 </popup>
+<popup name="location">
+	<placeholder name="Clipboard Actions">
+		<menuitem name="Cut" action="LocationCut"/>
+		<menuitem name="Copy" action="LocationCopy"/>
+		<menuitem name="Paste" action="LocationPaste"/>
+	</placeholder>
+	<separator/>
+	<placeholder name="Dangerous File Actions">
+		<menuitem name="Trash" action="LocationTrash"/>
+		<menuitem name="Delete" action="LocationDelete"/>
+	</placeholder>
+	<separator/>
+	<menuitem name="Properties" action="LocationProperties"/>
+</popup>
 </ui>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]