[gtk/prop-list: 44/83] filechooser: Use a dropdown for the filter combo



commit db83ed064e9ee096d7660c50be700857f8cf7938
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Dec 21 20:12:11 2019 -0500

    filechooser: Use a dropdown for the filter combo

 gtk/gtkfilechooserwidget.c     | 109 +++++++++++++++++++++--------------------
 gtk/ui/gtkfilechooserwidget.ui |   6 +--
 2 files changed, 58 insertions(+), 57 deletions(-)
---
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index 7ac3e20889..452c3714db 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -29,6 +29,7 @@
 #include "gtkcellrendererpixbuf.h"
 #include "gtkcellrenderertext.h"
 #include "gtkcheckmenuitem.h"
+#include "gtkdropdown.h"
 #include "gtkcomboboxtext.h"
 #include "gtkcssnumbervalueprivate.h"
 #include "gtkdragsource.h"
@@ -330,7 +331,7 @@ struct _GtkFileChooserWidgetPrivate {
   GSList *pending_select_files;
 
   GtkFileFilter *current_filter;
-  GSList *filters;
+  GListStore *filters;
 
   GtkBookmarksManager *bookmarks_manager;
 
@@ -565,7 +566,8 @@ static void set_current_filter   (GtkFileChooserWidget *impl,
                                   GtkFileFilter         *filter);
 static void check_preview_change (GtkFileChooserWidget *impl);
 
-static void filter_combo_changed       (GtkComboBox           *combo_box,
+static void filter_combo_changed       (GtkDropDown          *dropdown,
+                                        GParamSpec           *pspec,
                                         GtkFileChooserWidget *impl);
 
 static gboolean list_select_func   (GtkTreeSelection      *selection,
@@ -702,7 +704,7 @@ gtk_file_chooser_widget_finalize (GObject *object)
 
   g_free (priv->browse_files_last_selected_name);
 
-  g_slist_free_full (priv->filters, g_object_unref);
+  g_clear_object (&priv->filters);
   g_clear_object (&priv->current_filter);
   g_clear_object (&priv->current_folder);
   g_clear_object (&priv->browse_path_bar_size_group);
@@ -6093,24 +6095,18 @@ gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser,
 {
   GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
   GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
-  const gchar *name;
 
-  if (g_slist_find (priv->filters, filter))
+  if (g_list_store_find (priv->filters, filter, NULL))
     {
       g_warning ("gtk_file_chooser_add_filter() called on filter already in list");
       return;
     }
 
   g_object_ref_sink (filter);
-  priv->filters = g_slist_append (priv->filters, filter);
-
-  name = gtk_file_filter_get_name (filter);
-  if (!name)
-    name = "Untitled filter";   /* Place-holder, doesn't need to be marked for translation */
-
-  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (priv->filter_combo), name);
+  g_list_store_append (priv->filters, filter);
+  g_object_unref (filter);
 
-  if (!g_slist_find (priv->filters, priv->current_filter))
+  if (!priv->current_filter)
     set_current_filter (impl, filter);
 
   show_filters (impl, TRUE);
@@ -6122,35 +6118,28 @@ gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
 {
   GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
   GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  gint filter_index;
+  guint filter_index;
 
-  filter_index = g_slist_index (priv->filters, filter);
-
-  if (filter_index < 0)
+  if (!g_list_store_find (priv->filters, filter, &filter_index))
     {
       g_warning ("gtk_file_chooser_remove_filter() called on filter not in list");
       return;
     }
 
-  priv->filters = g_slist_remove (priv->filters, filter);
+  g_list_store_remove (priv->filters, filter_index);
 
   if (filter == priv->current_filter)
     {
       if (priv->filters)
-        set_current_filter (impl, priv->filters->data);
+        {
+          GtkFileFilter *f = g_list_model_get_item (G_LIST_MODEL (priv->filters), 0);
+          set_current_filter (impl, f);
+          g_object_unref (f);
+        }
       else
         set_current_filter (impl, NULL);
     }
 
-  /* Remove row from the combo box */
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->filter_combo));
-  if (!gtk_tree_model_iter_nth_child  (model, &iter, NULL, filter_index))
-    g_assert_not_reached ();
-
-  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-
   g_object_unref (filter);
 
   if (!priv->filters)
@@ -6162,8 +6151,19 @@ gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser)
 {
   GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
   GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
+  GSList *filters;
+  guint i;
 
-  return g_slist_copy (priv->filters);
+  filters = NULL;
+
+  for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (priv->filters)); i++)
+    {
+      GtkFileFilter *filter = g_list_model_get_item (G_LIST_MODEL (priv->filters), i);
+      filters = g_slist_append (filters, filter);
+      g_object_unref (filter);
+    }
+      
+  return filters;
 }
 
 static gboolean
@@ -7580,11 +7580,11 @@ set_current_filter (GtkFileChooserWidget *impl,
 
   if (priv->current_filter != filter)
     {
-      int filter_index;
+      guint filter_index;
 
+g_print ("set current filter\n");
       /* NULL filters are allowed to reset to non-filtered status */
-      filter_index = g_slist_index (priv->filters, filter);
-      if (priv->filters && filter && filter_index < 0)
+      if (filter && !g_list_store_find (priv->filters, filter, &filter_index))
         return;
 
       if (priv->current_filter)
@@ -7593,9 +7593,9 @@ set_current_filter (GtkFileChooserWidget *impl,
       if (priv->current_filter)
         g_object_ref_sink (priv->current_filter);
 
-      if (priv->filters)
-        gtk_combo_box_set_active (GTK_COMBO_BOX (priv->filter_combo), filter_index);
+      gtk_drop_down_set_selected (GTK_DROP_DOWN (priv->filter_combo), filter_index);
 
+g_print ("set current filter %u\n", filter_index);
       clear_model_cache (impl, MODEL_COL_IS_SENSITIVE);
       set_model_filter (impl, priv->current_filter);
       g_object_notify (G_OBJECT (impl), "filter");
@@ -7603,20 +7603,22 @@ set_current_filter (GtkFileChooserWidget *impl,
 }
 
 static void
-filter_combo_changed (GtkComboBox          *combo_box,
+filter_combo_changed (GtkDropDown          *dropdown,
+                      GParamSpec           *pspec,
                       GtkFileChooserWidget *impl)
 {
   GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
   gint new_index;
   GtkFileFilter *new_filter;
 
-  new_index = gtk_combo_box_get_active (combo_box);
-  new_filter = g_slist_nth_data (priv->filters, new_index);
+  new_index = gtk_drop_down_get_selected (dropdown);
+  new_filter = g_list_model_get_item (G_LIST_MODEL (priv->filters), new_index);
   set_current_filter (impl, new_filter);
 
   if (priv->location_entry != NULL)
     _gtk_file_chooser_entry_set_file_filter (GTK_FILE_CHOOSER_ENTRY (priv->location_entry),
                                              new_filter);
+  g_object_unref (new_filter);
 }
 
 static void
@@ -8509,8 +8511,6 @@ post_process_ui (GtkFileChooserWidget *impl)
 {
   GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
   GtkTreeSelection *selection;
-  GtkCellRenderer  *cell;
-  GList            *cells;
   GFile            *file;
 
   /* Setup file list treeview */
@@ -8537,20 +8537,6 @@ post_process_ui (GtkFileChooserWidget *impl)
   file_list_set_sort_column_ids (impl);
   update_cell_renderer_attributes (impl);
 
-  /* Get the combo's text renderer and set ellipsize parameters,
-   * perhaps GtkComboBoxText should declare the cell renderer
-   * as an 'internal-child', then we could configure it in GtkBuilder
-   * instead of hard coding it here.
-   */
-  cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->filter_combo));
-  g_assert (cells);
-  cell = cells->data;
-  g_object_set (G_OBJECT (cell),
-                "ellipsize", PANGO_ELLIPSIZE_END,
-                NULL);
-
-  g_list_free (cells);
-
   /* Set the GtkPathBar file system backend */
   _gtk_path_bar_set_file_system (GTK_PATH_BAR (priv->browse_path_bar), priv->file_system);
   file = g_file_new_for_path ("/");
@@ -8599,10 +8585,17 @@ display_changed_cb (GtkWidget            *wiget,
   check_icon_theme (impl);
 }
 
+static char *
+filter_name (GtkFileFilter *filter)
+{
+  return g_strdup (gtk_file_filter_get_name (filter));
+}
+
 static void
 gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
 {
   GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
+  GtkExpression *expression;
 
   profile_start ("start", NULL);
 #ifdef PROFILE_FILE_CHOOSER
@@ -8645,6 +8638,16 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
   priv->file_system = _gtk_file_system_new ();
   priv->bookmarks_manager = _gtk_bookmarks_manager_new (NULL, NULL);
 
+  priv->filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
+  gtk_drop_down_set_model (GTK_DROP_DOWN (priv->filter_combo), G_LIST_MODEL (priv->filters));
+
+  expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
+                                            0, NULL,
+                                            G_CALLBACK (filter_name),
+                                            NULL, NULL);
+  gtk_drop_down_set_expression (GTK_DROP_DOWN (priv->filter_combo), expression);
+  gtk_expression_unref (expression);
+
   /* Setup various attributes and callbacks in the UI
    * which cannot be done with GtkBuilder
    */
diff --git a/gtk/ui/gtkfilechooserwidget.ui b/gtk/ui/gtkfilechooserwidget.ui
index 263bd6af2a..23bf89ef50 100644
--- a/gtk/ui/gtkfilechooserwidget.ui
+++ b/gtk/ui/gtkfilechooserwidget.ui
@@ -358,13 +358,11 @@
             <child type="end">
               <object class="GtkBox" id="filter_combo_hbox">
                 <child>
-                  <object class="GtkComboBoxText" id="filter_combo">
+                  <object class="GtkDropDown" id="filter_combo">
                     <property name="tooltip-text" translatable="yes">Select which types of files are 
shown</property>
                     <property name="focus-on-click">0</property>
-                    <property name="entry-text-column">0</property>
-                    <property name="id-column">1</property>
                     <property name="valign">start</property>
-                    <signal name="changed" handler="filter_combo_changed" swapped="no"/>
+                    <signal name="notify::selected" handler="filter_combo_changed" swapped="no"/>
                   </object>
                 </child>
               </object>


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