[PATCH][RFC] Location button context menu



I've tried to model some actions referring to the open folder into a
popup menu for the location button in the buttom left corner of the
nautilus window.
This patch is experimental. Sometimes Nautilus freezes upon icon
activation, but that could be due to my broken desktop, or maybe I'm
doing something heavily wrong. I'd really like to get some feedback on
it since it is IMHO the right direction, but we're not yet quiet there.

Observations:

For renaming a folder, it would be required to open a parent folder and
selecting the open folder afterwards, starting a rename. There is not
yet any API to do that. Maybe you can somehow connect to the
asynchronous loading of the parent window, but I don't know how.

It is not yet possible to open a folder using another application
through the context menu. Might need some serious love, hopefully
without much code duplication.

While the UI definitions sit in nautilus-shell-ui.xml (they refer to the
windows), the actions definitions sit in fm-directory-view.c. This is no
problem at popup time, because FMDirectoryView is loaded always, but
when Nautilus reads the xml file, it doesn't know about those actions
yet, yelling that it can't find the actions I refer to. FMDirectoryView
and NautilusWindow should experience some integration (or shouldn't
they, architecturally?). It just seemed to me that NautilusView is an
abstraction layer that was introduced when nautilus was (ab)used as
document viewer.

The browser doesn't currently use the popup menu. I'd like to open it on
a "Location:" label right-click.

Folders in trash aren't yet handled right when it comes to the delete
label and delete action. We have to decide whether it's more common to
delete a folder from trash or resurrect it. If the matter is true, we'd
have to provide at least a "folder-name (in Trash)" window title to
denote that the user acts on a folder in trash - this is because after
moving the window to trash, the folder's attributes don't change and the
user might suppose that nothing happened, trying to right-click the
button again and deleting it finally from trash, without being able to
restore the file later.

Any further observations? Suggestions, anybody?

-- 
Christian Neumair <chris gnome-de org>
? src/nautilus-spatial-window-SAVE.c
Index: src/nautilus-shell-ui.xml
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-shell-ui.xml,v
retrieving revision 1.117
diff -u -r1.117 nautilus-shell-ui.xml
--- src/nautilus-shell-ui.xml	22 Nov 2004 15:24:37 -0000	1.117
+++ src/nautilus-shell-ui.xml	11 Feb 2005 21:02:59 -0000
@@ -79,4 +79,45 @@
         <separator/>
 	<placeholder name="After Zoom Items"/>
 </popup>
+<popup name="location">
+	<placeholder name="Open Placeholder"/>
+	<separator/>
+<!--	<placeholder name="Location Open Placeholder">
+		<menuitem name="LocationOpen" action="LocationOpen"/>
+		<menuitem name="LocationOpenAlternate" action="LocationOpenAlternate"/>
+		<placeholder name="Location Applications Placeholder">
+		</placeholder>
+		<menu action="Location Open With">
+			<placeholder name="Location Applications Placeholder"/>
+			<separator name="Location Open With Separator"/>
+		<menuitem name="LocationOtherApplication" action="LocationOtherApplication1"/>
+		</menu>
+		<placeholder name="LocationOtherApplicationPlaceholder">
+			<menuitem name="LocationOtherApplication" action="LocationOtherApplication2"/>
+		</placeholder>
+		<menu action="LocationScripts">
+			 <placeholder name="Location Scripts Placeholder"/>
+			 <separator name="After Location Scripts"/>
+			 <menuitem name="Open Scripts Folder" action="Open Scripts Folder"/>
+		</menu>
+	</placeholder> !-->
+
+	<separator/>
+
+	<menuitem name="Cut" action="LocationCut"/>
+	<menuitem name="Copy" action="LocationCopy"/>
+	<menuitem name="Paste" action="LocationPaste"/>
+
+	<separator/>
+
+	<menuitem name="Rename" action="LocationRename"/>
+
+	<separator/>
+
+	<menuitem name="Trash" action="LocationTrash"/>
+
+	<separator/>
+
+	<menuitem name="Properties" action="LocationProperties"/>
+</popup>
 </ui>
Index: src/nautilus-spatial-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-spatial-window.c,v
retrieving revision 1.436
diff -u -r1.436 nautilus-spatial-window.c
--- src/nautilus-spatial-window.c	27 Jan 2005 12:35:47 -0000	1.436
+++ src/nautilus-spatial-window.c	11 Feb 2005 21:03:01 -0000
@@ -479,6 +479,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)
 {
@@ -614,6 +641,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);
@@ -623,7 +654,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.4
diff -u -r1.4 fm-actions.h
--- src/file-manager/fm-actions.h	23 Jan 2005 19:03:56 -0000	1.4
+++ src/file-manager/fm-actions.h	11 Feb 2005 21:03:01 -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"
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.660
diff -u -r1.660 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	9 Feb 2005 10:51:53 -0000	1.660
+++ src/file-manager/fm-directory-view.c	11 Feb 2005 21:03:48 -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 {
@@ -356,6 +363,24 @@
 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_rename_callback     (GtkAction *action,
+						 gpointer   callback_data);
+
+static void action_location_trash_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)
@@ -5167,15 +5192,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;
@@ -5229,14 +5252,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 *
@@ -5667,6 +5698,69 @@
 	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_rename_callback (GtkAction *action,
+				 gpointer   callback_data)
+{
+	g_warning ("Not yet implemented");
+}
+
+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);
+
+	copy_or_cut_files (view, files, FALSE);
+
+	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)
 {
@@ -5837,6 +5931,38 @@
     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) },
+
+
+  { "LocationRename", NULL,                  /* name, stock id */
+    N_("_Rename..."), "",                /* label, accelerator */
+    N_("Rename the open folder"),                   /* tooltip */ 
+    G_CALLBACK (action_location_rename_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) },
+
+  { "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[] = {
@@ -5920,11 +6046,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);
@@ -6092,6 +6220,8 @@
 	gboolean is_read_only;
 	GtkAction *action;
 
+	int i;
+
 	selection_is_read_only = selection_count == 1
 		&& !nautilus_file_can_write (NAUTILUS_FILE (selection->data));
 	
@@ -6100,9 +6230,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);
@@ -6416,6 +6548,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	11 Feb 2005 21:03:50 -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);


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