filechooserwidget: Port to GtkSignalListItemFactory
authorCorey Berla <corey@berla.me>
Fri, 21 Apr 2023 14:45:08 +0000 (07:45 -0700)
committerCorey Berla <corey@berla.me>
Fri, 21 Apr 2023 15:14:32 +0000 (08:14 -0700)
BuilderListItemFactory isn't quite suited for our purposes, primarily
because you can't pass user data to BuilderListItemFactory.  Because
we can't get the data we are using a workaround to get the
GtkFileChooserWidget ancestory, which used to work, but with the
recent list view changes no longer doesn't.  Use GtkSignalListItemFactory
with the GtkFileChooserWidget as the user data.

gtk/gtkfilechooserwidget.c
gtk/ui/gtkfilechooserwidget.ui

index 787a728ac2bbe8241c4ba001417bcebf91dfb6ed..510f663a02c4faa99edf2f7b6631a3c3ecc2dce5 100644 (file)
@@ -44,6 +44,7 @@
 #include "gtkgestureclick.h"
 #include "gtkgesturelongpress.h"
 #include "gtkgrid.h"
+#include "gtkinscription.h"
 #include "gtklabel.h"
 #include "gtkmarshalers.h"
 #include "gtkalertdialog.h"
@@ -70,6 +71,7 @@
 #include "gtkscrollable.h"
 #include "gtkpopover.h"
 #include "gtkrevealer.h"
+#include "gtksignallistitemfactory.h"
 #include "gtkspinner.h"
 #include "gtkeventcontrollerkey.h"
 #include "gtkdebug.h"
@@ -1946,20 +1948,14 @@ files_list_restrict_key_presses (GtkEventControllerKey *controller,
 }
 
 static char *
-column_view_get_file_date (GtkColumnViewCell *cell,
+get_file_date (GtkFileChooserWidget *impl,
                            GFileInfo        *info)
 {
-  GtkFileChooserWidget *impl;
   glong time;
 
   if (!info)
     return NULL;
 
-  impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_column_view_cell_get_child (cell),
-                                                           GTK_TYPE_FILE_CHOOSER_WIDGET));
-  if (!impl)
-    return NULL;
-
   if (impl->operation_mode == OPERATION_MODE_RECENT)
     time = (glong) g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
   else
@@ -1982,20 +1978,14 @@ column_view_get_file_display_name (GtkColumnViewCell *cell,
 }
 
 static char *
-column_view_get_file_time (GtkColumnViewCell *cell,
+get_file_time (GtkFileChooserWidget *impl,
                            GFileInfo        *info)
 {
-  GtkFileChooserWidget *impl;
   glong time;
 
   if (!info)
     return NULL;
 
-  impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_column_view_cell_get_child (cell),
-                                                           GTK_TYPE_FILE_CHOOSER_WIDGET));
-  if (!impl)
-    return NULL;
-
   if (impl->operation_mode == OPERATION_MODE_RECENT)
     time = (glong) g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
   else
@@ -2007,23 +1997,6 @@ column_view_get_file_time (GtkColumnViewCell *cell,
   return my_g_format_time_for_display (impl, time);
 }
 
-static char *
-column_view_get_file_type (GtkColumnViewCell *cell,
-                           GFileInfo        *info)
-{
-  GtkFileChooserWidget *impl;
-
-  if (!info || _gtk_file_info_consider_as_directory (info))
-    return NULL;
-
-  impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_column_view_cell_get_child (cell),
-                                                           GTK_TYPE_FILE_CHOOSER_WIDGET));
-  if (!impl)
-    return NULL;
-
-  return get_type_information (impl, info);
-}
-
 static void
 column_view_row_bind (GtkListItemFactory *factory,
                       GtkColumnViewRow   *row,
@@ -2097,22 +2070,7 @@ file_chooser_get_location (GtkFileChooserWidget *impl,
 }
 
 static char *
-column_view_get_location (GtkColumnViewCell *cell,
-                          GFileInfo         *info)
-{
-  GtkFileChooserWidget *impl;
-
-  impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (gtk_column_view_cell_get_child (cell),
-                                                           GTK_TYPE_FILE_CHOOSER_WIDGET));
-  if (!impl)
-    return NULL;
-
-  return file_chooser_get_location (impl, info);
-}
-
-static char *
-column_view_get_size (GtkColumnViewCell *cell,
-                      GFileInfo         *info)
+column_view_get_size (GFileInfo *info)
 {
   if (info && !_gtk_file_info_consider_as_directory (info))
     return g_format_size (g_file_info_get_size (info));
@@ -2121,8 +2079,8 @@ column_view_get_size (GtkColumnViewCell *cell,
 }
 
 static char *
-column_view_get_tooltip_text (GtkColumnViewCell *cell,
-                              GFileInfo         *info)
+column_view_get_tooltip_text (GtkListItem *cell,
+                              GFileInfo   *info)
 {
   GFile *file;
 
@@ -6809,12 +6767,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
   gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, browse_path_bar_size_group);
   gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, browse_path_bar);
   gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, browse_toggle_view_button);
-  gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, column_view_name_column);
-  gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, column_view_location_column);
-  gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, column_view_size_column);
-  gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, column_view_time_column);
   gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, filter_combo_hbox);
-  gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, column_view_type_column);
   gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, filter_combo);
   gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, extra_align);
   gtk_widget_class_bind_template_child (widget_class, GtkFileChooserWidget, extra_and_filters);
@@ -6848,12 +6801,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
   gtk_widget_class_bind_template_callback (widget_class, rename_file_name_changed);
   gtk_widget_class_bind_template_callback (widget_class, rename_file_rename_clicked);
   gtk_widget_class_bind_template_callback (widget_class, rename_file_end);
-  gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_date);
   gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_display_name);
-  gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_time);
-  gtk_widget_class_bind_template_callback (widget_class, column_view_get_file_type);
-  gtk_widget_class_bind_template_callback (widget_class, column_view_get_location);
-  gtk_widget_class_bind_template_callback (widget_class, column_view_get_size);
   gtk_widget_class_bind_template_callback (widget_class, column_view_get_tooltip_text);
   gtk_widget_class_bind_template_callback (widget_class, column_view_row_bind);
 
@@ -7309,6 +7257,170 @@ file_chooser_widget_long_pressed (GtkEventController *controller,
   popup_menu (widget, x, y);
 }
 
+static void
+bind_cell_common (GtkColumnViewCell *column_cell,
+                  GtkWidget         *child,
+                  GFileInfo         *info)
+{
+  char *tooltip;
+  GtkFileChooserCell *cell = gtk_file_chooser_cell_new ();
+
+  g_object_set (cell, "list-item", column_cell, "item", info, NULL);
+  gtk_widget_insert_before (child, GTK_WIDGET (cell), NULL);
+  tooltip = column_view_get_tooltip_text (NULL, info);
+  gtk_widget_set_tooltip_text (child, tooltip);
+  gtk_column_view_cell_set_child (column_cell, GTK_WIDGET (cell));
+
+  g_free (tooltip);
+}
+
+static void
+bind_name_cell (GtkFileChooserWidget *impl,
+                GtkColumnViewCell    *column_cell)
+{
+  GtkFileThumbnail *thumbnail;
+  GtkWidget *box;
+  GtkWidget *inscription;
+  GFileInfo *info = gtk_column_view_cell_get_item (column_cell);
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  thumbnail = g_object_new (GTK_TYPE_FILE_THUMBNAIL, NULL);
+  gtk_widget_set_margin_start (GTK_WIDGET (thumbnail), 6);
+  gtk_widget_set_margin_end (GTK_WIDGET (thumbnail), 6);
+  _gtk_file_thumbnail_set_info (thumbnail, info);
+
+  inscription = gtk_inscription_new (g_file_info_get_display_name (info));
+  gtk_widget_set_hexpand (inscription, TRUE);
+  gtk_inscription_set_min_chars (GTK_INSCRIPTION (inscription), 10);
+
+  gtk_box_append (GTK_BOX (box), GTK_WIDGET (thumbnail));
+  gtk_box_append (GTK_BOX (box), inscription);
+
+  bind_cell_common (column_cell, box, info);
+}
+
+
+static void
+bind_location_cell (GtkFileChooserWidget *impl,
+                    GtkColumnViewCell    *column_cell)
+{
+  GtkWidget *inscription;
+  char *text;
+  GFileInfo *info = gtk_column_view_cell_get_item (column_cell);
+
+  text = file_chooser_get_location (impl, info);
+  inscription = gtk_inscription_new (text);
+  gtk_widget_set_hexpand (inscription, TRUE);
+  gtk_inscription_set_xalign (GTK_INSCRIPTION (inscription), 0);
+  gtk_inscription_set_min_chars (GTK_INSCRIPTION (inscription), 10);
+  gtk_widget_set_margin_start (inscription, 6);
+  gtk_widget_set_margin_end (inscription, 6);
+
+  bind_cell_common (column_cell, inscription, info);
+
+  g_free (text);
+}
+
+static void
+bind_size_cell (GtkFileChooserWidget *impl,
+                GtkColumnViewCell    *column_cell)
+{
+  GtkWidget *label;
+  char *text;
+  GFileInfo *info = gtk_column_view_cell_get_item (column_cell);
+
+  text = column_view_get_size (info);
+  label = gtk_label_new (text);
+  gtk_widget_set_hexpand (label, TRUE);
+  gtk_label_set_xalign (GTK_LABEL (label), 0);
+  bind_cell_common (column_cell, label, info);
+
+  g_free (text);
+}
+
+static void
+bind_time_cell (GtkFileChooserWidget *impl,
+                GtkColumnViewCell    *column_cell)
+{
+  GtkWidget *box;
+  GtkWidget *label;
+  char *text;
+  GFileInfo *info = gtk_column_view_cell_get_item (column_cell);
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  text = get_file_date (impl, info);
+  label = gtk_label_new (text);
+  g_free (text);
+  gtk_box_append (GTK_BOX (box), label);
+  text = get_file_time (impl, info);
+  label = gtk_label_new (text);
+  g_object_bind_property (impl, "show-time", label, "visible", G_BINDING_SYNC_CREATE);
+  gtk_box_append (GTK_BOX (box), label);
+
+  bind_cell_common (column_cell, box, info);
+
+  g_free (text);
+}
+
+static void
+bind_type_cell (GtkFileChooserWidget *impl,
+                GtkColumnViewCell    *column_cell)
+{
+  GtkWidget *label;
+  char *display_name;
+  GFileInfo *info = gtk_column_view_cell_get_item (column_cell);
+
+  if (_gtk_file_info_consider_as_directory (info))
+    display_name = NULL;
+  else
+    display_name = get_type_information (impl, info);
+
+  label = gtk_label_new (display_name);
+  gtk_widget_set_hexpand (label, TRUE);
+  gtk_label_set_xalign (GTK_LABEL (label), 0);
+  bind_cell_common (column_cell, label, info);
+
+  g_free (display_name);
+}
+
+static void
+setup_columns (GtkColumnView        *view,
+               GtkFileChooserWidget *impl)
+{
+  GtkListItemFactory *factory;
+
+  factory = gtk_signal_list_item_factory_new ();
+  g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_name_cell), impl);
+  impl->column_view_name_column = gtk_column_view_column_new (_("Name"), factory);
+  gtk_column_view_column_set_expand (impl->column_view_name_column, TRUE);
+  gtk_column_view_column_set_resizable (impl->column_view_name_column, TRUE);
+  gtk_column_view_append_column (view, impl->column_view_name_column);
+
+  factory = gtk_signal_list_item_factory_new ();
+  g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_location_cell), impl);
+  impl->column_view_location_column = gtk_column_view_column_new (_("Location"), factory);
+  gtk_column_view_column_set_expand (impl->column_view_location_column, TRUE);
+  gtk_column_view_column_set_resizable (impl->column_view_location_column, TRUE);
+  gtk_column_view_column_set_visible (impl->column_view_location_column, FALSE);
+  gtk_column_view_append_column (view, impl->column_view_location_column);
+
+  factory = gtk_signal_list_item_factory_new ();
+  g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_size_cell), impl);
+  impl->column_view_size_column = gtk_column_view_column_new (_("Size"), factory);
+  gtk_column_view_append_column (view, impl->column_view_size_column);
+
+  factory = gtk_signal_list_item_factory_new ();
+  g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_type_cell), impl);
+  impl->column_view_type_column = gtk_column_view_column_new (_("Type"), factory);
+  gtk_column_view_column_set_resizable (impl->column_view_type_column, TRUE);
+  gtk_column_view_append_column (view, impl->column_view_type_column);
+
+  factory = gtk_signal_list_item_factory_new ();
+  g_signal_connect_swapped (factory, "bind", G_CALLBACK (bind_time_cell), impl);
+  impl->column_view_time_column = gtk_column_view_column_new (_("Modified"), factory);
+  gtk_column_view_append_column (view, impl->column_view_time_column);
+}
+
 static void
 gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
 {
@@ -7359,6 +7471,7 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
   gtk_sort_list_model_set_model (impl->sort_model, G_LIST_MODEL (impl->filter_model));
 
   gtk_column_view_set_model (GTK_COLUMN_VIEW (impl->browse_files_column_view), impl->selection_model);
+  setup_columns (GTK_COLUMN_VIEW (impl->browse_files_column_view), impl);
 
   g_object_set_data (G_OBJECT (impl->column_view_name_column), "column", GINT_TO_POINTER (0));
   g_object_set_data (G_OBJECT (impl->column_view_size_column), "column", GINT_TO_POINTER (1));
index 33a3f390552e0382f4b2bcf7ea45c8ba8ab27fdc..4a6fe9150cbfbb3495facab3df95c11b9352840c 100644 (file)
                                             </property>
                                             <signal name="activate" handler="browse_files_view_row_activated_cb" swapped="no"/>
                                             <signal name="keynav-failed" handler="browse_files_view_keynav_failed_cb"/>
-                                            <child>
-                                              <object class="GtkColumnViewColumn" id="column_view_name_column">
-                                                <property name="title" translatable="yes">Name</property>
-                                                <property name="expand">1</property>
-                                                <property name="resizable">1</property>
-                                                <property name="factory">
-                                                  <object class="GtkBuilderListItemFactory">
-                                                    <property name="bytes"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <template class="GtkColumnViewCell">
-    <property name="child">
-      <object class="GtkFileChooserCell">
-        <binding name="item">
-          <lookup name="item">GtkColumnViewCell</lookup>
-        </binding>
-        <property name="list-item">GtkColumnViewCell</property>
-        <child>
-          <object class="GtkBox">
-            <binding name="tooltip-text">
-              <closure type="gchararray" function="column_view_get_tooltip_text">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-            <child>
-              <object class="GtkFileThumbnail">
-                <property name="margin-start">6</property>
-                <property name="margin-end">6</property>
-                <binding name="file-info">
-                  <lookup name="item">GtkColumnViewCell</lookup>
-                </binding>
-              </object>
-            </child>
-            <child>
-              <object class="GtkInscription">
-                <property name="hexpand">1</property>
-                <property name="xalign">0</property>
-                <property name="min-chars">10</property>
-                <binding name="text">
-                  <closure type="gchararray" function="column_view_get_file_display_name">
-                    <lookup name="item">GtkColumnViewCell</lookup>
-                  </closure>
-                </binding>
-              </object>
-            </child>
-          </object>
-        </child>
-      </object>
-    </property>
-  </template>
-</interface>
-                                                ]]></property>
-                                                  </object>
-                                                </property>
-                                              </object>
-                                            </child>
-
-                                            <child>
-                                              <object class="GtkColumnViewColumn" id="column_view_location_column">
-                                                <property name="title" translatable="yes">Location</property>
-                                                <property name="resizable">1</property>
-                                                <property name="visible">0</property>
-                                                <property name="expand">1</property>
-                                                <property name="factory">
-                                                  <object class="GtkBuilderListItemFactory">
-                                                    <property name="bytes"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <template class="GtkColumnViewCell">
-    <property name="child">
-      <object class="GtkFileChooserCell">
-        <binding name="item">
-          <lookup name="item">GtkColumnViewCell</lookup>
-        </binding>
-        <property name="list-item">GtkColumnViewCell</property>
-        <child>
-          <object class="GtkInscription">
-            <property name="hexpand">1</property>
-            <property name="xalign">0</property>
-            <property name="min-chars">10</property>
-            <property name="margin-start">6</property>
-            <property name="margin-end">6</property>
-            <binding name="text">
-              <closure type="gchararray" function="column_view_get_location">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-            <binding name="tooltip-text">
-              <closure type="gchararray" function="column_view_get_tooltip_text">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-          </object>
-        </child>
-      </object>
-    </property>
-  </template>
-</interface>
-                                                ]]></property>
-                                                  </object>
-                                                </property>
-                                              </object>
-                                            </child>
-
-                                            <child>
-                                              <object class="GtkColumnViewColumn" id="column_view_size_column">
-                                                <property name="title" translatable="yes">Size</property>
-                                                <property name="factory">
-                                                  <object class="GtkBuilderListItemFactory">
-                                                    <property name="bytes"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <template class="GtkColumnViewCell">
-    <property name="child">
-      <object class="GtkFileChooserCell">
-        <binding name="item">
-          <lookup name="item">GtkColumnViewCell</lookup>
-        </binding>
-        <property name="list-item">GtkColumnViewCell</property>
-        <child>
-          <object class="GtkLabel">
-            <property name="hexpand">1</property>
-            <property name="xalign">0</property>
-            <binding name="label">
-              <closure type="gchararray" function="column_view_get_size">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-            <binding name="tooltip-text">
-              <closure type="gchararray" function="column_view_get_tooltip_text">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-          </object>
-        </child>
-      </object>
-    </property>
-  </template>
-</interface>
-                                                ]]></property>
-                                                  </object>
-                                                </property>
-                                              </object>
-                                            </child>
-
-                                            <child>
-                                              <object class="GtkColumnViewColumn" id="column_view_type_column">
-                                                <property name="title" translatable="yes">Type</property>
-                                                <property name="resizable">1</property>
-                                                <property name="factory">
-                                                  <object class="GtkBuilderListItemFactory">
-                                                    <property name="bytes"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <template class="GtkColumnViewCell">
-    <property name="child">
-      <object class="GtkFileChooserCell">
-        <binding name="item">
-          <lookup name="item">GtkColumnViewCell</lookup>
-        </binding>
-        <property name="list-item">GtkColumnViewCell</property>
-        <child>
-          <object class="GtkLabel">
-            <property name="hexpand">1</property>
-            <property name="xalign">0</property>
-            <binding name="label">
-              <closure type="gchararray" function="column_view_get_file_type">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-            <binding name="tooltip-text">
-              <closure type="gchararray" function="column_view_get_tooltip_text">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-          </object>
-        </child>
-      </object>
-    </property>
-  </template>
-</interface>
-                                                ]]></property>
-                                                  </object>
-                                                </property>
-                                              </object>
-                                            </child>
-
-                                            <child>
-                                              <object class="GtkColumnViewColumn" id="column_view_time_column">
-                                                <property name="title" translatable="yes">Modified</property>
-                                                <property name="factory">
-                                                  <object class="GtkBuilderListItemFactory">
-                                                    <property name="bytes"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <template class="GtkColumnViewCell">
-    <property name="child">
-      <object class="GtkFileChooserCell" id="file_chooser_cell">
-        <binding name="item">
-          <lookup name="item">GtkColumnViewCell</lookup>
-        </binding>
-        <property name="list-item">GtkColumnViewCell</property>
-        <child>
-          <object class="GtkBox">
-            <property name="spacing">6</property>
-            <binding name="tooltip-text">
-              <closure type="gchararray" function="column_view_get_tooltip_text">
-                <lookup name="item">GtkColumnViewCell</lookup>
-              </closure>
-            </binding>
-            <child>
-              <object class="GtkLabel">
-                <binding name="label">
-                  <closure type="gchararray" function="column_view_get_file_date">
-                    <lookup name="item">GtkColumnViewCell</lookup>
-                  </closure>
-                </binding>
-              </object>
-            </child>
-            <child>
-              <object class="GtkLabel">
-                <property name="visible" bind-source="file_chooser_cell" bind-property="show-time" bind-flags="sync-create"/>
-                <binding name="label">
-                  <closure type="gchararray" function="column_view_get_file_time">
-                    <lookup name="item">GtkColumnViewCell</lookup>
-                  </closure>
-                </binding>
-              </object>
-            </child>
-          </object>
-        </child>
-      </object>
-    </property>
-  </template>
-</interface>
-                                                ]]></property>
-                                                  </object>
-                                                </property>
-                                              </object>
-                                            </child>
-
                                           </object>
                                         </child>
                                       </object>