1 /* GTK - The GIMP Toolkit
2 * gtkrecentfilter.h - Filter object for recently used resources
3 * Copyright (C) 2006, Emmanuele Bassi
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 "gtkrecentfilter.h"
25 #include "gtkobject.h"
27 #include "gtkprivate.h"
32 #define XDG_PREFIX _gtk_xdg
33 #include "xdgmime/xdgmime.h"
36 typedef struct _GtkRecentFilterClass GtkRecentFilterClass;
37 typedef struct _FilterRule FilterRule;
41 FILTER_RULE_DISPLAY_NAME,
42 FILTER_RULE_MIME_TYPE,
43 FILTER_RULE_PIXBUF_FORMATS,
44 FILTER_RULE_APPLICATION,
50 struct _GtkRecentFilter
52 GtkObject parent_instance;
57 GtkRecentFilterFlags needed;
60 struct _GtkRecentFilterClass
62 GtkObjectClass parent_class;
68 GtkRecentFilterFlags needed;
74 GSList *pixbuf_formats;
79 GtkRecentFilterFunc func;
81 GDestroyNotify data_destroy;
86 G_DEFINE_TYPE (GtkRecentFilter, gtk_recent_filter, GTK_TYPE_OBJECT)
90 filter_rule_free (FilterRule *rule)
94 case FILTER_RULE_MIME_TYPE:
95 g_free (rule->u.mime_type);
100 case FILTER_RULE_DISPLAY_NAME:
101 g_free (rule->u.pattern);
103 case FILTER_RULE_PIXBUF_FORMATS:
104 g_slist_free (rule->u.pixbuf_formats);
106 case FILTER_RULE_AGE:
108 case FILTER_RULE_APPLICATION:
109 g_free (rule->u.application);
111 case FILTER_RULE_GROUP:
112 g_free (rule->u.group);
114 case FILTER_RULE_CUSTOM:
115 if (rule->u.custom.data_destroy)
116 rule->u.custom.data_destroy (rule->u.custom.data);
119 g_assert_not_reached ();
127 gtk_recent_filter_finalize (GObject *object)
129 GtkRecentFilter *filter = GTK_RECENT_FILTER (object);
132 g_free (filter->name);
136 g_slist_foreach (filter->rules,
137 (GFunc) filter_rule_free,
139 g_slist_free (filter->rules);
142 G_OBJECT_CLASS (gtk_recent_filter_parent_class)->finalize (object);
146 gtk_recent_filter_class_init (GtkRecentFilterClass *klass)
148 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
150 gobject_class->finalize = gtk_recent_filter_finalize;
154 gtk_recent_filter_init (GtkRecentFilter *filter)
164 * gtk_recent_filter_new:
166 * Creates a new #GtkRecentFilter with no rules added to it.
167 * Such filter does not accept any recently used resources, so is not
168 * particularly useful until you add rules with
169 * gtk_recent_filter_add_pattern(), gtk_recent_filter_add_mime_type(),
170 * gtk_recent_filter_add_application(), gtk_recent_filter_add_age().
171 * To create a filter that accepts any recently used resource, use:
173 * <informalexample><programlisting>
174 * GtkRecentFilter *filter = gtk_recent_filter_new (<!-- -->);
175 * gtk_recent_filter_add_pattern (filter, "*");
176 * </programlisting></informalexample>
178 * Return value: a new #GtkRecentFilter
183 gtk_recent_filter_new (void)
185 return g_object_new (GTK_TYPE_RECENT_FILTER, NULL);
189 * gtk_recent_filter_set_name:
190 * @filter: a #GtkRecentFilter
191 * @name: then human readable name of @filter
193 * Sets the human-readable name of the filter; this is the string
194 * that will be displayed in the recently used resources selector
195 * user interface if there is a selectable list of filters.
200 gtk_recent_filter_set_name (GtkRecentFilter *filter,
203 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
206 g_free (filter->name);
209 filter->name = g_strdup (name);
213 * gtk_recent_filter_get_name:
214 * @filter: a #GtkRecentFilter
216 * Gets the human-readable name for the filter.
217 * See gtk_recent_filter_set_name().
219 * Return value: the name of the filter, or %NULL. The returned string
220 * is owned by the filter object and should not be freed.
224 G_CONST_RETURN gchar *
225 gtk_recent_filter_get_name (GtkRecentFilter *filter)
227 g_return_val_if_fail (GTK_IS_RECENT_FILTER (filter), NULL);
233 * gtk_recent_filter_get_needed:
234 * @filter: a #GtkRecentFilter
236 * Gets the fields that need to be filled in for the structure
237 * passed to gtk_recent_filter_filter()
239 * This function will not typically be used by applications; it
240 * is intended principally for use in the implementation of
243 * Return value: bitfield of flags indicating needed fields when
244 * calling gtk_recent_filter_filter()
249 gtk_recent_filter_get_needed (GtkRecentFilter *filter)
251 return filter->needed;
255 recent_filter_add_rule (GtkRecentFilter *filter,
258 filter->needed |= rule->needed;
259 filter->rules = g_slist_append (filter->rules, rule);
263 * gtk_recent_filter_add_mime_type:
264 * @filter: a #GtkRecentFilter
265 * @mime_type: a MIME type
267 * Adds a rule that allows resources based on their registered MIME type.
272 gtk_recent_filter_add_mime_type (GtkRecentFilter *filter,
273 const gchar *mime_type)
277 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
278 g_return_if_fail (mime_type != NULL);
280 rule = g_new0 (FilterRule, 1);
281 rule->type = FILTER_RULE_MIME_TYPE;
282 rule->needed = GTK_RECENT_FILTER_MIME_TYPE;
283 rule->u.mime_type = g_strdup (mime_type);
285 recent_filter_add_rule (filter, rule);
289 * gtk_recent_filter_add_pattern:
290 * @filter: a #GtkRecentFilter
291 * @pattern: a file pattern
293 * Adds a rule that allows resources based on a pattern matching their
299 gtk_recent_filter_add_pattern (GtkRecentFilter *filter,
300 const gchar *pattern)
304 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
305 g_return_if_fail (pattern != NULL);
307 rule = g_new0 (FilterRule, 1);
308 rule->type = FILTER_RULE_DISPLAY_NAME;
309 rule->needed = GTK_RECENT_FILTER_DISPLAY_NAME;
310 rule->u.pattern = g_strdup (pattern);
312 recent_filter_add_rule (filter, rule);
316 * gtk_recent_filter_add_pixbuf_formats:
317 * @filter: a #GtkRecentFilter
319 * Adds a rule allowing image files in the formats supported
325 gtk_recent_filter_add_pixbuf_formats (GtkRecentFilter *filter)
329 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
331 rule = g_new0 (FilterRule, 1);
332 rule->type = FILTER_RULE_PIXBUF_FORMATS;
333 rule->needed = GTK_RECENT_FILTER_MIME_TYPE;
334 rule->u.pixbuf_formats = gdk_pixbuf_get_formats ();
336 recent_filter_add_rule (filter, rule);
340 * gtk_recent_filter_add_application:
341 * @filter: a #GtkRecentFilter
342 * @application: an application name
344 * Adds a rule that allows resources based on the name of the application
345 * that has registered them.
350 gtk_recent_filter_add_application (GtkRecentFilter *filter,
351 const gchar *application)
355 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
356 g_return_if_fail (application != NULL);
358 rule = g_new0 (FilterRule, 1);
359 rule->type = FILTER_RULE_APPLICATION;
360 rule->needed = GTK_RECENT_FILTER_APPLICATION;
361 rule->u.application = g_strdup (application);
363 recent_filter_add_rule (filter, rule);
367 * gtk_recent_filter_add_group:
368 * @filter: a #GtkRecentFilter
369 * @group: a group name
371 * Adds a rule that allows resources based on the name of the group
372 * to which they belong
377 gtk_recent_filter_add_group (GtkRecentFilter *filter,
382 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
383 g_return_if_fail (group != NULL);
385 rule = g_new0 (FilterRule, 1);
386 rule->type = FILTER_RULE_GROUP;
387 rule->needed = GTK_RECENT_FILTER_GROUP;
388 rule->u.group = g_strdup (group);
390 recent_filter_add_rule (filter, rule);
394 * gtk_recent_filter_add_age:
395 * @filter: a #GtkRecentFilter
396 * @days: number of days
398 * Adds a rule that allows resources based on their age - that is, the number
399 * of days elapsed since they were last modified.
404 gtk_recent_filter_add_age (GtkRecentFilter *filter,
409 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
411 rule = g_new0 (FilterRule, 1);
412 rule->type = FILTER_RULE_AGE;
413 rule->needed = GTK_RECENT_FILTER_AGE;
416 recent_filter_add_rule (filter, rule);
420 * gtk_recent_filter_add_custom:
421 * @filter: a #GtkRecentFilter
422 * @needed: bitfield of flags indicating the information that the custom
423 * filter function needs.
424 * @func: callback function; if the function returns %TRUE, then
425 * the file will be displayed.
426 * @data: data to pass to @func
427 * @data_destroy: function to call to free @data when it is no longer needed.
429 * Adds a rule to a filter that allows resources based on a custom callback
430 * function. The bitfield @needed which is passed in provides information
431 * about what sorts of information that the filter function needs;
432 * this allows GTK+ to avoid retrieving expensive information when
433 * it isn't needed by the filter.
438 gtk_recent_filter_add_custom (GtkRecentFilter *filter,
439 GtkRecentFilterFlags needed,
440 GtkRecentFilterFunc func,
442 GDestroyNotify data_destroy)
446 g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
447 g_return_if_fail (func != NULL);
449 rule = g_new0 (FilterRule, 1);
450 rule->type = FILTER_RULE_CUSTOM;
451 rule->needed = needed;
452 rule->u.custom.func = func;
453 rule->u.custom.data = data;
454 rule->u.custom.data_destroy = data_destroy;
456 recent_filter_add_rule (filter, rule);
461 * gtk_recent_filter_filter:
462 * @filter: a #GtkRecentFilter
463 * @filter_info: a #GtkRecentFilterInfo structure containing information
464 * about a recently used resource
466 * Tests whether a file should be displayed according to @filter.
467 * The #GtkRecentFilterInfo structure @filter_info should include
468 * the fields returned from gtk_recent_filter_get_needed().
470 * This function will not typically be used by applications; it
471 * is intended principally for use in the implementation of
474 * Return value: %TRUE if the file should be displayed
477 gtk_recent_filter_filter (GtkRecentFilter *filter,
478 const GtkRecentFilterInfo *filter_info)
482 g_return_val_if_fail (GTK_IS_RECENT_FILTER (filter), FALSE);
483 g_return_val_if_fail (filter_info != NULL, FALSE);
485 for (l = filter->rules; l != NULL; l = l->next)
487 FilterRule *rule = (FilterRule *) l->data;
489 if ((filter_info->contains & rule->needed) != rule->needed)
494 case FILTER_RULE_MIME_TYPE:
495 if ((filter_info->mime_type != NULL)
497 && (xdg_mime_mime_type_subclass (filter_info->mime_type, rule->u.mime_type)))
499 && (strcmp (filter_info->mime_type, rule->u.mime_type) == 0))
503 case FILTER_RULE_APPLICATION:
504 if (filter_info->applications)
508 for (i = 0; filter_info->applications[i] != NULL; i++)
510 if (strcmp (filter_info->applications[i], rule->u.application) == 0)
515 case FILTER_RULE_GROUP:
516 if (filter_info->groups)
520 for (i = 0; filter_info->groups[i] != NULL; i++)
522 if (strcmp (filter_info->groups[i], rule->u.group) == 0)
527 case FILTER_RULE_PIXBUF_FORMATS:
530 if (!filter_info->mime_type)
533 for (list = rule->u.pixbuf_formats; list; list = list->next)
538 mime_types = gdk_pixbuf_format_get_mime_types (list->data);
540 for (i = 0; mime_types[i] != NULL; i++)
542 if (strcmp (mime_types[i], filter_info->mime_type) == 0)
544 g_strfreev (mime_types);
549 g_strfreev (mime_types);
553 case FILTER_RULE_URI:
554 if ((filter_info->uri != NULL) &&
555 _gtk_fnmatch (rule->u.uri, filter_info->uri, FALSE))
558 case FILTER_RULE_DISPLAY_NAME:
559 if ((filter_info->display_name != NULL) &&
560 _gtk_fnmatch (rule->u.pattern, filter_info->display_name, FALSE))
563 case FILTER_RULE_AGE:
564 if ((filter_info->age != -1) &&
565 (filter_info->age < rule->u.age))
568 case FILTER_RULE_CUSTOM:
569 if (rule->u.custom.func (filter_info, rule->u.custom.data))
578 #define __GTK_RECENT_FILTER_C__
579 #include "gtkaliasdef.c"