summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2020-01-31 13:46:40 +0100
committerAntónio Fernandes <antoniojpfernandes@gmail.com>2020-02-04 11:50:11 +0000
commit57f6eee32cabc76a2361c9f372285140215f43c0 (patch)
tree42fa5888e482fe0145c755da11fed96cf3c99140
parenta9cd85a7bc045ae4b4661f0e6f9ece362a26c0c3 (diff)
downloadnautilus-57f6eee32cabc76a2361c9f372285140215f43c0.tar.gz
file-operations: Fix conflict dialog for google-drive
Conflict dialog doesn't work properly for google-drive files, because G_IO_ERROR_EXISTS can be returned even if a destination file based on a basename of a source file doesn't exists. This happens when a destination directory already contains some file with the same display_name as the source file has. Usually, display_name is based on filename, but google-drive is not traditional filesystem and uses unique IDs for files. Although, google-drive supports multiple files with the same display_bane in one folder, the copy and move operations behave traditionally and tries to overwrite existing files with the same title. Let's base the destination file on display_name for google-drive to fix issues with the conflict dialog. See: https://gitlab.gnome.org/GNOME/gvfs/merge_requests/58
-rw-r--r--src/nautilus-file-operations.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c
index e288a9afe..acf65f3cf 100644
--- a/src/nautilus-file-operations.c
+++ b/src/nautilus-file-operations.c
@@ -5049,6 +5049,57 @@ get_target_file_for_display_name (GFile *dir,
return dest;
}
+/* This is a workaround to resolve broken conflict dialog for google-drive
+ * locations. This is needed to provide POSIX-like behavior for google-drive
+ * filesystem, where each file has an unique identificator that is not tied to
+ * its display_name. See the following MR for more details:
+ * https://gitlab.gnome.org/GNOME/nautilus/merge_requests/514.
+ */
+static GFile *
+get_target_file_from_source_display_name (CopyMoveJob *copy_job,
+ GFile *src,
+ GFile *dir)
+{
+ CommonJob *job;
+ g_autoptr (GError) error = NULL;
+ g_autoptr (GFileInfo) info = NULL;
+ gchar *primary, *secondary;
+ GFile *dest = NULL;
+
+ job = (CommonJob *) copy_job;
+
+ info = g_file_query_info (src, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, &error);
+ if (info == NULL)
+ {
+ if (copy_job->is_move)
+ {
+ primary = g_strdup (_("Error while moving."));
+ }
+ else
+ {
+ primary = g_strdup (_("Error while copying."));
+ }
+ secondary = g_strdup (_("There was an error getting information about the source."));
+
+ run_error (job,
+ primary,
+ secondary,
+ error->message,
+ FALSE,
+ CANCEL,
+ NULL);
+
+ abort_job (job);
+ }
+ else
+ {
+ dest = get_target_file_for_display_name (dir, g_file_info_get_display_name (info));
+ }
+
+ return dest;
+}
+
+
/* Debuting files is non-NULL only for toplevel items */
static void
copy_move_file (CopyMoveJob *copy_job,
@@ -5102,6 +5153,15 @@ copy_move_file (CopyMoveJob *copy_job,
dest = get_target_file_with_custom_name (src, dest_dir, *dest_fs_type, same_fs,
copy_job->target_name);
}
+ else if (g_file_has_uri_scheme (src, "google-drive") &&
+ g_file_has_uri_scheme (dest_dir, "google-drive"))
+ {
+ dest = get_target_file_from_source_display_name (copy_job, src, dest_dir);
+ if (dest == NULL)
+ {
+ return;
+ }
+ }
else
{
dest = get_target_file (src, dest_dir, *dest_fs_type, same_fs);
@@ -5901,7 +5961,19 @@ move_file_prepare (CopyMoveJob *move_job,
job = (CommonJob *) move_job;
- dest = get_target_file (src, dest_dir, *dest_fs_type, same_fs);
+ if (g_file_has_uri_scheme (src, "google-drive") &&
+ g_file_has_uri_scheme (dest_dir, "google-drive"))
+ {
+ dest = get_target_file_from_source_display_name (move_job, src, dest_dir);
+ if (dest == NULL)
+ {
+ return;
+ }
+ }
+ else
+ {
+ dest = get_target_file (src, dest_dir, *dest_fs_type, same_fs);
+ }
/* Don't allow recursive move/copy into itself.