[nautilus/1344-be-a-little-more-helpful-with-renaming-duplicate-files: 129/130] file-conflict-dialog: Automatically suggest new name




commit bd6975f00e78cfa6bc61acb3792e91a2da75811a
Author: António Fernandes <antoniof gnome org>
Date:   Thu Jan 30 01:00:26 2020 +0000

    file-conflict-dialog: Automatically suggest new name
    
    When "Select new name for the destination" expander is selected, the
    users must type a new name in order to proceed.
    
    This makes them go and look at the destination to see what would even
    make a unique name.
    
    Let's be more helpful and suggest a unique name based on the original.
    
    Closes https://gitlab.gnome.org/GNOME/nautilus/issues/1344

 src/nautilus-file-conflict-dialog.c  | 10 ++++-
 src/nautilus-file-conflict-dialog.h  |  4 +-
 src/nautilus-operations-ui-manager.c | 74 ++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+), 2 deletions(-)
---
diff --git a/src/nautilus-file-conflict-dialog.c b/src/nautilus-file-conflict-dialog.c
index 8adb4bb14..c48bd7bfb 100644
--- a/src/nautilus-file-conflict-dialog.c
+++ b/src/nautilus-file-conflict-dialog.c
@@ -38,6 +38,7 @@ struct _NautilusFileConflictDialog
     GtkDialog parent_instance;
 
     gchar *conflict_name;
+    gchar *suggested_name;
 
     /* UI objects */
     GtkWidget *titles_vbox;
@@ -135,8 +136,14 @@ nautilus_file_conflict_dialog_set_conflict_name (NautilusFileConflictDialog *fcd
                                                  gchar                      *conflict_name)
 {
     fcd->conflict_name = g_strdup (conflict_name);
+}
 
-    gtk_entry_set_text (GTK_ENTRY (fcd->entry), fcd->conflict_name);
+void
+nautilus_file_conflict_dialog_set_suggested_name (NautilusFileConflictDialog *fcd,
+                                                  gchar                      *suggested_name)
+{
+    fcd->suggested_name = g_strdup (suggested_name);
+    gtk_entry_set_text (GTK_ENTRY (fcd->entry), suggested_name);
 }
 
 void
@@ -352,6 +359,7 @@ do_finalize (GObject *self)
     NautilusFileConflictDialog *dialog = NAUTILUS_FILE_CONFLICT_DIALOG (self);
 
     g_free (dialog->conflict_name);
+    g_free (dialog->suggested_name);
 
     G_OBJECT_CLASS (nautilus_file_conflict_dialog_parent_class)->finalize (self);
 }
diff --git a/src/nautilus-file-conflict-dialog.h b/src/nautilus-file-conflict-dialog.h
index e54071b02..e7d34f6fd 100644
--- a/src/nautilus-file-conflict-dialog.h
+++ b/src/nautilus-file-conflict-dialog.h
@@ -45,6 +45,8 @@ void nautilus_file_conflict_dialog_set_file_labels (NautilusFileConflictDialog *
                                                     gchar *source_label);
 void nautilus_file_conflict_dialog_set_conflict_name (NautilusFileConflictDialog *fcd,
                                                       gchar *conflict_name);
+void nautilus_file_conflict_dialog_set_suggested_name (NautilusFileConflictDialog *fcd,
+                                                       gchar *suggested_name);
 void nautilus_file_conflict_dialog_set_replace_button_label (NautilusFileConflictDialog *fcd,
                                                              gchar *label);
 
@@ -55,4 +57,4 @@ void nautilus_file_conflict_dialog_disable_apply_to_all (NautilusFileConflictDia
 char*      nautilus_file_conflict_dialog_get_new_name     (NautilusFileConflictDialog *dialog);
 gboolean   nautilus_file_conflict_dialog_get_apply_to_all (NautilusFileConflictDialog *dialog);
 
-G_END_DECLS
\ No newline at end of file
+G_END_DECLS
diff --git a/src/nautilus-operations-ui-manager.c b/src/nautilus-operations-ui-manager.c
index 790592f5a..9b00b773e 100644
--- a/src/nautilus-operations-ui-manager.c
+++ b/src/nautilus-operations-ui-manager.c
@@ -2,7 +2,10 @@
 
 #include "nautilus-operations-ui-manager.h"
 
+#include "eel/eel-vfs-extensions.h"
+
 #include "nautilus-file.h"
+#include "nautilus-directory.h"
 #include "nautilus-file-operations.h"
 #include "nautilus-file-conflict-dialog.h"
 #include "nautilus-mime-actions.h"
@@ -96,6 +99,8 @@ typedef struct
     NautilusFile *destination;
     NautilusFile *destination_directory_file;
 
+    NautilusDirectory *destination_directory;
+
     NautilusFileConflictDialog *dialog;
 
     NautilusFileListCallback on_file_list_ready;
@@ -369,6 +374,62 @@ file_icons_changed (NautilusFile           *file,
     set_images (data);
 }
 
+static void
+copy_move_conflict_on_directory_info_ready (NautilusDirectory *destination_directory,
+                                            GList             *file_list,
+                                            gpointer           user_data)
+{
+    FileConflictDialogData *data = user_data;
+    g_autolist (NautilusFile) files = NULL;
+    g_autofree gchar *destination_edit_name = NULL;
+    g_autofree gchar *filename_base = NULL;
+    g_autofree gchar *extension = NULL;
+    g_autofree gchar *suggested_name = NULL;
+    gint count;
+
+    files = nautilus_directory_get_file_list (destination_directory);
+    destination_edit_name = nautilus_file_get_edit_name (data->destination);
+    filename_base = eel_filename_strip_extension (destination_edit_name);
+    extension = g_strdup (destination_edit_name + strlen (filename_base));
+
+    count = 0;
+
+    while (count < G_MAXINT)
+    {
+        g_autofree gchar *count_string = NULL;
+        g_autofree gchar *test_name = NULL;
+        gboolean conflict_found;
+
+        count++;
+
+        count_string = g_strdup_printf (" (%d)", count);
+        test_name = g_strconcat (filename_base, count_string, extension, NULL);
+
+        conflict_found = FALSE;
+        for (GList *l = files; l != NULL; l = l->next)
+        {
+            g_autofree gchar *file_name = NULL;
+
+            file_name = nautilus_file_get_display_name (l->data);
+
+            if (g_strcmp0 (file_name, test_name) == 0)
+            {
+                conflict_found = TRUE;
+                break;
+            }
+        }
+
+        if (!conflict_found)
+        {
+            suggested_name = g_steal_pointer (&test_name);
+            break;
+        }
+    }
+
+    nautilus_file_conflict_dialog_set_suggested_name (data->dialog,
+                                                      suggested_name);
+}
+
 static void
 copy_move_conflict_on_file_list_ready (GList    *files,
                                        gpointer  user_data)
@@ -410,6 +471,12 @@ copy_move_conflict_on_file_list_ready (GList    *files,
                                                 G_CALLBACK (file_icons_changed), data);
     data->destination_handler_id = g_signal_connect (data->destination, "changed",
                                                      G_CALLBACK (file_icons_changed), data);
+
+    nautilus_directory_call_when_ready (data->destination_directory,
+                                        NAUTILUS_FILE_ATTRIBUTES_FOR_ICON,
+                                        TRUE,
+                                        copy_move_conflict_on_directory_info_ready,
+                                        data);
 }
 
 static gboolean
@@ -422,6 +489,7 @@ run_file_conflict_dialog (gpointer user_data)
     data->source = nautilus_file_get (data->source_name);
     data->destination = nautilus_file_get (data->destination_name);
     data->destination_directory_file = nautilus_file_get (data->destination_directory_name);
+    data->destination_directory = nautilus_directory_get (data->destination_directory_name);
 
     data->dialog = nautilus_file_conflict_dialog_new (data->parent);
 
@@ -442,6 +510,11 @@ run_file_conflict_dialog (gpointer user_data)
         nautilus_file_list_cancel_call_when_ready (data->handle);
     }
 
+    /* Cancel the callback added by on_file_list_ready() */
+    nautilus_directory_cancel_callback (data->destination_directory,
+                                        copy_move_conflict_on_directory_info_ready,
+                                        data);
+
     if (data->source_handler_id)
     {
         g_signal_handler_disconnect (data->source, data->source_handler_id);
@@ -473,6 +546,7 @@ run_file_conflict_dialog (gpointer user_data)
     nautilus_file_unref (data->source);
     nautilus_file_unref (data->destination);
     nautilus_file_unref (data->destination_directory_file);
+    nautilus_directory_unref (data->destination_directory);
     g_list_free (files);
 
     return G_SOURCE_REMOVE;


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