gedit r6427 - in trunk: . plugins/filebrowser



Author: jessevdk
Date: Tue Aug 19 13:00:18 2008
New Revision: 6427
URL: http://svn.gnome.org/viewvc/gedit?rev=6427&view=rev

Log:
	* plugins/filebrowser/gedit-file-bookmarks-store.[ch]:
	* plugins/filebrowser/gedit-file-browser-widget.c:
	
	Bug 548223 â Filemanager panel doesn't show gio mounts
	Drive/Volume/Mount handling is now approximately the same as in 
	the GtkFileChooser and in nautilus


Modified:
   trunk/ChangeLog
   trunk/plugins/filebrowser/gedit-file-bookmarks-store.c
   trunk/plugins/filebrowser/gedit-file-bookmarks-store.h
   trunk/plugins/filebrowser/gedit-file-browser-widget.c

Modified: trunk/plugins/filebrowser/gedit-file-bookmarks-store.c
==============================================================================
--- trunk/plugins/filebrowser/gedit-file-bookmarks-store.c	(original)
+++ trunk/plugins/filebrowser/gedit-file-bookmarks-store.c	Tue Aug 19 13:00:18 2008
@@ -41,12 +41,10 @@
 static void remove_node               (GtkTreeModel * model, 
                                        GtkTreeIter * iter);
 
-static void on_mount_added            (GVolumeMonitor * monitor,
-                                       GMount * mount,
-                                       GeditFileBookmarksStore * model);
-static void on_mount_removed          (GVolumeMonitor * monitor,
-                                       GMount * mount,
-                                       GeditFileBookmarksStore * model);
+static void on_fs_changed             (GVolumeMonitor 		*monitor,
+                                       GObject 			*object,
+                                       GeditFileBookmarksStore 	*model);
+                                       
 static void on_bookmarks_file_changed (GFileMonitor * monitor,
 				       GFile * file,
 				       GFile * other_file,
@@ -67,11 +65,9 @@
 
 	if (obj->priv->volume_monitor != NULL) {
 		g_signal_handlers_disconnect_by_func (obj->priv->volume_monitor,
-						      on_mount_added,
-						      obj);
-		g_signal_handlers_disconnect_by_func (obj->priv->volume_monitor,
-						      on_mount_removed,
+						      on_fs_changed,
 						      obj);
+
 		g_object_unref (obj->priv->volume_monitor);
 	}
 
@@ -107,8 +103,12 @@
 
 /* Private */
 static void
-add_node (GeditFileBookmarksStore * model, GdkPixbuf * pixbuf,
-	  gchar const *name, gpointer obj, guint flags, GtkTreeIter * iter)
+add_node (GeditFileBookmarksStore *model, 
+	  GdkPixbuf 		  *pixbuf,
+	  const gchar 		  *name, 
+	  GObject 		  *obj, 
+	  guint 		   flags, 
+	  GtkTreeIter 		  *iter)
 {
 	GtkTreeIter newiter;
 
@@ -126,12 +126,15 @@
 }
 
 static gboolean
-add_file (GeditFileBookmarksStore * model, GFile * file,
-	  gchar const * name, guint flags, GtkTreeIter * iter)
+add_file (GeditFileBookmarksStore *model, 
+	  GFile 		  *file,
+	  const gchar 		  *name, 
+	  guint 		   flags, 
+	  GtkTreeIter 		  *iter)
 {
-	GdkPixbuf * pixbuf = NULL;
+	GdkPixbuf *pixbuf = NULL;
 	gboolean native;
-	gchar * newname;
+	gchar *newname;
 
 	native = g_file_is_native (file);
 
@@ -156,7 +159,7 @@
 		newname = g_strdup (name);
 	}
 
-	add_node (model, pixbuf, newname, file, flags, iter);
+	add_node (model, pixbuf, newname, G_OBJECT (file), flags, iter);
 
 	if (pixbuf)
 		g_object_unref (pixbuf);
@@ -229,93 +232,229 @@
 }
 
 static void
-add_mount (GeditFileBookmarksStore * model, GMount * mount,
-	   const gchar * name, guint flags, GtkTreeIter * iter)
-{
-	GdkPixbuf *pixbuf = NULL;
-	GIcon *icon;
-
-	icon = g_mount_get_icon (mount);
+get_fs_properties (gpointer    fs,
+		   gchar     **name,
+		   GdkPixbuf **pixbuf,
+		   guint      *flags)
+{
+	GIcon *icon = NULL;
+
+	*flags = GEDIT_FILE_BOOKMARKS_STORE_IS_FS;
+	*name = NULL;
+	*pixbuf = NULL;
 	
-	if (icon) {
-		pixbuf = gedit_file_browser_utils_pixbuf_from_icon (icon, GTK_ICON_SIZE_MENU);
+	if (G_IS_DRIVE (fs))
+	{
+		icon = g_drive_get_icon (G_DRIVE (fs));
+		*name = g_drive_get_name (G_DRIVE (fs));
+		
+		*flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_DRIVE;
+	}
+	else if (G_IS_VOLUME (fs))
+	{
+		icon = g_volume_get_icon (G_VOLUME (fs));
+		*name = g_volume_get_name (G_VOLUME (fs));
+	
+		*flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_VOLUME;
+	}
+	else if (G_IS_MOUNT (fs))
+	{
+		icon = g_mount_get_icon (G_MOUNT (fs));
+		*name = g_mount_get_name (G_MOUNT (fs));
+		
+		*flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT;
+	}
+	
+	if (icon)
+	{
+		*pixbuf = gedit_file_browser_utils_pixbuf_from_icon (icon, GTK_ICON_SIZE_MENU);
 		g_object_unref (icon);
 	}
+}
+		   
 
-	add_node (model, pixbuf, name, mount,
-		  flags | GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT, iter);
-
+static void
+add_fs (GeditFileBookmarksStore *model,
+	gpointer 		 fs,
+	guint 			 flags,
+	GtkTreeIter		*iter)
+{
+	gchar *name;
+	GdkPixbuf *pixbuf;
+	guint fsflags;
+	
+	get_fs_properties (fs, &name, &pixbuf, &fsflags);
+	add_node (model, pixbuf, name, fs, flags | fsflags, iter);
+	
 	if (pixbuf)
 		g_object_unref (pixbuf);
 
-	check_mount_separator (model, GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT, TRUE);
+	g_free (name);
+	check_mount_separator (model, GEDIT_FILE_BOOKMARKS_STORE_IS_FS, TRUE);
 }
 
 static void
-process_mount (GeditFileBookmarksStore * model, GMount * mount,
-		gboolean * isroot)
+process_volume_cb (GVolume 		   *volume,
+		   GeditFileBookmarksStore *model)
 {
+	GMount *mount;
 	guint flags = GEDIT_FILE_BOOKMARKS_STORE_NONE;
-	GFile * root;
-	GFileInfo * info;
-	gchar * name;
-	gboolean local;
-
-	root = g_mount_get_root (mount);
+	mount = g_volume_get_mount (volume);
 	
-	if (!root)
-		return;
+	/* CHECK: should we use the LOCAL/REMOTE thing still? */
+	if (mount)
+	{
+		/* Show mounted volume */
+		add_fs (model, mount, flags, NULL);
+		g_object_unref (mount);
+	}
+	else if (g_volume_can_mount (volume))
+	{
+		/* We also show the unmounted volume here so users can
+		   mount it if they want to access it */
+		add_fs (model, volume, flags, NULL);
+	}
+}
 
-	info = g_file_query_info (root, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, G_FILE_QUERY_INFO_NONE, NULL, NULL);
+static void
+process_drive_novolumes (GeditFileBookmarksStore *model,
+			 GDrive			 *drive)
+{
+	if (g_drive_is_media_removable (drive) &&
+	   !g_drive_is_media_check_automatic (drive) &&
+	    g_drive_can_poll_for_media (drive))
+	{
+		/* This can be the case for floppy drives or other 
+		   drives where media detection fails. We show the
+		   drive and poll for media when the user activates
+		   it */
+		add_fs (model, drive, GEDIT_FILE_BOOKMARKS_STORE_NONE, NULL);
+	}
+}
 
-	/* Is this mount actually readable by the user */
-	if (info && g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) {
-		/* Here we set up the flags for the mount */
-		local = g_file_is_native (root);
-		
-		if (local) {
-			flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_LOCAL_MOUNT;
-		} else {
-			flags |= GEDIT_FILE_BOOKMARKS_STORE_IS_REMOTE_MOUNT;
-		}
+static void
+process_drive_cb (GDrive   	          *drive,
+	          GeditFileBookmarksStore *model)
+{
+	GList *volumes;
+
+	volumes = g_drive_get_volumes (drive);
+
+	if (volumes)
+	{
+		/* Add all volumes for the drive */
+		g_list_foreach (volumes, (GFunc)process_volume_cb, model);
+		g_list_free (volumes);
+	}
+	else
+	{
+		process_drive_novolumes (model, drive);
+	}	
+}
+
+static void
+init_drives (GeditFileBookmarksStore *model)
+{
+	GList *drives;
 		
-		name = g_mount_get_name (mount);
-		add_mount (model, mount, name, flags, NULL);
-		g_free (name);
+	drives = g_volume_monitor_get_connected_drives (model->priv->volume_monitor);
+
+	g_list_foreach (drives, (GFunc)process_drive_cb, model);
+	g_list_foreach (drives, (GFunc)g_object_unref, NULL);
+	g_list_free (drives);
+}
+
+static void
+process_volume_nodrive_cb (GVolume 		   *volume,
+			   GeditFileBookmarksStore *model)
+{
+	GDrive *drive;
+	
+	drive = g_volume_get_drive (volume);
+	
+	if (drive)
+	{
+		g_object_unref (drive);
+		return;
 	}
 	
-	if (info)
-		g_object_unref (info);
+	process_volume_cb (volume, model);
+}
+
+static void
+init_volumes (GeditFileBookmarksStore *model)
+{
+	GList *volumes;
+		
+	volumes = g_volume_monitor_get_volumes (model->priv->volume_monitor);
 	
-	g_object_unref (root);
+	g_list_foreach (volumes, (GFunc)process_volume_nodrive_cb, model);
+	g_list_foreach (volumes, (GFunc)g_object_unref, NULL);
+	g_list_free (volumes);
 }
 
 static void
-init_mounts (GeditFileBookmarksStore * model)
+process_mount_novolume_cb (GMount 		   *mount,
+			   GeditFileBookmarksStore *model)
 {
-	GList * mounts;
-	GList * item;
-	gboolean root = FALSE;
+	GVolume *volume;
+	
+	volume = g_mount_get_volume (mount);
+	
+	if (volume)
+	{
+		g_object_unref (volume);
+	}
+	else
+	{
+		/* Add the mount */
+		add_fs (model, mount, GEDIT_FILE_BOOKMARKS_STORE_NONE, NULL);
+	}
+}
+
+static void
+init_mounts (GeditFileBookmarksStore *model)
+{
+	GList *mounts;
+		
+	mounts = g_volume_monitor_get_mounts (model->priv->volume_monitor);
+	
+	g_list_foreach (mounts, (GFunc)process_mount_novolume_cb, model);
+	g_list_foreach (mounts, (GFunc)g_object_unref, NULL);
+	g_list_free (mounts);
+}
 
+static void
+init_fs (GeditFileBookmarksStore * model)
+{
 	if (model->priv->volume_monitor == NULL) {
+		const gchar **ptr;
+		const gchar *signals[] = {
+			"drive-connected", "drive-changed", "drive-disconnected",
+			"volume-added", "volume-removed", "volume-changed",
+			"mount-added", "mount-removed", "mount-changed",
+			NULL
+		};
+		
 		model->priv->volume_monitor = g_volume_monitor_get ();
 
-		/* Connect signals */
-		g_signal_connect (model->priv->volume_monitor,
-				  "mount-added",
-				  G_CALLBACK (on_mount_added), model);
-		g_signal_connect (model->priv->volume_monitor,
-				  "mount-removed",
-				  G_CALLBACK (on_mount_removed), model);
+		/* Connect signals */		
+		for (ptr = signals; *ptr; ptr++)
+		{
+			g_signal_connect (model->priv->volume_monitor,
+					  *ptr,
+					  G_CALLBACK (on_fs_changed), model);
+		}
 	}
 
-	mounts = g_volume_monitor_get_mounts (model->priv->volume_monitor);
-
-	for (item = mounts; item; item = item->next)
-		process_mount (model, G_MOUNT(item->data), &root);
-
-	g_list_foreach (mounts, (GFunc)g_object_unref, NULL);
-	g_list_free (mounts);
+	/* First go through all the connected drives */
+	init_drives (model);
+	
+	/* Then add all volumes, not associated with a drive */
+	init_volumes (model);
+	
+	/* Then finally add all mounts that have no volume */
+	init_mounts (model);
 }
 
 static gboolean
@@ -446,8 +585,7 @@
 	GEDIT_FILE_BOOKMARKS_STORE_IS_DESKTOP,
 	GEDIT_FILE_BOOKMARKS_STORE_IS_SPECIAL_DIR,
 	GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT,
-	GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT,
-	GEDIT_FILE_BOOKMARKS_STORE_IS_LOCAL_MOUNT,
+	GEDIT_FILE_BOOKMARKS_STORE_IS_FS,
 	GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK,
 	-1
 };
@@ -595,9 +733,9 @@
 			    -1);
 
 	if (!(flags & GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR)) {
-		if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT) {
+		if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_FS) {
 			check_mount_separator (GEDIT_FILE_BOOKMARKS_STORE (model),
-			     		       flags & GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT,
+			     		       flags & GEDIT_FILE_BOOKMARKS_STORE_IS_FS,
 					       FALSE);
 		}
 	}
@@ -621,7 +759,7 @@
 initialize_fill (GeditFileBookmarksStore * model)
 {
 	init_special_directories (model);
-	init_mounts (model);
+	init_fs (model);
 	init_bookmarks (model);
 }
 
@@ -662,6 +800,7 @@
 	GFile * file = NULL;
 	guint flags;
 	gchar * ret = NULL;
+	gboolean isfs;
 	
 	g_return_val_if_fail (GEDIT_IS_FILE_BOOKMARKS_STORE (model), NULL);
 	g_return_val_if_fail (iter != NULL, NULL);
@@ -669,21 +808,28 @@
 	gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
 			    GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS,
 			    &flags,
-			    GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, &obj,
+			    GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT, 
+			    &obj,
 			    -1);
 
 	if (obj == NULL)
 		return NULL;
 
-	if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT) {
+	isfs = (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_FS);
+	
+	if (isfs && (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT))
+	{
 		file = g_mount_get_root (G_MOUNT (obj));
-	} else {
+	}
+	else if (!isfs)
+	{
 		file = g_object_ref (obj);
 	}
 	
 	g_object_unref (obj);
 	
-	if (file) {
+	if (file)
+	{
 		ret = g_file_get_uri (file);
 		g_object_unref (file);
 	}
@@ -698,27 +844,22 @@
 	initialize_fill (model);
 }
 
-/* Signal handlers */
 static void
-on_mount_added (GVolumeMonitor * monitor,
-		GMount * mount,
-		GeditFileBookmarksStore * model)
-{
-	process_mount (model, mount, NULL);
-}
-
-static void
-on_mount_removed (GVolumeMonitor * monitor,
-		  GMount * mount,
-		  GeditFileBookmarksStore * model)
-{
+on_fs_changed (GVolumeMonitor 	      *monitor,
+	       GObject 		      *object,
+	       GeditFileBookmarksStore *model)
+{
+	GtkTreeModel *tree_model = GTK_TREE_MODEL (model);
+	guint flags = GEDIT_FILE_BOOKMARKS_STORE_IS_FS;
+	guint noflags = GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR;
 	GtkTreeIter iter;
 
-	/* Find the mount and remove it */
-	if (find_with_flags (GTK_TREE_MODEL (model), &iter, mount,
-			     GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT,
-			     GEDIT_FILE_BOOKMARKS_STORE_IS_SEPARATOR))
-		remove_node (GTK_TREE_MODEL (model), &iter);
+	/* clear all fs items */
+	while (find_with_flags (tree_model, &iter, NULL, flags, noflags))
+		remove_node (tree_model, &iter);
+	
+	/* then reinitialize */
+	init_fs (model);
 }
 
 static void

Modified: trunk/plugins/filebrowser/gedit-file-bookmarks-store.h
==============================================================================
--- trunk/plugins/filebrowser/gedit-file-bookmarks-store.h	(original)
+++ trunk/plugins/filebrowser/gedit-file-bookmarks-store.h	Tue Aug 19 13:00:18 2008
@@ -54,13 +54,14 @@
 	GEDIT_FILE_BOOKMARKS_STORE_IS_HOME         	= 1 << 2,  /* The special Home user directory */
 	GEDIT_FILE_BOOKMARKS_STORE_IS_DESKTOP      	= 1 << 3,  /* The special Desktop user directory */
 	GEDIT_FILE_BOOKMARKS_STORE_IS_DOCUMENTS    	= 1 << 4,  /* The special Documents user directory */
-	GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT        	= 1 << 5,  /* A mount point on file:// */
-	GEDIT_FILE_BOOKMARKS_STORE_IS_REMOTE_MOUNT 	= 1 << 6,  /* A remote mount point (ssh://) */
-	GEDIT_FILE_BOOKMARKS_STORE_IS_LOCAL_MOUNT 	= 1 << 7,  /* A remote mount point (ssh://) */
-	GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT         	= 1 << 8,  /* The root file system (file:///) */
-	GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK     	= 1 << 9,  /* A gtk bookmark */
-	GEDIT_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK	= 1 << 10, /* A remote gtk bookmark */
-	GEDIT_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK	= 1 << 11  /* A local gtk bookmark */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_FS        	= 1 << 5,  /* A mount object */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT        	= 1 << 6,  /* A mount object */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_VOLUME        	= 1 << 7,  /* A volume object */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_DRIVE        	= 1 << 8,  /* A drive object */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_ROOT         	= 1 << 9,  /* The root file system (file:///) */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_BOOKMARK     	= 1 << 10,  /* A gtk bookmark */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_REMOTE_BOOKMARK	= 1 << 11, /* A remote gtk bookmark */
+	GEDIT_FILE_BOOKMARKS_STORE_IS_LOCAL_BOOKMARK	= 1 << 12  /* A local gtk bookmark */
 };
 
 struct _GeditFileBookmarksStore 

Modified: trunk/plugins/filebrowser/gedit-file-browser-widget.c
==============================================================================
--- trunk/plugins/filebrowser/gedit-file-browser-widget.c	(original)
+++ trunk/plugins/filebrowser/gedit-file-browser-widget.c	Tue Aug 19 13:00:18 2008
@@ -147,6 +147,8 @@
 	GtkWidget *current_location_menu_item;
 	
 	gboolean enable_delete;
+	
+	GCancellable *cancellable;
 };
 
 static void set_enable_delete		       (GeditFileBrowserWidget *obj,
@@ -185,7 +187,7 @@
 static gboolean on_entry_filter_activate       (GeditFileBrowserWidget * obj);
 static void on_location_jump_activate          (GtkMenuItem * item,
 						GeditFileBrowserWidget * obj);
-static void on_bookmarks_row_inserted          (GtkTreeModel * model, 
+static void on_bookmarks_row_changed           (GtkTreeModel * model, 
                                                 GtkTreePath * path,
                                                 GtkTreeIter * iter,
                                                 GeditFileBrowserWidget * obj);
@@ -302,6 +304,18 @@
 }
 
 static void
+cancel_async_operation (GeditFileBrowserWidget *widget)
+{
+	if (!widget->priv->cancellable)
+		return;
+	
+	g_cancellable_cancel (widget->priv->cancellable);
+	g_object_unref (widget->priv->cancellable);
+
+	widget->priv->cancellable = NULL;
+}
+
+static void
 gedit_file_browser_widget_finalize (GObject * object)
 {
 	GeditFileBrowserWidget *obj = GEDIT_FILE_BROWSER_WIDGET (object);
@@ -328,6 +342,8 @@
 	g_list_free (obj->priv->locations);
 
 	g_hash_table_destroy (obj->priv->bookmarks_hash);
+	
+	cancel_async_operation (obj);
 	G_OBJECT_CLASS (gedit_file_browser_widget_parent_class)->finalize (object);
 }
 
@@ -1013,7 +1029,7 @@
 	uri = gedit_file_bookmarks_store_get_uri (obj->priv->
 						  bookmarks_store,
 						  iter);
-	
+
 	if (uri == NULL)
 		return;
 	
@@ -1051,8 +1067,8 @@
 	} while (gtk_tree_model_iter_next (model, &iter));
 	
 	g_signal_connect (obj->priv->bookmarks_store,
-		          "row-inserted",
-		          G_CALLBACK (on_bookmarks_row_inserted),
+		          "row-changed",
+		          G_CALLBACK (on_bookmarks_row_changed),
 		          obj);
 
 	g_signal_connect (obj->priv->bookmarks_store,
@@ -1898,6 +1914,278 @@
 	return result;
 }
 
+typedef struct
+{
+	GeditFileBrowserWidget *widget;
+	GCancellable *cancellable;
+} AsyncData;
+
+static AsyncData *
+async_data_new (GeditFileBrowserWidget *widget)
+{
+	AsyncData *ret;
+	
+	ret = g_new (AsyncData, 1);
+	ret->widget = widget;
+	
+	cancel_async_operation (widget);
+	widget->priv->cancellable = g_cancellable_new ();
+	
+	ret->cancellable = g_object_ref (widget->priv->cancellable);
+	
+	return ret;
+}
+
+static void
+async_free (AsyncData *async)
+{
+	g_object_unref (async->cancellable);
+	g_free (async);
+}
+
+static void
+set_busy (GeditFileBrowserWidget *obj, gboolean busy)
+{
+	GdkCursor *cursor;
+	GdkWindow *window;
+	
+	window = GTK_WIDGET (obj->priv->treeview)->window;
+	
+	if (!GDK_IS_WINDOW (window))
+		return;
+
+	if (busy)
+	{
+		cursor = gdk_cursor_new (GDK_WATCH);
+		gdk_window_set_cursor (window, cursor);
+		gdk_cursor_unref (cursor);
+	}
+	else
+	{
+		gdk_window_set_cursor (window, NULL);
+	}
+}
+
+static void try_mount_volume (GeditFileBrowserWidget *widget, GVolume *volume);
+
+static void
+activate_mount (GeditFileBrowserWidget *widget,
+		GVolume		       *volume,
+		GMount		       *mount)
+{
+	GFile *root;
+	gchar *uri;
+	
+	if (!mount)
+	{
+		gchar *message;
+		gchar *name;
+		
+		name = g_volume_get_name (volume);
+		message = g_strdup_printf (_("No mount object for mounted volume: %s"), name);
+		
+		g_signal_emit (widget, 
+			       signals[ERROR], 
+			       0, 
+			       GEDIT_FILE_BROWSER_ERROR_SET_ROOT,
+			       message);
+		
+		g_free (name);
+		g_free (message);
+		return;
+	}
+	
+	root = g_mount_get_root (mount);
+	uri = g_file_get_uri (root);
+	
+	gedit_file_browser_widget_set_root (widget, uri, FALSE);
+	
+	g_free (uri);
+	g_object_unref (root);
+}
+
+static void
+try_activate_drive (GeditFileBrowserWidget *widget,
+		    GDrive 		   *drive)
+{
+	GList *volumes;
+	GVolume *volume;
+	GMount *mount;
+	
+	volumes = g_drive_get_volumes (drive);
+	
+	volume = G_VOLUME (volumes->data);
+	mount = g_volume_get_mount (volume);
+	
+	if (mount)
+	{
+		/* try set the root of the mount */
+		activate_mount (widget, volume, mount);
+		g_object_unref (mount);
+	}
+	else
+	{
+		/* try to mount it then? */
+		try_mount_volume (widget, volume);
+	}
+	
+	g_list_foreach (volumes, (GFunc)g_object_unref, NULL);
+	g_list_free (volumes);
+}
+
+static void
+poll_for_media_cb (GDrive       *drive,
+		   GAsyncResult *res,
+		   AsyncData 	*async)
+{
+	GError *error = NULL;
+
+	/* check for cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_free (async);
+		return;
+	}
+	
+	/* finish poll operation */
+	set_busy (async->widget, FALSE);
+	
+	if (g_drive_poll_for_media_finish (drive, res, &error) && 
+	    g_drive_has_media (drive) &&
+	    g_drive_has_volumes (drive))
+	{
+		try_activate_drive (async->widget, drive);
+	}
+	else
+	{
+		gchar *message;
+		gchar *name;
+		
+		name = g_drive_get_name (drive);
+		message = g_strdup_printf (_("Could not open media: %s"), name);
+
+		g_signal_emit (async->widget, 
+			       signals[ERROR], 
+			       0, 
+			       GEDIT_FILE_BROWSER_ERROR_SET_ROOT,
+			       message);
+
+		g_free (name);
+		g_free (message);
+		
+		g_error_free (error);
+	}
+	
+	async_free (async);
+}
+
+static void
+mount_volume_cb (GVolume      *volume,
+		 GAsyncResult *res,
+		 AsyncData    *async)
+{
+	GError *error = NULL;
+
+	/* check for cancelled state */
+	if (g_cancellable_is_cancelled (async->cancellable))
+	{
+		async_free (async);
+		return;
+	}
+	
+	if (g_volume_mount_finish (volume, res, &error))
+	{
+		GMount *mount;
+		
+		mount = g_volume_get_mount (volume);
+		activate_mount (async->widget, volume, mount);
+		
+		if (mount)
+			g_object_unref (mount);
+	}
+	else
+	{
+		gchar *message;
+		gchar *name;
+		
+		name = g_volume_get_name (volume);
+		message = g_strdup_printf (_("Could not mount volume: %s"), name);
+
+		g_signal_emit (async->widget, 
+			       signals[ERROR], 
+			       0, 
+			       GEDIT_FILE_BROWSER_ERROR_SET_ROOT,
+			       message);
+
+		g_free (name);
+		g_free (message);
+		
+		g_error_free (error);
+	}
+	
+	set_busy (async->widget, FALSE);
+	async_free (async);
+}
+
+static void
+activate_drive (GeditFileBrowserWidget *obj,
+		GtkTreeIter	       *iter)
+{
+	GDrive *drive;
+	AsyncData *async;
+
+	gtk_tree_model_get (GTK_TREE_MODEL (obj->priv->bookmarks_store), iter,
+			    GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT,
+			    &drive, -1);
+
+	/* most common use case is a floppy drive, we'll poll for media and
+	   go from there */
+	async = async_data_new (obj);
+	g_drive_poll_for_media (drive, 
+				async->cancellable, 
+				(GAsyncReadyCallback)poll_for_media_cb,
+				async);
+
+	g_object_unref (drive);
+	set_busy (obj, TRUE);
+}
+
+static void 
+try_mount_volume (GeditFileBrowserWidget *widget, 
+		  GVolume 		 *volume)
+{
+	GMountOperation *operation;
+	AsyncData *async;
+
+	operation = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget))));
+	async = async_data_new (widget);
+	
+	g_volume_mount (volume,
+			G_MOUNT_MOUNT_NONE,
+			operation,
+			async->cancellable,
+			(GAsyncReadyCallback)mount_volume_cb,
+			async);
+			
+	g_object_unref (operation);
+	set_busy (widget, TRUE);
+}
+
+static void
+activate_volume (GeditFileBrowserWidget *obj,
+		 GtkTreeIter	        *iter)
+{
+	GVolume *volume;
+	
+	gtk_tree_model_get (GTK_TREE_MODEL (obj->priv->bookmarks_store), iter,
+			    GEDIT_FILE_BOOKMARKS_STORE_COLUMN_OBJECT,
+			    &volume, -1);
+
+	/* see if we can mount the volume */
+	try_mount_volume (obj, volume);	
+	g_object_unref (volume);
+}
+
 /* Callbacks */
 static void
 on_bookmark_activated (GeditFileBrowserView   *tree_view,
@@ -1907,14 +2195,28 @@
 	GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
 	gchar *uri;
 	gint flags;
+
+	gtk_tree_model_get (model, iter,
+			    GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS,
+			    &flags, -1);
 	
+	if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_DRIVE)
+	{
+		/* handle a drive node */
+		activate_drive (obj, iter);
+		return;
+	}
+	else if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_VOLUME)
+	{
+		/* handle a volume node */
+		activate_volume (obj, iter);
+		return;
+	}
+
 	uri =
 	    gedit_file_bookmarks_store_get_uri
 	    (GEDIT_FILE_BOOKMARKS_STORE (model), iter);
 
-	gtk_tree_model_get (model, iter,
-			    GEDIT_FILE_BOOKMARKS_STORE_COLUMN_FLAGS,
-			    &flags, -1);
 
 	if (uri) {
 		if (flags & GEDIT_FILE_BOOKMARKS_STORE_IS_MOUNT) {
@@ -2113,6 +2415,9 @@
 					      G_CALLBACK
 					      (on_bookmark_activated), obj));
 	} else if (GEDIT_IS_FILE_BROWSER_STORE (model)) {
+		/* make sure any async operation is cancelled */
+		cancel_async_operation (obj);
+
 		add_signal (obj, gobject,
 			    g_signal_connect (gobject, "file-activated",
 					      G_CALLBACK
@@ -2348,10 +2653,10 @@
 }
 
 static void
-on_bookmarks_row_inserted (GtkTreeModel * model, 
-                           GtkTreePath * path,
-                           GtkTreeIter * iter,
-                           GeditFileBrowserWidget *obj)
+on_bookmarks_row_changed (GtkTreeModel * model, 
+                          GtkTreePath * path,
+                          GtkTreeIter * iter,
+                          GeditFileBrowserWidget *obj)
 {
 	add_bookmark_hash (obj, iter);
 }



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