Commit 733f4489 authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

File filter objects.

Wed Jul 23 11:23:43 2003  Owen Taylor  <otaylor@redhat.com>

        * gtkfilefilter.[ch]: File filter objects.

        * gtkfilechooser.[ch] gtkfilechooserutils.[ch]: Add
        file filtering to API.

        * gtkfilechooserimpldefault.c: Implement file filters.

        * testfilechooser.c: Try out the filter functionality.

        * gtkfilesystemmodel.c: Add
        _gtk_file_system_model_set_filter() to set a callback
        function for filtering.

        * gtkfilechooserutils.c: Propagate property notification
        to the receiver.

        * fnmatch.c: Copy this from GTK+ temporarily to get
        UTF-8 pattern matching functionality.
parent 96ba7bb6
...@@ -91,6 +91,12 @@ gtk_file_chooser_base_init (gpointer g_iface) ...@@ -91,6 +91,12 @@ gtk_file_chooser_base_init (gpointer g_iface)
_("File system object to use"), _("File system object to use"),
GTK_TYPE_FILE_SYSTEM, GTK_TYPE_FILE_SYSTEM,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property (g_iface,
g_param_spec_object ("filter",
_("Filter"),
_("The current filter for selecting which files are displayed"),
GTK_TYPE_FILE_FILTER,
G_PARAM_READWRITE));
g_object_interface_install_property (g_iface, g_object_interface_install_property (g_iface,
g_param_spec_boolean ("folder-mode", g_param_spec_boolean ("folder-mode",
_("Folder Mode"), _("Folder Mode"),
...@@ -932,6 +938,13 @@ gtk_file_chooser_get_preview_widget (GtkFileChooser *chooser) ...@@ -932,6 +938,13 @@ gtk_file_chooser_get_preview_widget (GtkFileChooser *chooser)
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL); g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
g_object_get (chooser, "preview-widget", &preview_widget, NULL); g_object_get (chooser, "preview-widget", &preview_widget, NULL);
/* Horrid hack; g_object_get() refs returned objects but
* that contradicts the memory management conventions
* for accessors.
*/
if (preview_widget)
g_object_unref (preview_widget);
return preview_widget; return preview_widget;
} }
...@@ -1046,3 +1059,107 @@ gtk_file_chooser_get_preview_uri (GtkFileChooser *chooser) ...@@ -1046,3 +1059,107 @@ gtk_file_chooser_get_preview_uri (GtkFileChooser *chooser)
return result; return result;
} }
/**
* gtk_file_chooser_add_filter:
* @chooser: a #GtkFileChooser
* @filter: a #GtkFileFilter
*
* Adds @filter to the list of filters that the user can select between.
* When a filter is selected, only files that are passed by that
* filter are displayed.
**/
void
gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_filter (chooser, filter);
}
/**
* gtk_file_chooser_add_filter:
* @chooser: a #GtkFileChooser
* @filter: a #GtkFileFilter
*
* Removes @filter from the list of filters that the user can select between.
**/
void
gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_filter (chooser, filter);
}
/**
* gtk_file_chooser_list_filters:
* @choooser: a #GtkFileChooser
*
* Lists the current set of user-selectable filters; see
* gtk_file_chooser_add_filter(), gtk_file_chooser_remove_filter().
*
* Return value: a #GSList containing the current set of
* user selectable filters. The contents of the list are
* owned by GTK+, but you must free the list itself with
* g_slist_free() when you are done with it.
**/
GSList *
gtk_file_chooser_list_filters (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_filters (chooser);
}
/**
* gtk_file_chooser_set_filter:
* @chooser: a #GtkFileChooser
* @filter: a #GtkFileFilter
*
* Sets the current filter; only the files that pass the
* filter will be displayed. If the user-selectable list of filters
* is non-empty, then the filter should be one of the filters
* in that list. Setting the current filter when the list of
* filters is empty is useful if you want to restrict the displayed
* set of files without letting the user change it.
**/
void
gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
g_return_if_fail (GTK_IS_FILE_FILTER (filter));
g_object_set (chooser, "filter", filter, NULL);
}
/**
* gtk_file_chooser_get_filter:
* @chooser: a #GtkFileChooser
*
* Gets the current filter; see gtk_file_chooser_set_filter().
*
* Return value: the current filter, or %NULL
**/
GtkFileFilter *
gtk_file_chooser_get_filter (GtkFileChooser *chooser)
{
GtkFileFilter *filter;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
g_object_get (chooser, "filter", &filter, NULL);
/* Horrid hack; g_object_get() refs returned objects but
* that contradicts the memory management conventions
* for accessors.
*/
if (filter)
g_object_unref (filter);
return filter;
}
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#ifndef __GTK_FILE_CHOOSER_H__ #ifndef __GTK_FILE_CHOOSER_H__
#define __GTK_FILE_CHOOSER_H__ #define __GTK_FILE_CHOOSER_H__
#include "gtkfilefilter.h"
#include <gtk/gtkwidget.h> #include <gtk/gtkwidget.h>
G_BEGIN_DECLS G_BEGIN_DECLS
...@@ -100,29 +101,19 @@ gboolean gtk_file_chooser_get_preview_widget_active (GtkFileChooser *chooser); ...@@ -100,29 +101,19 @@ gboolean gtk_file_chooser_get_preview_widget_active (GtkFileChooser *chooser);
const char *gtk_file_chooser_get_preview_filename (GtkFileChooser *file_chooser); const char *gtk_file_chooser_get_preview_filename (GtkFileChooser *file_chooser);
const char *gtk_file_chooser_get_preview_uri (GtkFileChooser *file_chooser); const char *gtk_file_chooser_get_preview_uri (GtkFileChooser *file_chooser);
/* List of user selectable filters
#if 0
/* Filters
*/ */
void gtk_file_chooser_add_filter (GtkFileChooser *chooser, void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter); GtkFileFilter *filter);
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser, void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter); GtkFileFilter *filter);
GList *gtk_file_chooser_get_filters (GtkFileChooser *chooser); GSList *gtk_file_chooser_list_filters (GtkFileChooser *chooser);
/************************************************/
static gboolean (*GtkFileFilterFunc) (const char *uri, /* Current filter
const char *filename, */
gpointer data); void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *gtk_file_filter_new_pattern (const char *pattern); GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
GtkFileFilter *gtk_file_filter_new_mime_type (const char *mime_type);
GtkFileFilter *gtk_file_filter_new_callback (GtkFileFilterFunction *func,
gpointer data,
GDestroyNotify notify);
#endif
G_END_DECLS G_END_DECLS
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "gtkfilechooser.h" #include "gtkfilechooser.h"
#include "gtkfilesystemmodel.h" #include "gtkfilesystemmodel.h"
#include <gtk/gtkalignment.h>
#include <gtk/gtkcellrendererpixbuf.h> #include <gtk/gtkcellrendererpixbuf.h>
#include <gtk/gtkcellrenderertext.h> #include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkentry.h> #include <gtk/gtkentry.h>
...@@ -32,6 +33,8 @@ ...@@ -32,6 +33,8 @@
#include <gtk/gtkhpaned.h> #include <gtk/gtkhpaned.h>
#include <gtk/gtkicontheme.h> #include <gtk/gtkicontheme.h>
#include <gtk/gtklabel.h> #include <gtk/gtklabel.h>
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkoptionmenu.h>
#include <gtk/gtkscrolledwindow.h> #include <gtk/gtkscrolledwindow.h>
#include <gtk/gtktreeview.h> #include <gtk/gtktreeview.h>
#include <gtk/gtktreemodelsort.h> #include <gtk/gtktreemodelsort.h>
...@@ -62,6 +65,9 @@ struct _GtkFileChooserImplDefault ...@@ -62,6 +65,9 @@ struct _GtkFileChooserImplDefault
GtkFileChooserAction action; GtkFileChooserAction action;
GtkFileFilter *current_filter;
GSList *filters;
GtkFilePath *current_folder; GtkFilePath *current_folder;
guint folder_mode : 1; guint folder_mode : 1;
...@@ -70,6 +76,8 @@ struct _GtkFileChooserImplDefault ...@@ -70,6 +76,8 @@ struct _GtkFileChooserImplDefault
guint select_multiple : 1; guint select_multiple : 1;
guint show_hidden : 1; guint show_hidden : 1;
GtkWidget *filter_alignment;
GtkWidget *filter_option_menu;
GtkWidget *tree_scrollwin; GtkWidget *tree_scrollwin;
GtkWidget *tree; GtkWidget *tree;
GtkWidget *list_scrollwin; GtkWidget *list_scrollwin;
...@@ -94,6 +102,7 @@ static void gtk_file_chooser_impl_default_get_property (GObject ...@@ -94,6 +102,7 @@ static void gtk_file_chooser_impl_default_get_property (GObject
guint prop_id, guint prop_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gtk_file_chooser_impl_default_show_all (GtkWidget *widget);
static void gtk_file_chooser_impl_default_set_current_folder (GtkFileChooser *chooser, static void gtk_file_chooser_impl_default_set_current_folder (GtkFileChooser *chooser,
const GtkFilePath *path); const GtkFilePath *path);
...@@ -108,13 +117,23 @@ static void gtk_file_chooser_impl_default_select_all (GtkFileC ...@@ -108,13 +117,23 @@ static void gtk_file_chooser_impl_default_select_all (GtkFileC
static void gtk_file_chooser_impl_default_unselect_all (GtkFileChooser *chooser); static void gtk_file_chooser_impl_default_unselect_all (GtkFileChooser *chooser);
static GSList * gtk_file_chooser_impl_default_get_paths (GtkFileChooser *chooser); static GSList * gtk_file_chooser_impl_default_get_paths (GtkFileChooser *chooser);
static GtkFileSystem *gtk_file_chooser_impl_default_get_file_system (GtkFileChooser *chooser); static GtkFileSystem *gtk_file_chooser_impl_default_get_file_system (GtkFileChooser *chooser);
static void gtk_file_chooser_impl_default_add_filter (GtkFileChooser *chooser,
static void tree_selection_changed (GtkTreeSelection *tree_selection, GtkFileFilter *filter);
GtkFileChooserImplDefault *impl); static void gtk_file_chooser_impl_default_remove_filter (GtkFileChooser *chooser,
static void list_selection_changed (GtkTreeSelection *tree_selection, GtkFileFilter *filter);
GtkFileChooserImplDefault *impl); static GSList * gtk_file_chooser_impl_default_list_filters (GtkFileChooser *chooser);
static void entry_activate (GtkEntry *entry,
GtkFileChooserImplDefault *impl); static void set_current_filter (GtkFileChooserImplDefault *impl,
GtkFileFilter *filter);
static void filter_option_menu_changed (GtkOptionMenu *option_menu,
GtkFileChooserImplDefault *impl);
static void tree_selection_changed (GtkTreeSelection *tree_selection,
GtkFileChooserImplDefault *impl);
static void list_selection_changed (GtkTreeSelection *tree_selection,
GtkFileChooserImplDefault *impl);
static void entry_activate (GtkEntry *entry,
GtkFileChooserImplDefault *impl);
static void tree_name_data_func (GtkTreeViewColumn *tree_column, static void tree_name_data_func (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell, GtkCellRenderer *cell,
...@@ -180,6 +199,7 @@ static void ...@@ -180,6 +199,7 @@ static void
gtk_file_chooser_impl_default_class_init (GtkFileChooserImplDefaultClass *class) gtk_file_chooser_impl_default_class_init (GtkFileChooserImplDefaultClass *class)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (class); GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
parent_class = g_type_class_peek_parent (class); parent_class = g_type_class_peek_parent (class);
...@@ -188,6 +208,8 @@ gtk_file_chooser_impl_default_class_init (GtkFileChooserImplDefaultClass *class) ...@@ -188,6 +208,8 @@ gtk_file_chooser_impl_default_class_init (GtkFileChooserImplDefaultClass *class)
gobject_class->set_property = gtk_file_chooser_impl_default_set_property; gobject_class->set_property = gtk_file_chooser_impl_default_set_property;
gobject_class->get_property = gtk_file_chooser_impl_default_get_property; gobject_class->get_property = gtk_file_chooser_impl_default_get_property;
widget_class->show_all = gtk_file_chooser_impl_default_show_all;
_gtk_file_chooser_install_properties (gobject_class); _gtk_file_chooser_install_properties (gobject_class);
} }
...@@ -203,6 +225,9 @@ gtk_file_chooser_impl_default_iface_init (GtkFileChooserIface *iface) ...@@ -203,6 +225,9 @@ gtk_file_chooser_impl_default_iface_init (GtkFileChooserIface *iface)
iface->set_current_folder = gtk_file_chooser_impl_default_set_current_folder; iface->set_current_folder = gtk_file_chooser_impl_default_set_current_folder;
iface->get_current_folder = gtk_file_chooser_impl_default_get_current_folder; iface->get_current_folder = gtk_file_chooser_impl_default_get_current_folder;
iface->set_current_name = gtk_file_chooser_impl_default_set_current_name; iface->set_current_name = gtk_file_chooser_impl_default_set_current_name;
iface->add_filter = gtk_file_chooser_impl_default_add_filter;
iface->remove_filter = gtk_file_chooser_impl_default_remove_filter;
iface->list_filters = gtk_file_chooser_impl_default_list_filters;
} }
static void static void
...@@ -274,6 +299,30 @@ gtk_file_chooser_impl_default_constructor (GType type, ...@@ -274,6 +299,30 @@ gtk_file_chooser_impl_default_constructor (GType type,
gtk_widget_push_composite_child (); gtk_widget_push_composite_child ();
impl->filter_alignment = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
gtk_alignment_set_padding (GTK_ALIGNMENT (impl->filter_alignment), 0, 6, 0, 0);
gtk_box_pack_start (GTK_BOX (impl), impl->filter_alignment, FALSE, FALSE, 0);
/* Don't show filter initially */
hbox = gtk_hbox_new (FALSE, 6);
gtk_container_add (GTK_CONTAINER (impl->filter_alignment), hbox);
gtk_widget_show (hbox);
label = gtk_label_new_with_mnemonic ("Files of _type:");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
impl->filter_option_menu = gtk_option_menu_new ();
gtk_option_menu_set_menu (GTK_OPTION_MENU (impl->filter_option_menu),
gtk_menu_new ());
gtk_box_pack_start (GTK_BOX (hbox), impl->filter_option_menu, FALSE, FALSE, 0);
gtk_widget_show (impl->filter_option_menu);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), impl->filter_option_menu);
g_signal_connect (impl->filter_option_menu, "changed",
G_CALLBACK (filter_option_menu_changed), impl);
hpaned = gtk_hpaned_new (); hpaned = gtk_hpaned_new ();
gtk_box_pack_start (GTK_BOX (impl), hpaned, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (impl), hpaned, TRUE, TRUE, 0);
gtk_widget_show (hpaned); gtk_widget_show (hpaned);
...@@ -415,6 +464,9 @@ gtk_file_chooser_impl_default_set_property (GObject *object, ...@@ -415,6 +464,9 @@ gtk_file_chooser_impl_default_set_property (GObject *object,
} }
} }
break; break;
case GTK_FILE_CHOOSER_PROP_FILTER:
set_current_filter (impl, g_value_get_object (value));
break;
case GTK_FILE_CHOOSER_PROP_FOLDER_MODE: case GTK_FILE_CHOOSER_PROP_FOLDER_MODE:
{ {
gboolean folder_mode = g_value_get_boolean (value); gboolean folder_mode = g_value_get_boolean (value);
...@@ -481,6 +533,9 @@ gtk_file_chooser_impl_default_get_property (GObject *object, ...@@ -481,6 +533,9 @@ gtk_file_chooser_impl_default_get_property (GObject *object,
case GTK_FILE_CHOOSER_PROP_ACTION: case GTK_FILE_CHOOSER_PROP_ACTION:
g_value_set_enum (value, impl->action); g_value_set_enum (value, impl->action);
break; break;
case GTK_FILE_CHOOSER_PROP_FILTER:
g_value_set_object (value, impl->current_filter);
break;
case GTK_FILE_CHOOSER_PROP_FOLDER_MODE: case GTK_FILE_CHOOSER_PROP_FOLDER_MODE:
g_value_set_boolean (value, impl->folder_mode); g_value_set_boolean (value, impl->folder_mode);
break; break;
...@@ -505,6 +560,16 @@ gtk_file_chooser_impl_default_get_property (GObject *object, ...@@ -505,6 +560,16 @@ gtk_file_chooser_impl_default_get_property (GObject *object,
} }
} }
/* We override show-all since we have internal widgets that
* shouldn't be shown when you call show_all(), like the filter
* option menu.
*/
static void
gtk_file_chooser_impl_default_show_all (GtkWidget *widget)
{
gtk_widget_show (widget);
}
static void static void
expand_and_select_func (GtkFileSystemModel *model, expand_and_select_func (GtkFileSystemModel *model,
GtkTreePath *path, GtkTreePath *path,
...@@ -587,7 +652,7 @@ gtk_file_chooser_impl_default_select_path (GtkFileChooser *chooser, ...@@ -587,7 +652,7 @@ gtk_file_chooser_impl_default_select_path (GtkFileChooser *chooser,
_gtk_file_chooser_set_current_folder_path (chooser, parent_path); _gtk_file_chooser_set_current_folder_path (chooser, parent_path);
gtk_file_path_free (parent_path); gtk_file_path_free (parent_path);
_gtk_file_system_model_path_do (impl->list_model, path, _gtk_file_system_model_path_do (impl->list_model, path,
select_func, impl); select_func, impl);
} }
} }
...@@ -691,6 +756,209 @@ gtk_file_chooser_impl_default_get_file_system (GtkFileChooser *chooser) ...@@ -691,6 +756,209 @@ gtk_file_chooser_impl_default_get_file_system (GtkFileChooser *chooser)
return impl->file_system; return impl->file_system;
} }
static GtkWidget *
find_filter_menu_item (GtkFileChooserImplDefault *impl,
GtkFileFilter *filter,
gint *index_return)
{
GtkWidget *menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (impl->filter_option_menu));
GList *children = gtk_container_get_children (GTK_CONTAINER (menu));
GList *tmp_list;
int index = 0;
if (index_return)
*index_return = -1;
for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
{
if (g_object_get_data (tmp_list->data, "gtk-file-filter") == filter)
{
if (index_return)
*index_return = index;
return tmp_list->data;
}
index++;
}
g_list_free (children);
return NULL;
}
static void
gtk_file_chooser_impl_default_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter)
{
GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
GtkWidget *menu;
GtkWidget *menu_item;
const gchar *name;
if (g_slist_find (impl->filters, filter))
{
g_warning ("gtk_file_chooser_add_filter() called on filter already in list\n");
return;
}
g_object_ref (filter);
gtk_object_sink (GTK_OBJECT (filter));
impl->filters = g_slist_append (impl->filters, filter);
name = gtk_file_filter_get_name (filter);
if (!name)
name = "Untitled filter"; /* Place-holder, doesn't need to be marked for translation */
menu_item = gtk_menu_item_new_with_label (name);
g_object_set_data (G_OBJECT (menu_item), "gtk-file-filter", filter);
gtk_widget_show (menu_item);
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (impl->filter_option_menu));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
/* Option menus don't react to menu size changes properly */
gtk_widget_size_request (menu, NULL);
if (!g_slist_find (impl->filters, impl->current_filter))
set_current_filter (impl, filter);
gtk_widget_show (impl->filter_alignment);
}
static void
gtk_file_chooser_impl_default_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter)
{
GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
GtkWidget *menu;
GtkWidget *menu_item;
if (!g_slist_find (impl->filters, filter))
{
g_warning ("gtk_file_chooser_remove_filter() called on filter not in list\n");
return;
}
impl->filters = g_slist_remove (impl->filters, filter);
if (filter == impl->current_filter)
{
if (impl->filters)
set_current_filter (impl, impl->filters->data);
else
set_current_filter (impl, NULL);
}
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (impl->filter_option_menu));
menu_item = find_filter_menu_item (impl, filter, NULL);
g_assert (menu_item);
gtk_widget_destroy (menu_item);
/* Option menus don't react to menu size changes properly */
gtk_widget_size_request (menu, NULL);
g_object_unref (filter);
if (!impl->filters)
gtk_widget_hide (impl->filter_alignment);
}
static GSList *
gtk_file_chooser_impl_default_list_filters (GtkFileChooser *chooser)
{
GtkFileChooserImplDefault *impl = GTK_FILE_CHOOSER_IMPL_DEFAULT (chooser);
return g_slist_copy (impl->filters);
}
static gboolean
list_model_filter_func (GtkFileSystemModel *model,
GtkFilePath *path,
const GtkFileInfo *file_info,
gpointer user_data)
{
GtkFileChooserImplDefault *impl = user_data;
GtkFileFilterInfo filter_info;
GtkFileFilterFlags needed;
gboolean result;
if (!impl->current_filter)
return TRUE;
filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
needed = gtk_file_filter_get_needed (impl->current_filter);
filter_info.display_name = gtk_file_info_get_display_name (file_info);
filter_info.mime_type = gtk_file_info_get_mime_type (file_info);
if (needed & GTK_FILE_FILTER_FILENAME)
{
filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
if (filter_info.filename)
filter_info.contains |= GTK_FILE_FILTER_FILENAME;
}
else
filter_info.filename = NULL;
if (needed & GTK_FILE_FILTER_URI)
{
filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
if (filter_info.filename)
filter_info.contains |= GTK_FILE_FILTER_URI;
}
else
filter_info.uri = NULL;
result = gtk_file_filter_filter (impl->current_filter, &filter_info);
if (filter_info.filename)
g_free ((gchar *)filter_info.filename);
if (filter_info.uri)
g_free ((gchar *)filter_info.uri);
return result;
}
static void
install_list_model_filter (GtkFileChooserImplDefault *impl)
{
if (impl->current_filter)
_gtk_file_system_model_set_filter (impl->list_model,
list_model_filter_func,
impl);
}
static void
set_current_filter (GtkFileChooserImplDefault *impl,
GtkFileFilter *filter)
{
if (impl->current_filter != filter)
{
int menu_item_index;
/* If we have filters, new filter must be one of them
*/
find_filter_menu_item (impl, filter, &menu_item_index);
if (impl->filters && menu_item_index < 0)
return;
if (impl->current_filter)
g_object_unref (impl->current_filter);
impl->current_filter = filter;
if (impl->current_filter)
{
g_object_ref (impl->current_filter);
gtk_object_sink (GTK_OBJECT (filter));
}
if (impl->filters)
gtk_option_menu_set_history (GTK_OPTION_MENU (impl->filter_option_menu),
menu_item_index);
install_list_model_filter (impl);
g_object_notify (G_OBJECT (impl), "filter");
}
}
static gint static gint
name_sort_func (GtkTreeModel *model, name_sort_func (GtkTreeModel *model,
GtkTreeIter *a, GtkTreeIter *a,
...@@ -797,6 +1065,16 @@ update_chooser_entry (GtkFileChooserImplDefault *impl) ...@@ -797,6 +1065,16 @@ update_chooser_entry (GtkFileChooserImplDefault *impl)
gtk_file_info_get_display_name (info)); gtk_file_info_get_display_name (info));
} }
static void
filter_option_menu_changed (GtkOptionMenu *option_menu,
GtkFileChooserImplDefault *impl)
{
gint new_index = gtk_option_menu_get_history (GTK_OPTION_MENU (option_menu));
GtkFileFilter *new_filter = g_slist_nth_data (impl->filters, new_index);
set_current_filter (impl, new_filter);
}
static void static void
tree_selection_changed (GtkTreeSelection *selection, tree_selection_changed (GtkTreeSelection *selection,
GtkFileChooserImplDefault *impl) GtkFileChooserImplDefault *impl)
...@@ -843,6 +1121,7 @@ tree_selection_changed (GtkTreeSelection *selection, ...@@ -843,6 +1121,7 @@ tree_selection_changed (GtkTreeSelection *selection,
GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_DISPLAY_NAME |
GTK_FILE_INFO_SIZE); GTK_FILE_INFO_SIZE);
_gtk_file_system_model_set_show_folders (impl->list_model, FALSE); _gtk_file_system_model_set_show_folders (impl->list_model, FALSE);
install_list_model_filter (impl);
impl->sort_model = (GtkTreeModelSort *)gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->list_model)); impl->sort_model = (GtkTreeModelSort *)gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->list_model));
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), 0, name_sort_func, impl, NULL); gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), 0, name_sort_func, impl, NULL);
......
...@@ -34,18 +34,6 @@ struct _GtkFileChooserIface ...@@ -34,18 +34,6 @@ struct _GtkFileChooserIface
{ {
GTypeInterface base_iface; GTypeInterface base_iface;
/* GtkFileChooser interface has the following properties: