filechooserwidget: Add a filter model

Put a filter model between the selection model and
the filesystem model, and make it filter on the
filechooser::visible attribute. This makes the filer
combo in the filterchooser and the 'show hidden files'
item work. But we need to prod the filter to trigger
a refiltering every now and then.
This commit is contained in:
Matthias Clasen 2022-10-10 22:21:39 -04:00
parent 83431a999c
commit 280adcbb8c

View File

@ -93,6 +93,8 @@
#include "gtkshortcutaction.h" #include "gtkshortcutaction.h"
#include "gtkshortcut.h" #include "gtkshortcut.h"
#include "gtkstringlist.h" #include "gtkstringlist.h"
#include "gtkfilterlistmodel.h"
#include "gtkcustomfilter.h"
#ifndef G_OS_WIN32 #ifndef G_OS_WIN32
#include "gopenuriportal.h" #include "gopenuriportal.h"
@ -198,6 +200,7 @@ struct _GtkFileChooserWidget
* selection model. * selection model.
*/ */
GtkSelectionModel *selection_model; GtkSelectionModel *selection_model;
GtkFilterListModel *filter_model;
/* The file browsing widgets */ /* The file browsing widgets */
GtkWidget *browse_widgets_hpaned; GtkWidget *browse_widgets_hpaned;
@ -596,6 +599,9 @@ gtk_file_chooser_widget_finalize (GObject *object)
recent_clear_model (impl, FALSE); recent_clear_model (impl, FALSE);
g_clear_object (&impl->model_for_search); g_clear_object (&impl->model_for_search);
g_clear_object (&impl->selection_model);
g_clear_object (&impl->filter_model);
/* stopping the load above should have cleared this */ /* stopping the load above should have cleared this */
g_assert (impl->load_timeout_id == 0); g_assert (impl->load_timeout_id == 0);
@ -618,28 +624,16 @@ get_toplevel (GtkWidget *widget)
static GListModel * static GListModel *
get_current_model (GtkFileChooserWidget *self) get_current_model (GtkFileChooserWidget *self)
{ {
g_assert (self->selection_model != NULL); return gtk_filter_list_model_get_model (self->filter_model);
g_assert (GTK_IS_MULTI_SELECTION (self->selection_model) ||
GTK_IS_SINGLE_SELECTION (self->selection_model));
if (GTK_IS_MULTI_SELECTION (self->selection_model))
return gtk_multi_selection_get_model (GTK_MULTI_SELECTION (self->selection_model));
else
return gtk_single_selection_get_model (GTK_SINGLE_SELECTION (self->selection_model));
} }
static void static void
set_current_model (GtkFileChooserWidget *self, set_current_model (GtkFileChooserWidget *self,
GListModel *model) GListModel *model)
{ {
g_assert (self->selection_model != NULL); gtk_filter_list_model_set_model (self->filter_model, model);
g_assert (GTK_IS_MULTI_SELECTION (self->selection_model) || gtk_filter_changed (gtk_filter_list_model_get_filter (self->filter_model),
GTK_IS_SINGLE_SELECTION (self->selection_model)); GTK_FILTER_CHANGE_DIFFERENT);
if (GTK_IS_MULTI_SELECTION (self->selection_model))
gtk_multi_selection_set_model (GTK_MULTI_SELECTION (self->selection_model), model);
else
gtk_single_selection_set_model (GTK_SINGLE_SELECTION (self->selection_model), model);
} }
/* Extracts the parent folders out of the supplied list of GtkRecentInfo* items, and returns /* Extracts the parent folders out of the supplied list of GtkRecentInfo* items, and returns
@ -1575,6 +1569,9 @@ set_model_filter (GtkFileChooserWidget *impl,
if (impl->recent_model) if (impl->recent_model)
_gtk_file_system_model_set_filter (impl->recent_model, filter); _gtk_file_system_model_set_filter (impl->recent_model, filter);
gtk_filter_changed (gtk_filter_list_model_get_filter (impl->filter_model),
GTK_FILTER_CHANGE_DIFFERENT);
} }
static void static void
@ -2566,9 +2563,9 @@ switch_to_home_dir (GtkFileChooserWidget *impl)
/* Sets the file chooser to multiple selection mode */ /* Sets the file chooser to multiple selection mode */
static void static void
set_select_multiple (GtkFileChooserWidget *impl, set_select_multiple (GtkFileChooserWidget *impl,
gboolean select_multiple) gboolean select_multiple)
{ {
GListModel *model = NULL; GListModel *model;
if (select_multiple == impl->select_multiple) if (select_multiple == impl->select_multiple)
return; return;
@ -2576,7 +2573,7 @@ set_select_multiple (GtkFileChooserWidget *impl,
gtk_column_view_set_enable_rubberband (GTK_COLUMN_VIEW (impl->browse_files_column_view), gtk_column_view_set_enable_rubberband (GTK_COLUMN_VIEW (impl->browse_files_column_view),
select_multiple); select_multiple);
model = get_current_model (impl); model = g_object_ref (G_LIST_MODEL (impl->filter_model));
g_clear_object (&impl->selection_model); g_clear_object (&impl->selection_model);
@ -2585,10 +2582,10 @@ set_select_multiple (GtkFileChooserWidget *impl,
else else
impl->selection_model = GTK_SELECTION_MODEL (gtk_single_selection_new (model)); impl->selection_model = GTK_SELECTION_MODEL (gtk_single_selection_new (model));
g_signal_connect (impl->selection_model, g_signal_connect (impl->selection_model, "selection-changed",
"selection-changed", G_CALLBACK (list_selection_changed), impl);
G_CALLBACK (list_selection_changed), g_signal_connect (impl->selection_model, "items-changed",
impl); G_CALLBACK (list_items_changed), impl);
g_signal_connect (impl->selection_model, g_signal_connect (impl->selection_model,
"items-changed", "items-changed",
@ -2920,6 +2917,9 @@ set_show_hidden (GtkFileChooserWidget *impl,
if (impl->browse_files_model) if (impl->browse_files_model)
_gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden); _gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden);
gtk_filter_changed (gtk_filter_list_model_get_filter (impl->filter_model),
GTK_FILTER_CHANGE_DIFFERENT);
} }
} }
@ -7113,12 +7113,19 @@ filter_name (GtkFileFilter *filter)
return g_strdup (gtk_file_filter_get_name (filter)); return g_strdup (gtk_file_filter_get_name (filter));
} }
static gboolean
match_func (gpointer item, gpointer user_data)
{
return g_file_info_get_attribute_boolean (G_FILE_INFO (item), "filechooser::visible");
}
static void static void
gtk_file_chooser_widget_init (GtkFileChooserWidget *impl) gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
{ {
GtkExpression *expression; GtkExpression *expression;
impl->selection_model = GTK_SELECTION_MODEL (gtk_single_selection_new (NULL)); impl->selection_model = GTK_SELECTION_MODEL (gtk_single_selection_new (NULL));
impl->filter_model = gtk_filter_list_model_new (NULL, GTK_FILTER (gtk_custom_filter_new (match_func, NULL, NULL)));
impl->select_multiple = FALSE; impl->select_multiple = FALSE;
impl->show_hidden = FALSE; impl->show_hidden = FALSE;
impl->show_size_column = TRUE; impl->show_size_column = TRUE;
@ -7134,6 +7141,8 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
impl->auto_selecting_first_row = FALSE; impl->auto_selecting_first_row = FALSE;
impl->renamed_file = NULL; impl->renamed_file = NULL;
gtk_single_selection_set_model (GTK_SINGLE_SELECTION (impl->selection_model), G_LIST_MODEL (impl->filter_model));
g_signal_connect (impl->selection_model, "selection-changed", g_signal_connect (impl->selection_model, "selection-changed",
G_CALLBACK (list_selection_changed), impl); G_CALLBACK (list_selection_changed), impl);
g_signal_connect (impl->selection_model, "items-changed", g_signal_connect (impl->selection_model, "items-changed",