Re: Trash directory on removable media - Bug 138058
- From: "Jesse Stockall" <jesse cleverone org>
- To: nautilus-list gnome org
- Subject: Re: Trash directory on removable media - Bug 138058
- Date: Fri, 2 Feb 2007 07:32:18 -0500
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.
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,
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]