filechooserwidget: Forward file filter to entry

And in the entry, apply the currently used filter as a second step to
the completion items.

https://bugzilla.gnome.org/show_bug.cgi?id=773007
This commit is contained in:
Timm Bäder 2016-11-15 10:51:41 +01:00
parent f4929360aa
commit 55fda57c44
3 changed files with 99 additions and 4 deletions

View File

@ -32,6 +32,7 @@
#include "gtkwindow.h" #include "gtkwindow.h"
#include "gtkintl.h" #include "gtkintl.h"
#include "gtkmarshalers.h" #include "gtkmarshalers.h"
#include "gtkfilefilterprivate.h"
typedef struct _GtkFileChooserEntryClass GtkFileChooserEntryClass; typedef struct _GtkFileChooserEntryClass GtkFileChooserEntryClass;
@ -56,6 +57,7 @@ struct _GtkFileChooserEntry
gchar *file_part; gchar *file_part;
GtkTreeModel *completion_store; GtkTreeModel *completion_store;
GtkFileFilter *current_filter;
guint current_folder_loaded : 1; guint current_folder_loaded : 1;
guint complete_on_load : 1; guint complete_on_load : 1;
@ -179,6 +181,83 @@ _gtk_file_chooser_entry_class_init (GtkFileChooserEntryClass *class)
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
} }
static gboolean
match_func (GtkEntryCompletion *compl,
const gchar *key,
GtkTreeIter *iter,
gpointer user_data)
{
GtkFileChooserEntry *chooser_entry = user_data;
/* If we arrive here, the GtkFileSystemModel's GtkFileFilter already filtered out all
* files that don't start with the current prefix, so we manually apply the GtkFileChooser's
* current file filter (e.g. just jpg files) here. */
if (chooser_entry->current_filter != NULL)
{
char *mime_type = NULL;
gboolean matches;
GFile *file;
GFileInfo *file_info;
GtkFileFilterInfo filter_info;
GtkFileFilterFlags needed_flags;
file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
iter);
file_info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
iter);
/* We always allow navigating into subfolders, so don't ever filter directories */
if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR)
return TRUE;
needed_flags = gtk_file_filter_get_needed (chooser_entry->current_filter);
filter_info.display_name = g_file_info_get_display_name (file_info);
filter_info.contains |= GTK_FILE_FILTER_DISPLAY_NAME;
if (needed_flags & GTK_FILE_FILTER_MIME_TYPE)
{
const char *s = g_file_info_get_content_type (file_info);
if (s != NULL)
{
mime_type = g_content_type_get_mime_type (s);
if (mime_type != NULL)
{
filter_info.mime_type = mime_type;
filter_info.contains |= GTK_FILE_FILTER_MIME_TYPE;
}
}
}
if (needed_flags & GTK_FILE_FILTER_FILENAME)
{
const char *path = g_file_get_path (file);
if (path != NULL)
{
filter_info.filename = path;
filter_info.contains |= GTK_FILE_FILTER_FILENAME;
}
}
if (needed_flags & GTK_FILE_FILTER_URI)
{
const char *uri = g_file_get_uri (file);
if (uri)
{
filter_info.uri = uri;
filter_info.contains |= GTK_FILE_FILTER_URI;
}
}
matches = gtk_file_filter_filter (chooser_entry->current_filter, &filter_info);
g_free (mime_type);
return matches;
}
return TRUE;
}
static void static void
_gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry) _gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry)
{ {
@ -198,9 +277,9 @@ _gtk_file_chooser_entry_init (GtkFileChooserEntry *chooser_entry)
/* Need a match func here or entry completion uses a wrong one. /* Need a match func here or entry completion uses a wrong one.
* We do our own filtering after all. */ * We do our own filtering after all. */
gtk_entry_completion_set_match_func (comp, gtk_entry_completion_set_match_func (comp,
(GtkEntryCompletionMatchFunc) gtk_true, match_func,
chooser_entry, chooser_entry,
NULL); NULL);
cell = gtk_cell_renderer_text_new (); cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comp), gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comp),
@ -546,7 +625,8 @@ populate_completion_store (GtkFileChooserEntry *chooser_entry)
{ {
chooser_entry->completion_store = GTK_TREE_MODEL ( chooser_entry->completion_store = GTK_TREE_MODEL (
_gtk_file_system_model_new_for_directory (chooser_entry->current_folder_file, _gtk_file_system_model_new_for_directory (chooser_entry->current_folder_file,
"standard::name,standard::display-name,standard::type", "standard::name,standard::display-name,standard::type,"
"standard::content-type",
completion_store_set, completion_store_set,
chooser_entry, chooser_entry,
N_COLUMNS, N_COLUMNS,
@ -983,3 +1063,10 @@ _gtk_file_chooser_entry_get_local_only (GtkFileChooserEntry *chooser_entry)
{ {
return chooser_entry->local_only; return chooser_entry->local_only;
} }
void
_gtk_file_chooser_entry_set_file_filter (GtkFileChooserEntry *chooser_entry,
GtkFileFilter *filter)
{
chooser_entry->current_filter = filter;
}

View File

@ -46,6 +46,8 @@ void _gtk_file_chooser_entry_select_filename (GtkFileChooserEnt
void _gtk_file_chooser_entry_set_local_only (GtkFileChooserEntry *chooser_entry, void _gtk_file_chooser_entry_set_local_only (GtkFileChooserEntry *chooser_entry,
gboolean local_only); gboolean local_only);
gboolean _gtk_file_chooser_entry_get_local_only (GtkFileChooserEntry *chooser_entry); gboolean _gtk_file_chooser_entry_get_local_only (GtkFileChooserEntry *chooser_entry);
void _gtk_file_chooser_entry_set_file_filter (GtkFileChooserEntry *chooser_entry,
GtkFileFilter *filter);
G_END_DECLS G_END_DECLS

View File

@ -2610,6 +2610,8 @@ location_entry_setup (GtkFileChooserWidget *impl)
_gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (priv->location_entry), priv->local_only); _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (priv->location_entry), priv->local_only);
_gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (priv->location_entry), priv->action); _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (priv->location_entry), priv->action);
_gtk_file_chooser_entry_set_file_filter (GTK_FILE_CHOOSER_ENTRY (priv->location_entry),
priv->current_filter);
gtk_entry_set_width_chars (GTK_ENTRY (priv->location_entry), 45); gtk_entry_set_width_chars (GTK_ENTRY (priv->location_entry), 45);
gtk_entry_set_activates_default (GTK_ENTRY (priv->location_entry), TRUE); gtk_entry_set_activates_default (GTK_ENTRY (priv->location_entry), TRUE);
} }
@ -7669,6 +7671,10 @@ filter_combo_changed (GtkComboBox *combo_box,
new_index = gtk_combo_box_get_active (combo_box); new_index = gtk_combo_box_get_active (combo_box);
new_filter = g_slist_nth_data (priv->filters, new_index); new_filter = g_slist_nth_data (priv->filters, new_index);
set_current_filter (impl, new_filter); 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);
} }
static void static void