[gtk/file-chooser-api-cleanup-2: 24/24] filechooser: Make get_files return a list model



commit 89bf8af8784513cf95b31812a1c7fb68753b9b87
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Jul 9 01:29:20 2020 -0400

    filechooser: Make get_files return a list model
    
    Like the other list getters in this interface,
    make gtk_file_chooser_get_files() return a
    list model.

 gtk/gtkfilechooser.c        | 31 ++++++++----------
 gtk/gtkfilechooser.h        |  2 +-
 gtk/gtkfilechooserbutton.c  | 16 +++++++---
 gtk/gtkfilechooserdialog.c  |  6 ++--
 gtk/gtkfilechoosernative.c  | 13 ++++++--
 gtk/gtkfilechooserprivate.h |  2 +-
 gtk/gtkfilechooserutils.c   |  4 +--
 gtk/gtkfilechooserwidget.c  | 55 +++++++++++++++++++++-----------
 tests/testfilechooser.c     | 78 +++++++++++++++++++--------------------------
 tests/testgtk.c             | 14 +++++---
 10 files changed, 120 insertions(+), 101 deletions(-)
---
diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c
index b77652bd1c..ff70023af9 100644
--- a/gtk/gtkfilechooser.c
+++ b/gtk/gtkfilechooser.c
@@ -508,16 +508,15 @@ gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
 /**
  * gtk_file_chooser_get_files:
  * @chooser: a #GtkFileChooser
- * 
- * Lists all the selected files and subfolders in the current folder of @chooser
- * as #GFile.
  *
- * Returns: (element-type GFile) (transfer full): a list
- *   containing a #GFile for each selected file and subfolder in the
- *   current folder.  Free the returned list with g_slist_free(), and
- *   the files with g_object_unref().
- **/
-GSList *
+ * Lists all the selected files and subfolders in the current folder
+ * of @chooser as #GFile.
+ *
+ * Returns: (transfer full): a list model containing a #GFile for each
+ *     selected file and subfolder in the current folder. Free the returned
+ *     list with g_object_unref().
+ */
+GListModel *
 gtk_file_chooser_get_files (GtkFileChooser *chooser)
 {
   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
@@ -597,19 +596,15 @@ gtk_file_chooser_set_file (GtkFileChooser  *chooser,
 GFile *
 gtk_file_chooser_get_file (GtkFileChooser *chooser)
 {
-  GSList *list;
+  GListModel *list;
   GFile *result = NULL;
-  
+
   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
 
   list = gtk_file_chooser_get_files (chooser);
-  if (list)
-    {
-      result = list->data;
-      list = g_slist_delete_link (list, list);
-
-      g_slist_free_full (list, g_object_unref);
-    }
+  if (g_list_model_get_n_items (list) > 0)
+    result = g_list_model_get_item (list, 0);
+  g_object_unref (list);
 
   return result;
 }
diff --git a/gtk/gtkfilechooser.h b/gtk/gtkfilechooser.h
index b3b5aec9b8..9fd20da3c9 100644
--- a/gtk/gtkfilechooser.h
+++ b/gtk/gtkfilechooser.h
@@ -123,7 +123,7 @@ gboolean             gtk_file_chooser_set_file            (GtkFileChooser
                                                            GFile                *file,
                                                            GError              **error);
 GDK_AVAILABLE_IN_ALL
-GSList *             gtk_file_chooser_get_files           (GtkFileChooser       *chooser);
+GListModel *         gtk_file_chooser_get_files           (GtkFileChooser       *chooser);
 GDK_AVAILABLE_IN_ALL
 gboolean             gtk_file_chooser_set_current_folder  (GtkFileChooser       *chooser,
                                                            GFile                *file,
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index 97bd4eab90..c8d24fdb33 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -244,7 +244,7 @@ static gboolean gtk_file_chooser_button_select_file (GtkFileChooser *chooser,
 static void gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser,
                                                   GFile          *file);
 static void gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser);
-static GSList *gtk_file_chooser_button_get_files (GtkFileChooser *chooser);
+static GListModel *gtk_file_chooser_button_get_files (GtkFileChooser *chooser);
 static gboolean gtk_file_chooser_button_add_shortcut_folder     (GtkFileChooser      *chooser,
                                                                 GFile               *file,
                                                                 GError             **error);
@@ -750,17 +750,23 @@ get_selected_file (GtkFileChooserButton *button)
     return NULL;
 }
 
-static GSList *
+static GListModel *
 gtk_file_chooser_button_get_files (GtkFileChooser *chooser)
 {
   GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
   GFile *file;
+  GListStore *store;
+
+  store = g_list_store_new (G_TYPE_FILE);
 
   file = get_selected_file (button);
   if (file)
-    return g_slist_prepend (NULL, file);
-  else
-    return NULL;
+    {
+      g_list_store_append (store, file);
+      g_object_unref (file);
+    }
+
+  return G_LIST_MODEL (store);
 }
 
 static gboolean
diff --git a/gtk/gtkfilechooserdialog.c b/gtk/gtkfilechooserdialog.c
index 46ce76e4d7..dd22c08a7e 100644
--- a/gtk/gtkfilechooserdialog.c
+++ b/gtk/gtkfilechooserdialog.c
@@ -381,7 +381,7 @@ file_chooser_widget_selection_changed (GtkWidget            *widget,
 {
   GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (dialog);
   GtkWidget *button;
-  GSList *files;
+  GListModel *files;
   gboolean sensitive;
 
   button = get_accept_action_widget (GTK_DIALOG (dialog), FALSE);
@@ -389,10 +389,10 @@ file_chooser_widget_selection_changed (GtkWidget            *widget,
     return;
 
   files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (priv->widget));
-  sensitive = (files != NULL);
+  sensitive = (g_list_model_get_n_items (files) > 0);
   gtk_widget_set_sensitive (button, sensitive);
 
-  g_slist_free_full (files, g_object_unref);
+  g_object_unref (files);
 }
 
 static void
diff --git a/gtk/gtkfilechoosernative.c b/gtk/gtkfilechoosernative.c
index 4eb46e4a4e..d4c6563d25 100644
--- a/gtk/gtkfilechoosernative.c
+++ b/gtk/gtkfilechoosernative.c
@@ -683,7 +683,7 @@ gtk_file_chooser_native_set_current_name (GtkFileChooser    *chooser,
   g_clear_object (&self->current_file);
 }
 
-static GSList *
+static GListModel *
 gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
 {
   GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
@@ -693,7 +693,16 @@ gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
     case MODE_PORTAL:
     case MODE_WIN32:
     case MODE_QUARTZ:
-      return g_slist_copy_deep (self->custom_files, (GCopyFunc)g_object_ref, NULL);
+      {
+        GListStore *store;
+        GSList *l;
+
+        store = g_list_store_new (G_TYPE_FILE);
+        for (l = self->custom_files; l; l = l->next)
+          g_list_store_append (store, l->data);
+
+        return G_LIST_MODEL (store);
+      }
 
     case MODE_FALLBACK:
     default:
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index a88fe367f7..092d785eb9 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -72,7 +72,7 @@ struct _GtkFileChooserIface
                                             GFile             *file);
   void           (*select_all)             (GtkFileChooser    *chooser);
   void           (*unselect_all)           (GtkFileChooser    *chooser);
-  GSList *       (*get_files)              (GtkFileChooser    *chooser);
+  GListModel *   (*get_files)              (GtkFileChooser    *chooser);
   GtkFileSystem *(*get_file_system)        (GtkFileChooser    *chooser);
   void           (*add_filter)             (GtkFileChooser    *chooser,
                                             GtkFileFilter     *filter);
diff --git a/gtk/gtkfilechooserutils.c b/gtk/gtkfilechooserutils.c
index d41d9513cb..d05585c299 100644
--- a/gtk/gtkfilechooserutils.c
+++ b/gtk/gtkfilechooserutils.c
@@ -39,7 +39,7 @@ static void           delegate_unselect_file          (GtkFileChooser    *choose
                                                       GFile             *file);
 static void           delegate_select_all             (GtkFileChooser    *chooser);
 static void           delegate_unselect_all           (GtkFileChooser    *chooser);
-static GSList *       delegate_get_files              (GtkFileChooser    *chooser);
+static GListModel *   delegate_get_files              (GtkFileChooser    *chooser);
 static GtkFileSystem *delegate_get_file_system        (GtkFileChooser    *chooser);
 static void           delegate_add_filter             (GtkFileChooser    *chooser,
                                                       GtkFileFilter     *filter);
@@ -221,7 +221,7 @@ delegate_unselect_all (GtkFileChooser *chooser)
   gtk_file_chooser_unselect_all (get_delegate (chooser));
 }
 
-static GSList *
+static GListModel *
 delegate_get_files (GtkFileChooser *chooser)
 {
   return gtk_file_chooser_get_files (get_delegate (chooser));
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index 3551463c23..9a6f3b31fe 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -479,7 +479,7 @@ static void           gtk_file_chooser_widget_unselect_file                (GtkF
                                                                             GFile             *file);
 static void           gtk_file_chooser_widget_select_all                   (GtkFileChooser    *chooser);
 static void           gtk_file_chooser_widget_unselect_all                 (GtkFileChooser    *chooser);
-static GSList *       gtk_file_chooser_widget_get_files                    (GtkFileChooser    *chooser);
+static GListModel *   gtk_file_chooser_widget_get_files                    (GtkFileChooser    *chooser);
 static GtkFileSystem *gtk_file_chooser_widget_get_file_system              (GtkFileChooser    *chooser);
 static void           gtk_file_chooser_widget_add_filter                   (GtkFileChooser    *chooser,
                                                                             GtkFileFilter     *filter);
@@ -5408,7 +5408,7 @@ check_save_entry (GtkFileChooserWidget  *impl,
 
 struct get_files_closure {
   GtkFileChooserWidget *impl;
-  GSList *result;
+  GListStore *result;
   GFile *file_from_entry;
 };
 
@@ -5425,10 +5425,25 @@ get_files_foreach (GtkTreeModel *model,
   file = _gtk_file_system_model_get_file (fs_model, iter);
 
   if (!info->file_from_entry || !g_file_equal (info->file_from_entry, file))
-    info->result = g_slist_prepend (info->result, g_object_ref (file));
+    g_list_store_append (info->result, file);
 }
 
-static GSList *
+static GListModel *
+get_selected_files_as_model (GtkFileChooserWidget *impl)
+{
+  GListStore *store;
+  GSList *files, *l;
+
+  store = g_list_store_new (G_TYPE_FILE);
+  files = get_selected_files (impl);
+  for (l = files; l; l = l->next)
+    g_list_store_append (store, l->data);
+  g_slist_free_full (files, g_object_unref);
+
+  return G_LIST_MODEL (store);
+}
+
+static GListModel *
 gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
 {
   GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
@@ -5437,12 +5452,8 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
   GtkWidget *current_focus;
   gboolean file_list_seen;
 
-  info.impl = impl;
-  info.result = NULL;
-  info.file_from_entry = NULL;
-
   if (impl->operation_mode == OPERATION_MODE_SEARCH)
-    return get_selected_files (impl);
+    return get_selected_files_as_model (impl);
 
   if (impl->operation_mode == OPERATION_MODE_RECENT)
     {
@@ -5452,9 +5463,13 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
           goto file_entry;
         }
       else
-        return get_selected_files (impl);
+        return get_selected_files_as_model (impl);
     }
 
+  info.impl = impl;
+  info.result = g_list_store_new (G_TYPE_FILE);
+  info.file_from_entry = NULL;
+
   toplevel = get_toplevel (GTK_WIDGET (impl));
   if (toplevel)
     current_focus = gtk_root_get_focus (GTK_ROOT (toplevel));
@@ -5498,7 +5513,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
         return NULL;
 
       if (info.file_from_entry)
-        info.result = g_slist_prepend (info.result, info.file_from_entry);
+        g_list_store_append (info.result, info.file_from_entry);
       else if (!file_list_seen)
         goto file_list;
       else
@@ -5530,10 +5545,10 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser)
       current_folder = gtk_file_chooser_get_current_folder (chooser);
 
       if (current_folder)
-        info.result = g_slist_prepend (info.result, current_folder);
+        g_list_store_append (info.result, current_folder);
     }
 
-  return g_slist_reverse (info.result);
+  return G_LIST_MODEL (info.result);
 }
 
 static GtkFileSystem *
@@ -6143,18 +6158,18 @@ location_popup_on_paste_handler (GtkFileChooserWidget *impl)
 static void
 add_selection_to_recent_list (GtkFileChooserWidget *impl)
 {
-  GSList *files;
-  GSList *l;
+  GListModel *files;
+  guint i, n;
 
   files = gtk_file_chooser_widget_get_files (GTK_FILE_CHOOSER (impl));
 
-
   if (!impl->recent_manager)
     impl->recent_manager = gtk_recent_manager_get_default ();
 
-  for (l = files; l; l = l->next)
+  n = g_list_model_get_n_items (files);
+  for (i = 0; i < n; i++)
     {
-      GFile *file = l->data;
+      GFile *file = g_list_model_get_item (files, i);
       char *uri;
 
       uri = g_file_get_uri (file);
@@ -6163,9 +6178,11 @@ add_selection_to_recent_list (GtkFileChooserWidget *impl)
           gtk_recent_manager_add_item (impl->recent_manager, uri);
           g_free (uri);
         }
+
+      g_object_unref (file);
     }
 
-  g_slist_free_full (files, g_object_unref);
+  g_object_unref (files);
 }
 
 static gboolean
diff --git a/tests/testfilechooser.c b/tests/testfilechooser.c
index eace90337c..d5eef8aeda 100644
--- a/tests/testfilechooser.c
+++ b/tests/testfilechooser.c
@@ -63,19 +63,21 @@ print_current_folder (GtkFileChooser *chooser)
 static void
 print_selected (GtkFileChooser *chooser)
 {
-  GSList *uris = gtk_file_chooser_get_files (chooser);
-  GSList *tmp_list;
+  GListModel *files = gtk_file_chooser_get_files (chooser);
+  guint i, n;
 
   g_print ("Selection changed :\n");
-  for (tmp_list = uris; tmp_list; tmp_list = tmp_list->next)
+  n = g_list_model_get_n_items (files);
+  for (i = 0; i < n; i++)
     {
-      GFile *file = tmp_list->data;
+      GFile *file = g_list_model_get_item (files, i);
       char *uri = g_file_get_uri (file);
       g_print ("  %s\n", uri ? uri : "(null)");
       g_free (uri);
+      g_object_unref (files);
     }
   g_print ("\n");
-  g_slist_free_full (uris, g_object_unref);
+  g_object_unref (files);
 }
 
 static void
@@ -87,28 +89,23 @@ response_cb (GtkDialog *dialog,
 
   if (response_id == GTK_RESPONSE_OK)
     {
-      GSList *list;
-
-      list = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog));
-
-      if (list)
-       {
-         GSList *l;
-
-         g_print ("Selected files:\n");
-
-         for (l = list; l; l = l->next)
-           {
-              GFile *file = l->data;
-              char *uri = g_file_get_uri (file);
-             g_print ("  %s\n", uri ? uri : "(null)");
-             g_free (uri);
-           }
+      GListModel *files;
+      guint i, n;
+
+      files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog));
+      n = g_list_model_get_n_items (files);
+
+      g_print ("Selected files:\n");
+      for (i = 0; i < n; i++)
+        {
+          GFile *file = g_list_model_get_item (files, i);
+          char *uri = g_file_get_uri (file);
+          g_print ("  %s\n", uri ? uri : "(null)");
+          g_free (uri);
+          g_object_unref (file);
+        }
 
-         g_slist_free_full (list, g_object_unref);
-       }
-      else
-       g_print ("No selected files\n");
+      g_object_unref (files);
     }
   else
     g_print ("Dialog was closed\n");
@@ -208,33 +205,24 @@ static void
 get_selection_cb (GtkButton      *button,
                  GtkFileChooser *chooser)
 {
-  GSList *selection;
+  GListModel *selection;
+  guint i, n;
 
   selection = gtk_file_chooser_get_files (chooser);
+  n = g_list_model_get_n_items (selection);
 
   g_print ("Selection: ");
 
-  if (selection == NULL)
-    g_print ("empty\n");
-  else
+  for (i = 0; i < n; i++)
     {
-      GSList *l;
-      
-      for (l = selection; l; l = l->next)
-       {
-          GFile *file = l->data;
-         char *uri = g_file_get_uri (file);
-
-         g_print ("%s\n", uri);
-
-          g_free (uri);
-
-         if (l->next)
-           g_print ("           ");
-       }
+      GFile *file = g_list_model_get_item (selection, i);
+      char *uri = g_file_get_uri (file);
+      g_print ("%s\n", uri);
+      g_free (uri);
+      g_object_unref (file);
     }
 
-  g_slist_free_full (selection, g_object_unref);
+  g_object_unref (selection);
 }
 
 static void
diff --git a/tests/testgtk.c b/tests/testgtk.c
index 50db5c8111..acb14b7615 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -5507,22 +5507,26 @@ native_response (GtkNativeDialog *self,
 {
   static int count = 0;
   char *res;
-  GSList *uris, *l;
   GString *s;
   char *response;
   GtkFileFilter *filter;
+  GListModel *files;
+  guint i, n;
 
-  uris = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (self));
+  files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (self));
   filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
   s = g_string_new ("");
-  for (l = uris; l != NULL; l = l->next)
+  n = g_list_model_get_n_items (files);
+  for (i = 0; i < n; i++)
     {
-      char *uri = g_file_get_uri (l->data);
+      GFile *file = g_list_model_get_item (files, i);
+      char *uri = g_file_get_uri (file);
       g_string_prepend (s, uri);
       g_string_prepend (s, "\n");
       g_free (uri);
+      g_object_unref (file);
     }
-  g_slist_free_full (uris, g_object_unref);
+  g_object_unref (files);
 
   switch (response_id)
     {


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