[gtk/948-patch-renaming-a-file-can-make-it-to-loose-selection_GTK3] filechooser: keep file selected after being renamed



commit aff5c7ede6611ed645f48fef0cd678fdc2bb3e11
Author: Nelson Benítez León <nbenitezl gmail com>
Date:   Mon Aug 12 16:12:28 2019 -0400

    filechooser: keep file selected after being renamed
    
    Because otherwise when the file list is sorted "by name"
    and the new name causes the file to be re-sorted to another
    row, the selection stays in the old row which is now
    occupied by a different file.
    
    Fixed by keeping track of the renamed file and revealing
    it in the "row-changed" signal handler, which gets emitted
    after a file is renamed.
    
    Fixes issue #948

 gtk/gtkfilechooserwidget.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)
---
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index ce708670c9..fe9bceacdc 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -322,6 +322,7 @@ struct _GtkFileChooserWidgetPrivate {
   GFile *current_folder;
   GFile *preview_file;
   char *preview_display_name;
+  GFile *renamed_file;
 
   GtkTreeViewColumn *list_name_column;
   GtkCellRenderer *list_name_renderer;
@@ -703,6 +704,9 @@ gtk_file_chooser_widget_finalize (GObject *object)
   if (priv->browse_path_bar_size_group)
     g_object_unref (priv->browse_path_bar_size_group);
 
+  if (priv->renamed_file)
+    g_object_unref (priv->renamed_file);
+
   /* Free all the Models we have */
   stop_loading_and_clear_list_model (impl, FALSE);
   search_clear_model (impl, FALSE);
@@ -1596,6 +1600,9 @@ rename_file_rename_clicked (GtkButton            *button,
   new_name = gtk_entry_get_text (GTK_ENTRY (priv->rename_file_name_entry));
   dest = g_file_get_parent (priv->rename_file_source_file);
 
+  if (priv->renamed_file)
+    g_clear_object (&priv->renamed_file);
+
   if (dest)
     {
       GFile *child;
@@ -1607,6 +1614,12 @@ rename_file_rename_clicked (GtkButton            *button,
           if (!g_file_move (priv->rename_file_source_file, child, G_FILE_COPY_NONE,
                             NULL, NULL, NULL, &error))
             error_dialog (impl, _("The file could not be renamed"), error);
+          else
+            {
+              /* Rename succeded, save renamed file so it will
+               * be revealed by our "row-changed" handler */
+              priv->renamed_file = g_object_ref (child);
+            }
 
           g_object_unref (child);
         }
@@ -4673,6 +4686,36 @@ browse_files_model_finished_loading_cb (GtkFileSystemModel   *model,
   profile_end ("end", NULL);
 }
 
+/* Callback used when file system model adds or updates a file.
+ * We detect here when a new renamed file appears and reveal it */
+static void
+browse_files_model_row_changed_cb (GtkTreeModel *model,
+                                   GtkTreePath  *path,
+                                   GtkTreeIter  *iter,
+                                   gpointer      data)
+{
+  GtkFileChooserWidget *impl = data;
+  GtkFileChooserWidgetPrivate *priv = impl->priv;
+  GFile *file;
+  GSList files;
+
+  if (priv->renamed_file)
+    {
+      gtk_tree_model_get (model, iter, MODEL_COL_FILE, &file, -1);
+      if (g_file_equal (priv->renamed_file, file))
+        {
+          g_clear_object (&priv->renamed_file);
+
+          files.data = (gpointer) file;
+          files.next = NULL;
+
+          show_and_select_files (impl, &files);
+        }
+
+      g_object_unref (file);
+    }
+}
+
 static void
 stop_loading_and_clear_list_model (GtkFileChooserWidget *impl,
                                    gboolean              remove)
@@ -5113,6 +5156,9 @@ set_list_model (GtkFileChooserWidget  *impl,
   g_signal_connect (priv->browse_files_model, "finished-loading",
                     G_CALLBACK (browse_files_model_finished_loading_cb), impl);
 
+  g_signal_connect (priv->browse_files_model, "row-changed",
+                    G_CALLBACK (browse_files_model_row_changed_cb), impl);
+
   _gtk_file_system_model_set_filter (priv->browse_files_model, priv->current_filter);
 
   profile_end ("end", NULL);
@@ -8620,6 +8666,7 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
   priv->recent_manager = gtk_recent_manager_get_default ();
   priv->create_folders = TRUE;
   priv->auto_selecting_first_row = FALSE;
+  priv->renamed_file = NULL;
 
   /* Ensure GTK+ private types used by the template
    * definition before calling gtk_widget_init_template()


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