diff options
author | Razvan Chitu <razvan.ch95@gmail.com> | 2016-02-12 12:51:29 +0200 |
---|---|---|
committer | Carlos Soriano <csoriano@gnome.org> | 2016-02-25 13:39:39 +0100 |
commit | 9bf4390e67e374f7f4f3ee6e757d12feb0d165e6 (patch) | |
tree | 2920b884c8fa44e6a8c5e9ed94d5d9eec05f3516 /libnautilus-private/nautilus-file-undo-operations.c | |
parent | 8b565e14fa47972560afe7124e32fc7ee1a8fde8 (diff) | |
download | nautilus-9bf4390e67e374f7f4f3ee6e757d12feb0d165e6.tar.gz |
file-operations: check that trashed files are actually in the trash
In Nautilus, trash operations are performed and finalized before the trash is
updated. Because of this, the option to undo trashing becomes available even if
the trash is not aware of new files. If an undo is then requested, the operation
would do nothing, because the files would appear to not exist in the trash. A
better solution would be to wait for the trash to notified, and then check that
the trashed files are actually there. Only then should a trash operation be
considered finalized.
Add a signal to the trash-monitor that is emitted when the trash changes.
Connect trash operations to this signal. On signal emission, asynchronously
check that the files are in the trash. Finalize the job if the check was not
cancelled and successful.
https://bugzilla.gnome.org/show_bug.cgi?id=762126
Diffstat (limited to 'libnautilus-private/nautilus-file-undo-operations.c')
-rw-r--r-- | libnautilus-private/nautilus-file-undo-operations.c | 86 |
1 files changed, 8 insertions, 78 deletions
diff --git a/libnautilus-private/nautilus-file-undo-operations.c b/libnautilus-private/nautilus-file-undo-operations.c index 98e791048..773b8add7 100644 --- a/libnautilus-private/nautilus-file-undo-operations.c +++ b/libnautilus-private/nautilus-file-undo-operations.c @@ -33,13 +33,6 @@ #include "nautilus-file.h" #include "nautilus-file-undo-manager.h" -/* Since we use g_get_current_time for setting "orig_trash_time" in the undo - * info, there are situations where the difference between this value and the - * real deletion time can differ enough to make the rounding a difference of 1 - * second, failing the equality check. To make sure we avoid this, and to be - * preventive, use 2 seconds epsilon. - */ -#define TRASH_TIME_EPSILON 2 G_DEFINE_TYPE (NautilusFileUndoInfo, nautilus_file_undo_info, G_TYPE_OBJECT) @@ -1130,64 +1123,6 @@ trash_enumerate_children (GError **error) } static void -trash_match_files (GList *trash_children, - GHashTable *trashed, - GHashTable *matched_files) -{ - GFile *trash; - GList *l; - GFileInfo *info; - const char *original_path; - GFile *original_file; - gpointer lookup_value; - glong trash_time; - glong original_trash_time; - GFile *item; - - trash = g_file_new_for_uri ("trash:///"); - - /* Iterate over the trash children and check if they match the trashed - * files. This is not done as a match between two hash-tables because - * the trash can contain multiple files with the same original path - */ - for (l = trash_children; l != NULL; l = l->next) { - info = l->data; - /* Retrieve the original file uri */ - original_path = g_file_info_get_attribute_byte_string (info, - G_FILE_ATTRIBUTE_TRASH_ORIG_PATH); - original_file = g_file_new_for_path (original_path); - - lookup_value = g_hash_table_lookup (trashed, original_file); - - if (lookup_value) { - GDateTime *date; - - original_trash_time = GPOINTER_TO_SIZE (lookup_value); - trash_time = 0; - date = g_file_info_get_deletion_date (info); - if (date) { - trash_time = g_date_time_to_unix (date); - g_date_time_unref (date); - } - - if (abs (original_trash_time - trash_time) > TRASH_TIME_EPSILON) { - continue; - } - /* File in the trash */ - if (matched_files != NULL) { - item = g_file_get_child (trash, g_file_info_get_name (info)); - g_hash_table_insert (matched_files, item, g_object_ref (original_file)); - } - } - - g_object_unref (original_file); - - } - - g_object_unref (trash); -} - -static void trash_retrieve_files_to_restore_thread (GSimpleAsyncResult *res, GObject *object, GCancellable *cancellable) @@ -1202,7 +1137,7 @@ trash_retrieve_files_to_restore_thread (GSimpleAsyncResult *res, g_object_unref, g_object_unref); trash_children = trash_enumerate_children (&error); - trash_match_files (trash_children, + trash_files_match (trash_children, self->priv->trashed, to_restore); @@ -1285,9 +1220,7 @@ nautilus_file_undo_info_trash_init (NautilusFileUndoInfoTrash *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, nautilus_file_undo_info_trash_get_type (), NautilusFileUndoInfoTrashDetails); - self->priv->trashed = - g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, - g_object_unref, NULL); + self->priv->trashed = NULL; } static void @@ -1324,16 +1257,13 @@ nautilus_file_undo_info_trash_new (gint item_count) } void -nautilus_file_undo_info_trash_add_file (NautilusFileUndoInfoTrash *self, - GFile *file) +nautilus_file_undo_info_trash_set_trashed (NautilusFileUndoInfoTrash *self, + GHashTable *trashed) { - GTimeVal current_time; - gsize orig_trash_time; - - g_get_current_time (¤t_time); - orig_trash_time = current_time.tv_sec; - - g_hash_table_insert (self->priv->trashed, g_object_ref (file), GSIZE_TO_POINTER (orig_trash_time)); + if (self->priv->trashed) { + g_hash_table_destroy (self->priv->trashed); + } + self->priv->trashed = g_hash_table_ref (trashed); } GList * |