1 /* GTK - The GIMP Toolkit
2 * gtkfilefilter.c: Filters for selecting a file subset
3 * Copyright (C) 2003, Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
24 #include "gtkfilefilter.h"
25 #include "gtkobject.h"
27 #include "gtkprivate.h"
32 #define XDG_PREFIX _gtk_xdg
33 #include "xdgmime/xdgmime.h"
36 typedef struct _GtkFileFilterClass GtkFileFilterClass;
37 typedef struct _FilterRule FilterRule;
39 #define GTK_FILE_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_FILTER, GtkFileFilterClass))
40 #define GTK_IS_FILE_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_FILTER))
41 #define GTK_FILE_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_FILTER, GtkFileFilterClass))
45 FILTER_RULE_MIME_TYPE,
46 FILTER_RULE_PIXBUF_FORMATS,
50 struct _GtkFileFilterClass
52 GtkObjectClass parent_class;
57 GtkObject parent_instance;
62 GtkFileFilterFlags needed;
68 GtkFileFilterFlags needed;
73 GSList *pixbuf_formats;
75 GtkFileFilterFunc func;
77 GDestroyNotify notify;
82 static void gtk_file_filter_finalize (GObject *object);
85 G_DEFINE_TYPE (GtkFileFilter, gtk_file_filter, GTK_TYPE_OBJECT)
88 gtk_file_filter_init (GtkFileFilter *object)
93 gtk_file_filter_class_init (GtkFileFilterClass *class)
95 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
97 gobject_class->finalize = gtk_file_filter_finalize;
101 filter_rule_free (FilterRule *rule)
105 case FILTER_RULE_MIME_TYPE:
106 g_free (rule->u.mime_type);
108 case FILTER_RULE_PATTERN:
109 g_free (rule->u.pattern);
111 case FILTER_RULE_CUSTOM:
112 if (rule->u.custom.notify)
113 rule->u.custom.notify (rule->u.custom.data);
115 case FILTER_RULE_PIXBUF_FORMATS:
116 g_slist_free (rule->u.pixbuf_formats);
119 g_assert_not_reached ();
126 gtk_file_filter_finalize (GObject *object)
128 GtkFileFilter *filter = GTK_FILE_FILTER (object);
130 g_slist_foreach (filter->rules, (GFunc)filter_rule_free, NULL);
131 g_slist_free (filter->rules);
133 g_free (filter->name);
135 G_OBJECT_CLASS (gtk_file_filter_parent_class)->finalize (object);
139 * gtk_file_filter_new:
141 * Creates a new #GtkFileFilter with no rules added to it.
142 * Such a filter doesn't accept any files, so is not
143 * particularly useful until you add rules with
144 * gtk_file_filter_add_mime_type(), gtk_file_filter_add_pattern(),
145 * or gtk_file_filter_add_custom(). To create a filter
146 * that accepts any file, use:
148 * <informalexample><programlisting>
149 * GtkFileFilter *filter = gtk_file_filter_new (<!-- -->);
150 * gtk_file_filter_add_pattern (filter, "*");
151 * </programlisting></informalexample>
153 * Return value: a new #GtkFileFilter
158 gtk_file_filter_new (void)
160 return g_object_new (GTK_TYPE_FILE_FILTER, NULL);
164 * gtk_file_filter_set_name:
165 * @filter: a #GtkFileFilter
166 * @name: the human-readable-name for the filter, or %NULL
167 * to remove any existing name.
169 * Sets the human-readable name of the filter; this is the string
170 * that will be displayed in the file selector user interface if
171 * there is a selectable list of filters.
176 gtk_file_filter_set_name (GtkFileFilter *filter,
179 g_return_if_fail (GTK_IS_FILE_FILTER (filter));
181 g_free (filter->name);
183 filter->name = g_strdup (name);
187 * gtk_file_filter_get_name:
188 * @filter: a #GtkFileFilter
190 * Gets the human-readable name for the filter. See gtk_file_filter_set_name().
192 * Return value: The human-readable name of the filter,
193 * or %NULL. This value is owned by GTK+ and must not
194 * be modified or freed.
198 G_CONST_RETURN gchar *
199 gtk_file_filter_get_name (GtkFileFilter *filter)
201 g_return_val_if_fail (GTK_IS_FILE_FILTER (filter), NULL);
207 file_filter_add_rule (GtkFileFilter *filter,
210 filter->needed |= rule->needed;
211 filter->rules = g_slist_append (filter->rules, rule);
215 * gtk_file_filter_add_mime_type:
216 * @filter: A #GtkFileFilter
217 * @mime_type: name of a MIME type
219 * Adds a rule allowing a given mime type to @filter.
224 gtk_file_filter_add_mime_type (GtkFileFilter *filter,
225 const gchar *mime_type)
229 g_return_if_fail (GTK_IS_FILE_FILTER (filter));
230 g_return_if_fail (mime_type != NULL);
232 rule = g_new (FilterRule, 1);
233 rule->type = FILTER_RULE_MIME_TYPE;
234 rule->needed = GTK_FILE_FILTER_MIME_TYPE;
235 rule->u.mime_type = g_strdup (mime_type);
237 file_filter_add_rule (filter, rule);
241 * gtk_file_filter_add_pattern:
242 * @filter: a #GtkFileFilter
243 * @pattern: a shell style glob
245 * Adds a rule allowing a shell style glob to a filter.
250 gtk_file_filter_add_pattern (GtkFileFilter *filter,
251 const gchar *pattern)
255 g_return_if_fail (GTK_IS_FILE_FILTER (filter));
256 g_return_if_fail (pattern != NULL);
258 rule = g_new (FilterRule, 1);
259 rule->type = FILTER_RULE_PATTERN;
260 rule->needed = GTK_FILE_FILTER_DISPLAY_NAME;
261 rule->u.pattern = g_strdup (pattern);
263 file_filter_add_rule (filter, rule);
267 * gtk_file_filter_add_pixbuf_formats:
268 * @filter: a #GtkFileFilter
270 * Adds a rule allowing image files in the formats supported
276 gtk_file_filter_add_pixbuf_formats (GtkFileFilter *filter)
280 g_return_if_fail (GTK_IS_FILE_FILTER (filter));
282 rule = g_new (FilterRule, 1);
283 rule->type = FILTER_RULE_PIXBUF_FORMATS;
284 rule->needed = GTK_FILE_FILTER_MIME_TYPE;
285 rule->u.pixbuf_formats = gdk_pixbuf_get_formats ();
286 file_filter_add_rule (filter, rule);
291 * gtk_file_filter_add_custom:
292 * @filter: a #GtkFileFilter
293 * @needed: bitfield of flags indicating the information that the custom
294 * filter function needs.
295 * @func: callback function; if the function returns %TRUE, then
296 * the file will be displayed.
297 * @data: data to pass to @func
298 * @notify: function to call to free @data when it is no longer needed.
300 * Adds rule to a filter that allows files based on a custom callback
301 * function. The bitfield @needed which is passed in provides information
302 * about what sorts of information that the filter function needs;
303 * this allows GTK+ to avoid retrieving expensive information when
304 * it isn't needed by the filter.
309 gtk_file_filter_add_custom (GtkFileFilter *filter,
310 GtkFileFilterFlags needed,
311 GtkFileFilterFunc func,
313 GDestroyNotify notify)
317 g_return_if_fail (GTK_IS_FILE_FILTER (filter));
318 g_return_if_fail (func != NULL);
320 rule = g_new (FilterRule, 1);
321 rule->type = FILTER_RULE_CUSTOM;
322 rule->needed = needed;
323 rule->u.custom.func = func;
324 rule->u.custom.data = data;
325 rule->u.custom.notify = notify;
327 file_filter_add_rule (filter, rule);
331 * gtk_file_filter_get_needed:
332 * @filter: a #GtkFileFilter
334 * Gets the fields that need to be filled in for the structure
335 * passed to gtk_file_filter_filter()
337 * This function will not typically be used by applications; it
338 * is intended principally for use in the implementation of
341 * Return value: bitfield of flags indicating needed fields when
342 * calling gtk_file_filter_filter()
347 gtk_file_filter_get_needed (GtkFileFilter *filter)
349 return filter->needed;
353 * gtk_file_filter_filter:
354 * @filter: a #GtkFileFilter
355 * @filter_info: a #GtkFileFilterInfo structure containing information
358 * Tests whether a file should be displayed according to @filter.
359 * The #GtkFileFilterInfo structure @filter_info should include
360 * the fields returned from gtk_file_filter_get_needed().
362 * This function will not typically be used by applications; it
363 * is intended principally for use in the implementation of
366 * Return value: %TRUE if the file should be displayed
371 gtk_file_filter_filter (GtkFileFilter *filter,
372 const GtkFileFilterInfo *filter_info)
376 for (tmp_list = filter->rules; tmp_list; tmp_list = tmp_list->next)
378 FilterRule *rule = tmp_list->data;
380 if ((filter_info->contains & rule->needed) != rule->needed)
385 case FILTER_RULE_MIME_TYPE:
386 if (filter_info->mime_type != NULL
388 && xdg_mime_mime_type_subclass (filter_info->mime_type, rule->u.mime_type))
390 && strcmp (rule->u.mime_type, filter_info->mime_type) == 0)
394 case FILTER_RULE_PATTERN:
395 if (filter_info->display_name != NULL &&
396 _gtk_fnmatch (rule->u.pattern, filter_info->display_name, FALSE))
399 case FILTER_RULE_PIXBUF_FORMATS:
403 if (!filter_info->mime_type)
406 for (list = rule->u.pixbuf_formats; list; list = list->next)
411 mime_types = gdk_pixbuf_format_get_mime_types (list->data);
413 for (i = 0; mime_types[i] != NULL; i++)
415 if (strcmp (mime_types[i], filter_info->mime_type) == 0)
417 g_strfreev (mime_types);
422 g_strfreev (mime_types);
426 case FILTER_RULE_CUSTOM:
427 if (rule->u.custom.func (filter_info, rule->u.custom.data))
436 #define __GTK_FILE_FILTER_C__
437 #include "gtkaliasdef.c"