diff options
author | Ondrej Holy <oholy@redhat.com> | 2020-01-31 13:46:40 +0100 |
---|---|---|
committer | António Fernandes <antoniojpfernandes@gmail.com> | 2020-02-04 11:50:11 +0000 |
commit | 57f6eee32cabc76a2361c9f372285140215f43c0 (patch) | |
tree | 42fa5888e482fe0145c755da11fed96cf3c99140 | |
parent | a9cd85a7bc045ae4b4661f0e6f9ece362a26c0c3 (diff) | |
download | nautilus-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.c | 74 |
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. |