On 1/27/07, Jesse Stockall <[EMAIL PROTECTED]> wrote: > Summary: Deleted files on removable media remain in the ~/$USER-trash > directory after the device is unmounted. > > http://bugzilla.gnome.org/show_bug.cgi?id=138058 >
New patch that fixes the missing parts from the first attempt. It should probably also have a way to be disabled vis GConf. http://bugzilla.gnome.org/attachment.cgi?id=81733&action=view Jesse diff -ur nautilus-2.16.3-orig/src/file-manager/fm-directory-view.c nautilus-2.16.3/src/file-manager/fm-directory-view.c --- nautilus-2.16.3-orig/src/file-manager/fm-directory-view.c 2006-10-31 03:25:05.000000000 -0500 +++ nautilus-2.16.3/src/file-manager/fm-directory-view.c 2007-02-01 22:33:34.000000000 -0500 @@ -6328,12 +6328,14 @@ 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); + nautilus_file_operations_unmount_volume (GTK_WIDGET (view), 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); + nautilus_file_operations_unmount_drive (GTK_WIDGET (view), drive, + volume_or_drive_unmounted_callback, NULL); } } } @@ -6439,9 +6441,11 @@ file_get_volume_and_drive (file, &volume, &drive); if (volume != NULL) { - gnome_vfs_volume_unmount (volume, volume_or_drive_unmounted_callback, NULL); + nautilus_file_operations_unmount_volume (GTK_WIDGET (view), volume, + volume_or_drive_unmounted_callback, NULL); } else if (drive != NULL) { - gnome_vfs_drive_unmount (drive, volume_or_drive_unmounted_callback, NULL); + nautilus_file_operations_unmount_drive (GTK_WIDGET (view), drive, + volume_or_drive_unmounted_callback, NULL); } gnome_vfs_volume_unref (volume); diff -ur nautilus-2.16.3-orig/src/file-manager/fm-tree-view.c nautilus-2.16.3/src/file-manager/fm-tree-view.c --- nautilus-2.16.3-orig/src/file-manager/fm-tree-view.c 2006-08-07 06:34:31.000000000 -0400 +++ nautilus-2.16.3/src/file-manager/fm-tree-view.c 2007-01-27 23:17:13.000000000 -0500 @@ -1085,7 +1085,8 @@ if (eject_for_type (gnome_vfs_volume_get_device_type (volume))) { gnome_vfs_volume_eject (volume, volume_or_drive_unmounted_callback, GINT_TO_POINTER (TRUE)); } else { - gnome_vfs_volume_unmount (volume, volume_or_drive_unmounted_callback, GINT_TO_POINTER (FALSE)); + nautilus_file_operations_unmount_volume (GTK_WIDGET (view), volume, + volume_or_drive_unmounted_callback, GINT_TO_POINTER (FALSE)); } } } diff -ur nautilus-2.16.3-orig/src/nautilus-places-sidebar.c nautilus-2.16.3/src/nautilus-places-sidebar.c --- nautilus-2.16.3-orig/src/nautilus-places-sidebar.c 2006-09-14 04:24:30.000000000 -0400 +++ nautilus-2.16.3/src/nautilus-places-sidebar.c 2007-02-01 22:08:05.000000000 -0500 @@ -1264,9 +1264,11 @@ -1); if (volume != NULL) { - gnome_vfs_volume_unmount (volume, volume_op_callback, sidebar); + nautilus_file_operations_unmount_volume (GTK_WIDGET (sidebar->tree_view), + volume, volume_op_callback, sidebar); } else if (drive != NULL) { - gnome_vfs_drive_unmount (drive, volume_op_callback, sidebar); + nautilus_file_operations_unmount_drive (GTK_WIDGET (sidebar->tree_view), + drive, volume_op_callback, sidebar); } gnome_vfs_volume_unref (volume); gnome_vfs_drive_unref (drive); diff -ur nautilus-2.16.3-orig/libnautilus-private/nautilus-file-operations.c nautilus-2.16.3/libnautilus-private/nautilus-file-operations.c --- nautilus-2.16.3-orig/libnautilus-private/nautilus-file-operations.c 2006-11-06 07:21:46.000000000 -0500 +++ nautilus-2.16.3/libnautilus-private/nautilus-file-operations.c 2007-02-01 22:46:46.000000000 -0500 @@ -2898,6 +2898,248 @@ } } +gchar* +get_trash_uri_for_volume(GnomeVFSVolume *volume) +{ + gchar *uri = 0; + if (gnome_vfs_volume_handles_trash(volume)) { + GnomeVFSURI *trash_uri; + GnomeVFSURI *vol_uri; + gchar *vol_uri_str; + + vol_uri_str = gnome_vfs_volume_get_activation_uri (volume); + vol_uri = gnome_vfs_uri_new (vol_uri_str); + g_free (vol_uri_str); + + if (gnome_vfs_find_directory (vol_uri, + GNOME_VFS_DIRECTORY_KIND_TRASH, + &trash_uri, FALSE, TRUE, 0777) == GNOME_VFS_OK) + { + uri = gnome_vfs_uri_to_string (trash_uri, 0); + gnome_vfs_uri_unref (vol_uri); + gnome_vfs_uri_unref (trash_uri); + } + } + return uri; +} + +gint +num_entries_in_dir (gchar *dir_uri) +{ + gint num_entries = 0; + if (dir_uri) { + GList *entries; + GList *it; + if (gnome_vfs_directory_list_load (&entries, dir_uri, + GNOME_VFS_FILE_INFO_DEFAULT) == GNOME_VFS_OK) + { + num_entries = g_list_length (entries); + } + for (it = entries; it != NULL; it = g_list_next(it)) { + gchar *tmp = it->data; + g_free (tmp); + } + g_list_free (entries); + } + return num_entries; +} + +typedef struct { + gpointer volume; + GnomeVFSVolumeOpCallback callback; + gpointer user_data; +} NautilusUnmountCallback; + +static void +delete_callback (GnomeVFSAsyncHandle *handle, + GnomeVFSXferProgressInfo *info, + gpointer data) +{ + if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) { + NautilusUnmountCallback *unmount_info = data; + if (GNOME_IS_VFS_VOLUME(unmount_info->volume)) { + gnome_vfs_volume_unmount (unmount_info->volume, + unmount_info->callback, + unmount_info->user_data); + } else if (GNOME_IS_VFS_DRIVE(unmount_info->volume)) { + gnome_vfs_drive_unmount (unmount_info->volume, + unmount_info->callback, + unmount_info->user_data); + } + g_free (unmount_info); + } +} + +gint +prompt_empty_trash (GtkWidget *parent_view) +{ + gint result; - Show quoted text - + GtkWidget *dialog; + GdkScreen *screen; + + screen = gtk_widget_get_screen (parent_view); + + /* Do we need to be modal ? */ + dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, + _("Do you want to empty the trash before you umount?"), NULL); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("In order to regain the " + "free space on this device " + "the trash must be emptied. " + "All items in the trash " + "will be permanently lost. ")); + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + _("Don't Empty Trash"), GTK_RESPONSE_REJECT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("Empty Trash"), GTK_RESPONSE_ACCEPT, NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); + gtk_window_set_title (GTK_WINDOW (dialog), ""); /* as per HIG */ + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); + gtk_window_set_screen (GTK_WINDOW (dialog), screen); + atk_object_set_role (gtk_widget_get_accessible (dialog), ATK_ROLE_ALERT); + gtk_window_set_wmclass (GTK_WINDOW (dialog), "empty_trash", + "Nautilus"); + + /* Make transient for the window group */ + gtk_widget_realize (dialog); + gdk_window_set_transient_for (GTK_WIDGET (dialog)->window, + gdk_screen_get_root_window (screen)); + + result = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + return result; +} + +void +nautilus_file_operations_unmount_volume (GtkWidget *parent_view, + GnomeVFSVolume *volume, + GnomeVFSVolumeOpCallback callback, + gpointer user_data) +{ + g_return_if_fail (parent_view != NULL); + + gchar *trash_uri_str; + trash_uri_str = get_trash_uri_for_volume (volume); + /* It's faster to just check for the existence of the trash directory + * but that would prompt the user to delete an emtpy trash directory + * so check if there is anything other than . and .. in it. */ + if (num_entries_in_dir (trash_uri_str) > 2) { + switch (prompt_empty_trash(parent_view)) { + case GTK_RESPONSE_ACCEPT: + { + GList *trash_dir_list = NULL; + GnomeVFSURI *trash_uri; + GnomeVFSAsyncHandle *vfshandle; + NautilusUnmountCallback *unmount_cb; + + unmount_cb = g_new (NautilusUnmountCallback, 1); + unmount_cb->volume = volume; + unmount_cb->callback = callback; + unmount_cb->user_data = user_data; + trash_uri = gnome_vfs_uri_new (trash_uri_str); + trash_dir_list = g_list_append (trash_dir_list, trash_uri); + gnome_vfs_async_xfer (&vfshandle, trash_dir_list, NULL, + GNOME_VFS_XFER_DELETE_ITEMS | GNOME_VFS_XFER_RECURSIVE, + GNOME_VFS_XFER_ERROR_MODE_ABORT, + GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, + GNOME_VFS_PRIORITY_DEFAULT, + (GnomeVFSAsyncXferProgressCallback) delete_callback, + unmount_cb, NULL, NULL); + + gnome_vfs_uri_list_free (trash_dir_list); + /* volume is unmounted in the callback */ + break; + } + case GTK_RESPONSE_REJECT: + gnome_vfs_volume_unmount (volume, callback, user_data); + break; + default: + break; + } + } else { + /* no trash so unmount as usual */ + gnome_vfs_volume_unmount (volume, callback, user_data); + } + g_free (trash_uri_str); +} + +void +nautilus_file_operations_unmount_drive (GtkWidget *parent_view, + GnomeVFSDrive *drive, + GnomeVFSVolumeOpCallback callback, + gpointer user_data) +{ + g_return_if_fail (parent_view != NULL); + + GList *volumes; + GList *it; + GList *trash_dir_uris = NULL; + gboolean trash_is_empty = TRUE; + + volumes = gnome_vfs_drive_get_mounted_volumes (drive); + for (it = volumes; it != NULL; it = g_list_next(it)) { + GnomeVFSVolume *vol = it->data; + gchar *trash_uri_str = get_trash_uri_for_volume (vol); + trash_dir_uris = g_list_prepend (trash_dir_uris, trash_uri_str); + /* It's faster to just check for the existence of the trash directory + * but that would prompt the user to delete an emtpy trash directory + * so check if there is anything other than . and .. in it. */ + if (trash_is_empty && num_entries_in_dir (trash_uri_str) > 2) + trash_is_empty = FALSE; + + gnome_vfs_volume_unref (vol); + } + + if (trash_is_empty) { + /* no trash so unmount as usual */ + gnome_vfs_drive_unmount (drive, callback, user_data); + } else { + switch (prompt_empty_trash(parent_view)) { + case GTK_RESPONSE_ACCEPT: + { + GList *trash_dir_list = NULL; + GnomeVFSURI *trash_uri; + GnomeVFSAsyncHandle *vfshandle; + NautilusUnmountCallback *unmount_cb; + + unmount_cb = g_new (NautilusUnmountCallback, 1); + unmount_cb->volume = drive; + unmount_cb->callback = callback; + unmount_cb->user_data = user_data; + for (it = trash_dir_uris; it != NULL; it = g_list_next(it)) { + gchar *uri = it->data; + trash_dir_list = g_list_prepend (trash_dir_list, gnome_vfs_uri_new(uri)); + } + trash_dir_list = g_list_reverse (trash_dir_list); + + gnome_vfs_async_xfer (&vfshandle, trash_dir_list, NULL, + GNOME_VFS_XFER_DELETE_ITEMS | GNOME_VFS_XFER_RECURSIVE, + GNOME_VFS_XFER_ERROR_MODE_ABORT, + GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, + GNOME_VFS_PRIORITY_DEFAULT, + (GnomeVFSAsyncXferProgressCallback) delete_callback, + unmount_cb, NULL, NULL); + + for (it = trash_dir_uris; it != NULL; it = g_list_next(it)) { + gchar *tmp = it->data; + g_free (tmp); + } + g_list_free (trash_dir_uris); + gnome_vfs_uri_list_free (trash_dir_list); + + /* volume is unmounted in the callback */ + break; + } + case GTK_RESPONSE_REJECT: + gnome_vfs_drive_unmount (drive, callback, user_data); + break; + default: + break; + } + } +} + struct RecursivePermissionsInfo { GnomeVFSAsyncHandle *handle; GnomeVFSURI *current_dir; diff -ur nautilus-2.16.3-orig/libnautilus-private/nautilus-file-operations.h nautilus-2.16.3/libnautilus-private/nautilus-file-operations.h --- nautilus-2.16.3-orig/libnautilus-private/nautilus-file-operations.h 2006-10-02 06:46:28.000000000 -0400 +++ nautilus-2.16.3/libnautilus-private/nautilus-file-operations.h 2007-02-01 22:47:23.000000000 -0500 @@ -30,6 +30,8 @@ #include <gdk/gdkdnd.h> #include <gtk/gtkwidget.h> #include <libgnomevfs/gnome-vfs-types.h> +#include <libgnomevfs/gnome-vfs-utils.h> +#include <libgnomevfs/gnome-vfs-volume-monitor.h> typedef void (* NautilusCopyCallback) (GHashTable *debuting_uris, gpointer callback_data); @@ -79,4 +81,14 @@ NautilusSetPermissionsCallback callback, gpointer callback_data); +void nautilus_file_operations_unmount_volume (GtkWidget *parent_view, + GnomeVFSVolume *volume, + GnomeVFSVolumeOpCallback callback, + gpointer user_data); + +void nautilus_file_operations_unmount_drive (GtkWidget *parent_view, + GnomeVFSDrive *drive, + -- nautilus-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/nautilus-list
