Re: [PATCH] Allow to mount/unmount volume from within target URI



On Tue, 2006-02-14 at 15:36 +0100, Christian Neumair wrote:
> On Mon, 2006-02-13 at 10:25 +0100, Alexander Larsson wrote:
> > On Fri, 2006-02-10 at 22:43 +0100, Christian Neumair wrote:
> > > On Tue, 2006-02-07 at 11:38 +0100, Alexander Larsson wrote:
> > > > On Sun, 2006-02-05 at 14:11 +0100, Christian Neumair wrote:
> > > > > The attached patch is meant to allow the user to modify a volume from
> > > > > within its target directory. It's not very well-tested. For instance,
> > > > > I'm not sure whether not setting the volume in
> > > > > libnautilus-private/nautilus-directory-async.c:link_info_done if the
> > > > > volume_id is NULL causes some problems when unmounting a volume.
> > > > 
> > > > The general approach of having the link-to-volume object set the status
> > > > of the destination is wrong. It means the destination will work
> > > > differently depending on if the link to it is shown.
> > > 
> > > Here we go. This one adds a new volume monitor which only deals with the
> > > target URIs, and adds context menu entries to the file menu, the
> > > background and the location context menu, and also reorders the
> > > selection-related mount/unmount items to be above "Properties" for
> > > consistency reasons. It extremely improves my Nautilus experience and I
> > > really think it's worth to breaking a few freezes.
> > 
> > I don't like this patch, it always keeps all mountpoints always open,
> > which might lead to problems with unmounts, and it totally changes what
> > nautilus_file_has_volume/drive() means (it used to mean "this file
> > represents a volume, but now its also used for normal folders). 
> > 
> > I also think we don't need anything as complicated as a separate
> > monitor, since all it does is proxy information from the vfs monitor.
> > The only thing you need is to map from folder uri to what drive/monitor
> > is mounted there, and this info is availible using
> > GnomeVFSVolumeMonitor. Ideally there would be an API for it, but you can
> > just get all the volumes and look for it manually. This is not really a
> > performance problem, because there are not typically many volumes/drives
> > active, the objects are all in-memory, and this check is done seldom
> > (i.e. not for every file when loading a folder).
> 
> I hope you prefer this one.
> 
> I have no clue why I'm experiencing refcount issues. I initially thought
> it'd be my fault but even when adding multiple gnome_vfs_volume_ref and
> gnome_vfs_drive_ref calls, I had crashers. The volume monitor getters
> seem to dup the internal lists and ref each drive/volume, so I think I
> got the refcount right.
> 
> I also wonder whether strcmping the volume/drive and the file in
> question's URIs is OK instead of using helpers. Can we really expect
> GnomeVFS to provide valid URIs, taken that it just uses URIs stored in
> GConf?
> 
> During my debugging sessions I also discovered that
> _gnome_vfs_volume_monitor_disconnect_all and
> _gnome_vfs_volume_monitor_unmount_all don't free the list returned from
> gnome_vfs_volume_monitor_get_mounted_volumes.

This time with a patch.

-- 
Christian Neumair <chris gnome-de org>
Index: src/file-manager/fm-actions.h
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-actions.h,v
retrieving revision 1.10
diff -u -p -r1.10 fm-actions.h
--- src/file-manager/fm-actions.h	12 Dec 2005 16:59:11 -0000	1.10
+++ src/file-manager/fm-actions.h	14 Feb 2006 14:25:09 -0000
@@ -60,6 +60,10 @@
 #define FM_ACTION_UNMOUNT_VOLUME "Unmount Volume"
 #define FM_ACTION_EJECT_VOLUME "Eject Volume"
 #define FM_ACTION_FORMAT_VOLUME "Format Volume"
+#define FM_ACTION_SELF_MOUNT_VOLUME "Self Mount Volume"
+#define FM_ACTION_SELF_UNMOUNT_VOLUME "Self Unmount Volume"
+#define FM_ACTION_SELF_EJECT_VOLUME "Self Eject Volume"
+#define FM_ACTION_SELF_FORMAT_VOLUME "Self Format Volume"
 #define FM_ACTION_SCRIPTS "Scripts"
 #define FM_ACTION_NEW_DOCUMENTS "New Documents"
 #define FM_ACTION_NEW_EMPTY_FILE "New Empty 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.734
diff -u -p -r1.734 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	26 Jan 2006 22:20:59 -0000	1.734
+++ src/file-manager/fm-directory-view.c	14 Feb 2006 14:25:15 -0000
@@ -75,6 +75,7 @@
 #include <libgnomevfs/gnome-vfs-result.h>
 #include <libgnomevfs/gnome-vfs-uri.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-volume-monitor.h>
 #include <libnautilus-private/nautilus-recent.h>
 #include <libnautilus-extension/nautilus-menu-provider.h>
 #include <libnautilus-private/nautilus-clipboard-monitor.h>
@@ -385,6 +386,9 @@ 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);
@@ -6286,6 +6290,111 @@ action_eject_volume_callback (GtkAction 
 }
 
 static void
+action_self_mount_volume_callback (GtkAction *action,
+				   gpointer data)
+{
+	NautilusFile *file;
+	GnomeVFSDrive *drive;
+	FMDirectoryView *view;
+
+	view = FM_DIRECTORY_VIEW (data);
+
+	file = fm_directory_view_get_directory_as_file (view);
+	if (file == NULL) {
+		return;
+	}
+
+	file_get_volume_and_drive (file, NULL, &drive);
+
+	if (drive != NULL) {
+		gnome_vfs_drive_mount (drive, drive_mounted_callback, NULL);
+	}
+
+	gnome_vfs_drive_unref (drive);
+}
+
+static void
+action_self_unmount_volume_callback (GtkAction *action,
+				     gpointer data)
+{
+	NautilusFile *file;
+	GnomeVFSVolume *volume;
+	GnomeVFSDrive *drive;
+	FMDirectoryView *view;
+
+	view = FM_DIRECTORY_VIEW (data);
+
+	file = fm_directory_view_get_directory_as_file (view);
+	if (file == NULL) {
+		return;
+	}
+
+	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);
+}
+
+static void
+action_self_eject_volume_callback (GtkAction *action,
+				   gpointer data)
+{
+	NautilusFile *file;
+	GnomeVFSDrive *drive;
+	GnomeVFSVolume *volume;
+	FMDirectoryView *view;
+
+	view = FM_DIRECTORY_VIEW (data);
+
+	file = fm_directory_view_get_directory_as_file (view);
+	if (file == NULL) {
+		return;
+	}
+
+	file_get_volume_and_drive (file, &volume, &drive);
+
+	if (volume != NULL) {
+		gnome_vfs_volume_eject (volume, volume_or_drive_unmounted_callback, NULL);
+	} else if (drive != NULL) {
+		gnome_vfs_drive_eject (drive, volume_or_drive_unmounted_callback, NULL);
+	}
+
+	gnome_vfs_volume_unref (volume);
+	gnome_vfs_drive_unref (drive);
+}
+
+static void 
+action_self_format_volume_callback (GtkAction *action,
+				    gpointer   data)
+{
+	NautilusFile *file;
+	GnomeVFSDrive *drive;
+	FMDirectoryView *view;
+
+	view = FM_DIRECTORY_VIEW (data);
+
+	file = fm_directory_view_get_directory_as_file (view);
+	if (file == NULL) {
+		return;
+	}
+
+	file_get_volume_and_drive (file, NULL, &drive);
+
+	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);
+}
+
+static void
 connect_to_server_response_callback (GtkDialog *dialog,
 				     int response_id,
 				     gpointer data)
@@ -6682,6 +6791,22 @@ static const GtkActionEntry directory_vi
     N_("_Format"), NULL,                /* label, accelerator */
     N_("Format the selected volume"),                   /* tooltip */ 
     G_CALLBACK (action_format_volume_callback) },
+  { "Self Mount Volume", NULL,                  /* name, stock id */
+    N_("_Mount Volume"), NULL,                /* label, accelerator */
+    N_("Mount the volume associated with the open folder"),                   /* tooltip */ 
+    G_CALLBACK (action_self_mount_volume_callback) },
+  { "Self Unmount Volume", NULL,                  /* name, stock id */
+    N_("_Unmount Volume"), NULL,                /* label, accelerator */
+    N_("Unmount the volume associated with the open folder"),                   /* tooltip */ 
+    G_CALLBACK (action_self_unmount_volume_callback) },
+  { "Self Eject Volume", NULL,                  /* name, stock id */
+    N_("_Eject"), NULL,                /* label, accelerator */
+    N_("Eject the volume associated with the open folder"),                   /* tooltip */ 
+    G_CALLBACK (action_self_eject_volume_callback) },
+  { "Self Format Volume", NULL,                  /* name, stock id */
+    N_("_Format"), NULL,                /* label, accelerator */
+    N_("Format the volume associated with the open folder"),                   /* tooltip */ 
+    G_CALLBACK (action_self_format_volume_callback) },
   { "OpenCloseParent", NULL,                  /* name, stock id */
     N_("Open File and Close window"), "<alt><shift>Down",                /* label, accelerator */
     NULL,                   /* tooltip */ 
@@ -7015,6 +7140,108 @@ file_should_show_foreach (NautilusFile *
 }
 
 static void
+file_get_volume_and_drive (NautilusFile    *file,
+			   GnomeVFSVolume **volume,
+			   GnomeVFSDrive  **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; l = l->next) {
+			*volume = l->data;
+
+			one_uri = gnome_vfs_volume_get_activation_uri (*volume);
+			if (one_uri != NULL && (strcmp (uri, one_uri) == 0)) {
+				g_free (one_uri);
+				*volume = gnome_vfs_volume_ref (*volume);
+				break;
+			}
+
+			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) {
+			*drive = l->data;
+
+			one_uri = gnome_vfs_drive_get_activation_uri (*drive);
+			if (one_uri != NULL && (strcmp (uri, one_uri) == 0)) {
+				g_free (one_uri);
+				*drive = gnome_vfs_drive_ref (*drive);
+				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 &&
+		    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,
 			   gint selection_count)
@@ -7026,6 +7253,10 @@ real_update_menus_volumes (FMDirectoryVi
 	gboolean show_eject;
 	gboolean show_connect;
 	gboolean show_format;
+	gboolean show_self_mount;
+	gboolean show_self_unmount;
+	gboolean show_self_eject;
+	gboolean show_self_format;
 	GtkAction *action;
 
 	show_mount = (selection != NULL);
@@ -7084,6 +7315,31 @@ real_update_menus_volumes (FMDirectoryVi
 	action = gtk_action_group_get_action (view->details->dir_action_group,
 					      FM_ACTION_FORMAT_VOLUME);
 	gtk_action_set_visible (action, show_format);
+
+	show_self_mount = show_self_unmount = show_self_eject = show_self_format = FALSE;
+
+	file = fm_directory_view_get_directory_as_file (view);
+	file_should_show_self (file,
+			       &show_self_mount,
+			       &show_self_unmount,
+			       &show_self_eject,
+			       &show_self_format);
+
+	action = gtk_action_group_get_action (view->details->dir_action_group,
+					      FM_ACTION_SELF_MOUNT_VOLUME);
+	gtk_action_set_visible (action, show_self_mount);
+
+	action = gtk_action_group_get_action (view->details->dir_action_group,
+					      FM_ACTION_SELF_UNMOUNT_VOLUME);
+	gtk_action_set_visible (action, show_self_unmount);
+
+	action = gtk_action_group_get_action (view->details->dir_action_group,
+					      FM_ACTION_SELF_EJECT_VOLUME);
+	gtk_action_set_visible (action, show_self_eject);
+
+	action = gtk_action_group_get_action (view->details->dir_action_group,
+					      FM_ACTION_SELF_FORMAT_VOLUME);
+	gtk_action_set_visible (action, show_self_format);
 }
 
 static void
Index: src/file-manager/fm-tree-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-tree-view.c,v
retrieving revision 1.23
diff -u -p -r1.23 fm-tree-view.c
--- src/file-manager/fm-tree-view.c	16 Jan 2006 23:48:20 -0000	1.23
+++ src/file-manager/fm-tree-view.c	14 Feb 2006 14:25:16 -0000
@@ -1189,30 +1189,30 @@ create_popup_menu (FMTreeView *view)
 	separator_item = gtk_separator_menu_item_new ();
 	gtk_widget_show (separator_item);
 	gtk_menu_shell_append (GTK_MENU_SHELL (popup), separator_item);
-	
-	/* add the "properties" menu item */
-	menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_PROPERTIES, NULL);
+
+	/* add the "Unmount" menu item */
+	menu_item = gtk_image_menu_item_new_with_label ("eject label");
 	g_signal_connect (menu_item, "activate",
-			  G_CALLBACK (fm_tree_view_properties_cb),
+			  G_CALLBACK (fm_tree_view_unmount_cb),
 			  view);
 	gtk_widget_show (menu_item);
 	gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item);
-	view->details->popup_properties = menu_item;
+	view->details->popup_unmount = menu_item;
 
 	/* add the unmount separator menu item */
 	menu_item = gtk_separator_menu_item_new ();
 	gtk_widget_show (menu_item);
 	gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item);
 	view->details->popup_unmount_separator = menu_item;
-	
-	/* add the "Unmount" menu item */
-	menu_item = gtk_image_menu_item_new_with_label ("eject label");
+
+	/* add the "properties" menu item */
+	menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_PROPERTIES, NULL);
 	g_signal_connect (menu_item, "activate",
-			  G_CALLBACK (fm_tree_view_unmount_cb),
+			  G_CALLBACK (fm_tree_view_properties_cb),
 			  view);
 	gtk_widget_show (menu_item);
 	gtk_menu_shell_append (GTK_MENU_SHELL (popup), menu_item);
-	view->details->popup_unmount = menu_item;
+	view->details->popup_properties = menu_item;
 
 	view->details->popup = popup;
 }
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.79
diff -u -p -r1.79 nautilus-directory-view-ui.xml
--- src/file-manager/nautilus-directory-view-ui.xml	12 Dec 2005 16:59:11 -0000	1.79
+++ src/file-manager/nautilus-directory-view-ui.xml	14 Feb 2006 14:25:16 -0000
@@ -35,6 +35,11 @@
 			</menu>
 		</placeholder>
 		<placeholder name="File Items Placeholder">
+			<menuitem name="Self Mount Volume" action="Self Mount Volume"/>
+			<menuitem name="Self Unmount Volume" action="Self Unmount Volume"/>
+			<menuitem name="Self Eject Volume" action="Self Eject Volume"/>
+			<menuitem name="Self Format Volume" action="Self Format Volume"/>
+			<separator name="Properties Separator"/>
 			<menuitem name="Properties" action="Properties"/>
 		</placeholder>
 		<placeholder name="Global File Items Placeholder">
@@ -95,8 +100,14 @@
 			<menuitem name="Paste" action="Paste"/>
 		</placeholder>
 	</placeholder>
+
 	<separator name="Folder Items separator"/>
 	<placeholder name="Folder Items Placeholder">
+		<menuitem name="Self Mount Volume" action="Self Mount Volume"/>
+		<menuitem name="Self Unmount Volume" action="Self Unmount Volume"/>
+		<menuitem name="Self Eject Volume" action="Self Eject Volume"/>
+		<menuitem name="Self Format Volume" action="Self Format Volume"/>
+		<separator name="Properties separator"/>
 		<menuitem name="SelfProperties" action="SelfProperties"/>
 	</placeholder>
 
@@ -142,16 +153,16 @@
 	</placeholder>
 	<separator name="Extension actions separator"/>
 	<placeholder name="Extension Actions"/>
-        <separator name="Properties separator"/>
-        <menuitem name="Properties" action="Properties"/>
 	<separator name="Removable separator"/>
-        <placeholder name="Removable Media Placeholder">
-		<menuitem name="Mount Volume" action="Mount Volume"/>
-                <menuitem name="Unmount Volume" action="Unmount Volume"/>
-                <menuitem name="Eject Volume" action="Eject Volume"/>
-                <menuitem name="Format Volume" action="Format Volume"/>
+	<placeholder name="Removable Media Placeholder">
+		 <menuitem name="Mount Volume" action="Mount Volume"/>
+		 <menuitem name="Unmount Volume" action="Unmount Volume"/>
+		 <menuitem name="Eject Volume" action="Eject Volume"/>
+		 <menuitem name="Format Volume" action="Format Volume"/>
         </placeholder>
         <menuitem name="Connect To Server Link" action="Connect To Server Link"/>
+        <separator name="Properties Separator"/>
+        <menuitem name="Properties" action="Properties"/>
 </popup>
 <popup name="location">
 	<placeholder name="Open Placeholder">
@@ -168,6 +179,12 @@
 		<menuitem name="Delete" action="LocationDelete"/>
 	</placeholder>
 	<separator/>
+
+	<menuitem name="Self Mount Volume" action="Self Mount Volume"/>
+	<menuitem name="Self Unmount Volume" action="Self Unmount Volume"/>
+	<menuitem name="Self Eject Volume" action="Self Eject Volume"/>
+	<menuitem name="Self Format Volume" action="Self Format Volume"/>
+	<separator name="Properties Separator"/>
 	<menuitem name="Properties" action="SelfProperties"/>
 </popup>
 </ui>


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