From 10e8d6abca18836c69da9101421fc35f29a0a207 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 24 Jun 2009 16:36:20 +0200 Subject: [PATCH] Make the filesystem model filter API use a GtkFileFilter This gets rid of the vfunc API and does exactly what the file chooser wants. --- gtk/gtkfilechooserdefault.c | 36 +------------- gtk/gtkfilesystemmodel.c | 93 ++++++++++++++++++++++++++++++------- gtk/gtkfilesystemmodel.h | 13 ++---- 3 files changed, 82 insertions(+), 60 deletions(-) diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index c4643037b7..67537537b8 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -6167,45 +6167,11 @@ gtk_file_chooser_default_unmap (GtkWidget *widget) impl->reload_state = RELOAD_WAS_UNMAPPED; } -static gboolean -list_model_filter_func (GtkFileSystemModel *model, - GFile *file, - GFileInfo *file_info, - gpointer user_data) -{ - GtkFileChooserDefault *impl = user_data; - - if (!impl->current_filter) - return TRUE; - - if (_gtk_file_info_consider_as_directory (file_info)) - return TRUE; - - return !get_is_file_filtered (impl, file, file_info); -} - static void install_list_model_filter (GtkFileChooserDefault *impl) { - GtkFileSystemModelFilter filter; - gpointer data; - - g_assert (impl->browse_files_model != NULL); - - if (impl->current_filter) - { - filter = list_model_filter_func; - data = impl; - } - else - { - filter = NULL; - data = NULL; - } - _gtk_file_system_model_set_filter (impl->browse_files_model, - filter, - data); + impl->current_filter); } #define COMPARE_DIRECTORIES \ diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c index ef3df19ece..8da4a0f218 100644 --- a/gtk/gtkfilesystemmodel.c +++ b/gtk/gtkfilesystemmodel.c @@ -25,6 +25,7 @@ #include #include +#include "gtkfilesystem.h" #include "gtkintl.h" #include "gtkmarshalers.h" #include "gtktreedatalist.h" @@ -77,8 +78,7 @@ struct _GtkFileSystemModel GtkFileSystemModelGetValue get_func; /* function to call to fill in values in columns */ gpointer get_data; /* data to pass to get_func */ - GtkFileSystemModelFilter filter_func; /* filter to use for deciding which nodes are visible */ - gpointer filter_data; /* data to pass to filter_func */ + GtkFileFilter * filter; /* filter to use for deciding which nodes are visible */ int sort_column_id; /* current sorting column */ GtkSortType sort_order; /* current sorting order */ @@ -214,7 +214,12 @@ static gboolean node_should_be_visible (GtkFileSystemModel *model, guint id) { FileModelNode *node = get_node (model, id); - gboolean is_folder; + GtkFileFilterInfo filter_info = { 0, }; + GtkFileFilterFlags required; + gboolean is_folder, result; + char *mime_type = NULL; + char *filename = NULL; + char *uri = NULL; if (node->info == NULL) return FALSE; @@ -230,12 +235,65 @@ node_should_be_visible (GtkFileSystemModel *model, guint id) model->show_folders != is_folder) return FALSE; + if (is_folder) + return TRUE; - if (model->filter_func && - !model->filter_func (model, node->file, node->info, model->filter_data)) - return FALSE; + if (model->filter == NULL) + return TRUE; - return TRUE; + /* fill info */ + required = gtk_file_filter_get_needed (model->filter); + + filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME; + filter_info.display_name = g_file_info_get_display_name (node->info); + + if (required & GTK_FILE_FILTER_MIME_TYPE) + { + filter_info.mime_type = g_file_info_get_attribute_string (node->info, "filechooser::mime-type"); + if (filter_info.mime_type != NULL) + filter_info.contains |= GTK_FILE_FILTER_MIME_TYPE; + else + { + const char *s = g_file_info_get_content_type (node->info); + if (s) + { + mime_type = g_content_type_get_mime_type (s); + if (mime_type) + { + filter_info.mime_type = mime_type; + filter_info.contains |= GTK_FILE_FILTER_MIME_TYPE; + } + } + } + } + + if (required & GTK_FILE_FILTER_FILENAME) + { + filename = g_file_get_path (node->file); + if (filter_info.filename) + { + filter_info.filename = filename; + filter_info.contains |= GTK_FILE_FILTER_FILENAME; + } + } + + if (required & GTK_FILE_FILTER_URI) + { + uri = g_file_get_uri (node->file); + if (uri) + { + filter_info.uri = uri; + filter_info.contains |= GTK_FILE_FILTER_URI; + } + } + + result = gtk_file_filter_filter (model->filter, &filter_info); + + g_free (mime_type); + g_free (filename); + g_free (uri); + + return result; } /*** GtkTreeModel ***/ @@ -797,6 +855,8 @@ gtk_file_system_model_finalize (GObject *object) if (model->dir_monitor) g_object_unref (model->dir_monitor); g_hash_table_destroy (model->file_lookup); + if (model->filter) + g_object_unref (model->filter); _gtk_tree_data_list_header_free (model->sort_list); if (model->default_sort_destroy) @@ -1483,22 +1543,23 @@ _gtk_file_system_model_update_file (GtkFileSystemModel *model, /** * _gtk_file_system_model_set_filter: * @mode: a #GtkFileSystemModel - * @filter: function to be called for each file - * @user_data: data to pass to @filter + * @filter: %NULL or filter to use * - * Sets a callback called for each file/directory to see whether - * it should be included in model. If this function was made - * public, we'd want to include a GDestroyNotify as well. + * Sets a filter to be used for deciding if a row should be visible or not. + * Directories are always visible. **/ void _gtk_file_system_model_set_filter (GtkFileSystemModel *model, - GtkFileSystemModelFilter filter, - gpointer user_data) + GtkFileFilter * filter) { g_return_if_fail (GTK_IS_FILE_SYSTEM_MODEL (model)); + g_return_if_fail (filter == NULL || GTK_IS_FILE_FILTER (filter)); - model->filter_func = filter; - model->filter_data = user_data; + if (filter) + g_object_ref (filter); + if (model->filter) + g_object_unref (model->filter); + model->filter = filter; gtk_file_system_model_refilter_all (model); } diff --git a/gtk/gtkfilesystemmodel.h b/gtk/gtkfilesystemmodel.h index a6cc44b189..ae04e2f0ed 100644 --- a/gtk/gtkfilesystemmodel.h +++ b/gtk/gtkfilesystemmodel.h @@ -21,7 +21,8 @@ #ifndef __GTK_FILE_SYSTEM_MODEL_H__ #define __GTK_FILE_SYSTEM_MODEL_H__ -#include "gtkfilesystem.h" +#include +#include #include G_BEGIN_DECLS @@ -80,14 +81,8 @@ void _gtk_file_system_model_thaw_updates (GtkFileSystemModel void _gtk_file_system_model_clear_cache (GtkFileSystemModel *model, int column); -typedef gboolean (*GtkFileSystemModelFilter) (GtkFileSystemModel *model, - GFile *file, - GFileInfo *info, - gpointer user_data); - -void _gtk_file_system_model_set_filter (GtkFileSystemModel *model, - GtkFileSystemModelFilter filter, - gpointer user_data); +void _gtk_file_system_model_set_filter (GtkFileSystemModel *model, + GtkFileFilter *filter); void _gtk_file_system_model_add_editable (GtkFileSystemModel *model, GtkTreeIter *iter);