summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2007-10-25 14:41:56 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-10-25 14:41:56 +0000
commit915cb724446b273ec66ad11ed5aec89fc7d0c35d (patch)
treefb798683d641adfcd24e4c36f672a1da7a44bdf9
parentc09fc543a767f3e96cee66f696cd2330bd3ad35f (diff)
downloadnautilus-915cb724446b273ec66ad11ed5aec89fc7d0c35d.tar.gz
Rename some file change queue functions to _by_uri add GFile based version
2007-10-25 Alexander Larsson <alexl@redhat.com> * libnautilus-private/nautilus-file-changes-queue.[ch]: * libnautilus-private/nautilus-monitor.c: Rename some file change queue functions to _by_uri add GFile based version with the original name * libnautilus-private/nautilus-file-operations.[ch]: Add gio based nautilus_file_operations_trash_or_delete() call. * src/file-manager/fm-directory-view.c: Call nautilus_file_operations_trash_or_delete() Remove unused code svn path=/branches/gio-branch/; revision=13372
-rw-r--r--ChangeLog14
-rw-r--r--TODO-gio4
-rw-r--r--libnautilus-private/nautilus-file-changes-queue.c36
-rw-r--r--libnautilus-private/nautilus-file-changes-queue.h36
-rw-r--r--libnautilus-private/nautilus-file-operations.c462
-rw-r--r--libnautilus-private/nautilus-file-operations.h12
-rw-r--r--libnautilus-private/nautilus-monitor.c4
-rw-r--r--src/file-manager/fm-directory-view.c275
8 files changed, 579 insertions, 264 deletions
diff --git a/ChangeLog b/ChangeLog
index a9f6ac68c..b82ef4aa7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2007-10-25 Alexander Larsson <alexl@redhat.com>
+ * libnautilus-private/nautilus-file-changes-queue.[ch]:
+ * libnautilus-private/nautilus-monitor.c:
+ Rename some file change queue functions to _by_uri
+ add GFile based version with the original name
+
+ * libnautilus-private/nautilus-file-operations.[ch]:
+ Add gio based nautilus_file_operations_trash_or_delete() call.
+
+ * src/file-manager/fm-directory-view.c:
+ Call nautilus_file_operations_trash_or_delete()
+ Remove unused code
+
+2007-10-25 Alexander Larsson <alexl@redhat.com>
+
* src/file-manager/fm-directory-view.[ch]:
Make file activation handle mounting of mountables and non-mounted
locations. Also general cleanup of activation.
diff --git a/TODO-gio b/TODO-gio
index 0ceb55c1e..929945066 100644
--- a/TODO-gio
+++ b/TODO-gio
@@ -3,6 +3,10 @@ Monitor for UNMOUNT file change event and close window
Break out file activation from fm-directory-view.c
File actication cancellation not implemented yet
+convert delete to use trash_or_delete code
+recursive deletes
+progress for trash/delete
+
Automount location when loading it in a window and its not mounted.
"translate" gnome-vfs errors and update error handling
diff --git a/libnautilus-private/nautilus-file-changes-queue.c b/libnautilus-private/nautilus-file-changes-queue.c
index 0d7d7287c..bff9b9ed7 100644
--- a/libnautilus-private/nautilus-file-changes-queue.c
+++ b/libnautilus-private/nautilus-file-changes-queue.c
@@ -167,7 +167,7 @@ nautilus_file_changes_queue_file_changed (const char *uri)
}
void
-nautilus_file_changes_queue_file_removed (const char *uri)
+nautilus_file_changes_queue_file_removed_by_uri (const char *uri)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@@ -181,6 +181,20 @@ nautilus_file_changes_queue_file_removed (const char *uri)
}
void
+nautilus_file_changes_queue_file_removed (GFile *location)
+{
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
+
+ queue = nautilus_file_changes_queue_get();
+
+ new_item = g_new0 (NautilusFileChange, 1);
+ new_item->kind = CHANGE_FILE_REMOVED;
+ new_item->from_uri = g_file_get_uri (location);
+ nautilus_file_changes_queue_add_common (queue, new_item);
+}
+
+void
nautilus_file_changes_queue_file_moved (const char *from, const char *to)
{
NautilusFileChange *new_item;
@@ -197,7 +211,7 @@ nautilus_file_changes_queue_file_moved (const char *from, const char *to)
void
nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
- const char *to_uri)
+ const char *to_uri)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@@ -213,7 +227,7 @@ nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
void
nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
- const char *to_uri)
+ const char *to_uri)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@@ -228,7 +242,7 @@ nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
}
void
-nautilus_file_changes_queue_schedule_metadata_remove (const char *uri)
+nautilus_file_changes_queue_schedule_metadata_remove_by_uri (const char *uri)
{
NautilusFileChange *new_item;
NautilusFileChangesQueue *queue;
@@ -242,6 +256,20 @@ nautilus_file_changes_queue_schedule_metadata_remove (const char *uri)
}
void
+nautilus_file_changes_queue_schedule_metadata_remove (GFile *location)
+{
+ NautilusFileChange *new_item;
+ NautilusFileChangesQueue *queue;
+
+ queue = nautilus_file_changes_queue_get ();
+
+ new_item = g_new (NautilusFileChange, 1);
+ new_item->kind = CHANGE_METADATA_REMOVED;
+ new_item->from_uri = g_file_get_uri (location);
+ nautilus_file_changes_queue_add_common (queue, new_item);
+}
+
+void
nautilus_file_changes_queue_schedule_position_set (const char *uri,
GdkPoint point,
int screen)
diff --git a/libnautilus-private/nautilus-file-changes-queue.h b/libnautilus-private/nautilus-file-changes-queue.h
index 51b171c11..4f50a14c8 100644
--- a/libnautilus-private/nautilus-file-changes-queue.h
+++ b/libnautilus-private/nautilus-file-changes-queue.h
@@ -24,22 +24,26 @@
#define NAUTILUS_FILE_CHANGES_QUEUE_H
#include <gdk/gdktypes.h>
+#include <gio/gfile.h>
+
+void nautilus_file_changes_queue_file_added (const char *uri);
+void nautilus_file_changes_queue_file_changed (const char *uri);
+void nautilus_file_changes_queue_file_removed (GFile *location);
+void nautilus_file_changes_queue_file_removed_by_uri (const char *uri);
+void nautilus_file_changes_queue_file_moved (const char *from_uri,
+ const char *to_uri);
+void nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
+ const char *to_uri);
+void nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
+ const char *to_uri);
+void nautilus_file_changes_queue_schedule_metadata_remove (GFile *location);
+void nautilus_file_changes_queue_schedule_metadata_remove_by_uri (const char *uri);
+void nautilus_file_changes_queue_schedule_position_set (const char *uri,
+ GdkPoint point,
+ int screen);
+void nautilus_file_changes_queue_schedule_position_remove (const char *uri);
+
+void nautilus_file_changes_consume_changes (gboolean consume_all);
-void nautilus_file_changes_queue_file_added (const char *uri);
-void nautilus_file_changes_queue_file_changed (const char *uri);
-void nautilus_file_changes_queue_file_removed (const char *uri);
-void nautilus_file_changes_queue_file_moved (const char *from_uri,
- const char *to_uri);
-void nautilus_file_changes_queue_schedule_metadata_copy (const char *from_uri,
- const char *to_uri);
-void nautilus_file_changes_queue_schedule_metadata_move (const char *from_uri,
- const char *to_uri);
-void nautilus_file_changes_queue_schedule_metadata_remove (const char *uri);
-void nautilus_file_changes_queue_schedule_position_set (const char *uri,
- GdkPoint point,
- int screen);
-void nautilus_file_changes_queue_schedule_position_remove (const char *uri);
-
-void nautilus_file_changes_consume_changes (gboolean consume_all);
#endif /* NAUTILUS_FILE_CHANGES_QUEUE_H */
diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c
index 0d1435db5..700f643d5 100644
--- a/libnautilus-private/nautilus-file-operations.c
+++ b/libnautilus-private/nautilus-file-operations.c
@@ -32,8 +32,10 @@
#include "nautilus-debug-log.h"
#include "nautilus-file-operations-progress.h"
+#include "nautilus-file-changes-queue.h"
#include "nautilus-lib-self-check-functions.h"
+#include <eel/eel-alert-dialog.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-pango-extensions.h>
#include <eel/eel-gtk-extensions.h>
@@ -54,6 +56,9 @@
#include <libgnomevfs/gnome-vfs-utils.h>
#include <libgnomevfs/gnome-vfs-volume.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
+#include <gio/gfile.h>
+#include <gio/gurifuncs.h>
+#include <gio/gioscheduler.h>
#include "nautilus-file-changes-queue.h"
#include "nautilus-file-private.h"
#include "nautilus-desktop-icon-file.h"
@@ -63,6 +68,8 @@
#include "nautilus-trash-monitor.h"
#include "nautilus-file-utilities.h"
+static gboolean confirm_trash_auto_value;
+
typedef enum TransferKind TransferKind;
typedef struct TransferInfo TransferInfo;
typedef struct IconPositionIterator IconPositionIterator;
@@ -126,6 +133,17 @@ transfer_info_destroy (TransferInfo *transfer_info)
g_free (transfer_info);
}
+static void
+setup_autos (void)
+{
+ static gboolean setup_autos = FALSE;
+ if (!setup_autos) {
+ setup_autos = TRUE;
+ eel_preferences_add_auto_boolean (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
+ &confirm_trash_auto_value);
+ }
+}
+
/* Struct used to control applying icon positions to
* top level items during a copy, drag, new folder creation and
* link creation
@@ -1761,7 +1779,7 @@ sync_transfer_callback (GnomeVFSXferProgressInfo *progress_info, gpointer data)
*/
if (progress_info->source_name == NULL) {
/* remove any old metadata */
- nautilus_file_changes_queue_schedule_metadata_remove
+ nautilus_file_changes_queue_schedule_metadata_remove_by_uri
(progress_info->target_name);
} else {
nautilus_file_changes_queue_schedule_metadata_copy
@@ -1821,10 +1839,10 @@ sync_transfer_callback (GnomeVFSXferProgressInfo *progress_info, gpointer data)
case GNOME_VFS_XFER_PHASE_DELETESOURCE:
g_assert (progress_info->source_name != NULL);
if (progress_info->top_level_item) {
- nautilus_file_changes_queue_schedule_metadata_remove
+ nautilus_file_changes_queue_schedule_metadata_remove_by_uri
(progress_info->source_name);
}
- nautilus_file_changes_queue_file_removed (progress_info->source_name);
+ nautilus_file_changes_queue_file_removed_by_uri (progress_info->source_name);
break;
case GNOME_VFS_XFER_PHASE_COMPLETED:
@@ -2829,6 +2847,444 @@ nautilus_file_operations_delete (const GList *item_uris,
gnome_vfs_uri_list_free (uri_list);
}
+#if 0
+void
+nautilus_file_operations_delete (const GList *files,
+ GtkWidget *parent_view,
+ NautilusDeleteCallback done_callback,
+ gpointer done_callback_data)
+{
+}
+#endif
+
+typedef struct {
+ GList *files;
+ GtkWindow *parent_window;
+ gboolean try_trash;
+ gboolean delete_if_all_already_in_trash;
+ NautilusDeleteCallback done_callback;
+ gpointer done_callback_data;
+} DeleteJob;
+
+static gboolean
+can_delete_without_confirm (GFile *file)
+{
+ if (g_file_has_uri_scheme (file, "burn")) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+can_trash_file (GFile *file, GCancellable *cancellable)
+{
+ GFileInfo *info;
+ gboolean res;
+
+ res = FALSE;
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH,
+ 0,
+ cancellable,
+ NULL);
+
+ if (info) {
+ res = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH);
+ g_object_unref (info);
+ }
+
+ return res;
+}
+
+static char *
+get_display_name (GFile *file, GCancellable *cancellable)
+{
+ GFileInfo *info;
+ char *name, *basename;
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STD_DISPLAY_NAME,
+ 0, cancellable, NULL);
+
+ name = NULL;
+ if (info) {
+ name = g_strdup (g_file_info_get_display_name (info));
+ g_object_unref (info);
+ }
+
+ if (name == NULL) {
+ basename = g_file_get_basename (file);
+ if (g_utf8_validate (basename, -1, NULL)) {
+ name = basename;
+ } else {
+ name = g_uri_escape_string (basename, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
+ g_free (basename);
+ }
+ }
+
+ return name;
+}
+
+static void
+delete_files (GList *files, GCancellable *cancellable, GtkWindow *parent_window)
+{
+ GList *l;
+ GFile *file;
+ GError *error;
+
+ for (l = files; l != NULL; l = l->next) {
+ file = l->data;
+
+ error = NULL;
+ if (!g_file_delete (file, cancellable, &error)) {
+ /* TODO-gio */
+ g_print ("Error deleting file: %s\n", error->message);
+ } else {
+ nautilus_file_changes_queue_schedule_metadata_remove (file);
+ nautilus_file_changes_queue_file_removed (file);
+ }
+ }
+}
+
+static void
+trash_files (GList *files, GCancellable *cancellable, GtkWindow *parent_window)
+{
+ GList *l;
+ GFile *file;
+ GError *error;
+
+ for (l = files; l != NULL; l = l->next) {
+ file = l->data;
+
+ error = NULL;
+ if (!g_file_trash (file, cancellable, &error)) {
+ /* TODO-gio */
+ g_print ("Error trashing file: %s\n", error->message);
+ } else {
+ nautilus_file_changes_queue_schedule_metadata_remove (file);
+ nautilus_file_changes_queue_file_removed (file);
+ }
+ }
+}
+
+typedef struct {
+ GtkWindow *parent_window;
+ const char *primary_message;
+ const char *secondary_message;
+ const char *ok_label;
+ int response;
+} AlertInfo;
+
+static void
+run_alert (gpointer user_data)
+{
+ AlertInfo *info = user_data;
+ GtkDialog *dialog;
+
+ dialog = GTK_DIALOG (eel_alert_dialog_new (info->parent_window,
+ 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
+ info->primary_message,
+ info->secondary_message));
+ gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (dialog, info->ok_label, GTK_RESPONSE_YES);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+
+ info->response = gtk_dialog_run (dialog);
+ gtk_object_destroy (GTK_OBJECT (dialog));
+
+ return;
+}
+
+static int
+run_alert_in_main (GIOJob *job,
+ GtkWindow *parent_window,
+ const char *primary_message,
+ const char *secondary_message,
+ const char *ok_label)
+{
+ AlertInfo info;
+
+ info.parent_window = parent_window;
+ info.primary_message = primary_message;
+ info.secondary_message = secondary_message;
+ info.ok_label = ok_label;
+
+ g_io_job_send_to_mainloop (job,
+ run_alert,
+ &info,
+ NULL,
+ TRUE);
+
+ return info.response;
+}
+
+typedef struct {
+ const char *prompt;
+ const char *detail;
+ const char *yes_label;
+ const char *no_label;
+ GtkWindow *parent_window;
+ int response;
+} YesNoInfo;
+
+static void
+run_yes_no (gpointer data)
+{
+ YesNoInfo *info = data;
+ GtkDialog *dialog;
+
+ dialog = eel_show_yes_no_dialog
+ (info->prompt,
+ info->detail,
+ info->yes_label, info->no_label,
+ info->parent_window);
+
+ info->response = gtk_dialog_run (dialog);
+
+ gtk_object_destroy (GTK_OBJECT (dialog));
+}
+
+static int
+run_yes_no_dialog_in_main (GIOJob *job,
+ const char *prompt,
+ const char *detail,
+ const char *yes_label,
+ const char *no_label,
+ GtkWindow *parent_window)
+{
+ YesNoInfo info;
+
+ info.prompt = prompt;
+ info.detail = detail;
+ info.yes_label = yes_label;
+ info.no_label = no_label;
+ info.parent_window = parent_window;
+
+ g_io_job_send_to_mainloop (job,
+ run_yes_no,
+ &info,
+ NULL,
+ TRUE);
+
+ return info.response;
+}
+
+static gboolean
+confirm_delete_from_trash (GIOJob *job,
+ GtkWindow *parent_window,
+ GList *files)
+{
+ char *prompt;
+ char *file_name;
+ int file_count;
+ int response;
+
+ /* Just Say Yes if the preference says not to confirm. */
+ if (!confirm_trash_auto_value) {
+ return TRUE;
+ }
+
+ file_count = g_list_length (files);
+ g_assert (file_count > 0);
+
+ if (file_count == 1) {
+ file_name = get_display_name ((GFile *) files->data, NULL);
+ prompt = g_strdup_printf (_("Are you sure you want to permanently delete \"%s\" "
+ "from the trash?"), file_name);
+ g_free (file_name);
+ } else {
+ prompt = g_strdup_printf (ngettext("Are you sure you want to permanently delete "
+ "the %d selected item from the trash?",
+ "Are you sure you want to permanently delete "
+ "the %d selected items from the trash?",
+ file_count),
+ file_count);
+ }
+
+ response = run_alert_in_main (job, parent_window,
+ prompt,
+ _("If you delete an item, it will be permanently lost."),
+ GTK_STOCK_DELETE);
+
+ return (response == GTK_RESPONSE_YES);
+}
+
+static gboolean
+confirm_deletion (GIOJob *job,
+ GtkWindow *parent_window,
+ GList *files,
+ gboolean all)
+{
+ char *prompt;
+ char *detail;
+ int file_count;
+ GFile *file;
+ char *file_name;
+ int response;
+
+ file_count = g_list_length (files);
+ g_assert (file_count > 0);
+
+ if (file_count == 1) {
+ file = files->data;
+ if (g_file_has_uri_scheme (file, "x-nautilus-desktop")) {
+ /* Don't ask for desktop icons */
+ return TRUE;
+ }
+ file_name = get_display_name (file, NULL);
+ prompt = _("Cannot move file to trash, do you want to delete immediately?");
+ detail = g_strdup_printf (_("The file \"%s\" cannot be moved to the trash."), file_name);
+ g_free (file_name);
+ } else {
+ if (all) {
+ prompt = _("Cannot move items to trash, do you want to delete them immediately?");
+ detail = g_strdup_printf (ngettext("The selected item could not be moved to the Trash",
+ "The %d selected items could not be moved to the Trash",
+ file_count),
+ file_count);
+ } else {
+ prompt = _("Cannot move some items to trash, do you want to delete these immediately?");
+ detail = g_strdup_printf (_("%d of the selected items cannot be moved to the Trash"), file_count);
+ }
+ }
+
+ response = run_yes_no_dialog_in_main (job,
+ prompt,
+ detail,
+ GTK_STOCK_DELETE, GTK_STOCK_CANCEL,
+ parent_window);
+
+ g_free (detail);
+
+ return (response == GTK_RESPONSE_YES);
+}
+
+static void delete_job_done (gpointer data);
+
+static void
+delete_job (GIOJob *io_job,
+ GCancellable *cancellable,
+ gpointer user_data)
+{
+ DeleteJob *job = user_data;
+ GList *trashable_files;
+ GList *untrashable_files;
+ GList *in_trash_files;
+ GList *no_confirm_files;
+ GList *l;
+ GFile *file;
+
+ /* Collect three lists: (1) items that can be moved to trash,
+ * (2) items that can only be deleted in place, and (3) items that
+ * are already in trash.
+ *
+ * Always move (1) to trash if non-empty.
+ * Delete (3) only if (1) and (2) are non-empty, otherwise ignore (3).
+ * Ask before deleting (2) if non-empty.
+ * Ask before deleting (3) if non-empty.
+ */
+
+ trashable_files = NULL;
+ untrashable_files = NULL;
+ in_trash_files = NULL;
+ no_confirm_files = NULL;
+
+ if (job->try_trash) {
+ for (l = job->files; l != NULL; l = l->next) {
+ file = l->data;
+
+ if (job->delete_if_all_already_in_trash && g_file_has_uri_scheme (file, "trash")) {
+ in_trash_files = g_list_prepend (in_trash_files, file);
+ } else if (can_delete_without_confirm (file)) {
+ no_confirm_files = g_list_prepend (no_confirm_files, file);
+ } else if (can_trash_file (file, NULL)) {
+ trashable_files = g_list_prepend (trashable_files, file);
+ } else {
+ untrashable_files = g_list_prepend (untrashable_files, file);
+ }
+ }
+ } else {
+ no_confirm_files = g_list_copy (job->files);
+
+ }
+
+ if (in_trash_files != NULL && trashable_files == NULL && untrashable_files == NULL) {
+ if (confirm_delete_from_trash (io_job, job->parent_window, in_trash_files)) {
+ delete_files (in_trash_files, NULL, job->parent_window);
+ }
+ } else {
+ if (no_confirm_files != NULL) {
+ delete_files (no_confirm_files, NULL, job->parent_window);
+ }
+ if (trashable_files != NULL) {
+ trash_files (trashable_files, NULL, job->parent_window);
+ }
+ if (untrashable_files != NULL) {
+ if (confirm_deletion (io_job, job->parent_window, untrashable_files, trashable_files == NULL)) {
+ delete_files (untrashable_files, NULL, job->parent_window);
+ }
+ }
+ }
+
+ g_list_free (in_trash_files);
+ g_list_free (trashable_files);
+ g_list_free (untrashable_files);
+ g_list_free (no_confirm_files);
+
+ g_io_job_send_to_mainloop (io_job,
+ delete_job_done,
+ job,
+ NULL,
+ FALSE);
+
+}
+
+static void
+delete_job_done (gpointer user_data)
+{
+ DeleteJob *job = user_data;
+
+ eel_g_object_list_free (job->files);
+ if (job->parent_window) {
+ g_object_unref (job->parent_window);
+ }
+
+ if (job->done_callback) {
+ job->done_callback (/* TODO: debuting uris */NULL, job->done_callback_data);
+ }
+ g_free (job);
+
+ nautilus_file_changes_consume_changes (TRUE);
+}
+
+void
+nautilus_file_operations_trash_or_delete (GList *files,
+ GtkWindow *parent_window,
+ NautilusDeleteCallback done_callback,
+ gpointer done_callback_data)
+{
+ DeleteJob *job;
+
+ setup_autos ();
+
+ /* TODO: special case desktop icon link files ... */
+
+ job = g_new0 (DeleteJob, 1);
+ job->files = eel_g_object_list_copy (files);
+ job->parent_window = g_object_ref (parent_window);
+ job->try_trash = TRUE;
+ job->done_callback = done_callback;
+ job->done_callback_data = done_callback_data;
+
+ g_schedule_io_job (delete_job,
+ job,
+ NULL,
+ 0,
+ NULL);
+}
+
static void
do_empty_trash (GtkWidget *parent_view)
{
diff --git a/libnautilus-private/nautilus-file-operations.h b/libnautilus-private/nautilus-file-operations.h
index 9400631ce..12cd81972 100644
--- a/libnautilus-private/nautilus-file-operations.h
+++ b/libnautilus-private/nautilus-file-operations.h
@@ -72,10 +72,14 @@ void nautilus_file_operations_new_file_from_template (GtkWidget *p
NautilusNewFileCallback done_callback,
gpointer data);
-void nautilus_file_operations_delete (const GList *item_uris,
- GtkWidget *parent_view,
- NautilusDeleteCallback done_callback,
- gpointer done_callback_data);
+void nautilus_file_operations_delete (const GList *item_uris,
+ GtkWidget *parent_view,
+ NautilusDeleteCallback done_callback,
+ gpointer done_callback_data);
+void nautilus_file_operations_trash_or_delete (GList *files,
+ GtkWindow *parent_window,
+ NautilusDeleteCallback done_callback,
+ gpointer done_callback_data);
void nautilus_file_set_permissions_recursive (const char *directory,
GnomeVFSFilePermissions file_permissions,
diff --git a/libnautilus-private/nautilus-monitor.c b/libnautilus-private/nautilus-monitor.c
index 4a7911e39..5cb18d48d 100644
--- a/libnautilus-private/nautilus-monitor.c
+++ b/libnautilus-private/nautilus-monitor.c
@@ -98,8 +98,8 @@ dir_changed (GDirectoryMonitor* monitor,
nautilus_file_changes_queue_file_changed (uri);
break;
case G_FILE_MONITOR_EVENT_DELETED:
- nautilus_file_changes_queue_schedule_metadata_remove (uri);
- nautilus_file_changes_queue_file_removed (uri);
+ nautilus_file_changes_queue_schedule_metadata_remove_by_uri (uri);
+ nautilus_file_changes_queue_file_removed_by_uri (uri);
break;
case G_FILE_MONITOR_EVENT_CREATED:
nautilus_file_changes_queue_file_added (uri);
diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c
index 29f0cc4a4..f1cc51062 100644
--- a/src/file-manager/fm-directory-view.c
+++ b/src/file-manager/fm-directory-view.c
@@ -73,14 +73,6 @@
#include <libgnome/gnome-util.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libgnomeui/gnome-help.h>
-#include <libgnomevfs/gnome-vfs-async-ops.h>
-#include <libgnomevfs/gnome-vfs-file-info.h>
-#include <libgnomevfs/gnome-vfs-mime-handlers.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#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>
@@ -336,14 +328,12 @@ static void fm_directory_view_init (FMDirectoryView
static void fm_directory_view_duplicate_selection (FMDirectoryView *view,
GList *files,
GArray *item_locations);
-static gboolean fm_directory_view_confirm_deletion (GtkWindow *parent_window,
- GList *uris,
- gboolean all);
static void fm_directory_view_create_links_for_files (FMDirectoryView *view,
GList *files,
GArray *item_locations);
static void trash_or_delete_files (GtkWindow *parent_window,
- const GList *files);
+ const GList *files,
+ gboolean delete_if_all_already_in_trash);
static void fm_directory_view_activate_file (FMDirectoryView *view,
NautilusFile *file,
NautilusWindowOpenMode mode,
@@ -903,7 +893,7 @@ trash_or_delete_selected_files (FMDirectoryView *view)
*/
if (!view->details->selection_was_removed) {
selection = fm_directory_view_get_selection_for_file_transfer (view);
- trash_or_delete_files (fm_directory_view_get_containing_window (view), selection);
+ trash_or_delete_files (fm_directory_view_get_containing_window (view), selection, TRUE);
nautilus_file_list_free (selection);
view->details->selection_was_removed = TRUE;
}
@@ -1762,9 +1752,10 @@ fm_directory_view_get_selection_uris (NautilusView *view)
}
static GList *
-file_list_from_uri_list (GList *uri_list)
+file_list_from_uri_list (const GList *uri_list)
{
- GList *file_list, *node;
+ GList *file_list;
+ const GList *node;
file_list = NULL;
for (node = uri_list; node != NULL; node = node->next) {
@@ -1775,6 +1766,22 @@ file_list_from_uri_list (GList *uri_list)
return g_list_reverse (file_list);
}
+static GList *
+location_list_from_uri_list (const GList *uris)
+{
+ const GList *l;
+ GList *files;
+ GFile *f;
+
+ files = NULL;
+ for (l = uris; l != NULL; l = l->next) {
+ f = g_file_new_for_uri (l->data);
+ files = g_list_prepend (files, f);
+ }
+
+ return g_list_reverse (files);
+}
+
static void
fm_directory_view_set_selection_uris (NautilusView *nautilus_view,
GList *selection_uris)
@@ -3664,46 +3671,6 @@ desktop_or_home_dir_in_selection (FMDirectoryView *view)
}
static gboolean
-can_move_uri_to_trash (GtkWindow *parent_window, const char *file_uri_string)
-{
- /* Return TRUE if we can get a trash directory on the same volume as this file. */
- GnomeVFSURI *file_uri;
- GnomeVFSURI *directory_uri;
- GnomeVFSURI *trash_dir_uri;
- gboolean result;
-
- g_return_val_if_fail (file_uri_string != NULL, FALSE);
-
- file_uri = gnome_vfs_uri_new (file_uri_string);
-
- if (file_uri == NULL) {
- return FALSE;
- }
-
- /* FIXME: Why can't we just pass file_uri to gnome_vfs_find_directory? */
- directory_uri = gnome_vfs_uri_get_parent (file_uri);
- gnome_vfs_uri_unref (file_uri);
-
- if (directory_uri == NULL) {
- return FALSE;
- }
-
- /*
- * Create a new trash if needed but don't go looking for an old Trash.
- * Passing 0 permissions as gnome-vfs would override the permissions
- * passed with 700 while creating .Trash directory
- */
- result = gnome_vfs_find_directory (directory_uri, GNOME_VFS_DIRECTORY_KIND_TRASH,
- &trash_dir_uri, TRUE, FALSE, 0) == GNOME_VFS_OK;
- if (result) {
- gnome_vfs_uri_unref (trash_dir_uri);
- }
- gnome_vfs_uri_unref (directory_uri);
-
- return result;
-}
-
-static gboolean
can_delete_uri_without_confirm (const char *file_uri_string)
{
if (eel_istr_has_prefix (file_uri_string, "burn:") != FALSE) {
@@ -3726,193 +3693,28 @@ file_name_from_uri (const char *uri)
return file_name;
}
-static gboolean
-fm_directory_view_confirm_deletion (GtkWindow *parent_window, GList *uris, gboolean all)
-{
- GtkDialog *dialog;
- char *prompt;
- char *detail;
- int uri_count;
- char *uri;
- char *file_name;
- int response;
-
- uri_count = g_list_length (uris);
- g_assert (uri_count > 0);
-
- if (uri_count == 1) {
- uri = (char *) uris->data;
- if (eel_uri_is_desktop (uri)) {
- /* Don't ask for desktop icons */
- return TRUE;
- }
- file_name = file_name_from_uri (uri);
- prompt = _("Cannot move file to trash, do you want to delete immediately?");
- detail = g_strdup_printf (_("The file \"%s\" cannot be moved to the trash."), file_name);
- g_free (file_name);
- } else {
- if (all) {
- prompt = _("Cannot move items to trash, do you want to delete them immediately?");
- detail = g_strdup_printf (ngettext("The selected item could not be moved to the Trash",
- "The %d selected items could not be moved to the Trash",
- uri_count),
- uri_count);
- } else {
- prompt = _("Cannot move some items to trash, do you want to delete these immediately?");
- detail = g_strdup_printf (_("%d of the selected items cannot be moved to the Trash"), uri_count);
- }
- }
-
- dialog = eel_show_yes_no_dialog
- (prompt,
- detail, GTK_STOCK_DELETE, GTK_STOCK_CANCEL,
- parent_window);
-
- g_free (detail);
- response = gtk_dialog_run (dialog);
- gtk_object_destroy (GTK_OBJECT (dialog));
-
- return response == GTK_RESPONSE_YES;
-}
-
-static gboolean
-confirm_delete_from_trash (GtkWindow *parent_window, GList *uris)
-{
- GtkDialog *dialog;
- char *prompt;
- char *file_name;
- int uri_count;
- int response;
-
- /* Just Say Yes if the preference says not to confirm. */
- if (!confirm_trash_auto_value) {
- return TRUE;
- }
-
- uri_count = g_list_length (uris);
- g_assert (uri_count > 0);
-
- if (uri_count == 1) {
- file_name = file_name_from_uri ((char *) uris->data);
- prompt = g_strdup_printf (_("Are you sure you want to permanently delete \"%s\" "
- "from the trash?"), file_name);
- g_free (file_name);
- } else {
- prompt = g_strdup_printf (ngettext("Are you sure you want to permanently delete "
- "the %d selected item from the trash?",
- "Are you sure you want to permanently delete "
- "the %d selected items from the trash?",
- uri_count),
- uri_count);
- }
-
- dialog = GTK_DIALOG (eel_alert_dialog_new (parent_window,
- 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
- prompt,
- _("If you delete an item, it will be permanently lost.")));
- gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button (dialog, GTK_STOCK_DELETE, GTK_RESPONSE_YES);
-
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
-
- g_free (prompt);
-
- response = gtk_dialog_run (dialog);
- gtk_object_destroy (GTK_OBJECT (dialog));
-
- return response == GTK_RESPONSE_YES;
-}
-
-static void
-trash_or_delete_files_common (GtkWindow *parent_window,
- const GList *file_uris,
- GArray *relative_item_points,
- gboolean delete_if_all_already_in_trash)
-{
- const GList *file_node;
- char *file_uri;
- GList *moveable_uris;
- GList *unmoveable_uris;
- GList *in_trash_uris;
- GList *no_confirm_uris;
-
- /* Collect three lists: (1) items that can be moved to trash,
- * (2) items that can only be deleted in place, and (3) items that
- * are already in trash.
- *
- * Always move (1) to trash if non-empty.
- * Delete (3) only if (1) and (2) are non-empty, otherwise ignore (3).
- * Ask before deleting (2) if non-empty.
- * Ask before deleting (3) if non-empty.
- */
-
- moveable_uris = NULL;
- unmoveable_uris = NULL;
- in_trash_uris = NULL;
- no_confirm_uris = NULL;
-
- for (file_node = file_uris; file_node != NULL; file_node = file_node->next) {
- file_uri = (char *) file_node->data;
-
- if (delete_if_all_already_in_trash && eel_uri_is_trash (file_uri)) {
- in_trash_uris = g_list_prepend (in_trash_uris, g_strdup (file_uri));
- } else if (can_delete_uri_without_confirm (file_uri)) {
- no_confirm_uris = g_list_prepend (no_confirm_uris, g_strdup (file_uri));
- } else if (can_move_uri_to_trash (parent_window, file_uri)) {
- moveable_uris = g_list_prepend (moveable_uris, g_strdup (file_uri));
- } else {
- unmoveable_uris = g_list_prepend (unmoveable_uris, g_strdup (file_uri));
- }
- }
-
- if (in_trash_uris != NULL && moveable_uris == NULL && unmoveable_uris == NULL) {
- if (confirm_delete_from_trash (parent_window, in_trash_uris)) {
- nautilus_file_operations_delete (in_trash_uris, GTK_WIDGET (parent_window),
- NULL, NULL);
- }
- } else {
- if (no_confirm_uris != NULL) {
- nautilus_file_operations_delete (no_confirm_uris,
- GTK_WIDGET (parent_window), NULL, NULL);
- }
- if (moveable_uris != NULL) {
- nautilus_file_operations_copy_move (moveable_uris, relative_item_points,
- EEL_TRASH_URI, GDK_ACTION_MOVE, GTK_WIDGET (parent_window),
- NULL, NULL);
- }
- if (unmoveable_uris != NULL) {
- if (fm_directory_view_confirm_deletion (parent_window,
- unmoveable_uris,
- moveable_uris == NULL)) {
- nautilus_file_operations_delete (unmoveable_uris,
- GTK_WIDGET (parent_window), NULL, NULL);
- }
- }
- }
-
- eel_g_list_free_deep (in_trash_uris);
- eel_g_list_free_deep (moveable_uris);
- eel_g_list_free_deep (unmoveable_uris);
- eel_g_list_free_deep (no_confirm_uris);
-}
static void
trash_or_delete_files (GtkWindow *parent_window,
- const GList *files)
+ const GList *files,
+ gboolean delete_if_all_already_in_trash)
{
- GList *file_uris;
+ GList *locations;
const GList *node;
- file_uris = NULL;
+ locations = NULL;
for (node = files; node != NULL; node = node->next) {
- file_uris = g_list_prepend (file_uris,
- nautilus_file_get_uri ((NautilusFile *) node->data));
+ locations = g_list_prepend (locations,
+ nautilus_file_get_location ((NautilusFile *) node->data));
}
- file_uris = g_list_reverse (file_uris);
- trash_or_delete_files_common (parent_window, file_uris, NULL, TRUE);
- eel_g_list_free_deep (file_uris);
+ locations = g_list_reverse (locations);
+
+ nautilus_file_operations_trash_or_delete (locations,
+ parent_window,
+ NULL, NULL);
+ eel_g_object_list_free (locations);
}
static gboolean
@@ -6483,7 +6285,7 @@ action_location_trash_callback (GtkAction *action,
g_return_if_fail (file != NULL);
files = g_list_append (NULL, file);
- trash_or_delete_files (fm_directory_view_get_containing_window (view), files);
+ trash_or_delete_files (fm_directory_view_get_containing_window (view), files, TRUE);
g_list_free (files);
}
@@ -7819,7 +7621,7 @@ report_broken_symbolic_link (GtkWindow *parent_window, NautilusFile *file)
file_as_list.data = file;
file_as_list.next = NULL;
file_as_list.prev = NULL;
- trash_or_delete_files (parent_window, &file_as_list);
+ trash_or_delete_files (parent_window, &file_as_list, TRUE);
}
out:
@@ -9349,7 +9151,10 @@ fm_directory_view_move_copy_items (const GList *item_uris,
}
if (eel_uri_is_trash (target_uri) && copy_action == GDK_ACTION_MOVE) {
- trash_or_delete_files_common (fm_directory_view_get_containing_window (view), item_uris, relative_item_points, FALSE);
+ GList *locations;
+ locations = location_list_from_uri_list (item_uris);
+ trash_or_delete_files (fm_directory_view_get_containing_window (view), locations, FALSE);
+ eel_g_object_list_free (locations);
} else {
nautilus_file_operations_copy_move
(item_uris, relative_item_points,