1 /* gtkrecentchooserutils.h - Private utility functions for implementing a
2 * GtkRecentChooser interface
4 * Copyright (C) 2006 Emmanuele Bassi
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 * Based on gtkfilechooserutils.c:
22 * Copyright (C) 2003 Red Hat, Inc.
27 #include "gtkrecentchooserutils.h"
30 static void delegate_set_sort_func (GtkRecentChooser *chooser,
31 GtkRecentSortFunc sort_func,
33 GDestroyNotify data_destroy);
34 static void delegate_add_filter (GtkRecentChooser *chooser,
35 GtkRecentFilter *filter);
36 static void delegate_remove_filter (GtkRecentChooser *chooser,
37 GtkRecentFilter *filter);
38 static GSList *delegate_list_filters (GtkRecentChooser *chooser);
39 static gboolean delegate_select_uri (GtkRecentChooser *chooser,
42 static void delegate_unselect_uri (GtkRecentChooser *chooser,
44 static GList *delegate_get_items (GtkRecentChooser *chooser);
45 static GtkRecentManager *delegate_get_recent_manager (GtkRecentChooser *chooser);
46 static void delegate_select_all (GtkRecentChooser *chooser);
47 static void delegate_unselect_all (GtkRecentChooser *chooser);
48 static gboolean delegate_set_current_uri (GtkRecentChooser *chooser,
51 static gchar * delegate_get_current_uri (GtkRecentChooser *chooser);
54 static void delegate_notify (GObject *object,
57 static void delegate_selection_changed (GtkRecentChooser *receiver,
59 static void delegate_item_activated (GtkRecentChooser *receiver,
63 * _gtk_recent_chooser_install_properties:
64 * @klass: the class structure for a type deriving from #GObject
66 * Installs the necessary properties for a class implementing
67 * #GtkRecentChooser. A #GtkParamSpecOverride property is installed
68 * for each property, using the values from the #GtkRecentChooserProp
69 * enumeration. The caller must make sure itself that the enumeration
70 * values don't collide with some other property values they
74 _gtk_recent_chooser_install_properties (GObjectClass *klass)
76 g_object_class_override_property (klass,
77 GTK_RECENT_CHOOSER_PROP_RECENT_MANAGER,
79 g_object_class_override_property (klass,
80 GTK_RECENT_CHOOSER_PROP_SHOW_PRIVATE,
82 g_object_class_override_property (klass,
83 GTK_RECENT_CHOOSER_PROP_SHOW_TIPS,
85 g_object_class_override_property (klass,
86 GTK_RECENT_CHOOSER_PROP_SHOW_ICONS,
88 g_object_class_override_property (klass,
89 GTK_RECENT_CHOOSER_PROP_SHOW_NOT_FOUND,
91 g_object_class_override_property (klass,
92 GTK_RECENT_CHOOSER_PROP_SELECT_MULTIPLE,
94 g_object_class_override_property (klass,
95 GTK_RECENT_CHOOSER_PROP_LIMIT,
97 g_object_class_override_property (klass,
98 GTK_RECENT_CHOOSER_PROP_LOCAL_ONLY,
100 g_object_class_override_property (klass,
101 GTK_RECENT_CHOOSER_PROP_SORT_TYPE,
103 g_object_class_override_property (klass,
104 GTK_RECENT_CHOOSER_PROP_FILTER,
109 * _gtk_recent_chooser_delegate_iface_init:
110 * @iface: a #GtkRecentChooserIface
112 * An interface-initialization function for use in cases where
113 * an object is simply delegating the methods, signals of
114 * the #GtkRecentChooser interface to another object.
115 * _gtk_recent_chooser_set_delegate() must be called on each
116 * instance of the object so that the delegate object can
120 _gtk_recent_chooser_delegate_iface_init (GtkRecentChooserIface *iface)
122 iface->set_current_uri = delegate_set_current_uri;
123 iface->get_current_uri = delegate_get_current_uri;
124 iface->select_uri = delegate_select_uri;
125 iface->unselect_uri = delegate_unselect_uri;
126 iface->select_all = delegate_select_all;
127 iface->unselect_all = delegate_unselect_all;
128 iface->get_items = delegate_get_items;
129 iface->get_recent_manager = delegate_get_recent_manager;
130 iface->set_sort_func = delegate_set_sort_func;
131 iface->add_filter = delegate_add_filter;
132 iface->remove_filter = delegate_remove_filter;
133 iface->list_filters = delegate_list_filters;
137 * _gtk_recent_chooser_set_delegate:
138 * @receiver: a #GObject implementing #GtkRecentChooser
139 * @delegate: another #GObject implementing #GtkRecentChooser
141 * Establishes that calls on @receiver for #GtkRecentChooser
142 * methods should be delegated to @delegate, and that
143 * #GtkRecentChooser signals emitted on @delegate should be
144 * forwarded to @receiver. Must be used in conjunction with
145 * _gtk_recent_chooser_delegate_iface_init().
148 _gtk_recent_chooser_set_delegate (GtkRecentChooser *receiver,
149 GtkRecentChooser *delegate)
151 g_return_if_fail (GTK_IS_RECENT_CHOOSER (receiver));
152 g_return_if_fail (GTK_IS_RECENT_CHOOSER (delegate));
154 g_object_set_data (G_OBJECT (receiver),
155 "gtk-recent-chooser-delegate", delegate);
157 g_signal_connect (delegate, "notify",
158 G_CALLBACK (delegate_notify), receiver);
159 g_signal_connect (delegate, "selection-changed",
160 G_CALLBACK (delegate_selection_changed), receiver);
161 g_signal_connect (delegate, "item-activated",
162 G_CALLBACK (delegate_item_activated), receiver);
166 _gtk_recent_chooser_delegate_get_quark (void)
168 static GQuark quark = 0;
170 if (G_UNLIKELY (quark == 0))
171 quark = g_quark_from_static_string ("gtk-recent-chooser-delegate");
176 static GtkRecentChooser *
177 get_delegate (GtkRecentChooser *receiver)
179 return g_object_get_qdata (G_OBJECT (receiver),
180 GTK_RECENT_CHOOSER_DELEGATE_QUARK);
184 delegate_set_sort_func (GtkRecentChooser *chooser,
185 GtkRecentSortFunc sort_func,
187 GDestroyNotify data_destroy)
189 gtk_recent_chooser_set_sort_func (get_delegate (chooser),
196 delegate_add_filter (GtkRecentChooser *chooser,
197 GtkRecentFilter *filter)
199 gtk_recent_chooser_add_filter (get_delegate (chooser), filter);
203 delegate_remove_filter (GtkRecentChooser *chooser,
204 GtkRecentFilter *filter)
206 gtk_recent_chooser_remove_filter (get_delegate (chooser), filter);
210 delegate_list_filters (GtkRecentChooser *chooser)
212 return gtk_recent_chooser_list_filters (get_delegate (chooser));
216 delegate_select_uri (GtkRecentChooser *chooser,
220 return gtk_recent_chooser_select_uri (get_delegate (chooser), uri, error);
224 delegate_unselect_uri (GtkRecentChooser *chooser,
227 gtk_recent_chooser_unselect_uri (get_delegate (chooser), uri);
231 delegate_get_items (GtkRecentChooser *chooser)
233 return gtk_recent_chooser_get_items (get_delegate (chooser));
236 static GtkRecentManager *
237 delegate_get_recent_manager (GtkRecentChooser *chooser)
239 return _gtk_recent_chooser_get_recent_manager (get_delegate (chooser));
243 delegate_select_all (GtkRecentChooser *chooser)
245 gtk_recent_chooser_select_all (get_delegate (chooser));
249 delegate_unselect_all (GtkRecentChooser *chooser)
251 gtk_recent_chooser_unselect_all (get_delegate (chooser));
255 delegate_set_current_uri (GtkRecentChooser *chooser,
259 return gtk_recent_chooser_set_current_uri (get_delegate (chooser), uri, error);
263 delegate_get_current_uri (GtkRecentChooser *chooser)
265 return gtk_recent_chooser_get_current_uri (get_delegate (chooser));
269 delegate_notify (GObject *object,
275 iface = g_type_interface_peek (g_type_class_peek (G_OBJECT_TYPE (object)),
276 gtk_recent_chooser_get_type ());
277 if (g_object_interface_find_property (iface, pspec->name))
278 g_object_notify (user_data, pspec->name);
282 delegate_selection_changed (GtkRecentChooser *receiver,
285 _gtk_recent_chooser_selection_changed (GTK_RECENT_CHOOSER (user_data));
289 delegate_item_activated (GtkRecentChooser *receiver,
292 _gtk_recent_chooser_item_activated (GTK_RECENT_CHOOSER (user_data));
296 sort_recent_items_mru (GtkRecentInfo *a,
300 g_assert (a != NULL && b != NULL);
302 return gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a);
306 sort_recent_items_lru (GtkRecentInfo *a,
310 g_assert (a != NULL && b != NULL);
312 return -1 * (gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a));
317 GtkRecentSortFunc func;
321 /* our proxy sorting function */
323 sort_recent_items_proxy (gpointer *a,
327 GtkRecentInfo *info_a = (GtkRecentInfo *) a;
328 GtkRecentInfo *info_b = (GtkRecentInfo *) b;
329 SortRecentData *sort_recent = user_data;
331 if (sort_recent->func)
332 return (* sort_recent->func) (info_a, info_b, sort_recent->data);
339 get_is_recent_filtered (GtkRecentFilter *filter,
342 GtkRecentFilterInfo filter_info;
343 GtkRecentFilterFlags needed;
346 g_assert (info != NULL);
348 needed = gtk_recent_filter_get_needed (filter);
350 filter_info.contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
352 filter_info.uri = gtk_recent_info_get_uri (info);
353 filter_info.mime_type = gtk_recent_info_get_mime_type (info);
355 if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
357 filter_info.display_name = gtk_recent_info_get_display_name (info);
358 filter_info.contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
361 filter_info.uri = NULL;
363 if (needed & GTK_RECENT_FILTER_APPLICATION)
365 filter_info.applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
366 filter_info.contains |= GTK_RECENT_FILTER_APPLICATION;
369 filter_info.applications = NULL;
371 if (needed & GTK_RECENT_FILTER_GROUP)
373 filter_info.groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
374 filter_info.contains |= GTK_RECENT_FILTER_GROUP;
377 filter_info.groups = NULL;
379 if (needed & GTK_RECENT_FILTER_AGE)
381 filter_info.age = gtk_recent_info_get_age (info);
382 filter_info.contains |= GTK_RECENT_FILTER_AGE;
385 filter_info.age = -1;
387 retval = gtk_recent_filter_filter (filter, &filter_info);
390 if (filter_info.applications)
391 g_strfreev ((gchar **) filter_info.applications);
392 if (filter_info.groups)
393 g_strfreev ((gchar **) filter_info.groups);
399 * _gtk_recent_chooser_get_items:
400 * @chooser: a #GtkRecentChooser
401 * @filter: a #GtkRecentFilter
402 * @sort_func: (allow-none): sorting function, or %NULL
403 * @sort_data: (allow-none): sorting function data, or %NULL
405 * Default implementation for getting the filtered, sorted and
406 * clamped list of recently used resources from a #GtkRecentChooser.
407 * This function should be used by implementations of the
408 * #GtkRecentChooser interface inside the GtkRecentChooser::get_items
411 * Return value: a list of #GtkRecentInfo objects
414 _gtk_recent_chooser_get_items (GtkRecentChooser *chooser,
415 GtkRecentFilter *filter,
416 GtkRecentSortFunc sort_func,
419 GtkRecentManager *manager;
421 GtkRecentSortType sort_type;
423 GCompareDataFunc compare_func;
426 g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
428 manager = _gtk_recent_chooser_get_recent_manager (chooser);
432 items = gtk_recent_manager_get_items (manager);
436 limit = gtk_recent_chooser_get_limit (chooser);
442 GList *filter_items, *l;
443 gboolean local_only = FALSE;
444 gboolean show_private = FALSE;
445 gboolean show_not_found = FALSE;
447 g_object_get (G_OBJECT (chooser),
448 "local-only", &local_only,
449 "show-private", &show_private,
450 "show-not-found", &show_not_found,
454 for (l = items; l != NULL; l = l->next)
456 GtkRecentInfo *info = l->data;
457 gboolean remove_item = FALSE;
459 if (get_is_recent_filtered (filter, info))
462 if (local_only && !gtk_recent_info_is_local (info))
465 if (!show_private && gtk_recent_info_get_private_hint (info))
468 if (!show_not_found && !gtk_recent_info_exists (info))
472 filter_items = g_list_prepend (filter_items, info);
474 gtk_recent_info_unref (info);
478 items = filter_items;
484 sort_type = gtk_recent_chooser_get_sort_type (chooser);
487 case GTK_RECENT_SORT_NONE:
490 case GTK_RECENT_SORT_MRU:
491 compare_func = (GCompareDataFunc) sort_recent_items_mru;
493 case GTK_RECENT_SORT_LRU:
494 compare_func = (GCompareDataFunc) sort_recent_items_lru;
496 case GTK_RECENT_SORT_CUSTOM:
497 compare_func = (GCompareDataFunc) sort_recent_items_proxy;
500 g_assert_not_reached ();
506 SortRecentData sort_recent;
508 sort_recent.func = sort_func;
509 sort_recent.data = sort_data;
511 items = g_list_sort_with_data (items, compare_func, &sort_recent);
514 length = g_list_length (items);
515 if ((limit != -1) && (length > limit))
519 clamp = g_list_nth (items, limit - 1);
526 g_list_free_full (l, (GDestroyNotify) gtk_recent_info_unref);