[nautilus/wip/antoniof/update-starred-uris] tag-manager: Update starred URIs on move & rename




commit 024ae63c6a77aa0d5c94b6e2187daa675733e964
Author: António Fernandes <antoniof gnome org>
Date:   Wed Sep 9 23:32:01 2020 +0100

    tag-manager: Update starred URIs on move & rename
    
    We don't rely on tracker-miner-fs's rename tracking for starred files
    anymore, as explained in 29105fc9f6abf2eca6f986104763d21b9f22f0fb.
    
    However, losing track of starred files, when they or their containing
    folders are renamed or moved, is a major regression for this feature.
    
    The common case is that the operation is performed using this very app,
    so, we can largely restore the feature by updating URI on every rename
    and move operation we perform.

 src/nautilus-file-operations.c |  11 +++++
 src/nautilus-file.c            |  13 ++++-
 src/nautilus-tag-manager.c     | 110 +++++++++++++++++++++++++++++++++++++++++
 src/nautilus-tag-manager.h     |   3 ++
 4 files changed, 135 insertions(+), 2 deletions(-)
---
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c
index c61c3d9ef..3aebfb6e6 100644
--- a/src/nautilus-file-operations.c
+++ b/src/nautilus-file-operations.c
@@ -59,6 +59,7 @@
 #include "nautilus-file-utilities.h"
 #include "nautilus-file-undo-operations.h"
 #include "nautilus-file-undo-manager.h"
+#include "nautilus-tag-manager.h"
 #include "nautilus-ui-utilities.h"
 
 #ifdef GDK_WINDOWING_X11
@@ -5451,6 +5452,13 @@ retry:
                                                                 src, dest);
         }
 
+        if (copy_job->is_move)
+        {
+            g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get ();
+
+            nautilus_tag_manager_update_moved_uris (tag_manager, src, dest);
+        }
+
         g_object_unref (dest);
         return;
     }
@@ -6159,12 +6167,15 @@ retry:
                      NULL,
                      &error))
     {
+        g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get ();
+
         if (debuting_files)
         {
             g_hash_table_replace (debuting_files, g_object_ref (dest), GINT_TO_POINTER (TRUE));
         }
 
         nautilus_file_changes_queue_file_moved (src, dest);
+        nautilus_tag_manager_update_moved_uris (tag_manager, src, dest);
 
         dest_uri = g_file_get_uri (dest);
 
diff --git a/src/nautilus-file.c b/src/nautilus-file.c
index ff902db12..572183f97 100644
--- a/src/nautilus-file.c
+++ b/src/nautilus-file.c
@@ -1853,6 +1853,10 @@ rename_get_info_callback (GObject      *source_object,
     new_info = g_file_query_info_finish (G_FILE (source_object), res, &error);
     if (new_info != NULL)
     {
+        g_autoptr (NautilusTagManager) tag_manager = nautilus_tag_manager_get ();
+        g_autoptr (GFile) old_location = NULL;
+        g_autoptr (GFile) new_location = NULL;
+
         directory = op->file->details->directory;
 
         new_name = g_file_info_get_name (new_info);
@@ -1868,12 +1872,17 @@ rename_get_info_callback (GObject      *source_object,
             nautilus_file_changed (existing_file);
         }
 
-        old_uri = nautilus_file_get_uri (op->file);
+        old_location = nautilus_file_get_location (op->file);
+        old_uri = g_file_get_uri (old_location);
 
         update_info_and_name (op->file, new_info);
 
-        new_uri = nautilus_file_get_uri (op->file);
+        new_location = nautilus_file_get_location (op->file);
+        new_uri = g_file_get_uri (new_location);
+
         nautilus_directory_moved (old_uri, new_uri);
+        nautilus_tag_manager_update_moved_uris (tag_manager, old_location, new_location);
+
         g_free (new_uri);
         g_free (old_uri);
 
diff --git a/src/nautilus-tag-manager.c b/src/nautilus-tag-manager.c
index fbd8571e5..92121531e 100644
--- a/src/nautilus-tag-manager.c
+++ b/src/nautilus-tag-manager.c
@@ -700,6 +700,116 @@ nautilus_tag_manager_can_star_contents (NautilusTagManager *tag_manager,
     return g_file_has_prefix (directory, tag_manager->home) || g_file_equal (directory, tag_manager->home);
 }
 
+static void
+update_moved_uris_callback (GObject      *object,
+                            GAsyncResult *result,
+                            gpointer      user_data)
+{
+    g_autoptr (GError) error = NULL;
+    GList *new_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 updating moved uris: %s", error->message);
+    }
+    else
+    {
+        g_autoptr (NautilusTagManager) tag_manager = NULL;
+        g_autolist (NautilusFile) updated_files = NULL;
+
+        tag_manager = nautilus_tag_manager_get ();
+        updated_files = g_list_copy_deep (new_uris, (GCopyFunc) nautilus_file_get_by_uri, NULL);
+        g_signal_emit_by_name (tag_manager, "starred-changed", updated_files);
+    }
+
+    g_list_free_full (new_uris, (GDestroyNotify) g_free);
+}
+
+void
+nautilus_tag_manager_update_moved_uris (NautilusTagManager *self,
+                                        GFile              *src,
+                                        GFile              *dest)
+{
+    g_autoptr (GList) starred_files = NULL;
+    g_autoptr (GString) query = NULL;
+    g_autoptr (GList) old_uris = NULL;
+    g_autoptr (GList) new_uris = NULL;
+
+    if (!self->database_ok)
+    {
+        g_message ("nautilus-tag-manager: No Tracker connection");
+        return;
+    }
+
+    starred_files = nautilus_tag_manager_get_starred_files (self);
+    for (GList *l = starred_files; l != NULL; l = l->next)
+    {
+        g_autoptr (GFile) starred_location = NULL;
+        g_autofree gchar *relative_path = NULL;
+
+        starred_location = g_file_new_for_uri (l->data);
+
+        if (g_file_equal (starred_location, src))
+        {
+            old_uris = g_list_prepend (old_uris, l->data);
+            new_uris = g_list_prepend (new_uris, g_file_get_uri (dest));
+            continue;
+        }
+
+        relative_path = g_file_get_relative_path (src, starred_location);
+        if (relative_path != NULL)
+        {
+            g_autoptr (GFile) new_location = NULL;
+
+            new_location = g_file_resolve_relative_path (dest, relative_path);
+
+            old_uris = g_list_prepend (old_uris, l->data);
+            new_uris = g_list_prepend (new_uris, g_file_get_uri (new_location));
+        }
+    }
+
+    if (new_uris == NULL)
+    {
+        return;
+    }
+
+    DEBUG ("Updating moved URI for %i starred files", g_list_length (new_uris));
+
+    query = g_string_new ("DELETE DATA {");
+
+    for (GList *l = old_uris; l != NULL; l = l->next)
+    {
+        gchar *old_uri = l->data;
+        g_string_append_printf (query,
+                                "    <%s> a nautilus:File ; "
+                                "        nautilus:starred true . ",
+                                old_uri);
+    }
+
+    g_string_append (query, "} ; INSERT DATA {");
+
+    for (GList *l = new_uris; l != NULL; l = l->next)
+    {
+        gchar *new_uri = l->data;
+        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_moved_uris_callback,
+                                            g_steal_pointer (&new_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 2e926ae75..1ba8a48dd 100644
--- a/src/nautilus-tag-manager.h
+++ b/src/nautilus-tag-manager.h
@@ -53,6 +53,9 @@ gboolean            nautilus_tag_manager_file_is_starred   (NautilusTagManager *
 
 gboolean            nautilus_tag_manager_can_star_contents (NautilusTagManager *self,
                                                             GFile              *directory);
+void                nautilus_tag_manager_update_moved_uris  (NautilusTagManager *tag_manager,
+                                                             GFile              *src,
+                                                             GFile              *dest);
 
 void                nautilus_tag_manager_maybe_migrate_tracker2_data (NautilusTagManager *self);
 


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