1 /* GTK - The GIMP Toolkit
2  * gtkrecentchooser.c - Abstract interface for recent file selectors GUIs
3  *
4  * Copyright (C) 2006, Emmanuele Bassi
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "config.h"
21 
22 #include "gtkrecentchooser.h"
23 #include "gtkrecentchooserprivate.h"
24 #include "gtkrecentmanager.h"
25 #include "deprecated/gtkrecentaction.h"
26 #include "deprecated/gtkactivatable.h"
27 #include "gtkintl.h"
28 #include "gtktypebuiltins.h"
29 #include "gtkprivate.h"
30 #include "gtkmarshalers.h"
31 
32 /**
33  * SECTION:gtkrecentchooser
34  * @Short_description: Interface implemented by widgets displaying recently
35  *   used files
36  * @Title: GtkRecentChooser
37  * @See_also: #GtkRecentManager, #GtkRecentChooserDialog,
38  *   #GtkRecentChooserWidget, #GtkRecentChooserMenu
39  *
40  * #GtkRecentChooser is an interface that can be implemented by widgets
41  * displaying the list of recently used files.  In GTK+, the main objects
42  * that implement this interface are #GtkRecentChooserWidget,
43  * #GtkRecentChooserDialog and #GtkRecentChooserMenu.
44  *
45  * Recently used files are supported since GTK+ 2.10.
46  */
47 
48 
49 enum
50 {
51   ITEM_ACTIVATED,
52   SELECTION_CHANGED,
53 
54   LAST_SIGNAL
55 };
56 
57 static gboolean recent_chooser_has_show_numbers       (GtkRecentChooser *chooser);
58 
59 static GQuark      quark_gtk_related_action               = 0;
60 static GQuark      quark_gtk_use_action_appearance        = 0;
61 static const gchar gtk_related_action_key[]               = "gtk-related-action";
62 static const gchar gtk_use_action_appearance_key[]        = "gtk-use-action-appearance";
63 
64 
65 static guint chooser_signals[LAST_SIGNAL] = { 0, };
66 
67 
68 typedef GtkRecentChooserIface GtkRecentChooserInterface;
69 G_DEFINE_INTERFACE (GtkRecentChooser, gtk_recent_chooser, G_TYPE_OBJECT);
70 
71 
72 static void
gtk_recent_chooser_default_init(GtkRecentChooserInterface * iface)73 gtk_recent_chooser_default_init (GtkRecentChooserInterface *iface)
74 {
75   GType iface_type = G_TYPE_FROM_INTERFACE (iface);
76 
77   quark_gtk_related_action        = g_quark_from_static_string (gtk_related_action_key);
78   quark_gtk_use_action_appearance = g_quark_from_static_string (gtk_use_action_appearance_key);
79 
80   /**
81    * GtkRecentChooser::selection-changed:
82    * @chooser: the object which received the signal
83    *
84    * This signal is emitted when there is a change in the set of
85    * selected recently used resources.  This can happen when a user
86    * modifies the selection with the mouse or the keyboard, or when
87    * explicitly calling functions to change the selection.
88    *
89    * Since: 2.10
90    */
91   chooser_signals[SELECTION_CHANGED] =
92     g_signal_new (I_("selection-changed"),
93                   iface_type,
94                   G_SIGNAL_RUN_LAST,
95                   G_STRUCT_OFFSET (GtkRecentChooserIface, selection_changed),
96                   NULL, NULL,
97                   NULL,
98                   G_TYPE_NONE, 0);
99 
100   /**
101    * GtkRecentChooser::item-activated:
102    * @chooser: the object which received the signal
103    *
104    * This signal is emitted when the user "activates" a recent item
105    * in the recent chooser.  This can happen by double-clicking on an item
106    * in the recently used resources list, or by pressing
107    * `Enter`.
108    *
109    * Since: 2.10
110    */
111   chooser_signals[ITEM_ACTIVATED] =
112     g_signal_new (I_("item-activated"),
113                   iface_type,
114 		  G_SIGNAL_RUN_LAST,
115 		  G_STRUCT_OFFSET (GtkRecentChooserIface, item_activated),
116 		  NULL, NULL,
117 		  NULL,
118 		  G_TYPE_NONE, 0);
119 
120   /**
121    * GtkRecentChooser:recent-manager:
122    *
123    * The #GtkRecentManager instance used by the #GtkRecentChooser to
124    * display the list of recently used resources.
125    *
126    * Since: 2.10
127    */
128   g_object_interface_install_property (iface,
129                                        g_param_spec_object ("recent-manager",
130                                                             P_("Recent Manager"),
131                                                             P_("The RecentManager object to use"),
132                                                             GTK_TYPE_RECENT_MANAGER,
133                                                             GTK_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
134 
135   /**
136    * GtkRecentManager:show-private:
137    *
138    * Whether this #GtkRecentChooser should display recently used resources
139    * marked with the "private" flag. Such resources should be considered
140    * private to the applications and groups that have added them.
141    *
142    * Since: 2.10
143    */
144   g_object_interface_install_property (iface,
145                                        g_param_spec_boolean ("show-private",
146                                                              P_("Show Private"),
147                                                              P_("Whether the private items should be displayed"),
148                                                              FALSE,
149                                                              GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
150 
151   /**
152    * GtkRecentChooser:show-tips:
153    *
154    * Whether this #GtkRecentChooser should display a tooltip containing the
155    * full path of the recently used resources.
156    *
157    * Since: 2.10
158    */
159   g_object_interface_install_property (iface,
160                                        g_param_spec_boolean ("show-tips",
161                                                              P_("Show Tooltips"),
162                                                              P_("Whether there should be a tooltip on the item"),
163                                                              FALSE,
164                                                              GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
165 
166   /**
167    * GtkRecentChooser:show-icons:
168    *
169    * Whether this #GtkRecentChooser should display an icon near the item.
170    *
171    * Since: 2.10
172    */
173   g_object_interface_install_property (iface,
174                                        g_param_spec_boolean ("show-icons",
175                                                              P_("Show Icons"),
176                                                              P_("Whether there should be an icon near the item"),
177                                                              TRUE,
178                                                              GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
179 
180   /**
181    * GtkRecentChooser:show-not-found:
182    *
183    * Whether this #GtkRecentChooser should display the recently used resources
184    * even if not present anymore. Setting this to %FALSE will perform a
185    * potentially expensive check on every local resource (every remote
186    * resource will always be displayed).
187    *
188    * Since: 2.10
189    */
190   g_object_interface_install_property (iface,
191                                        g_param_spec_boolean ("show-not-found",
192                                                              P_("Show Not Found"),
193                                                              P_("Whether the items pointing to unavailable resources should be displayed"),
194                                                              TRUE,
195                                                              GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
196 
197   /**
198    * GtkRecentChooser:select-multiple:
199    *
200    * Allow the user to select multiple resources.
201    *
202    * Since: 2.10
203    */
204   g_object_interface_install_property (iface,
205                                        g_param_spec_boolean ("select-multiple",
206                                                              P_("Select Multiple"),
207                                                              P_("Whether to allow multiple items to be selected"),
208                                                              FALSE,
209                                                              GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
210 
211   /**
212    * GtkRecentChooser:local-only:
213    *
214    * Whether this #GtkRecentChooser should display only local (file:)
215    * resources.
216    *
217    * Since: 2.10
218    */
219   g_object_interface_install_property (iface,
220                                        g_param_spec_boolean ("local-only",
221                                                              P_("Local only"),
222                                                              P_("Whether the selected resource(s) should be limited to local file: URIs"),
223                                                              TRUE,
224                                                              GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
225 
226   /**
227    * GtkRecentChooser:limit:
228    *
229    * The maximum number of recently used resources to be displayed,
230    * or -1 to display all items.
231    *
232    * Since: 2.10
233    */
234   g_object_interface_install_property (iface,
235                                        g_param_spec_int ("limit",
236                                                          P_("Limit"),
237                                                          P_("The maximum number of items to be displayed"),
238                                                          -1, G_MAXINT, 50,
239                                                          GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
240 
241   /**
242    * GtkRecentChooser:sort-type:
243    *
244    * Sorting order to be used when displaying the recently used resources.
245    *
246    * Since: 2.10
247    */
248   g_object_interface_install_property (iface,
249                                        g_param_spec_enum ("sort-type",
250                                                           P_("Sort Type"),
251                                                           P_("The sorting order of the items displayed"),
252                                                           GTK_TYPE_RECENT_SORT_TYPE,
253                                                           GTK_RECENT_SORT_NONE,
254                                                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
255 
256   /**
257    * GtkRecentChooser:filter:
258    *
259    * The #GtkRecentFilter object to be used when displaying
260    * the recently used resources.
261    *
262    * Since: 2.10
263    */
264   g_object_interface_install_property (iface,
265                                        g_param_spec_object ("filter",
266                                                             P_("Filter"),
267                                                             P_("The current filter for selecting which resources are displayed"),
268                                                             GTK_TYPE_RECENT_FILTER,
269                                                             GTK_PARAM_READWRITE));
270 }
271 
272 GQuark
gtk_recent_chooser_error_quark(void)273 gtk_recent_chooser_error_quark (void)
274 {
275   return g_quark_from_static_string ("gtk-recent-chooser-error-quark");
276 }
277 
278 /**
279  * _gtk_recent_chooser_get_recent_manager:
280  * @chooser: a #GtkRecentChooser
281  *
282  * Gets the #GtkRecentManager used by @chooser.
283  *
284  * Returns: the recent manager for @chooser.
285  *
286  * Since: 2.10
287  */
288 GtkRecentManager *
_gtk_recent_chooser_get_recent_manager(GtkRecentChooser * chooser)289 _gtk_recent_chooser_get_recent_manager (GtkRecentChooser *chooser)
290 {
291   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
292 
293   return GTK_RECENT_CHOOSER_GET_IFACE (chooser)->get_recent_manager (chooser);
294 }
295 
296 /**
297  * gtk_recent_chooser_set_show_private:
298  * @chooser: a #GtkRecentChooser
299  * @show_private: %TRUE to show private items, %FALSE otherwise
300  *
301  * Whether to show recently used resources marked registered as private.
302  *
303  * Since: 2.10
304  */
305 void
gtk_recent_chooser_set_show_private(GtkRecentChooser * chooser,gboolean show_private)306 gtk_recent_chooser_set_show_private (GtkRecentChooser *chooser,
307 				     gboolean          show_private)
308 {
309   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
310 
311   g_object_set (chooser, "show-private", show_private, NULL);
312 }
313 
314 /**
315  * gtk_recent_chooser_get_show_private:
316  * @chooser: a #GtkRecentChooser
317  *
318  * Returns whether @chooser should display recently used resources
319  * registered as private.
320  *
321  * Returns: %TRUE if the recent chooser should show private items,
322  *   %FALSE otherwise.
323  *
324  * Since: 2.10
325  */
326 gboolean
gtk_recent_chooser_get_show_private(GtkRecentChooser * chooser)327 gtk_recent_chooser_get_show_private (GtkRecentChooser *chooser)
328 {
329   gboolean show_private;
330 
331   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
332 
333   g_object_get (chooser, "show-private", &show_private, NULL);
334 
335   return show_private;
336 }
337 
338 /**
339  * gtk_recent_chooser_set_show_not_found:
340  * @chooser: a #GtkRecentChooser
341  * @show_not_found: whether to show the local items we didn’t find
342  *
343  * Sets whether @chooser should display the recently used resources that
344  * it didn’t find.  This only applies to local resources.
345  *
346  * Since: 2.10
347  */
348 void
gtk_recent_chooser_set_show_not_found(GtkRecentChooser * chooser,gboolean show_not_found)349 gtk_recent_chooser_set_show_not_found (GtkRecentChooser *chooser,
350 				       gboolean          show_not_found)
351 {
352   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
353 
354   g_object_set (chooser, "show-not-found", show_not_found, NULL);
355 }
356 
357 /**
358  * gtk_recent_chooser_get_show_not_found:
359  * @chooser: a #GtkRecentChooser
360  *
361  * Retrieves whether @chooser should show the recently used resources that
362  * were not found.
363  *
364  * Returns: %TRUE if the resources not found should be displayed, and
365  *   %FALSE otheriwse.
366  *
367  * Since: 2.10
368  */
369 gboolean
gtk_recent_chooser_get_show_not_found(GtkRecentChooser * chooser)370 gtk_recent_chooser_get_show_not_found (GtkRecentChooser *chooser)
371 {
372   gboolean show_not_found;
373 
374   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
375 
376   g_object_get (chooser, "show-not-found", &show_not_found, NULL);
377 
378   return show_not_found;
379 }
380 
381 /**
382  * gtk_recent_chooser_set_show_icons:
383  * @chooser: a #GtkRecentChooser
384  * @show_icons: whether to show an icon near the resource
385  *
386  * Sets whether @chooser should show an icon near the resource when
387  * displaying it.
388  *
389  * Since: 2.10
390  */
391 void
gtk_recent_chooser_set_show_icons(GtkRecentChooser * chooser,gboolean show_icons)392 gtk_recent_chooser_set_show_icons (GtkRecentChooser *chooser,
393 				   gboolean          show_icons)
394 {
395   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
396 
397   g_object_set (chooser, "show-icons", show_icons, NULL);
398 }
399 
400 /**
401  * gtk_recent_chooser_get_show_icons:
402  * @chooser: a #GtkRecentChooser
403  *
404  * Retrieves whether @chooser should show an icon near the resource.
405  *
406  * Returns: %TRUE if the icons should be displayed, %FALSE otherwise.
407  *
408  * Since: 2.10
409  */
410 gboolean
gtk_recent_chooser_get_show_icons(GtkRecentChooser * chooser)411 gtk_recent_chooser_get_show_icons (GtkRecentChooser *chooser)
412 {
413   gboolean show_icons;
414 
415   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
416 
417   g_object_get (chooser, "show-icons", &show_icons, NULL);
418 
419   return show_icons;
420 }
421 
422 /**
423  * gtk_recent_chooser_set_select_multiple:
424  * @chooser: a #GtkRecentChooser
425  * @select_multiple: %TRUE if @chooser can select more than one item
426  *
427  * Sets whether @chooser can select multiple items.
428  *
429  * Since: 2.10
430  */
431 void
gtk_recent_chooser_set_select_multiple(GtkRecentChooser * chooser,gboolean select_multiple)432 gtk_recent_chooser_set_select_multiple (GtkRecentChooser *chooser,
433 					gboolean          select_multiple)
434 {
435   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
436 
437   g_object_set (chooser, "select-multiple", select_multiple, NULL);
438 }
439 
440 /**
441  * gtk_recent_chooser_get_select_multiple:
442  * @chooser: a #GtkRecentChooser
443  *
444  * Gets whether @chooser can select multiple items.
445  *
446  * Returns: %TRUE if @chooser can select more than one item.
447  *
448  * Since: 2.10
449  */
450 gboolean
gtk_recent_chooser_get_select_multiple(GtkRecentChooser * chooser)451 gtk_recent_chooser_get_select_multiple (GtkRecentChooser *chooser)
452 {
453   gboolean select_multiple;
454 
455   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
456 
457   g_object_get (chooser, "select-multiple", &select_multiple, NULL);
458 
459   return select_multiple;
460 }
461 
462 /**
463  * gtk_recent_chooser_set_local_only:
464  * @chooser: a #GtkRecentChooser
465  * @local_only: %TRUE if only local files can be shown
466  *
467  * Sets whether only local resources, that is resources using the file:// URI
468  * scheme, should be shown in the recently used resources selector.  If
469  * @local_only is %TRUE (the default) then the shown resources are guaranteed
470  * to be accessible through the operating system native file system.
471  *
472  * Since: 2.10
473  */
474 void
gtk_recent_chooser_set_local_only(GtkRecentChooser * chooser,gboolean local_only)475 gtk_recent_chooser_set_local_only (GtkRecentChooser *chooser,
476 				   gboolean          local_only)
477 {
478   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
479 
480   g_object_set (chooser, "local-only", local_only, NULL);
481 }
482 
483 /**
484  * gtk_recent_chooser_get_local_only:
485  * @chooser: a #GtkRecentChooser
486  *
487  * Gets whether only local resources should be shown in the recently used
488  * resources selector.  See gtk_recent_chooser_set_local_only()
489  *
490  * Returns: %TRUE if only local resources should be shown.
491  *
492  * Since: 2.10
493  */
494 gboolean
gtk_recent_chooser_get_local_only(GtkRecentChooser * chooser)495 gtk_recent_chooser_get_local_only (GtkRecentChooser *chooser)
496 {
497   gboolean local_only;
498 
499   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
500 
501   g_object_get (chooser, "local-only", &local_only, NULL);
502 
503   return local_only;
504 }
505 
506 /**
507  * gtk_recent_chooser_set_limit:
508  * @chooser: a #GtkRecentChooser
509  * @limit: a positive integer, or -1 for all items
510  *
511  * Sets the number of items that should be returned by
512  * gtk_recent_chooser_get_items() and gtk_recent_chooser_get_uris().
513  *
514  * Since: 2.10
515  */
516 void
gtk_recent_chooser_set_limit(GtkRecentChooser * chooser,gint limit)517 gtk_recent_chooser_set_limit (GtkRecentChooser *chooser,
518 			      gint              limit)
519 {
520   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
521 
522   g_object_set (chooser, "limit", limit, NULL);
523 }
524 
525 /**
526  * gtk_recent_chooser_get_limit:
527  * @chooser: a #GtkRecentChooser
528  *
529  * Gets the number of items returned by gtk_recent_chooser_get_items()
530  * and gtk_recent_chooser_get_uris().
531  *
532  * Returns: A positive integer, or -1 meaning that all items are
533  *   returned.
534  *
535  * Since: 2.10
536  */
537 gint
gtk_recent_chooser_get_limit(GtkRecentChooser * chooser)538 gtk_recent_chooser_get_limit (GtkRecentChooser *chooser)
539 {
540   gint limit;
541 
542   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), 10);
543 
544   g_object_get (chooser, "limit", &limit, NULL);
545 
546   return limit;
547 }
548 
549 /**
550  * gtk_recent_chooser_set_show_tips:
551  * @chooser: a #GtkRecentChooser
552  * @show_tips: %TRUE if tooltips should be shown
553  *
554  * Sets whether to show a tooltips containing the full path of each
555  * recently used resource in a #GtkRecentChooser widget.
556  *
557  * Since: 2.10
558  */
559 void
gtk_recent_chooser_set_show_tips(GtkRecentChooser * chooser,gboolean show_tips)560 gtk_recent_chooser_set_show_tips (GtkRecentChooser *chooser,
561 				  gboolean          show_tips)
562 {
563   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
564 
565   g_object_set (chooser, "show-tips", show_tips, NULL);
566 }
567 
568 /**
569  * gtk_recent_chooser_get_show_tips:
570  * @chooser: a #GtkRecentChooser
571  *
572  * Gets whether @chooser should display tooltips containing the full path
573  * of a recently user resource.
574  *
575  * Returns: %TRUE if the recent chooser should show tooltips,
576  *   %FALSE otherwise.
577  *
578  * Since: 2.10
579  */
580 gboolean
gtk_recent_chooser_get_show_tips(GtkRecentChooser * chooser)581 gtk_recent_chooser_get_show_tips (GtkRecentChooser *chooser)
582 {
583   gboolean show_tips;
584 
585   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
586 
587   g_object_get (chooser, "show-tips", &show_tips, NULL);
588 
589   return show_tips;
590 }
591 
592 static gboolean
recent_chooser_has_show_numbers(GtkRecentChooser * chooser)593 recent_chooser_has_show_numbers (GtkRecentChooser *chooser)
594 {
595   GParamSpec *pspec;
596 
597   /* This is the result of a minor screw up: the "show-numbers" property
598    * was removed from the GtkRecentChooser interface, but the accessors
599    * remained in the interface API; now we need to check whether the
600    * implementation of the RecentChooser interface has a "show-numbers"
601    * boolean property installed before accessing it, and avoid an
602    * assertion failure using a more graceful warning.  This should really
603    * go away as soon as we can break API and remove these accessors.
604    */
605   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (chooser),
606 		  			"show-numbers");
607 
608   return (pspec && pspec->value_type == G_TYPE_BOOLEAN);
609 }
610 
611 /**
612  * gtk_recent_chooser_set_sort_type:
613  * @chooser: a #GtkRecentChooser
614  * @sort_type: sort order that the chooser should use
615  *
616  * Changes the sorting order of the recently used resources list displayed by
617  * @chooser.
618  *
619  * Since: 2.10
620  */
621 void
gtk_recent_chooser_set_sort_type(GtkRecentChooser * chooser,GtkRecentSortType sort_type)622 gtk_recent_chooser_set_sort_type (GtkRecentChooser  *chooser,
623 				  GtkRecentSortType  sort_type)
624 {
625   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
626 
627   g_object_set (chooser, "sort-type", sort_type, NULL);
628 }
629 
630 /**
631  * gtk_recent_chooser_get_sort_type:
632  * @chooser: a #GtkRecentChooser
633  *
634  * Gets the value set by gtk_recent_chooser_set_sort_type().
635  *
636  * Returns: the sorting order of the @chooser.
637  *
638  * Since: 2.10
639  */
640 GtkRecentSortType
gtk_recent_chooser_get_sort_type(GtkRecentChooser * chooser)641 gtk_recent_chooser_get_sort_type (GtkRecentChooser *chooser)
642 {
643   GtkRecentSortType sort_type;
644 
645   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_NONE);
646 
647   g_object_get (chooser, "sort-type", &sort_type, NULL);
648 
649   return sort_type;
650 }
651 
652 /**
653  * gtk_recent_chooser_set_sort_func:
654  * @chooser: a #GtkRecentChooser
655  * @sort_func: the comparison function
656  * @sort_data: (allow-none): user data to pass to @sort_func, or %NULL
657  * @data_destroy: (allow-none): destroy notifier for @sort_data, or %NULL
658  *
659  * Sets the comparison function used when sorting to be @sort_func.  If
660  * the @chooser has the sort type set to #GTK_RECENT_SORT_CUSTOM then
661  * the chooser will sort using this function.
662  *
663  * To the comparison function will be passed two #GtkRecentInfo structs and
664  * @sort_data;  @sort_func should return a positive integer if the first
665  * item comes before the second, zero if the two items are equal and
666  * a negative integer if the first item comes after the second.
667  *
668  * Since: 2.10
669  */
670 void
gtk_recent_chooser_set_sort_func(GtkRecentChooser * chooser,GtkRecentSortFunc sort_func,gpointer sort_data,GDestroyNotify data_destroy)671 gtk_recent_chooser_set_sort_func  (GtkRecentChooser  *chooser,
672 				   GtkRecentSortFunc  sort_func,
673 				   gpointer           sort_data,
674 				   GDestroyNotify     data_destroy)
675 {
676   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
677 
678   GTK_RECENT_CHOOSER_GET_IFACE (chooser)->set_sort_func (chooser,
679   							 sort_func,
680   							 sort_data,
681   							 data_destroy);
682 }
683 
684 /**
685  * gtk_recent_chooser_set_current_uri:
686  * @chooser: a #GtkRecentChooser
687  * @uri: a URI
688  * @error: (allow-none): return location for a #GError, or %NULL
689  *
690  * Sets @uri as the current URI for @chooser.
691  *
692  * Returns: %TRUE if the URI was found.
693  *
694  * Since: 2.10
695  */
696 gboolean
gtk_recent_chooser_set_current_uri(GtkRecentChooser * chooser,const gchar * uri,GError ** error)697 gtk_recent_chooser_set_current_uri (GtkRecentChooser  *chooser,
698 				    const gchar       *uri,
699 				    GError           **error)
700 {
701   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
702 
703   return GTK_RECENT_CHOOSER_GET_IFACE (chooser)->set_current_uri (chooser, uri, error);
704 }
705 
706 /**
707  * gtk_recent_chooser_get_current_uri:
708  * @chooser: a #GtkRecentChooser
709  *
710  * Gets the URI currently selected by @chooser.
711  *
712  * Returns: a newly allocated string holding a URI.
713  *
714  * Since: 2.10
715  */
716 gchar *
gtk_recent_chooser_get_current_uri(GtkRecentChooser * chooser)717 gtk_recent_chooser_get_current_uri (GtkRecentChooser *chooser)
718 {
719   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
720 
721   return GTK_RECENT_CHOOSER_GET_IFACE (chooser)->get_current_uri (chooser);
722 }
723 
724 /**
725  * gtk_recent_chooser_get_current_item:
726  * @chooser: a #GtkRecentChooser
727  *
728  * Gets the #GtkRecentInfo currently selected by @chooser.
729  *
730  * Returns: a #GtkRecentInfo.  Use gtk_recent_info_unref() when
731  *   when you have finished using it.
732  *
733  * Since: 2.10
734  */
735 GtkRecentInfo *
gtk_recent_chooser_get_current_item(GtkRecentChooser * chooser)736 gtk_recent_chooser_get_current_item (GtkRecentChooser *chooser)
737 {
738   GtkRecentManager *manager;
739   GtkRecentInfo *retval;
740   gchar *uri;
741 
742   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
743 
744   uri = gtk_recent_chooser_get_current_uri (chooser);
745   if (!uri)
746     return NULL;
747 
748   manager = _gtk_recent_chooser_get_recent_manager (chooser);
749   retval = gtk_recent_manager_lookup_item (manager, uri, NULL);
750   g_free (uri);
751 
752   return retval;
753 }
754 
755 /**
756  * gtk_recent_chooser_select_uri:
757  * @chooser: a #GtkRecentChooser
758  * @uri: a URI
759  * @error: (allow-none): return location for a #GError, or %NULL
760  *
761  * Selects @uri inside @chooser.
762  *
763  * Returns: %TRUE if @uri was found.
764  *
765  * Since: 2.10
766  */
767 gboolean
gtk_recent_chooser_select_uri(GtkRecentChooser * chooser,const gchar * uri,GError ** error)768 gtk_recent_chooser_select_uri (GtkRecentChooser  *chooser,
769 			       const gchar       *uri,
770 			       GError           **error)
771 {
772   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), FALSE);
773 
774   return GTK_RECENT_CHOOSER_GET_IFACE (chooser)->select_uri (chooser, uri, error);
775 }
776 
777 /**
778  * gtk_recent_chooser_unselect_uri:
779  * @chooser: a #GtkRecentChooser
780  * @uri: a URI
781  *
782  * Unselects @uri inside @chooser.
783  *
784  * Since: 2.10
785  */
786 void
gtk_recent_chooser_unselect_uri(GtkRecentChooser * chooser,const gchar * uri)787 gtk_recent_chooser_unselect_uri (GtkRecentChooser *chooser,
788 				 const gchar      *uri)
789 {
790   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
791 
792   GTK_RECENT_CHOOSER_GET_IFACE (chooser)->unselect_uri (chooser, uri);
793 }
794 
795 /**
796  * gtk_recent_chooser_select_all:
797  * @chooser: a #GtkRecentChooser
798  *
799  * Selects all the items inside @chooser, if the @chooser supports
800  * multiple selection.
801  *
802  * Since: 2.10
803  */
804 void
gtk_recent_chooser_select_all(GtkRecentChooser * chooser)805 gtk_recent_chooser_select_all (GtkRecentChooser *chooser)
806 {
807   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
808 
809   GTK_RECENT_CHOOSER_GET_IFACE (chooser)->select_all (chooser);
810 }
811 
812 /**
813  * gtk_recent_chooser_unselect_all:
814  * @chooser: a #GtkRecentChooser
815  *
816  * Unselects all the items inside @chooser.
817  *
818  * Since: 2.10
819  */
820 void
gtk_recent_chooser_unselect_all(GtkRecentChooser * chooser)821 gtk_recent_chooser_unselect_all (GtkRecentChooser *chooser)
822 {
823   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
824 
825   GTK_RECENT_CHOOSER_GET_IFACE (chooser)->unselect_all (chooser);
826 }
827 
828 /**
829  * gtk_recent_chooser_get_items:
830  * @chooser: a #GtkRecentChooser
831  *
832  * Gets the list of recently used resources in form of #GtkRecentInfo objects.
833  *
834  * The return value of this function is affected by the “sort-type” and
835  * “limit” properties of @chooser.
836  *
837  * Returns:  (element-type GtkRecentInfo) (transfer full): A newly allocated
838  *   list of #GtkRecentInfo objects.  You should
839  *   use gtk_recent_info_unref() on every item of the list, and then free
840  *   the list itself using g_list_free().
841  *
842  * Since: 2.10
843  */
844 GList *
gtk_recent_chooser_get_items(GtkRecentChooser * chooser)845 gtk_recent_chooser_get_items (GtkRecentChooser *chooser)
846 {
847   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
848 
849   return GTK_RECENT_CHOOSER_GET_IFACE (chooser)->get_items (chooser);
850 }
851 
852 /**
853  * gtk_recent_chooser_get_uris:
854  * @chooser: a #GtkRecentChooser
855  * @length: (out) (allow-none): return location for a the length of the
856  *     URI list, or %NULL
857  *
858  * Gets the URI of the recently used resources.
859  *
860  * The return value of this function is affected by the “sort-type” and “limit”
861  * properties of @chooser.
862  *
863  * Since the returned array is %NULL terminated, @length may be %NULL.
864  *
865  * Returns: (array length=length zero-terminated=1) (transfer full):
866  *     A newly allocated, %NULL-terminated array of strings. Use
867  *     g_strfreev() to free it.
868  *
869  * Since: 2.10
870  */
871 gchar **
gtk_recent_chooser_get_uris(GtkRecentChooser * chooser,gsize * length)872 gtk_recent_chooser_get_uris (GtkRecentChooser *chooser,
873                              gsize            *length)
874 {
875   GList *items, *l;
876   gchar **retval;
877   gsize n_items, i;
878 
879   items = gtk_recent_chooser_get_items (chooser);
880 
881   n_items = g_list_length (items);
882   retval = g_new0 (gchar *, n_items + 1);
883 
884   for (l = items, i = 0; l != NULL; l = l->next)
885     {
886       GtkRecentInfo *info = (GtkRecentInfo *) l->data;
887       const gchar *uri;
888 
889       g_assert (info != NULL);
890 
891       uri = gtk_recent_info_get_uri (info);
892       g_assert (uri != NULL);
893 
894       retval[i++] = g_strdup (uri);
895     }
896   retval[i] = NULL;
897 
898   if (length)
899     *length = i;
900 
901   g_list_free_full (items, (GDestroyNotify) gtk_recent_info_unref);
902 
903   return retval;
904 }
905 
906 /**
907  * gtk_recent_chooser_add_filter:
908  * @chooser: a #GtkRecentChooser
909  * @filter: a #GtkRecentFilter
910  *
911  * Adds @filter to the list of #GtkRecentFilter objects held by @chooser.
912  *
913  * If no previous filter objects were defined, this function will call
914  * gtk_recent_chooser_set_filter().
915  *
916  * Since: 2.10
917  */
918 void
gtk_recent_chooser_add_filter(GtkRecentChooser * chooser,GtkRecentFilter * filter)919 gtk_recent_chooser_add_filter (GtkRecentChooser *chooser,
920 			       GtkRecentFilter  *filter)
921 {
922   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
923   g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
924 
925   GTK_RECENT_CHOOSER_GET_IFACE (chooser)->add_filter (chooser, filter);
926 }
927 
928 /**
929  * gtk_recent_chooser_remove_filter:
930  * @chooser: a #GtkRecentChooser
931  * @filter: a #GtkRecentFilter
932  *
933  * Removes @filter from the list of #GtkRecentFilter objects held by @chooser.
934  *
935  * Since: 2.10
936  */
937 void
gtk_recent_chooser_remove_filter(GtkRecentChooser * chooser,GtkRecentFilter * filter)938 gtk_recent_chooser_remove_filter (GtkRecentChooser *chooser,
939 				  GtkRecentFilter  *filter)
940 {
941   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
942   g_return_if_fail (GTK_IS_RECENT_FILTER (filter));
943 
944   GTK_RECENT_CHOOSER_GET_IFACE (chooser)->remove_filter (chooser, filter);
945 }
946 
947 /**
948  * gtk_recent_chooser_list_filters:
949  * @chooser: a #GtkRecentChooser
950  *
951  * Gets the #GtkRecentFilter objects held by @chooser.
952  *
953  * Returns: (element-type GtkRecentFilter) (transfer container): A singly linked list
954  *   of #GtkRecentFilter objects.  You
955  *   should just free the returned list using g_slist_free().
956  *
957  * Since: 2.10
958  */
959 GSList *
gtk_recent_chooser_list_filters(GtkRecentChooser * chooser)960 gtk_recent_chooser_list_filters (GtkRecentChooser *chooser)
961 {
962   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
963 
964   return GTK_RECENT_CHOOSER_GET_IFACE (chooser)->list_filters (chooser);
965 }
966 
967 /**
968  * gtk_recent_chooser_set_filter:
969  * @chooser: a #GtkRecentChooser
970  * @filter: (allow-none): a #GtkRecentFilter
971  *
972  * Sets @filter as the current #GtkRecentFilter object used by @chooser
973  * to affect the displayed recently used resources.
974  *
975  * Since: 2.10
976  */
977 void
gtk_recent_chooser_set_filter(GtkRecentChooser * chooser,GtkRecentFilter * filter)978 gtk_recent_chooser_set_filter (GtkRecentChooser *chooser,
979 			       GtkRecentFilter  *filter)
980 {
981   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
982   g_return_if_fail (filter == NULL || GTK_IS_RECENT_FILTER (filter));
983 
984   g_object_set (G_OBJECT (chooser), "filter", filter, NULL);
985 }
986 
987 /**
988  * gtk_recent_chooser_get_filter:
989  * @chooser: a #GtkRecentChooser
990  *
991  * Gets the #GtkRecentFilter object currently used by @chooser to affect
992  * the display of the recently used resources.
993  *
994  * Returns: (transfer none): a #GtkRecentFilter object.
995  *
996  * Since: 2.10
997  */
998 GtkRecentFilter *
gtk_recent_chooser_get_filter(GtkRecentChooser * chooser)999 gtk_recent_chooser_get_filter (GtkRecentChooser *chooser)
1000 {
1001   GtkRecentFilter *filter;
1002 
1003   g_return_val_if_fail (GTK_IS_RECENT_CHOOSER (chooser), NULL);
1004 
1005   g_object_get (G_OBJECT (chooser), "filter", &filter, NULL);
1006 
1007   /* we need this hack because g_object_get() increases the refcount
1008    * of the returned object; see also gtk_file_chooser_get_filter()
1009    * inside gtkfilechooser.c
1010    */
1011   if (filter)
1012     g_object_unref (filter);
1013 
1014   return filter;
1015 }
1016 
1017 void
_gtk_recent_chooser_item_activated(GtkRecentChooser * chooser)1018 _gtk_recent_chooser_item_activated (GtkRecentChooser *chooser)
1019 {
1020   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
1021 
1022   g_signal_emit (chooser, chooser_signals[ITEM_ACTIVATED], 0);
1023 }
1024 
1025 void
_gtk_recent_chooser_selection_changed(GtkRecentChooser * chooser)1026 _gtk_recent_chooser_selection_changed (GtkRecentChooser *chooser)
1027 {
1028   g_return_if_fail (GTK_IS_RECENT_CHOOSER (chooser));
1029 
1030   g_signal_emit (chooser, chooser_signals[SELECTION_CHANGED], 0);
1031 }
1032 
1033 void
_gtk_recent_chooser_update(GtkActivatable * activatable,GtkAction * action,const gchar * property_name)1034 _gtk_recent_chooser_update (GtkActivatable *activatable,
1035 			    GtkAction      *action,
1036 			    const gchar    *property_name)
1037 {
1038   GtkRecentChooser *recent_chooser;
1039   GtkRecentChooser *action_chooser;
1040   GtkRecentAction  *recent_action;
1041 
1042   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1043   recent_chooser = GTK_RECENT_CHOOSER (activatable);
1044   action_chooser = GTK_RECENT_CHOOSER (action);
1045   recent_action  = GTK_RECENT_ACTION (action);
1046   G_GNUC_END_IGNORE_DEPRECATIONS;
1047 
1048   if (strcmp (property_name, "show-numbers") == 0 && recent_chooser_has_show_numbers (recent_chooser))
1049     {
1050       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1051       g_object_set (recent_chooser, "show-numbers",
1052                     gtk_recent_action_get_show_numbers (recent_action), NULL);
1053       G_GNUC_END_IGNORE_DEPRECATIONS;
1054     }
1055   else if (strcmp (property_name, "show-private") == 0)
1056     gtk_recent_chooser_set_show_private (recent_chooser, gtk_recent_chooser_get_show_private (action_chooser));
1057   else if (strcmp (property_name, "show-not-found") == 0)
1058     gtk_recent_chooser_set_show_not_found (recent_chooser, gtk_recent_chooser_get_show_not_found (action_chooser));
1059   else if (strcmp (property_name, "show-tips") == 0)
1060     gtk_recent_chooser_set_show_tips (recent_chooser, gtk_recent_chooser_get_show_tips (action_chooser));
1061   else if (strcmp (property_name, "show-icons") == 0)
1062     gtk_recent_chooser_set_show_icons (recent_chooser, gtk_recent_chooser_get_show_icons (action_chooser));
1063   else if (strcmp (property_name, "limit") == 0)
1064     gtk_recent_chooser_set_limit (recent_chooser, gtk_recent_chooser_get_limit (action_chooser));
1065   else if (strcmp (property_name, "local-only") == 0)
1066     gtk_recent_chooser_set_local_only (recent_chooser, gtk_recent_chooser_get_local_only (action_chooser));
1067   else if (strcmp (property_name, "sort-type") == 0)
1068     gtk_recent_chooser_set_sort_type (recent_chooser, gtk_recent_chooser_get_sort_type (action_chooser));
1069   else if (strcmp (property_name, "filter") == 0)
1070     gtk_recent_chooser_set_filter (recent_chooser, gtk_recent_chooser_get_filter (action_chooser));
1071 }
1072 
1073 void
_gtk_recent_chooser_sync_action_properties(GtkActivatable * activatable,GtkAction * action)1074 _gtk_recent_chooser_sync_action_properties (GtkActivatable *activatable,
1075 			                    GtkAction      *action)
1076 {
1077   GtkRecentChooser *recent_chooser;
1078   GtkRecentChooser *action_chooser;
1079 
1080   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1081   recent_chooser = GTK_RECENT_CHOOSER (activatable);
1082   action_chooser = GTK_RECENT_CHOOSER (action);
1083   G_GNUC_END_IGNORE_DEPRECATIONS;
1084 
1085   if (!action)
1086     return;
1087 
1088   if (recent_chooser_has_show_numbers (recent_chooser))
1089     {
1090       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1091       g_object_set (recent_chooser, "show-numbers",
1092                     gtk_recent_action_get_show_numbers (GTK_RECENT_ACTION (action)),
1093                     NULL);
1094       G_GNUC_END_IGNORE_DEPRECATIONS;
1095     }
1096   gtk_recent_chooser_set_show_private (recent_chooser, gtk_recent_chooser_get_show_private (action_chooser));
1097   gtk_recent_chooser_set_show_not_found (recent_chooser, gtk_recent_chooser_get_show_not_found (action_chooser));
1098   gtk_recent_chooser_set_show_tips (recent_chooser, gtk_recent_chooser_get_show_tips (action_chooser));
1099   gtk_recent_chooser_set_show_icons (recent_chooser, gtk_recent_chooser_get_show_icons (action_chooser));
1100   gtk_recent_chooser_set_limit (recent_chooser, gtk_recent_chooser_get_limit (action_chooser));
1101   gtk_recent_chooser_set_local_only (recent_chooser, gtk_recent_chooser_get_local_only (action_chooser));
1102   gtk_recent_chooser_set_sort_type (recent_chooser, gtk_recent_chooser_get_sort_type (action_chooser));
1103   gtk_recent_chooser_set_filter (recent_chooser, gtk_recent_chooser_get_filter (action_chooser));
1104 }
1105 
1106 void
_gtk_recent_chooser_set_related_action(GtkRecentChooser * recent_chooser,GtkAction * action)1107 _gtk_recent_chooser_set_related_action (GtkRecentChooser *recent_chooser,
1108 					GtkAction        *action)
1109 {
1110   GtkAction *prev_action;
1111 
1112   prev_action = g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action);
1113 
1114   if (prev_action == action)
1115     return;
1116 
1117   G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1118   gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (recent_chooser), action);
1119   G_GNUC_END_IGNORE_DEPRECATIONS;
1120   g_object_set_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action, action);
1121 }
1122 
1123 GtkAction *
_gtk_recent_chooser_get_related_action(GtkRecentChooser * recent_chooser)1124 _gtk_recent_chooser_get_related_action (GtkRecentChooser *recent_chooser)
1125 {
1126   return g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action);
1127 }
1128 
1129 /* The default for use-action-appearance is TRUE, so we try to set the
1130  * qdata backwards for this case.
1131  */
1132 void
_gtk_recent_chooser_set_use_action_appearance(GtkRecentChooser * recent_chooser,gboolean use_appearance)1133 _gtk_recent_chooser_set_use_action_appearance (GtkRecentChooser *recent_chooser,
1134 					       gboolean          use_appearance)
1135 {
1136   GtkAction *action;
1137   gboolean   use_action_appearance;
1138 
1139   action                = g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_related_action);
1140   use_action_appearance = !GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_use_action_appearance));
1141 
1142   if (use_action_appearance != use_appearance)
1143     {
1144 
1145       g_object_set_qdata (G_OBJECT (recent_chooser), quark_gtk_use_action_appearance, GINT_TO_POINTER (!use_appearance));
1146 
1147       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1148       gtk_activatable_sync_action_properties (GTK_ACTIVATABLE (recent_chooser), action);
1149       G_GNUC_END_IGNORE_DEPRECATIONS;
1150     }
1151 }
1152 
1153 gboolean
_gtk_recent_chooser_get_use_action_appearance(GtkRecentChooser * recent_chooser)1154 _gtk_recent_chooser_get_use_action_appearance (GtkRecentChooser *recent_chooser)
1155 {
1156   return !GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (recent_chooser), quark_gtk_use_action_appearance));
1157 }
1158