[nautilus] batch-rename: fix file reordering before the rename



commit fc4135d8124157d2435d66aceea5958ed643227d
Author: Alexandru Pandelea <alexandru pandelea gmail com>
Date:   Sun Oct 16 19:28:12 2016 +0300

    batch-rename: fix file reordering before the rename
    
    There are cases where the files are not reordered correctly.
    
    To fix this, the order of the files is checked until no more changes
    are made.
    
    In this patch, the reordering code is also extracted in a common function.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=771583

 src/nautilus-batch-rename-dialog.c    |   48 +------------
 src/nautilus-batch-rename-utilities.c |  114 ++++++++++++++++++++++++++++++
 src/nautilus-batch-rename-utilities.h |    7 ++
 src/nautilus-file-undo-operations.c   |  125 ++++-----------------------------
 4 files changed, 137 insertions(+), 157 deletions(-)
---
diff --git a/src/nautilus-batch-rename-dialog.c b/src/nautilus-batch-rename-dialog.c
index e135f64..20f99de 100644
--- a/src/nautilus-batch-rename-dialog.c
+++ b/src/nautilus-batch-rename-dialog.c
@@ -474,53 +474,7 @@ static void
 begin_batch_rename (NautilusBatchRenameDialog *dialog,
                     GList                     *new_names)
 {
-    GList *new_names_list;
-    GList *files;
-    GList *files2;
-    GList *new_names_list2;
-    gchar *file_name;
-    gchar *old_file_name;
-    GString *new_file_name;
-    GString *new_name;
-    NautilusFile *file;
-
-    /* in the following case:
-     * file1 -> file2
-     * file2 -> file3
-     * file2 must be renamed first, so because of that, the list has to be reordered */
-    for (new_names_list = new_names, files = dialog->selection;
-         new_names_list != NULL && files != NULL;
-         new_names_list = new_names_list->next, files = files->next)
-    {
-        old_file_name = nautilus_file_get_name (NAUTILUS_FILE (files->data));
-        new_file_name = new_names_list->data;
-
-        for (files2 = dialog->selection, new_names_list2 = new_names;
-             files2 != NULL && new_names_list2 != NULL;
-             files2 = files2->next, new_names_list2 = new_names_list2->next)
-        {
-            file_name = nautilus_file_get_name (NAUTILUS_FILE (files2->data));
-            if (files2 != files && g_strcmp0 (file_name, new_file_name->str) == 0)
-            {
-                file = NAUTILUS_FILE (files2->data);
-                new_name = new_names_list2->data;
-
-                dialog->selection = g_list_remove_link (dialog->selection, files2);
-                new_names = g_list_remove_link (new_names, new_names_list2);
-
-                dialog->selection = g_list_prepend (dialog->selection, file);
-                new_names = g_list_prepend (new_names, new_name);
-
-                g_free (file_name);
-
-                break;
-            }
-
-            g_free (file_name);
-        }
-
-        g_free (old_file_name);
-    }
+    batch_rename_sort_lists_for_rename (&dialog->selection, &new_names, NULL, NULL, NULL, FALSE);
 
     /* do the actual rename here */
     nautilus_file_batch_rename (dialog->selection, new_names, NULL, NULL);
diff --git a/src/nautilus-batch-rename-utilities.c b/src/nautilus-batch-rename-utilities.c
index 95fd358..9349666 100644
--- a/src/nautilus-batch-rename-utilities.c
+++ b/src/nautilus-batch-rename-utilities.c
@@ -139,6 +139,120 @@ batch_rename_replace (gchar *string,
     return new_string;
 }
 
+void
+batch_rename_sort_lists_for_rename (GList    **selection,
+                                    GList    **new_names,
+                                    GList    **old_names,
+                                    GList    **new_files,
+                                    GList    **old_files,
+                                    gboolean   is_undo_redo)
+{
+    GList *new_names_list;
+    GList *new_names_list2;
+    GList *files;
+    GList *files2;
+    GList *old_names_list = NULL;
+    GList *new_files_list = NULL;
+    GList *old_files_list = NULL;
+    GList *old_names_list2 = NULL;
+    GList *new_files_list2 = NULL;
+    GList *old_files_list2 = NULL;
+    GString *new_file_name;
+    GString *new_name;
+    GString *old_name;
+    GFile *new_file;
+    GFile *old_file;
+    NautilusFile *file;
+    gboolean order_changed = TRUE;
+
+    /* in the following case:
+     * file1 -> file2
+     * file2 -> file3
+     * file2 must be renamed first, so because of that, the list has to be reordered
+     */
+    while (order_changed)
+    {
+        order_changed = FALSE;
+
+        if (is_undo_redo)
+        {
+            old_names_list = *old_names;
+            new_files_list = *new_files;
+            old_files_list = *old_files;
+        }
+
+        for (new_names_list = *new_names, files = *selection;
+             new_names_list != NULL && files != NULL;
+             new_names_list = new_names_list->next, files = files->next)
+        {
+            g_autofree gchar *old_file_name = NULL;
+
+            old_file_name = nautilus_file_get_name (NAUTILUS_FILE (files->data));
+            new_file_name = new_names_list->data;
+
+            if (is_undo_redo)
+            {
+                old_names_list2 = old_names_list;
+                new_files_list2 = new_files_list;
+                old_files_list2 = old_files_list;
+            }
+
+            for (files2 = files, new_names_list2 = new_names_list;
+                 files2 != NULL && new_names_list2 != NULL;
+                 files2 = files2->next, new_names_list2 = new_names_list2->next)
+            {
+                g_autofree gchar *file_name = NULL;
+
+                file_name = nautilus_file_get_name (NAUTILUS_FILE (files2->data));
+                new_name = new_names_list2->data;
+
+                if (files2 != files && g_strcmp0 (file_name, new_file_name->str) == 0)
+                {
+                    file = NAUTILUS_FILE (files2->data);
+
+                    *selection = g_list_remove_link (*selection, files2);
+                    *new_names = g_list_remove_link (*new_names, new_names_list2);
+
+                    *selection = g_list_prepend (*selection, file);
+                    *new_names = g_list_prepend (*new_names, new_name);
+
+                    if (is_undo_redo)
+                    {
+                        old_name = old_names_list2->data;
+                        new_file = new_files_list2->data;
+                        old_file = old_files_list2->data;
+
+                        *old_names = g_list_remove_link (*old_names, old_names_list2);
+                        *new_files = g_list_remove_link (*new_files, new_files_list2);
+                        *old_files = g_list_remove_link (*old_files, old_files_list2);
+
+                        *old_names = g_list_prepend (*old_names, old_name);
+                        *new_files = g_list_prepend (*new_files, new_file);
+                        *old_files = g_list_prepend (*old_files, old_file);
+                    }
+
+                    order_changed = TRUE;
+                    break;
+                }
+
+                if (is_undo_redo)
+                {
+                    old_names_list2 = old_names_list2->next;
+                    new_files_list2 = new_files_list2->next;
+                    old_files_list2 = old_files_list2->next;
+                }
+            }
+
+            if (is_undo_redo)
+            {
+                old_names_list = old_names_list->next;
+                new_files_list = new_files_list->next;
+                old_files_list = old_files_list->next;
+            }
+        }
+    }
+}
+
 /* This function changes the background color of the replaced part of the name */
 GString *
 batch_rename_replace_label_text (gchar       *label,
diff --git a/src/nautilus-batch-rename-utilities.h b/src/nautilus-batch-rename-utilities.h
index 49631b7..178f1ae 100644
--- a/src/nautilus-batch-rename-utilities.h
+++ b/src/nautilus-batch-rename-utilities.h
@@ -62,4 +62,11 @@ GString* batch_rename_replace_label_text        (gchar             *label,
 
 gchar*   batch_rename_get_tag_text_representation (TagConstants tag_constants);
 
+void batch_rename_sort_lists_for_rename (GList    **selection,
+                                         GList    **new_names,
+                                         GList    **old_names,
+                                         GList    **new_files,
+                                         GList    **old_files,
+                                         gboolean   is_undo_redo);
+
 #endif /* NAUTILUS_BATCH_RENAME_UTILITIES_H */
diff --git a/src/nautilus-file-undo-operations.c b/src/nautilus-file-undo-operations.c
index 61a789d..19d7d90 100644
--- a/src/nautilus-file-undo-operations.c
+++ b/src/nautilus-file-undo-operations.c
@@ -31,6 +31,9 @@
 #include "nautilus-file-operations.h"
 #include "nautilus-file.h"
 #include "nautilus-file-undo-manager.h"
+#include "nautilus-batch-rename-dialog.h"
+#include "nautilus-batch-rename-utilities.h"
+
 
 /* Since we use g_get_current_time for setting "orig_trash_time" in the undo
  * info, there are situations where the difference between this value and the
@@ -1125,19 +1128,6 @@ batch_rename_redo_func (NautilusFileUndoInfo *info,
     GList *l, *files;
     NautilusFile *file;
     GFile *old_file;
-    GFile *new_file;
-    GList *l1;
-    GList *l2;
-    GList *l3;
-    GList *l4;
-    GList *l5;
-    GList *l6;
-    GList *l7;
-    gchar *file_name;
-    gchar *old_file_name;
-    GString *new_file_name;
-    GString *new_name;
-    GString *old_name;
 
     files = NULL;
 
@@ -1149,48 +1139,12 @@ batch_rename_redo_func (NautilusFileUndoInfo *info,
         files = g_list_prepend (files, file);
     }
 
-    files = g_list_reverse (files);
-
-    for (l1 = self->priv->new_display_names, l2 = files; l1 != NULL && l2 != NULL; l1 = l1->next, l2 = 
l2->next)
-    {
-        old_file_name = nautilus_file_get_name (NAUTILUS_FILE (l2->data));
-        new_file_name = l1->data;
-
-        for (l3 = files, l4 = self->priv->new_display_names, l5 = self->priv->old_display_names, l6 = 
self->priv->old_files, l7 = self->priv->new_files;
-             l3 != NULL && l4 != NULL && l5 != NULL && l6 != NULL && l7 != NULL;
-             l3 = l3->next, l4 = l4->next, l5 = l5->next, l6 = l6->next, l7 = l7->next)
-        {
-            file_name = nautilus_file_get_name (NAUTILUS_FILE (l3->data));
-            if (l3 != l2 && g_strcmp0 (file_name, new_file_name->str) == 0)
-            {
-                file = NAUTILUS_FILE (l3->data);
-                new_name = l4->data;
-                old_name = l5->data;
-                old_file = l6->data;
-                new_file = l7->data;
-
-                files = g_list_remove_link (files, l3);
-                self->priv->new_display_names = g_list_remove_link (self->priv->new_display_names, l4);
-                self->priv->old_display_names = g_list_remove_link (self->priv->old_display_names, l5);
-                self->priv->old_files = g_list_remove_link (self->priv->old_files, l6);
-                self->priv->new_files = g_list_remove_link (self->priv->new_files, l7);
-
-                files = g_list_prepend (files, file);
-                self->priv->new_display_names = g_list_prepend (self->priv->new_display_names, new_name);
-                self->priv->old_display_names = g_list_prepend (self->priv->old_display_names, old_name);
-                self->priv->old_files = g_list_prepend (self->priv->old_files, old_file);
-                self->priv->new_files = g_list_prepend (self->priv->new_files, new_file);
-
-                g_free (file_name);
-
-                break;
-            }
-
-            g_free (file_name);
-        }
-
-        g_free (old_file_name);
-    }
+    batch_rename_sort_lists_for_rename (&files,
+                                        &self->priv->new_display_names,
+                                        &self->priv->old_display_names,
+                                        &self->priv->new_files,
+                                        &self->priv->old_files,
+                                        TRUE);
 
     nautilus_file_batch_rename (files, self->priv->new_display_names, file_undo_info_operation_callback, 
self);
 }
@@ -1204,19 +1158,6 @@ batch_rename_undo_func (NautilusFileUndoInfo *info,
     GList *l, *files;
     NautilusFile *file;
     GFile *new_file;
-    GFile *old_file;
-    GList *l1;
-    GList *l2;
-    GList *l3;
-    GList *l4;
-    GList *l5;
-    GList *l6;
-    GList *l7;
-    gchar *file_name;
-    gchar *old_file_name;
-    GString *new_file_name;
-    GString *new_name;
-    GString *old_name;
 
     files = NULL;
 
@@ -1228,48 +1169,12 @@ batch_rename_undo_func (NautilusFileUndoInfo *info,
         files = g_list_prepend (files, file);
     }
 
-    files = g_list_reverse (files);
-
-    for (l1 = self->priv->old_display_names, l2 = files; l1 != NULL && l2 != NULL; l1 = l1->next, l2 = 
l2->next)
-    {
-        old_file_name = nautilus_file_get_name (NAUTILUS_FILE (l2->data));
-        new_file_name = l1->data;
-
-        for (l3 = files, l4 = self->priv->old_display_names, l5 = self->priv->new_display_names, l6 = 
self->priv->old_files, l7 = self->priv->new_files;
-             l3 != NULL && l4 != NULL && l5 != NULL && l6 != NULL && l7 != NULL;
-             l3 = l3->next, l4 = l4->next, l5 = l5->next, l6 = l6->next, l7 = l7->next)
-        {
-            file_name = nautilus_file_get_name (NAUTILUS_FILE (l3->data));
-            if (l3 != l2 && g_strcmp0 (file_name, new_file_name->str) == 0)
-            {
-                file = NAUTILUS_FILE (l3->data);
-                new_name = l4->data;
-                old_name = l5->data;
-                old_file = l6->data;
-                new_file = l7->data;
-
-                files = g_list_remove_link (files, l3);
-                self->priv->old_display_names = g_list_remove_link (self->priv->old_display_names, l4);
-                self->priv->new_display_names = g_list_remove_link (self->priv->new_display_names, l5);
-                self->priv->old_files = g_list_remove_link (self->priv->old_files, l6);
-                self->priv->new_files = g_list_remove_link (self->priv->new_files, l7);
-
-                files = g_list_prepend (files, file);
-                self->priv->old_display_names = g_list_prepend (self->priv->old_display_names, new_name);
-                self->priv->new_display_names = g_list_prepend (self->priv->new_display_names, old_name);
-                self->priv->old_files = g_list_prepend (self->priv->old_files, old_file);
-                self->priv->new_files = g_list_prepend (self->priv->new_files, new_file);
-
-                g_free (file_name);
-
-                break;
-            }
-
-            g_free (file_name);
-        }
-
-        g_free (old_file_name);
-    }
+    batch_rename_sort_lists_for_rename (&files,
+                                        &self->priv->old_display_names,
+                                        &self->priv->new_display_names,
+                                        &self->priv->old_files,
+                                        &self->priv->new_files,
+                                        TRUE);
 
     nautilus_file_batch_rename (files, self->priv->old_display_names, file_undo_info_operation_callback, 
self);
 }


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