[PATCH] Add functions for looking up drive/volume for file, use it in FMDirectoryView+FMPropertiesWindow



The attached patch adds proper volume/drive handling caps to Nautilus.
It ensures that users can operate on both the selection and the menu for
the currently displayed location.

It also prevents Nautilus from displaying "Unmount" when the
drive/volume requires ejection anyway, because they are identical in
that case.

I didn't do any profiling, but I hope the lookup doesn't slow down
Nautilus signifcantly.

We might use some form of caching for the volume/drive lookup if this
turns out to be a problem.

This should finally fix bug 336828:
http://bugzilla.gnome.org/show_bug.cgi?id=336828

-- 
Christian Neumair <chris gnome-de org>
Index: libnautilus-private/nautilus-file.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file.c,v
retrieving revision 1.395
diff -u -p -r1.395 nautilus-file.c
--- libnautilus-private/nautilus-file.c	6 Nov 2006 12:58:58 -0000	1.395
+++ libnautilus-private/nautilus-file.c	21 Dec 2006 21:25:25 -0000
@@ -928,6 +928,134 @@ nautilus_file_get_drive (NautilusFile *f
 				  "nautilus_file_drive");
 }
 
+GnomeVFSVolume *
+nautilus_file_lookup_volume (NautilusFile *file)
+{
+	GnomeVFSVolume *volume;
+	GnomeVFSVolume *one_volume;
+	GList *l, *list;
+	char *uri, *symlink_target_uri, *one_uri;
+
+	g_assert (file != NULL);
+
+	uri = nautilus_file_get_uri (file);
+	g_assert (uri != NULL);
+
+	symlink_target_uri = NULL;
+	if (nautilus_file_is_symbolic_link (file)) {
+		symlink_target_uri = nautilus_file_get_symbolic_link_target_uri (file);
+	}
+
+	volume = NULL;
+
+	list = gnome_vfs_volume_monitor_get_mounted_volumes (gnome_vfs_get_volume_monitor ());
+
+	for (l = list; l != NULL; l = l->next) {
+		one_volume = l->data;
+
+		one_uri = gnome_vfs_volume_get_activation_uri (one_volume);
+		if (one_uri != NULL &&
+		    ((strcmp (uri, one_uri) == 0) ||
+		     (symlink_target_uri != NULL &&
+		      (strcmp (symlink_target_uri, one_uri) == 0)))) {
+			volume = gnome_vfs_volume_ref (one_volume);
+		}
+
+		g_free (one_uri);
+
+
+		if (volume != NULL) {
+			break;
+		}
+	}
+
+	g_list_foreach (list, (GFunc) gnome_vfs_volume_unref, NULL);
+	g_list_free (list);
+
+	g_free (uri);
+	g_free (symlink_target_uri);
+
+	return volume;
+}
+
+GnomeVFSDrive *
+nautilus_file_lookup_drive (NautilusFile *file)
+{
+	GnomeVFSDrive *drive;
+	GnomeVFSDrive *one_drive;
+	GList *l, *list;
+	char *uri, *symlink_target_uri, *one_uri;
+
+	g_assert (file != NULL);
+
+	uri = nautilus_file_get_uri (file);
+	g_assert (uri != NULL);
+
+	symlink_target_uri = NULL;
+	if (nautilus_file_is_symbolic_link (file)) {
+		symlink_target_uri = nautilus_file_get_symbolic_link_target_uri (file);
+	}
+
+	drive = NULL;
+
+	list = gnome_vfs_volume_monitor_get_connected_drives (gnome_vfs_get_volume_monitor ());
+
+	for (l = list; l != NULL; l = l->next) {
+		GList *volume_list;
+		GList *l2;
+
+		one_drive = l->data;
+
+		volume_list = gnome_vfs_drive_get_mounted_volumes (one_drive);
+		if (volume_list != NULL) {
+			for (l2 = volume_list; l2 != NULL; l2 = l2->next) {
+				GnomeVFSVolume *one_volume;
+
+				one_volume = l2->data;
+
+				one_uri = gnome_vfs_volume_get_activation_uri (one_volume);
+				if (one_uri != NULL &&
+				    ((strcmp (uri, one_uri) == 0) ||
+				     (symlink_target_uri != NULL &&
+				      (strcmp (symlink_target_uri, one_uri) == 0)))) {
+					drive = gnome_vfs_drive_ref (one_drive);
+				}
+				g_free (one_uri);
+
+				if (drive != NULL) {
+					break;
+				}
+			}
+
+			gnome_vfs_drive_volume_list_free (volume_list);
+		}
+
+		one_uri = gnome_vfs_drive_get_activation_uri (one_drive);
+		if (one_uri != NULL &&
+		    drive == NULL &&
+		    ((strcmp (uri, one_uri) == 0) ||
+		     (symlink_target_uri != NULL &&
+		      (strcmp (symlink_target_uri, one_uri) == 0)))) {
+			drive = gnome_vfs_drive_ref (one_drive);
+		}
+
+		g_free (one_uri);
+
+		if (drive != NULL) {
+			break;
+		}
+	}
+
+	g_list_foreach (list, (GFunc) gnome_vfs_drive_unref, NULL);
+	g_list_free (list);
+
+	g_free (uri);
+	g_free (symlink_target_uri);
+
+	return drive;
+}
+
+
 static GnomeVFSURI *
 nautilus_file_get_gnome_vfs_uri (NautilusFile *file)
 {
Index: libnautilus-private/nautilus-file.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file.h,v
retrieving revision 1.113
diff -u -p -r1.113 nautilus-file.h
--- libnautilus-private/nautilus-file.h	16 Jun 2006 15:02:57 -0000	1.113
+++ libnautilus-private/nautilus-file.h	21 Dec 2006 21:25:26 -0000
@@ -27,6 +27,7 @@
 
 #include <gtk/gtkobject.h>
 #include <libgnomevfs/gnome-vfs-types.h>
+#include <libgnomevfs/gnome-vfs-drive.h>
 #include <libgnomevfs/gnome-vfs-volume.h>
 #include <libnautilus-private/nautilus-file-attributes.h>
 
@@ -212,6 +213,9 @@ gboolean                nautilus_file_ha
 gboolean                nautilus_file_has_drive                         (NautilusFile                   *file);
 GnomeVFSVolume *        nautilus_file_get_volume                        (NautilusFile                   *file);
 GnomeVFSDrive *         nautilus_file_get_drive                         (NautilusFile                   *file);
+
+GnomeVFSVolume *        nautilus_file_lookup_volume                     (NautilusFile			*file);
+GnomeVFSDrive *         nautilus_file_lookup_drive                      (NautilusFile			*file);
 
 /* Basic operations for file objects. */
 void                    nautilus_file_set_owner                         (NautilusFile                   *file,
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.754
diff -u -p -r1.754 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	18 Dec 2006 09:32:21 -0000	1.754
+++ src/file-manager/fm-directory-view.c	21 Dec 2006 21:25:48 -0000
@@ -390,10 +391,6 @@ static gboolean activate_check_mime_type
 								gboolean warn_on_mismatch);
 static GdkDragAction ask_link_action                           (FMDirectoryView      *view);
 
-static void file_get_volume_and_drive (NautilusFile    *file,
-				       GnomeVFSVolume **volume,
-				       GnomeVFSDrive  **drive);
-
 static void action_open_scripts_folder_callback    (GtkAction *action,
 						    gpointer   callback_data);
 static void action_cut_files_callback              (GtkAction *action,
@@ -6346,6 +6343,30 @@ volume_or_drive_ejected_callback (gboole
 	}
 }
 
+static void
+file_get_volume_and_drive (NautilusFile *file,
+			   GnomeVFSVolume **volume,
+			   GnomeVFSDrive **drive)
+{
+	if (volume != NULL) {
+		*volume = nautilus_file_get_volume (file);
+		if (*volume != NULL) {
+			gnome_vfs_volume_ref (*volume);
+		} else {
+			*volume = nautilus_file_lookup_volume (file);
+		}
+	}
+
+	if (drive != NULL) {
+		*drive = nautilus_file_get_drive (file);
+		if (*drive != NULL) {
+			gnome_vfs_drive_ref (*drive);
+		} else {
+			*drive = nautilus_file_lookup_drive (file);
+		}
+	}
+}
+
 
 static void
 action_unmount_volume_callback (GtkAction *action,
@@ -6363,17 +6384,16 @@ action_unmount_volume_callback (GtkActio
 
 	for (l = selection; l != NULL; l = l->next) {
 		file = NAUTILUS_FILE (l->data);
-		if (nautilus_file_has_volume (file)) {
-			volume = nautilus_file_get_volume (file);
-			if (volume != NULL) {
-				gnome_vfs_volume_unmount (volume, volume_or_drive_unmounted_callback, NULL);
-			}
-		} else if (nautilus_file_has_drive (file)) {
-			drive = nautilus_file_get_drive (file);
-			if (drive != NULL) {
-				gnome_vfs_drive_unmount (drive, volume_or_drive_unmounted_callback, NULL);
-			}
+		file_get_volume_and_drive (file, &volume, &drive);
+
+		if (volume != NULL) {
+			gnome_vfs_volume_unmount (volume, volume_or_drive_unmounted_callback, NULL);
+		} else if (drive != NULL) {
+			gnome_vfs_drive_unmount (drive, volume_or_drive_unmounted_callback, NULL);
 		}
+
+		gnome_vfs_volume_unref (volume);
+		gnome_vfs_drive_unref (drive);
 	}
 	nautilus_file_list_free (selection);
 }
@@ -6392,13 +6412,14 @@ action_format_volume_callback (GtkAction
 	selection = fm_directory_view_get_selection (view);
 	for (l = selection; l != NULL; l = l->next) {
 		file = NAUTILUS_FILE (l->data);
+		file_get_volume_and_drive (file, NULL, &drive);
 
-		if (nautilus_file_has_drive (file)) {
-			drive = nautilus_file_get_drive (file);
-			if (gnome_vfs_drive_get_device_type (drive) == GNOME_VFS_DEVICE_TYPE_FLOPPY) {
-				g_spawn_command_line_async ("gfloppy", NULL);
-			}
+		if (drive != NULL &&
+		    gnome_vfs_drive_get_device_type (drive) == GNOME_VFS_DEVICE_TYPE_FLOPPY) {
+			g_spawn_command_line_async ("gfloppy", NULL);
 		}
+
+		gnome_vfs_drive_unref (drive);
 	}	
 	nautilus_file_list_free (selection);
 }
@@ -6418,18 +6439,16 @@ action_eject_volume_callback (GtkAction 
 	selection = fm_directory_view_get_selection (view);
 	for (l = selection; l != NULL; l = l->next) {
 		file = NAUTILUS_FILE (l->data);
-		
-		if (nautilus_file_has_volume (file)) {
-			volume = nautilus_file_get_volume (file);
-			if (volume != NULL) {
-				gnome_vfs_volume_eject (volume, volume_or_drive_ejected_callback, NULL);
-			}
-		} else if (nautilus_file_has_drive (file)) {
-			drive = nautilus_file_get_drive (file);
-			if (drive != NULL) {
-				gnome_vfs_drive_eject (drive, volume_or_drive_ejected_callback, NULL);
-			}
+		file_get_volume_and_drive (file, &volume, &drive);
+
+		if (volume != NULL) {
+			gnome_vfs_volume_eject (volume, volume_or_drive_ejected_callback, NULL);
+		} else if (drive != NULL) {
+			gnome_vfs_drive_eject (drive, volume_or_drive_ejected_callback, NULL);
 		}
+
+		gnome_vfs_volume_unref (volume);
+		gnome_vfs_drive_unref (drive);
 	}	
 	nautilus_file_list_free (selection);
 }
@@ -7156,7 +7175,7 @@ clipboard_targets_received (GtkClipboard
 					      FM_ACTION_PASTE_FILES_INTO);
 	gtk_action_set_sensitive (action,
 				  can_paste && count == 1 &&
-				  nautilus_file_is_directory (NAUTILUS_FILE (selection->data)) &&
+				  file_list_all_are_folders (selection) &&
 				  nautilus_file_can_write (NAUTILUS_FILE (selection->data)));
 	
 	nautilus_file_list_free (selection);
@@ -7233,6 +7252,23 @@ file_list_all_are_folders (GList *file_l
 	return TRUE;
 }
 
+static gboolean
+volume_needs_eject (GnomeVFSVolume *volume)
+{
+	GnomeVFSDrive *drive;
+	gboolean needs_eject;
+
+	needs_eject = FALSE;
+
+	drive = gnome_vfs_volume_get_drive (volume);
+	if (drive != NULL) {
+		needs_eject = gnome_vfs_drive_needs_eject (drive);
+		gnome_vfs_drive_unref (drive);
+	}
+
+	return needs_eject;
+}
+
 static void
 file_should_show_foreach (NautilusFile *file,
 			  gboolean     *show_mount,
@@ -7251,16 +7287,25 @@ file_should_show_foreach (NautilusFile *
 	*show_connect = FALSE;
 	*show_format = FALSE;
 
-	if (nautilus_file_has_volume (file)) {
-		*show_unmount = TRUE;
+	if (file == NULL) {
+		return;
+	}
+
+	file_get_volume_and_drive (file, &volume, &drive);
 
-		volume = nautilus_file_get_volume (file);
-		*show_eject = eject_for_type (gnome_vfs_volume_get_device_type (volume));
-	} else if (nautilus_file_has_drive (file)) {
-		drive = nautilus_file_get_drive (file);
-		*show_eject = eject_for_type (gnome_vfs_drive_get_device_type (drive));
-		if (gnome_vfs_drive_is_mounted (drive)) {
+	if (volume != NULL) {
+		*show_eject = volume_needs_eject (volume) ||
+			      eject_for_type (gnome_vfs_volume_get_device_type (volume));
+		if (!volume_needs_eject (volume)) {
 			*show_unmount = TRUE;
+		}
+	} else if (drive != NULL) {
+		*show_eject = gnome_vfs_drive_needs_eject (drive) ||
+			      eject_for_type (gnome_vfs_drive_get_device_type (drive));
+		if (gnome_vfs_drive_is_mounted (drive)) {
+			if (!gnome_vfs_drive_needs_eject (drive)) {
+				*show_unmount = TRUE;
+			}
 		} else {
 			*show_mount = TRUE;
 		}
@@ -7283,112 +7328,11 @@ file_should_show_foreach (NautilusFile *
 					       "x-directory/smb-share")) {
 		*show_connect = TRUE;
 	}
-}
-
-static void
-file_get_volume_and_drive (NautilusFile    *file,
-			   GnomeVFSVolume **volume,
-			   GnomeVFSDrive  **drive)
-{
-	GnomeVFSVolume *one_volume;
-	GnomeVFSDrive *one_drive;
-	GList *l, *list;
-	char *uri, *one_uri;
-
-	g_assert (file != NULL);
-
-	uri = nautilus_file_get_uri (file);
-	g_assert (uri != NULL);
-
-	if (volume != NULL) {
-		*volume = NULL;
-
-		list = gnome_vfs_volume_monitor_get_mounted_volumes (gnome_vfs_get_volume_monitor ());
-
-		for (l = list; l != NULL && *volume == NULL; l = l->next) {
-			one_volume = l->data;
-
-			one_uri = gnome_vfs_volume_get_activation_uri (one_volume);
-			if (one_uri != NULL && (strcmp (uri, one_uri) == 0)) {
-				*volume = gnome_vfs_volume_ref (one_volume);
-			}
-
-			g_free (one_uri);
-		}
-
-		g_list_foreach (list, (GFunc) gnome_vfs_volume_unref, NULL);
-		g_list_free (list);
-	}
-
-	if (drive != NULL) {
-		*drive = NULL;
-
-		list = gnome_vfs_volume_monitor_get_connected_drives (gnome_vfs_get_volume_monitor ());
-
-		for (l = list; l != NULL; l = l->next) {
-			one_drive = l->data;
-
-			one_uri = gnome_vfs_drive_get_activation_uri (one_drive);
-			if (one_uri != NULL && (strcmp (uri, one_uri) == 0)) {
-				*drive = gnome_vfs_drive_ref (one_drive);
-				g_free (one_uri);
-				break;
-			}
-
-			g_free (one_uri);
-		}
-
-		g_list_foreach (list, (GFunc) gnome_vfs_drive_unref, NULL);
-		g_list_free (list);
-	}
-
-	g_free (uri);
-}
-
-static void
-file_should_show_self (NautilusFile *file,
-		       gboolean     *show_mount,
-		       gboolean     *show_unmount,
-		       gboolean     *show_eject,
-		       gboolean     *show_format)
-{
-	GnomeVFSVolume *volume;
-	GnomeVFSDrive *drive;
-
-	*show_mount = FALSE;
-	*show_unmount = FALSE;
-	*show_eject = FALSE;
-	*show_format = FALSE;
-
-	if (file == NULL) {
-		return;
-	}
-
-	file_get_volume_and_drive (file, &volume, &drive);
-
-	if (volume != NULL) {
-		*show_unmount = TRUE;
-		*show_eject = eject_for_type (gnome_vfs_volume_get_device_type (volume));
-	} else if (drive != NULL) {
-		*show_eject = eject_for_type (gnome_vfs_drive_get_device_type (drive));
-		if (gnome_vfs_drive_is_mounted (drive)) {
-			*show_unmount = TRUE;
-		} else {
-			*show_mount = TRUE;
-		}
-
-		if (gnome_vfs_drive_get_device_type (drive) == GNOME_VFS_DEVICE_TYPE_FLOPPY &&
-		    !gnome_vfs_drive_is_mounted (drive) &&
-		    g_find_program_in_path ("gfloppy")) {
-			*show_format = TRUE;
-		}
-	}
 
 	gnome_vfs_volume_unref (volume);
 	gnome_vfs_drive_unref (drive);
 }
 
-
 static void
 real_update_menus_volumes (FMDirectoryView *view,
 			   GList *selection,
@@ -7404,6 +7348,7 @@ real_update_menus_volumes (FMDirectoryVi
 	gboolean show_self_mount;
 	gboolean show_self_unmount;
 	gboolean show_self_eject;
+	gboolean show_self_connect;
 	gboolean show_self_format;
 	GtkAction *action;
 
@@ -7424,6 +7369,7 @@ real_update_menus_volumes (FMDirectoryVi
 		gboolean show_format_one;
 
 		file = NAUTILUS_FILE (l->data);
+
 		file_should_show_foreach (file,
 					  &show_mount_one,
 					  &show_unmount_one,
@@ -7464,13 +7410,14 @@ real_update_menus_volumes (FMDirectoryVi
 					      FM_ACTION_FORMAT_VOLUME);
 	gtk_action_set_visible (action, show_format);
 
-	show_self_mount = show_self_unmount = show_self_eject = show_self_format = FALSE;
+	show_self_mount = show_self_unmount = show_self_eject = show_self_connect = show_self_format = FALSE;
 
 	file = fm_directory_view_get_directory_as_file (view);
-	file_should_show_self (file,
+	file_should_show_foreach (file,
 			       &show_self_mount,
 			       &show_self_unmount,
 			       &show_self_eject,
+			       &show_self_connect,
 			       &show_self_format);
 
 	action = gtk_action_group_get_action (view->details->dir_action_group,
@@ -7484,6 +7431,8 @@ real_update_menus_volumes (FMDirectoryVi
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_SELF_EJECT_VOLUME);
 	gtk_action_set_visible (action, show_self_eject);
+
+	/* TODO add FM_ACTION_SELF_CONNECT (after freezes). */
 
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_SELF_FORMAT_VOLUME);
Index: src/file-manager/fm-properties-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-properties-window.c,v
retrieving revision 1.236
diff -u -p -r1.236 fm-properties-window.c
--- src/file-manager/fm-properties-window.c	30 Oct 2006 19:58:32 -0000	1.236
+++ src/file-manager/fm-properties-window.c	21 Dec 2006 21:25:56 -0000
@@ -69,6 +69,7 @@
 #include <libnautilus-extension/nautilus-property-page-provider.h>
 #include <libnautilus-private/nautilus-customization-data.h>
 #include <libnautilus-private/nautilus-entry.h>
+#include <libnautilus-private/nautilus-file.h>
 #include <libnautilus-private/nautilus-file-attributes.h>
 #include <libnautilus-private/nautilus-file-operations.h>
 #include <libnautilus-private/nautilus-desktop-icon-file.h>
@@ -301,17 +302,33 @@ get_target_file_for_original_file (Nauti
 	if (nautilus_file_has_volume (file)) {
 		volume = nautilus_file_get_volume (file);
 		if (volume != NULL) {
+			gnome_vfs_volume_ref (volume);
+		} else {
+			volume = nautilus_file_lookup_volume (file);
+		}
+
+		if (volume != NULL) {
 			uri_to_display = gnome_vfs_volume_get_activation_uri (volume);
 			target_file = nautilus_file_get (uri_to_display);
 			g_free (uri_to_display);
 		}
+
+		gnome_vfs_volume_unref (volume);
 	} else if (nautilus_file_has_drive (file)) {
 		drive = nautilus_file_get_drive (file);
 		if (drive != NULL) {
+			gnome_vfs_drive_ref (drive);
+		} else {
+			drive = nautilus_file_lookup_drive (file);
+		}
+
+		if (drive != NULL) {
 			uri_to_display = gnome_vfs_drive_get_activation_uri (drive);
 			target_file = nautilus_file_get (uri_to_display);
 			g_free (uri_to_display);
 		}
+
+		gnome_vfs_drive_unref (drive);
 	} else if (NAUTILUS_IS_DESKTOP_ICON_FILE (file)) {
 		link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (file));
 


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