Re: Trash directory on removable media - Bug 138058



On 1/27/07, Jesse Stockall <jesse cleverone org> wrote:
Summary: Deleted files on removable media remain in the ~/$USER-trash
directory after the device is unmounted.


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;
+       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,
+
GnomeVFSVolumeOpCallback callback,
+
gpointer user_data);
+
#endif /* NAUTILUS_FILE_OPERATIONS_H */



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