File nautilus-155010-desktop-volume-policy.diff of Package nautilus

2006-05-11  Federico Mena Quintero  <federico@novell.com>

	* libnautilus-private/nautilus-desktop-link-monitor.c
	(volume_delete_dialog): Oops, don't free detail_str; it's a static
	string from gettext().  Fixes
	https://bugzilla.novell.com/show_bug.cgi?id=175076

2006-04-25  Federico Mena Quintero  <federico@novell.com>

	Fix https://bugzilla.novell.com/show_bug.cgi?id=168280:

	* libnautilus-private/nautilus-desktop-link-monitor.c
	(volume_mounted_callback): Just call refresh_volume_links(); this
	will regenerate the whole list of drives/volumes, and avoid having
	duplicates for user-visible drives that are also mounted.
	(volume_unmounted_callback): Likewise.
	(NautilusDesktopLinkMonitorDetails): Added fields connected_id and
	disconnected_id.
	(nautilus_desktop_link_monitor_init): Connect to "drive_connected"
	and "drive_disconnected" on the volume_monitor.
	(drive_connect_disconnect_callback): New callback; simply calls
	refresh_volume_links().

2006-04-12  Federico Mena Quintero  <federico@novell.com>

	* src/nautilus-places-sidebar.c: Adapted patch from
	http://bugzilla.gnome.org/show_bug.cgi?id=321320.  This makes the
	Places sidebar follow the same policy for showing drives and
	volumes as GtkFileSystemGnomeVFS.

2006-04-10  Federico Mena Quintero  <federico@novell.com>

	Allow displaying certain unmounted drives as icons in the desktop,
	not just mounted volumes.  Fixes the desktop part of bug #321320.

	Desktop link internals:

	* libnautilus-private/nautilus-desktop-link.c
	(NautilusDesktopLinkDetails): Renamed the "volume" field to
	"drive_or_volume".
	(nautilus_desktop_link_new_from_drive_or_volume): Renamed from
	nautilus_desktop_link_new_from_volume().  Take a GObject, which we
	check to be of type GnomeVFSDrive or GnomeVFSVolume.  Extract the
	information from the GnomeVFSDrive if appropriate.
	(nautilus_desktop_link_get_drive_or_volume): Renamed from
	nautilus_desktop_link_get_volume(); return a GObject.

	* libnautilus-private/nautilus-desktop-link.h: Changed the
	prototypes for the public functions above.

	Populate the drives/volumes:

	* libnautilus-private/nautilus-desktop-link-monitor.c
	(refresh_volume_links): New helper function.  This is now the
	master function that populates the list of drives/volumes.
	(desktop_volumes_visible_changed): Use refresh_volume_links() to
	avoid code duplication with nautilus_desktop_link_monitor_init().
	(nautilus_desktop_link_monitor_init): Use refresh_volume_links()
	to avoid code duplication with desktop_volumes_visible_changed().
	(create_drive_link): New helper function.
	(create_volume_link): Use
	nautilus_desktop_link_new_from_drive_or_volume().
	(volume_delete_dialog): Handle both drives and volumes.
	(volume_unmounted_callback): Use
	nautilus_desktop_link_get_drive_or_volume().

	* libnautilus-private/nautilus-desktop-icon-file.c
	(update_info_from_link): Use
	nautilus_desktop_link_get_drive_or_volume().

Index: libnautilus-private/nautilus-desktop-icon-file.c
===================================================================
RCS file: /cvsroot/novell/nautilus/libnautilus-private/nautilus-desktop-icon-file.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -p -r1.1.1.1 -r1.2
--- libnautilus-private/nautilus-desktop-icon-file.c	7 Apr 2006 20:12:27 -0000	1.1.1.1
+++ libnautilus-private/nautilus-desktop-icon-file.c	11 Apr 2006 16:46:34 -0000	1.2
@@ -179,7 +179,7 @@ update_info_from_link (NautilusDesktopIc
 	NautilusFile *file;
 	GnomeVFSFileInfo *file_info;
 	NautilusDesktopLink *link;
-	GnomeVFSVolume *volume;
+	GObject *drive_or_volume;
 	
 	file = NAUTILUS_FILE (icon_file);
 	
@@ -213,9 +213,21 @@ update_info_from_link (NautilusDesktopIc
 		GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS |
 		GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT;
 
-	volume = nautilus_desktop_link_get_volume (link);
-	nautilus_file_set_volume (file, volume);
-	gnome_vfs_volume_unref (volume);
+	drive_or_volume = nautilus_desktop_link_get_drive_or_volume (link);
+
+	if (GNOME_IS_VFS_VOLUME (drive_or_volume)) {
+		GnomeVFSVolume *volume;
+
+		volume = GNOME_VFS_VOLUME (drive_or_volume);
+		nautilus_file_set_volume (file, volume);
+		gnome_vfs_volume_unref (volume);
+	} else {
+		GnomeVFSDrive *drive;
+
+		drive = GNOME_VFS_DRIVE (drive_or_volume);
+		nautilus_file_set_drive (file, drive);
+		gnome_vfs_drive_unref (drive);
+	}
 	
 	file->details->file_info_is_up_to_date = TRUE;
 
Index: libnautilus-private/nautilus-desktop-link-monitor.c
===================================================================
RCS file: /cvsroot/novell/nautilus/libnautilus-private/nautilus-desktop-link-monitor.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -p -r1.1.1.1 -r1.3
--- libnautilus-private/nautilus-desktop-link-monitor.c	7 Apr 2006 20:12:27 -0000	1.1.1.1
+++ libnautilus-private/nautilus-desktop-link-monitor.c	26 Apr 2006 14:29:51 -0000	1.3
@@ -52,13 +52,14 @@ struct NautilusDesktopLinkMonitorDetails
 	NautilusDesktopLink *trash_link;
 	NautilusDesktopLink *network_link;
 
+	gulong connected_id;
+	gulong disconnected_id;
 	gulong mount_id;
 	gulong unmount_id;
 	
 	GList *volume_links;
 };
 
-
 static void nautilus_desktop_link_monitor_init       (gpointer              object,
 						      gpointer              klass);
 static void nautilus_desktop_link_monitor_class_init (gpointer              klass);
@@ -69,6 +70,8 @@ EEL_CLASS_BOILERPLATE (NautilusDesktopLi
 
 static NautilusDesktopLinkMonitor *the_link_monitor = NULL;
 
+static void refresh_volume_links (NautilusDesktopLinkMonitor *monitor);
+
 static void
 destroy_desktop_link_monitor (void)
 {
@@ -104,41 +107,48 @@ static void
 volume_delete_dialog (GtkWidget *parent_view,
                       NautilusDesktopLink *link)
 {
-	GnomeVFSVolume *volume;
+	GObject *drive_or_volume;
 	char *dialog_str;
+	char *detail_str;
 	char *display_name;
 
-	volume = nautilus_desktop_link_get_volume (link);
+	drive_or_volume = nautilus_desktop_link_get_drive_or_volume (link);
+	if (drive_or_volume == NULL)
+		return;
+
+	display_name = nautilus_desktop_link_get_display_name (link);
 
-	if (volume != NULL) {
-		display_name = nautilus_desktop_link_get_display_name (link);
+	if (GNOME_IS_VFS_VOLUME (drive_or_volume)) {
 		dialog_str = g_strdup_printf (_("You cannot move the volume \"%s\" to the trash."),
 					      display_name);
-		g_free (display_name);
 
-		if (eject_for_type (gnome_vfs_volume_get_device_type (volume))) {
-			eel_run_simple_dialog
-				(parent_view, 
-				 FALSE,
-				 GTK_MESSAGE_ERROR,
-				 dialog_str,
-				 _("If you want to eject the volume, please use \"Eject\" in the "
-				   "popup menu of the volume."),
-				 NULL, GTK_STOCK_OK, NULL);
+		if (eject_for_type (gnome_vfs_volume_get_device_type (GNOME_VFS_VOLUME (drive_or_volume)))) {
+			detail_str = _("If you want to eject the volume, please use \"Eject\" in the "
+				       "popup menu of the volume.");
 		} else {
-			eel_run_simple_dialog
-				(parent_view, 
-				 FALSE,
-				 GTK_MESSAGE_ERROR,
-				 dialog_str,
-				 _("If you want to unmount the volume, please use \"Unmount Volume\" in the "
-				   "popup menu of the volume."),
-				 NULL, GTK_STOCK_OK, NULL);
+			detail_str = _("If you want to unmount the volume, please use \"Unmount Volume\" in the "
+				       "popup menu of the volume.");
 		}
+	} else {
+		dialog_str = g_strdup_printf (_("You cannot move the drive \"%s\" to the trash."),
+					      display_name);
+
+		detail_str = NULL;
+	}
+
+	eel_run_simple_dialog (parent_view, FALSE, GTK_MESSAGE_ERROR,
+			       dialog_str,
+			       detail_str,
+			       NULL, GTK_STOCK_OK, NULL);
 
-		gnome_vfs_volume_unref (volume);
-		g_free (dialog_str);
+	if (GNOME_IS_VFS_VOLUME (drive_or_volume)) {
+		gnome_vfs_volume_unref (GNOME_VFS_VOLUME (drive_or_volume));
+	} else {
+		gnome_vfs_drive_unref (GNOME_VFS_DRIVE (drive_or_volume));
 	}
+
+	g_free (display_name);
+	g_free (dialog_str);
 }
 
 void
@@ -197,6 +207,21 @@ nautilus_desktop_link_monitor_make_filen
 }
 
 static void
+create_drive_link (NautilusDesktopLinkMonitor *monitor,
+		   GnomeVFSDrive *drive)
+{
+	NautilusDesktopLink *link;
+
+	if (!(eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)
+	      && gnome_vfs_drive_is_user_visible (drive)
+	      && !gnome_vfs_drive_is_mounted (drive)))
+		return;
+
+	link = nautilus_desktop_link_new_from_drive_or_volume (G_OBJECT (drive));
+	monitor->details->volume_links = g_list_prepend (monitor->details->volume_links, link);
+}
+
+static void
 create_volume_link (NautilusDesktopLinkMonitor *monitor,
 		    GnomeVFSVolume *volume)
 {
@@ -209,19 +234,29 @@ create_volume_link (NautilusDesktopLinkM
 	}
 
 	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) {
-		link = nautilus_desktop_link_new_from_volume (volume);
+		link = nautilus_desktop_link_new_from_drive_or_volume (G_OBJECT (volume));
 		monitor->details->volume_links = g_list_prepend (monitor->details->volume_links, link);
 	}
 }
 
-
+static void
+drive_connect_disconnect_callback (GnomeVFSVolumeMonitor *volume_monitor,
+				   GnomeVFSDrive *drive,
+				   NautilusDesktopLinkMonitor *monitor)
+{
+	refresh_volume_links (monitor);
+}
 
 static void
 volume_mounted_callback (GnomeVFSVolumeMonitor *volume_monitor,
 			 GnomeVFSVolume *volume, 
 			 NautilusDesktopLinkMonitor *monitor)
 {
+#if 0
 	create_volume_link (monitor, volume);
+#else
+	refresh_volume_links (monitor);
+#endif
 }
 
 
@@ -230,25 +265,34 @@ volume_unmounted_callback (GnomeVFSVolum
 			   GnomeVFSVolume *volume, 
 			   NautilusDesktopLinkMonitor *monitor)
 {
+#if 0
 	GList *l;
 	NautilusDesktopLink *link;
-	GnomeVFSVolume *other_volume;
+	GObject *other_volume;
 
 	link = NULL;
 	for (l = monitor->details->volume_links; l != NULL; l = l->next) {
-		other_volume = nautilus_desktop_link_get_volume (l->data);
-		if (volume == other_volume) {
-			gnome_vfs_volume_unref (other_volume);
+		other_volume = nautilus_desktop_link_get_drive_or_volume (l->data);
+		if (GNOME_IS_VFS_VOLUME (other_volume) && volume == GNOME_VFS_VOLUME (other_volume)) {
+			gnome_vfs_volume_unref (GNOME_VFS_VOLUME (other_volume));
 			link = l->data;
 			break;
 		}
-		gnome_vfs_volume_unref (other_volume);
+
+		if (GNOME_IS_VFS_VOLUME (other_volume)) {
+			gnome_vfs_volume_unref (GNOME_VFS_VOLUME (other_volume));
+		} else {
+			gnome_vfs_drive_unref (GNOME_VFS_DRIVE (other_volume));
+		}
 	}
 
 	if (link) {
 		monitor->details->volume_links = g_list_remove (monitor->details->volume_links, link);
 		g_object_unref (link);
 	}
+#else
+	refresh_volume_links (monitor);
+#endif
 }
 
 static void
@@ -322,32 +366,60 @@ desktop_network_visible_changed (gpointe
 }
 
 static void
-desktop_volumes_visible_changed (gpointer callback_data)
+refresh_volume_links (NautilusDesktopLinkMonitor *monitor)
 {
 	GnomeVFSVolumeMonitor *volume_monitor;
-	NautilusDesktopLinkMonitor *monitor;
-	GList *l, *volumes;
 	
 	volume_monitor = gnome_vfs_get_volume_monitor ();
-	monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data);
+
+	/* Free existing links */
+
+	g_list_foreach (monitor->details->volume_links, (GFunc)g_object_unref, NULL);
+	g_list_free (monitor->details->volume_links);
+	monitor->details->volume_links = NULL;
+
+	/* Scan the links again */
 
 	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) {
-		if (monitor->details->volume_links == NULL) {
-			volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
-			for (l = volumes; l != NULL; l = l->next) {
-				create_volume_link (monitor, l->data);
-				gnome_vfs_volume_unref (l->data);
-			}
-			g_list_free (volumes);
+		GList *l;
+		GList *volumes, *drives;
+
+		/* Unmounted drives */
+
+		drives = gnome_vfs_volume_monitor_get_connected_drives (volume_monitor);
+		for (l = drives; l != NULL; l = l->next) {
+			GnomeVFSDrive *drive;
+
+			drive = GNOME_VFS_DRIVE (l->data);
+			create_drive_link (monitor, drive);
+			gnome_vfs_drive_unref (drive);
 		}
-	} else {
-		g_list_foreach (monitor->details->volume_links, (GFunc)g_object_unref, NULL);
-		g_list_free (monitor->details->volume_links);
-		monitor->details->volume_links = NULL;
+		g_list_free (drives);
+
+		/* Volumes */
+
+		volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
+		for (l = volumes; l != NULL; l = l->next) {
+			GnomeVFSVolume *volume;
+
+			volume = GNOME_VFS_VOLUME (l->data);
+			create_volume_link (monitor, volume);
+			gnome_vfs_volume_unref (volume);
+		}
+		g_list_free (volumes);
 	}
 }
 
 static void
+desktop_volumes_visible_changed (gpointer callback_data)
+{
+	NautilusDesktopLinkMonitor *monitor;
+
+	monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data);
+	refresh_volume_links (monitor);
+}
+
+static void
 create_link_and_add_preference (NautilusDesktopLink   **link_ref,
 				NautilusDesktopLinkType link_type,
 				const char             *preference_key,
@@ -365,8 +437,6 @@ static void
 nautilus_desktop_link_monitor_init (gpointer object, gpointer klass)
 {
 	NautilusDesktopLinkMonitor *monitor;
-	GList *l, *volumes;
-	GnomeVFSVolume *volume;
 	GnomeVFSVolumeMonitor *volume_monitor;
 
 	monitor = NAUTILUS_DESKTOP_LINK_MONITOR (object);
@@ -404,22 +474,22 @@ nautilus_desktop_link_monitor_init (gpoi
 					desktop_network_visible_changed,
 					monitor);
 
-	/* Volume links */
+	/* Drives and volumes */
 
-	volume_monitor = gnome_vfs_get_volume_monitor ();
-	
-	volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
-	for (l = volumes; l != NULL; l = l->next) {
-		volume = l->data;
-		create_volume_link (monitor, volume);
-		gnome_vfs_volume_unref (volume);
-	}
-	g_list_free (volumes);
+	refresh_volume_links (monitor);
 
 	eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE,
 				      desktop_volumes_visible_changed,
 				      monitor);
 
+	volume_monitor = gnome_vfs_get_volume_monitor ();
+
+	monitor->details->connected_id = g_signal_connect_object (volume_monitor, "drive_connected",
+								  G_CALLBACK (drive_connect_disconnect_callback),
+								  monitor, 0);
+	monitor->details->disconnected_id = g_signal_connect_object (volume_monitor, "drive_connected",
+								     G_CALLBACK (drive_connect_disconnect_callback),
+								     monitor, 0);
 	monitor->details->mount_id = g_signal_connect_object (volume_monitor, "volume_mounted",
 							      G_CALLBACK (volume_mounted_callback), monitor, 0);
 	monitor->details->unmount_id = g_signal_connect_object (volume_monitor, "volume_unmounted",
Index: libnautilus-private/nautilus-desktop-link.c
===================================================================
RCS file: /cvsroot/novell/nautilus/libnautilus-private/nautilus-desktop-link.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -p -r1.1.1.1 -r1.2
--- libnautilus-private/nautilus-desktop-link.c	7 Apr 2006 20:12:27 -0000	1.1.1.1
+++ libnautilus-private/nautilus-desktop-link.c	11 Apr 2006 16:46:34 -0000	1.2
@@ -53,8 +53,8 @@ struct NautilusDesktopLinkDetails {
 	/* Just for trash icons: */
 	gulong trash_state_handler;
 
-	/* Just for volume icons: */
-	GnomeVFSVolume *volume;
+	/* Just for drive/volume icons */
+	GObject *drive_or_volume;
 };
 
 static void nautilus_desktop_link_init       (gpointer              object,
@@ -193,27 +193,53 @@ nautilus_desktop_link_new (NautilusDeskt
 }
 
 NautilusDesktopLink *
-nautilus_desktop_link_new_from_volume (GnomeVFSVolume *volume)
+nautilus_desktop_link_new_from_drive_or_volume (GObject *object)
 {
 	NautilusDesktopLink *link;
-	GnomeVFSDrive *drive;
 	char *name, *filename;
+	char *display_name, *activation_uri, *icon;
+	gboolean is_volume;
+
+	is_volume = GNOME_IS_VFS_VOLUME (object);
+
+	g_return_val_if_fail (GNOME_IS_VFS_DRIVE (object) || is_volume, NULL);
 
 	link = NAUTILUS_DESKTOP_LINK (g_object_new (NAUTILUS_TYPE_DESKTOP_LINK, NULL));
 	
 	link->details->type = NAUTILUS_DESKTOP_LINK_VOLUME;
 
-	link->details->volume = gnome_vfs_volume_ref (volume);
+	if (is_volume) {
+		GnomeVFSVolume *volume;
+		GnomeVFSDrive *drive;
+
+		volume = gnome_vfs_volume_ref (GNOME_VFS_VOLUME (object));
+		link->details->drive_or_volume = G_OBJECT (volume);
+
+		/* We try to use the drive name to get somewhat stable filenames
+		   for metadata */
+		drive = gnome_vfs_volume_get_drive (volume);
+		if (drive != NULL) {
+			name = gnome_vfs_drive_get_display_name (drive);
+		} else {
+			name = gnome_vfs_volume_get_display_name (volume);
+		}
+		gnome_vfs_drive_unref (drive);
 
-	/* We try to use the drive name to get somewhat stable filenames
-	   for metadata */
-	drive = gnome_vfs_volume_get_drive (volume);
-	if (drive != NULL) {
-		name = gnome_vfs_drive_get_display_name (drive);
+		display_name = gnome_vfs_volume_get_display_name (volume);
+		activation_uri = gnome_vfs_volume_get_activation_uri (volume);
+		icon = gnome_vfs_volume_get_icon (volume);
 	} else {
-		name = gnome_vfs_volume_get_display_name (volume);
+		GnomeVFSDrive *drive;
+
+		drive = gnome_vfs_drive_ref (GNOME_VFS_DRIVE (object));
+		link->details->drive_or_volume = G_OBJECT (drive);
+
+		name = gnome_vfs_drive_get_display_name (drive);
+
+		display_name = gnome_vfs_drive_get_display_name (drive);
+		activation_uri = NULL; /* We don't know the activation URI until the drive gets mounted */
+		icon = gnome_vfs_drive_get_icon (drive);
 	}
-	gnome_vfs_drive_unref (drive);
 
 	filename = g_strconcat (name, ".volume", NULL);
 	link->details->filename =
@@ -221,21 +247,23 @@ nautilus_desktop_link_new_from_volume (G
 								    filename);
 	g_free (filename);
 	g_free (name);
-	
-	link->details->display_name = gnome_vfs_volume_get_display_name (volume);
-	
-	link->details->activation_uri = gnome_vfs_volume_get_activation_uri (volume);
-	link->details->icon = gnome_vfs_volume_get_icon (volume);
+
+	link->details->display_name = display_name;
+	link->details->activation_uri = activation_uri;
+	link->details->icon = icon;
 
 	create_icon_file (link);
 
 	return link;
 }
 
-GnomeVFSVolume *
-nautilus_desktop_link_get_volume (NautilusDesktopLink *link)
+GObject *
+nautilus_desktop_link_get_drive_or_volume (NautilusDesktopLink *link)
 {
-	return gnome_vfs_volume_ref (link->details->volume);
+	if (GNOME_IS_VFS_VOLUME (link->details->drive_or_volume))
+		return G_OBJECT (gnome_vfs_volume_ref (GNOME_VFS_VOLUME (link->details->drive_or_volume)));
+	else
+		return G_OBJECT (gnome_vfs_drive_ref (GNOME_VFS_DRIVE (link->details->drive_or_volume)));
 }
 
 
@@ -389,7 +417,11 @@ desktop_link_finalize (GObject *object)
 	}
 
 	if (link->details->type == NAUTILUS_DESKTOP_LINK_VOLUME) {
-		gnome_vfs_volume_unref (link->details->volume);
+		if (GNOME_IS_VFS_VOLUME (link->details->drive_or_volume)) {
+			gnome_vfs_volume_unref (GNOME_VFS_VOLUME (link->details->drive_or_volume));
+		} else {
+			gnome_vfs_drive_unref (GNOME_VFS_DRIVE (link->details->drive_or_volume));
+		}
 	}
 
 	g_free (link->details->filename);
Index: libnautilus-private/nautilus-desktop-link.h
===================================================================
RCS file: /cvsroot/novell/nautilus/libnautilus-private/nautilus-desktop-link.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -p -r1.1.1.1 -r1.2
--- libnautilus-private/nautilus-desktop-link.h	7 Apr 2006 20:12:27 -0000	1.1.1.1
+++ libnautilus-private/nautilus-desktop-link.h	11 Apr 2006 16:46:34 -0000	1.2
@@ -26,6 +26,7 @@
 #define NAUTILUS_DESKTOP_LINK_H
 
 #include <libnautilus-private/nautilus-file.h>
+#include <libgnomevfs/gnome-vfs-drive.h>
 #include <libgnomevfs/gnome-vfs-volume.h>
 
 #define NAUTILUS_TYPE_DESKTOP_LINK \
@@ -61,7 +62,7 @@ typedef enum {
 GType   nautilus_desktop_link_get_type (void);
 
 NautilusDesktopLink *   nautilus_desktop_link_new                (NautilusDesktopLinkType  type);
-NautilusDesktopLink *   nautilus_desktop_link_new_from_volume    (GnomeVFSVolume          *volume);
+NautilusDesktopLink *   nautilus_desktop_link_new_from_drive_or_volume (GObject           *object);
 NautilusDesktopLinkType nautilus_desktop_link_get_link_type      (NautilusDesktopLink     *link);
 char *                  nautilus_desktop_link_get_file_name      (NautilusDesktopLink     *link);
 char *                  nautilus_desktop_link_get_display_name   (NautilusDesktopLink     *link);
@@ -70,7 +71,7 @@ char *                  nautilus_desktop
 gboolean                nautilus_desktop_link_get_date           (NautilusDesktopLink     *link,
 								  NautilusDateType         date_type,
 								  time_t                  *date);
-GnomeVFSVolume *        nautilus_desktop_link_get_volume         (NautilusDesktopLink     *link);
+GObject *               nautilus_desktop_link_get_drive_or_volume (NautilusDesktopLink     *link);
 
 gboolean                nautilus_desktop_link_can_rename         (NautilusDesktopLink     *link);
 gboolean                nautilus_desktop_link_rename             (NautilusDesktopLink     *link,
Index: src/nautilus-places-sidebar.c
===================================================================
RCS file: /cvsroot/novell/nautilus/src/nautilus-places-sidebar.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -p -r1.1.1.1 -r1.3
--- src/nautilus-places-sidebar.c	7 Apr 2006 20:12:28 -0000	1.1.1.1
+++ src/nautilus-places-sidebar.c	13 Apr 2006 03:50:35 -0000	1.3
@@ -28,6 +28,7 @@
 #include <eel/eel-glib-extensions.h>
 #include <eel/eel-preferences.h>
 #include <eel/eel-string.h>
+#include <eel/eel-stock-dialogs.h>
 #include <eel/eel-vfs-extensions.h>
 #include <gtk/gtkalignment.h>
 #include <gtk/gtkbutton.h>
@@ -46,6 +47,7 @@
 #include <libnautilus-private/nautilus-sidebar-provider.h>
 #include <libnautilus-private/nautilus-module.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
+#include <libnautilus-private/nautilus-search-engine.h>
 #include <libnautilus-private/nautilus-search-directory.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
 #include <libgnomevfs/gnome-vfs-volume-monitor.h>
@@ -82,6 +84,7 @@ typedef struct {
 enum {
 	PLACES_SIDEBAR_COLUMN_ROW_TYPE,
 	PLACES_SIDEBAR_COLUMN_URI,
+	PLACES_SIDEBAR_COLUMN_DRIVE,
 	PLACES_SIDEBAR_COLUMN_NAME,
 	PLACES_SIDEBAR_COLUMN_ICON,
 	
@@ -111,7 +114,8 @@ G_DEFINE_TYPE_WITH_CODE (NautilusPlacesS
 
 static GtkTreeIter
 add_place (GtkListStore *store, PlaceType place_type,
-	   const char *name, const char *icon, const char *uri)
+	   const char *name, const char *icon, const char *uri,
+	   GnomeVFSDrive *drive)
 {
 	GdkPixbuf            *pixbuf;
 	GtkTreeIter           iter;
@@ -122,6 +126,7 @@ add_place (GtkListStore *store, PlaceTyp
 			    PLACES_SIDEBAR_COLUMN_ICON, pixbuf,
 			    PLACES_SIDEBAR_COLUMN_NAME, name,
 			    PLACES_SIDEBAR_COLUMN_URI, uri,
+			    PLACES_SIDEBAR_COLUMN_DRIVE, drive,
 			    PLACES_SIDEBAR_COLUMN_ROW_TYPE, place_type,
 			    -1);
 	if (pixbuf != NULL) {
@@ -137,8 +142,10 @@ update_places (NautilusPlacesSidebar *si
 	GtkTreeSelection      *selection;
 	GtkTreeIter           iter, last_iter;
 	GnomeVFSVolumeMonitor *volume_monitor;
-	GList 		      *volumes, *l;
-	GnomeVFSVolume 	      *volume;
+	GList 		      *volumes, *l, *ll;
+	GnomeVFSVolume	      *volume;
+	GList		      *drives;
+	GnomeVFSDrive	      *drive;
 	int 		      bookmark_count, index;
 	char 		      *location, *icon, *mount_uri, *name, *desktop_path;
 		
@@ -149,7 +156,8 @@ update_places (NautilusPlacesSidebar *si
 	if (nautilus_search_engine_enabled ()) {
 		/* add search item */
 		last_iter = add_place (sidebar->store, PLACES_SEARCH,
-				       _("Search"), "gnome-searchtool", NULL);
+				       _("Search"), "gnome-searchtool", NULL,
+				       NULL);
 		/* add separator */
 
 		gtk_list_store_append (sidebar->store, &iter);
@@ -168,7 +176,8 @@ update_places (NautilusPlacesSidebar *si
 		mount_uri = gnome_vfs_get_uri_from_local_path (g_get_home_dir ());
 		display_name = g_filename_display_basename (g_get_home_dir ());
 		last_iter = add_place (sidebar->store, PLACES_BUILT_IN,
-				       display_name, "gnome-fs-home", mount_uri);
+				       display_name, "gnome-fs-home", mount_uri,
+				       NULL);
 		g_free (display_name);
 		if (strcmp (location, mount_uri) == 0) {
 			gtk_tree_selection_select_iter (selection, &last_iter);
@@ -178,7 +187,8 @@ update_places (NautilusPlacesSidebar *si
 
 	mount_uri = gnome_vfs_get_uri_from_local_path (desktop_path);
 	last_iter = add_place (sidebar->store, PLACES_BUILT_IN,
-			       _("Desktop"), "gnome-fs-desktop", mount_uri);
+			       _("Desktop"), "gnome-fs-desktop", mount_uri,
+			       NULL);
 	if (strcmp (location, mount_uri) == 0) {
 		gtk_tree_selection_select_iter (selection, &last_iter);
 	}	
@@ -187,25 +197,79 @@ update_places (NautilusPlacesSidebar *si
 	
  	mount_uri = "file:///"; /* No need to strdup */
 	last_iter = add_place (sidebar->store, PLACES_BUILT_IN,
-			       _("File System"), "gnome-dev-harddisk", mount_uri);
+			       _("File System"), "gnome-dev-harddisk", mount_uri,
+			       NULL);
 	if (strcmp (location, mount_uri) == 0) {
 		gtk_tree_selection_select_iter (selection, &last_iter);
 	}	
 
 	mount_uri = "network:///"; /* No need to strdup */
 	last_iter = add_place (sidebar->store, PLACES_BUILT_IN,
-			       _("Network Servers"), "gnome-fs-network", mount_uri);
+			       _("Network Servers"), "gnome-fs-network", mount_uri,
+			       NULL);
 	if (strcmp (location, mount_uri) == 0) {
 		gtk_tree_selection_select_iter (selection, &last_iter);
 	}
 
-	/* add mounted volumes */
+	/* for all drives add all its volumes */
 
 	volume_monitor = gnome_vfs_get_volume_monitor ();
+
+	drives = gnome_vfs_volume_monitor_get_connected_drives (volume_monitor);
+	drives = g_list_sort (drives, (GCompareFunc)gnome_vfs_drive_compare);
+	for (l = drives; l != NULL; l = l->next) {
+		drive = l->data;
+		if (!gnome_vfs_drive_is_user_visible (drive)) {
+			gnome_vfs_drive_unref (drive);
+			continue;
+		}
+		if (gnome_vfs_drive_is_mounted (drive)) {
+			/* The drive is mounted, add all its volumes */
+			volumes = gnome_vfs_drive_get_mounted_volumes (drive);
+			volumes = g_list_sort (volumes, (GCompareFunc)gnome_vfs_volume_compare);
+			for (ll = volumes; ll != NULL; ll = ll->next) {
+				volume = ll->data;
+				if (!gnome_vfs_volume_is_user_visible (volume)) {
+					gnome_vfs_volume_unref (volume);
+					continue;
+				}
+				icon = gnome_vfs_volume_get_icon (volume);
+				mount_uri = gnome_vfs_volume_get_activation_uri (volume);
+				name = gnome_vfs_volume_get_display_name (volume);
+				last_iter = add_place (sidebar->store, PLACES_MOUNTED_VOLUME,
+						       name, icon, mount_uri, drive);
+				if (strcmp (location, mount_uri) == 0) {
+					gtk_tree_selection_select_iter (selection, &last_iter);
+				}
+				gnome_vfs_volume_unref (volume);
+				g_free (icon);
+				g_free (name);
+				g_free (mount_uri);
+			}
+			g_list_free (volumes);
+		} else {
+			/* The drive is unmounted but visible, add it.
+			 * This is for drives like floppy that can't be
+			 * auto-mounted */
+			icon = gnome_vfs_drive_get_icon (drive);
+			name = gnome_vfs_drive_get_display_name (drive);
+			last_iter = add_place (sidebar->store, PLACES_BUILT_IN,
+					       name, icon, NULL, drive);
+			g_free (icon);
+			g_free (name);
+		}		
+		gnome_vfs_drive_unref (drive);
+	}
+	g_list_free (drives);
+
+	/* add mounted volumes that have no drive (ftp, sftp,...) */
+
 	volumes = gnome_vfs_volume_monitor_get_mounted_volumes (volume_monitor);
 	for (l = volumes; l != NULL; l = l->next) {
 		volume = l->data;
-		if (!gnome_vfs_volume_is_user_visible (volume)) {
+		drive = gnome_vfs_volume_get_drive (volume);
+		if (!gnome_vfs_volume_is_user_visible (volume) || drive != NULL) {
+		    	gnome_vfs_drive_unref (drive);
 			gnome_vfs_volume_unref (volume);
 			continue;
 		}
@@ -213,7 +277,8 @@ update_places (NautilusPlacesSidebar *si
 		mount_uri = gnome_vfs_volume_get_activation_uri (volume);
 		name = gnome_vfs_volume_get_display_name (volume);
 		last_iter = add_place (sidebar->store, PLACES_MOUNTED_VOLUME,
-				       name, icon, mount_uri);
+				       name, icon, mount_uri,
+				       NULL);
 		if (strcmp (location, mount_uri) == 0) {
 			gtk_tree_selection_select_iter (selection, &last_iter);
 		}
@@ -247,7 +312,7 @@ update_places (NautilusPlacesSidebar *si
 		icon = nautilus_bookmark_get_icon (bookmark);
 		mount_uri = nautilus_bookmark_get_uri (bookmark);
 		last_iter = add_place (sidebar->store, PLACES_BOOKMARK,
-				       name, icon, mount_uri);
+				       name, icon, mount_uri, NULL);
 		if (strcmp (location, mount_uri) == 0) {
 			gtk_tree_selection_select_iter (selection, &last_iter);
 		}
@@ -294,6 +359,23 @@ volume_unmounted_callback (GnomeVFSVolum
 }
 
 static void
+mount_volume_callback (gboolean succeeded,
+		       char *error,
+		       char *detailed_error,
+		       gpointer user_data)
+{
+	if (!succeeded) {
+		if (*error == 0 &&
+		    detailed_error != NULL && *detailed_error == 0) {
+			/* This means the mount command displays its own errors */
+			return;
+		}
+		eel_show_error_dialog_with_details (error, NULL, _("Mount failed"),
+						    detailed_error, NULL);
+	}
+}
+
+static void
 row_activated_callback (GtkTreeView *tree_view,
 			GtkTreePath *path,
 			GtkTreeViewColumn *column,
@@ -329,6 +411,14 @@ row_activated_callback (GtkTreeView *tre
 			(sidebar->window, 
 			 uri, NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE, 0, NULL);
 		g_free (uri);
+	} else {
+		GnomeVFSDrive *drive;
+		gtk_tree_model_get 
+			(model, &iter, PLACES_SIDEBAR_COLUMN_DRIVE, &drive, -1);
+		if (drive != NULL) {
+			gnome_vfs_drive_mount (drive, mount_volume_callback, sidebar);
+			gnome_vfs_drive_unref (drive);
+		}
 	}
 }
 
@@ -443,6 +533,7 @@ nautilus_places_sidebar_init (NautilusPl
 	sidebar->store = gtk_list_store_new (PLACES_SIDEBAR_COLUMN_COUNT,
 					     G_TYPE_INT, 
 					     G_TYPE_STRING,
+					     GNOME_VFS_TYPE_DRIVE,
 					     G_TYPE_STRING,
 					     GDK_TYPE_PIXBUF
 					     );
openSUSE Build Service is sponsored by