Re: [PATCH] Allow to mount/unmount volume from within target URI
- From: Christian Neumair <chris gnome-de org>
- To: Alexander Larsson <alexl redhat com>
- Cc: nautilus-list <nautilus-list gnome org>
- Subject: Re: [PATCH] Allow to mount/unmount volume from within target URI
- Date: Tue, 14 Feb 2006 15:39:24 +0100
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]