[nautilus/wip/antoniof/update-starred-uris: 3/3] undo-operations: Restore stars if trashing is undone




commit 8bcbe4dd0d1d4da65d2ccba7da86f0aeae3d28f8
Author: António Fernandes <antoniof gnome org>
Date:   Sun Sep 13 19:13:57 2020 +0100

    undo-operations: Restore stars if trashing is undone
    
    Undo operations should aim to restore the previous state as much as
    possible.
    
    Thus, if starred files were moved to trash, let's store that information
    in order to get them starred again if this operation is undone.
    
    Note: This doesn't apply to the "Restore from Trash" action performed
    directly in trash:/// contents.

 src/nautilus-file-operations.c      |  9 ++--
 src/nautilus-file-undo-operations.c | 17 ++++++-
 src/nautilus-file-undo-operations.h |  3 +-
 src/nautilus-tag-manager.c          | 95 ++++++++++++++++++++++++++++++++++++-
 src/nautilus-tag-manager.h          |  5 +-
 5 files changed, 122 insertions(+), 7 deletions(-)
---
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c
index 6506183a1..3da3c336b 100644
--- a/src/nautilus-file-operations.c
+++ b/src/nautilus-file-operations.c
@@ -2016,7 +2016,7 @@ file_deleted_callback (GFile    *file,
         g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get ();
 
         nautilus_file_changes_queue_file_removed (file);
-        nautilus_tag_manager_update_removed_uris (tag_manager, file);
+        nautilus_tag_manager_update_removed_uris (tag_manager, file, NULL);
         report_delete_progress (data->job, data->source_info, data->transfer_info);
 
         return;
@@ -2325,14 +2325,17 @@ trash_file (CommonJob     *job,
     if (g_file_trash (file, job->cancellable, &error))
     {
         g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get ();
+        g_autoptr (GPtrArray) starred_uris = NULL;
 
         transfer_info->num_files++;
         nautilus_file_changes_queue_file_removed (file);
-        nautilus_tag_manager_update_removed_uris (tag_manager, file);
+        nautilus_tag_manager_update_removed_uris (tag_manager, file, &starred_uris);
 
         if (job->undo_info != NULL)
         {
-            nautilus_file_undo_info_trash_add_file (NAUTILUS_FILE_UNDO_INFO_TRASH (job->undo_info), file);
+            nautilus_file_undo_info_trash_add_file (NAUTILUS_FILE_UNDO_INFO_TRASH (job->undo_info),
+                                                    file,
+                                                    g_steal_pointer (&starred_uris));
         }
 
         report_trash_progress (job, source_info, transfer_info);
diff --git a/src/nautilus-file-undo-operations.c b/src/nautilus-file-undo-operations.c
index b263a33d3..1e5533b4b 100644
--- a/src/nautilus-file-undo-operations.c
+++ b/src/nautilus-file-undo-operations.c
@@ -1595,6 +1595,7 @@ struct _NautilusFileUndoInfoTrash
     NautilusFileUndoInfo parent_instance;
 
     GHashTable *trashed;
+    GPtrArray *starred_uris;
 };
 
 G_DEFINE_TYPE (NautilusFileUndoInfoTrash, nautilus_file_undo_info_trash, NAUTILUS_TYPE_FILE_UNDO_INFO)
@@ -1813,6 +1814,7 @@ trash_retrieve_files_ready (GObject      *source,
         GList *gfiles_in_trash, *l;
         GFile *item;
         GFile *dest;
+        g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get ();
 
         gfiles_in_trash = g_hash_table_get_keys (files_to_restore);
 
@@ -1826,6 +1828,8 @@ trash_retrieve_files_ready (GObject      *source,
 
         g_list_free (gfiles_in_trash);
 
+        nautilus_tag_manager_update_restored_uris (tag_manager, self->starred_uris);
+
         /* Here we must do what's necessary for the callback */
         file_undo_info_transfer_callback (NULL, (error == NULL), self);
     }
@@ -1857,6 +1861,7 @@ nautilus_file_undo_info_trash_init (NautilusFileUndoInfoTrash *self)
 {
     self->trashed = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
                                            g_object_unref, NULL);
+    self->starred_uris = g_ptr_array_new_with_free_func (g_free);
 }
 
 static void
@@ -1864,6 +1869,7 @@ nautilus_file_undo_info_trash_finalize (GObject *obj)
 {
     NautilusFileUndoInfoTrash *self = NAUTILUS_FILE_UNDO_INFO_TRASH (obj);
     g_hash_table_destroy (self->trashed);
+    g_ptr_array_unref (self->starred_uris);
 
     G_OBJECT_CLASS (nautilus_file_undo_info_trash_parent_class)->finalize (obj);
 }
@@ -1890,9 +1896,17 @@ nautilus_file_undo_info_trash_new (gint item_count)
                          NULL);
 }
 
+/**
+ * nautilus_file_undo_info_trash_add_file:
+ * @self: The undo info instance.
+ * @file: The original location of the trashed file.
+ * @starred_uris: (transfer full) (element-type utf8): Starred URIs removed as
+ * a result of @file being moved to trash.
+ */
 void
 nautilus_file_undo_info_trash_add_file (NautilusFileUndoInfoTrash *self,
-                                        GFile                     *file)
+                                        GFile                     *file,
+                                        GPtrArray                 *starred_uris)
 {
     GTimeVal current_time;
     gsize orig_trash_time;
@@ -1901,6 +1915,7 @@ nautilus_file_undo_info_trash_add_file (NautilusFileUndoInfoTrash *self,
     orig_trash_time = current_time.tv_sec;
 
     g_hash_table_insert (self->trashed, g_object_ref (file), GSIZE_TO_POINTER (orig_trash_time));
+    g_ptr_array_extend_and_steal (self->starred_uris, starred_uris);
 }
 
 GList *
diff --git a/src/nautilus-file-undo-operations.h b/src/nautilus-file-undo-operations.h
index f96f2fe69..602cfc3a3 100644
--- a/src/nautilus-file-undo-operations.h
+++ b/src/nautilus-file-undo-operations.h
@@ -167,7 +167,8 @@ G_DECLARE_FINAL_TYPE (NautilusFileUndoInfoTrash, nautilus_file_undo_info_trash,
 
 NautilusFileUndoInfo *nautilus_file_undo_info_trash_new (gint item_count);
 void nautilus_file_undo_info_trash_add_file (NautilusFileUndoInfoTrash *self,
-                                             GFile                     *file);
+                                             GFile                     *file,
+                                             GPtrArray                 *starred_uris);
 GList *nautilus_file_undo_info_trash_get_files (NautilusFileUndoInfoTrash *self);
 
 /* recursive permissions */
diff --git a/src/nautilus-tag-manager.c b/src/nautilus-tag-manager.c
index 9c71e731e..aa687e610 100644
--- a/src/nautilus-tag-manager.c
+++ b/src/nautilus-tag-manager.c
@@ -857,13 +857,19 @@ update_removed_uris_callback (GObject      *object,
  * nautilus_tag_manager_update_removed_uris:
  * @self: The tag manager singleton
  * @src: The deleted/trashed location as a #GFile
+ * @removed_uris: (out) (optional): Location for a #GPtrArray of removed URIs.
  *
  * Checks whether the deleted/trashed item @src was starred or contained starred
  * items, and erases the respective URIs from the database.
+ *
+ * If @removed_uris is not %NULL, creates an array with copies of the removed
+ * URIs which can be passed to nautilus_tag_manager_update_restored_uris() if
+ * the trashing operation is undone. If no URI is removed, the array is empty.
  */
 void
 nautilus_tag_manager_update_removed_uris (NautilusTagManager *self,
-                                          GFile              *src)
+                                          GFile              *src,
+                                          GPtrArray         **removed_uris)
 {
     GHashTableIter starred_iter;
     gchar *starred_uri;
@@ -892,6 +898,12 @@ nautilus_tag_manager_update_removed_uris (NautilusTagManager *self,
         }
     }
 
+    if (removed_uris != NULL)
+    {
+        *removed_uris = g_ptr_array_copy (broken_starred_uris, g_strdup, NULL);
+        g_ptr_array_set_free_func (*removed_uris, g_free);
+    }
+
     if (broken_starred_uris->len == 0)
     {
         /* No starred files are affected by this move/rename */
@@ -920,6 +932,87 @@ nautilus_tag_manager_update_removed_uris (NautilusTagManager *self,
                                             NULL);
 }
 
+static void
+update_restored_uris_callback (GObject      *object,
+                               GAsyncResult *result,
+                               gpointer      user_data)
+{
+    g_autoptr (GError) error = NULL;
+    g_autoptr (GPtrArray) restored_uris = user_data;
+
+    tracker_sparql_connection_update_finish (TRACKER_SPARQL_CONNECTION (object),
+                                             result,
+                                             &error);
+
+    if (error != NULL && error->code != G_IO_ERROR_CANCELLED)
+    {
+        g_warning ("Error restoring URIs of previously starred items: %s", error->message);
+    }
+    else
+    {
+        g_autolist (NautilusFile) restored_files = NULL;
+        g_autoptr (NautilusTagManager) tag_manager = NULL;
+
+        for (guint i = 0; i < restored_uris->len; i++)
+        {
+            gchar *restored_uri = g_ptr_array_index (restored_uris, i);
+
+            restored_files = g_list_prepend (restored_files, nautilus_file_get_by_uri (restored_uri));
+        }
+
+        tag_manager = nautilus_tag_manager_get ();
+        g_signal_emit_by_name (tag_manager, "starred-changed", restored_files);
+    }
+}
+
+/**
+ * nautilus_tag_manager_update_restored_uris:
+ * @self: The tag manager singleton
+ * @restored_uris: A #GPtrArray of previously starred URIs.
+ *
+ * Adds back URIs previously removed from database. To be used when a trashing
+ * operation is undone, such that restored items keep their starred status.
+ */
+void
+nautilus_tag_manager_update_restored_uris (NautilusTagManager *self,
+                                           GPtrArray          *restored_uris)
+{
+    g_autoptr (GString) query = NULL;
+
+    if (!self->database_ok)
+    {
+        g_message ("nautilus-tag-manager: No Tracker connection");
+        return;
+    }
+
+    if (restored_uris->len == 0)
+    {
+        /* No starred files were trashed in the undone operation */
+        return;
+    }
+
+    DEBUG ("Adding back %i previously trashed starred URIs", restored_uris->len);
+
+    query = g_string_new ("INSERT DATA {");
+
+    for (guint i = 0; i < restored_uris->len; i++)
+    {
+        gchar *new_uri = g_ptr_array_index (restored_uris, i);
+        g_string_append_printf (query,
+                                "    <%s> a nautilus:File ; "
+                                "        nautilus:starred true . ",
+                                new_uri);
+    }
+
+    g_string_append (query, "}");
+
+    tracker_sparql_connection_update_async (self->db,
+                                            query->str,
+                                            self->cancellable,
+                                            update_restored_uris_callback,
+                                            g_ptr_array_ref (restored_uris));
+}
+
 static void
 process_tracker2_data_cb (GObject      *source_object,
                           GAsyncResult *res,
diff --git a/src/nautilus-tag-manager.h b/src/nautilus-tag-manager.h
index dfc1e2d49..c70af1d2e 100644
--- a/src/nautilus-tag-manager.h
+++ b/src/nautilus-tag-manager.h
@@ -57,7 +57,10 @@ void                nautilus_tag_manager_update_moved_uris  (NautilusTagManager
                                                              GFile              *src,
                                                              GFile              *dest);
 void                nautilus_tag_manager_update_removed_uris  (NautilusTagManager *tag_manager,
-                                                               GFile              *src);
+                                                               GFile              *src,
+                                                               GPtrArray         **removed_uris);
+void                nautilus_tag_manager_update_restored_uris  (NautilusTagManager *tag_manager,
+                                                                GPtrArray          *restored_uris);
 
 void                nautilus_tag_manager_maybe_migrate_tracker2_data (NautilusTagManager *self);
 


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