]> Pileus Git - ~andy/gtk/blob - gtk/gtkrecentaction.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtkrecentaction.c
1 /* GTK - The GIMP Toolkit
2  * Recent chooser action for GtkUIManager
3  *
4  * Copyright (C) 2007, 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 "gtkintl.h"
23 #include "gtkrecentaction.h"
24 #include "gtkimagemenuitem.h"
25 #include "gtkmenutoolbutton.h"
26 #include "gtkrecentchooser.h"
27 #include "gtkrecentchoosermenu.h"
28 #include "gtkrecentchooserutils.h"
29 #include "gtkrecentchooserprivate.h"
30 #include "gtkprivate.h"
31
32 /**
33  * SECTION:gtkrecentaction
34  * @Short_description: An action of which represents a list of recently used files
35  * @Title: GtkRecentAction
36  *
37  * A #GtkRecentAction represents a list of recently used files, which
38  * can be shown by widgets such as #GtkRecentChooserDialog or
39  * #GtkRecentChooserMenu.
40  *
41  * To construct a submenu showing recently used files, use a #GtkRecentAction
42  * as the action for a &lt;menuitem&gt;. To construct a menu toolbutton showing
43  * the recently used files in the popup menu, use a #GtkRecentAction as the
44  * action for a &lt;toolitem&gt; element.
45  */
46
47
48 #define FALLBACK_ITEM_LIMIT     10
49
50
51 struct _GtkRecentActionPrivate
52 {
53   GtkRecentManager *manager;
54
55   guint show_numbers   : 1;
56
57   /* RecentChooser properties */
58   guint show_private   : 1;
59   guint show_not_found : 1;
60   guint show_tips      : 1;
61   guint show_icons     : 1;
62   guint local_only     : 1;
63
64   gint limit;
65
66   GtkRecentSortType sort_type;
67   GtkRecentSortFunc sort_func;
68   gpointer          sort_data;
69   GDestroyNotify    data_destroy;
70
71   GtkRecentFilter *current_filter;
72
73   GSList *choosers;
74   GtkRecentChooser *current_chooser;
75 };
76
77 enum
78 {
79   PROP_0,
80
81   PROP_SHOW_NUMBERS
82 };
83
84 static void gtk_recent_chooser_iface_init (GtkRecentChooserIface *iface);
85
86 G_DEFINE_TYPE_WITH_CODE (GtkRecentAction,
87                          gtk_recent_action,
88                          GTK_TYPE_ACTION,
89                          G_IMPLEMENT_INTERFACE (GTK_TYPE_RECENT_CHOOSER,
90                                                 gtk_recent_chooser_iface_init));
91
92 static gboolean
93 gtk_recent_action_set_current_uri (GtkRecentChooser  *chooser,
94                                    const gchar       *uri,
95                                    GError           **error)
96 {
97   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
98   GtkRecentActionPrivate *priv = action->priv;
99   GSList *l;
100
101   for (l = priv->choosers; l; l = l->next)
102     {
103       GtkRecentChooser *recent_chooser = l->data;
104
105       if (!gtk_recent_chooser_set_current_uri (recent_chooser, uri, error))
106         return FALSE;
107     }
108
109   return TRUE;
110 }
111
112 static gchar *
113 gtk_recent_action_get_current_uri (GtkRecentChooser *chooser)
114 {
115   GtkRecentAction *recent_action = GTK_RECENT_ACTION (chooser);
116   GtkRecentActionPrivate *priv = recent_action->priv;
117
118   if (priv->current_chooser)
119     return gtk_recent_chooser_get_current_uri (priv->current_chooser);
120
121   return NULL;
122 }
123
124 static gboolean
125 gtk_recent_action_select_uri (GtkRecentChooser  *chooser,
126                               const gchar       *uri,
127                               GError           **error)
128 {
129   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
130   GtkRecentActionPrivate *priv = action->priv;
131   GSList *l;
132
133   for (l = priv->choosers; l; l = l->next)
134     {
135       GtkRecentChooser *recent_chooser = l->data;
136
137       if (!gtk_recent_chooser_select_uri (recent_chooser, uri, error))
138         return FALSE;
139     }
140
141   return TRUE;
142 }
143
144 static void
145 gtk_recent_action_unselect_uri (GtkRecentChooser *chooser,
146                                 const gchar      *uri)
147 {
148   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
149   GtkRecentActionPrivate *priv = action->priv;
150   GSList *l;
151
152   for (l = priv->choosers; l; l = l->next)
153     {
154       GtkRecentChooser *chooser = l->data;
155       
156       gtk_recent_chooser_unselect_uri (chooser, uri);
157     }
158 }
159
160 static void
161 gtk_recent_action_select_all (GtkRecentChooser *chooser)
162 {
163   g_warning ("This function is not implemented for "
164              "widgets of class '%s'",
165              g_type_name (G_OBJECT_TYPE (chooser)));
166 }
167
168 static void
169 gtk_recent_action_unselect_all (GtkRecentChooser *chooser)
170 {
171   g_warning ("This function is not implemented for "
172              "widgets of class '%s'",
173              g_type_name (G_OBJECT_TYPE (chooser)));
174 }
175
176
177 static GList *
178 gtk_recent_action_get_items (GtkRecentChooser *chooser)
179 {
180   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
181   GtkRecentActionPrivate *priv = action->priv;
182
183   return _gtk_recent_chooser_get_items (chooser,
184                                         priv->current_filter,
185                                         priv->sort_func,
186                                         priv->sort_data);
187 }
188
189 static GtkRecentManager *
190 gtk_recent_action_get_recent_manager (GtkRecentChooser *chooser)
191 {
192   return GTK_RECENT_ACTION (chooser)->priv->manager;
193 }
194
195 static void
196 gtk_recent_action_set_sort_func (GtkRecentChooser  *chooser,
197                                  GtkRecentSortFunc  sort_func,
198                                  gpointer           sort_data,
199                                  GDestroyNotify     data_destroy)
200 {
201   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
202   GtkRecentActionPrivate *priv = action->priv;
203   GSList *l;
204   
205   if (priv->data_destroy)
206     {
207       priv->data_destroy (priv->sort_data);
208       priv->data_destroy = NULL;
209     }
210       
211   priv->sort_func = NULL;
212   priv->sort_data = NULL;
213   
214   if (sort_func)
215     {
216       priv->sort_func = sort_func;
217       priv->sort_data = sort_data;
218       priv->data_destroy = data_destroy;
219     }
220
221   for (l = priv->choosers; l; l = l->next)
222     {
223       GtkRecentChooser *chooser_menu = l->data;
224       
225       gtk_recent_chooser_set_sort_func (chooser_menu, priv->sort_func,
226                                         priv->sort_data,
227                                         priv->data_destroy);
228     }
229 }
230
231 static void
232 set_current_filter (GtkRecentAction *action,
233                     GtkRecentFilter *filter)
234 {
235   GtkRecentActionPrivate *priv = action->priv;
236
237   g_object_ref (action);
238
239   if (priv->current_filter)
240     g_object_unref (priv->current_filter);
241
242   priv->current_filter = filter;
243
244   if (priv->current_filter)
245     g_object_ref_sink (priv->current_filter);
246
247   g_object_notify (G_OBJECT (action), "filter");
248
249   g_object_unref (action);
250 }
251
252 static void
253 gtk_recent_action_add_filter (GtkRecentChooser *chooser,
254                               GtkRecentFilter  *filter)
255 {
256   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
257   GtkRecentActionPrivate *priv = action->priv;
258
259   if (priv->current_filter != filter)
260     set_current_filter (GTK_RECENT_ACTION (chooser), filter);
261 }
262
263 static void
264 gtk_recent_action_remove_filter (GtkRecentChooser *chooser,
265                                  GtkRecentFilter  *filter)
266 {
267   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
268   GtkRecentActionPrivate *priv = action->priv;
269
270   if (priv->current_filter == filter)
271     set_current_filter (GTK_RECENT_ACTION (chooser), NULL);
272 }
273
274 static GSList *
275 gtk_recent_action_list_filters (GtkRecentChooser *chooser)
276 {
277   GtkRecentAction *action = GTK_RECENT_ACTION (chooser);
278   GtkRecentActionPrivate *priv = action->priv;
279   GSList *retval = NULL;
280   GtkRecentFilter *current_filter;
281
282   current_filter = priv->current_filter;
283   retval = g_slist_prepend (retval, current_filter);
284
285   return retval;
286 }
287
288
289 static void
290 gtk_recent_chooser_iface_init (GtkRecentChooserIface *iface)
291 {
292   iface->set_current_uri = gtk_recent_action_set_current_uri;
293   iface->get_current_uri = gtk_recent_action_get_current_uri;
294   iface->select_uri = gtk_recent_action_select_uri;
295   iface->unselect_uri = gtk_recent_action_unselect_uri;
296   iface->select_all = gtk_recent_action_select_all;
297   iface->unselect_all = gtk_recent_action_unselect_all;
298   iface->get_items = gtk_recent_action_get_items;
299   iface->get_recent_manager = gtk_recent_action_get_recent_manager;
300   iface->set_sort_func = gtk_recent_action_set_sort_func;
301   iface->add_filter = gtk_recent_action_add_filter;
302   iface->remove_filter = gtk_recent_action_remove_filter;
303   iface->list_filters = gtk_recent_action_list_filters;
304 }
305
306 static void
307 gtk_recent_action_activate (GtkAction *action)
308 {
309   GtkRecentAction *recent_action = GTK_RECENT_ACTION (action);
310   GtkRecentActionPrivate *priv = recent_action->priv;
311
312   /* we have probably been invoked by a menu tool button or by a
313    * direct call of gtk_action_activate(); since no item has been
314    * selected, we must unset the current recent chooser pointer
315    */
316   priv->current_chooser = NULL;
317 }
318
319 static void
320 delegate_selection_changed (GtkRecentAction  *action,
321                             GtkRecentChooser *chooser)
322 {
323   GtkRecentActionPrivate *priv = action->priv;
324
325   priv->current_chooser = chooser;
326
327   g_signal_emit_by_name (action, "selection-changed");
328 }
329
330 static void
331 delegate_item_activated (GtkRecentAction  *action,
332                          GtkRecentChooser *chooser)
333 {
334   GtkRecentActionPrivate *priv = action->priv;
335
336   priv->current_chooser = chooser;
337
338   g_signal_emit_by_name (action, "item-activated");
339 }
340
341 static void
342 gtk_recent_action_connect_proxy (GtkAction *action,
343                                  GtkWidget *widget)
344 {
345   GtkRecentAction *recent_action = GTK_RECENT_ACTION (action);
346   GtkRecentActionPrivate *priv = recent_action->priv;
347
348   /* it can only be a recent chooser implementor anyway... */
349   if (GTK_IS_RECENT_CHOOSER (widget) &&
350       !g_slist_find (priv->choosers, widget))
351     {
352       if (priv->sort_func)
353         {
354           gtk_recent_chooser_set_sort_func (GTK_RECENT_CHOOSER (widget),
355                                             priv->sort_func,
356                                             priv->sort_data,
357                                             priv->data_destroy);
358         }
359
360       g_signal_connect_swapped (widget, "selection_changed",
361                                 G_CALLBACK (delegate_selection_changed),
362                                 action);
363       g_signal_connect_swapped (widget, "item-activated",
364                                 G_CALLBACK (delegate_item_activated),
365                                 action);
366     }
367
368   if (GTK_ACTION_CLASS (gtk_recent_action_parent_class)->connect_proxy)
369     GTK_ACTION_CLASS (gtk_recent_action_parent_class)->connect_proxy (action, widget);
370 }
371
372 static void
373 gtk_recent_action_disconnect_proxy (GtkAction *action,
374                                     GtkWidget *widget)
375 {
376   GtkRecentAction *recent_action = GTK_RECENT_ACTION (action);
377   GtkRecentActionPrivate *priv = recent_action->priv;
378
379   /* if it was one of the recent choosers we created, remove it
380    * from the list
381    */
382   if (g_slist_find (priv->choosers, widget))
383     priv->choosers = g_slist_remove (priv->choosers, widget);
384
385   if (GTK_ACTION_CLASS (gtk_recent_action_parent_class)->disconnect_proxy)
386     GTK_ACTION_CLASS (gtk_recent_action_parent_class)->disconnect_proxy (action, widget);
387 }
388
389 static GtkWidget *
390 gtk_recent_action_create_menu (GtkAction *action)
391 {
392   GtkRecentAction *recent_action = GTK_RECENT_ACTION (action);
393   GtkRecentActionPrivate *priv = recent_action->priv;
394   GtkWidget *widget;
395
396   widget = g_object_new (GTK_TYPE_RECENT_CHOOSER_MENU,
397                          "show-private", priv->show_private,
398                          "show-not-found", priv->show_not_found,
399                          "show-tips", priv->show_tips,
400                          "show-icons", priv->show_icons,
401                          "show-numbers", priv->show_numbers,
402                          "limit", priv->limit,
403                          "sort-type", priv->sort_type,
404                          "recent-manager", priv->manager,
405                          "filter", priv->current_filter,
406                          "local-only", priv->local_only,
407                          NULL);
408   
409   if (priv->sort_func)
410     {
411       gtk_recent_chooser_set_sort_func (GTK_RECENT_CHOOSER (widget),
412                                         priv->sort_func,
413                                         priv->sort_data,
414                                         priv->data_destroy);
415     }
416
417   g_signal_connect_swapped (widget, "selection_changed",
418                             G_CALLBACK (delegate_selection_changed),
419                             recent_action);
420   g_signal_connect_swapped (widget, "item-activated",
421                             G_CALLBACK (delegate_item_activated),
422                             recent_action);
423
424   /* keep track of the choosers we create */
425   priv->choosers = g_slist_prepend (priv->choosers, widget);
426
427   return widget;
428 }
429
430 static GtkWidget *
431 gtk_recent_action_create_menu_item (GtkAction *action)
432 {
433   GtkWidget *menu;
434   GtkWidget *menuitem;
435
436   menu = gtk_recent_action_create_menu (action);
437   menuitem = g_object_new (GTK_TYPE_IMAGE_MENU_ITEM, NULL);
438   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
439   gtk_widget_show (menu);
440
441   return menuitem;
442 }
443
444 static GtkWidget *
445 gtk_recent_action_create_tool_item (GtkAction *action)
446 {
447   GtkWidget *menu;
448   GtkWidget *toolitem;
449
450   menu = gtk_recent_action_create_menu (action);
451   toolitem = g_object_new (GTK_TYPE_MENU_TOOL_BUTTON, NULL);
452   gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (toolitem), menu);
453   gtk_widget_show (menu);
454
455   return toolitem;
456 }
457
458 static void
459 set_recent_manager (GtkRecentAction  *action,
460                     GtkRecentManager *manager)
461 {
462   GtkRecentActionPrivate *priv = action->priv;
463
464   if (manager)
465     priv->manager = NULL;
466   else
467     priv->manager = gtk_recent_manager_get_default ();
468 }
469
470 static void
471 gtk_recent_action_finalize (GObject *gobject)
472 {
473   GtkRecentAction *action = GTK_RECENT_ACTION (gobject);
474   GtkRecentActionPrivate *priv = action->priv;
475
476   priv->manager = NULL;
477   
478   if (priv->data_destroy)
479     {
480       priv->data_destroy (priv->sort_data);
481       priv->data_destroy = NULL;
482     }
483
484   priv->sort_data = NULL;
485   priv->sort_func = NULL;
486
487   g_slist_free (priv->choosers);
488
489   G_OBJECT_CLASS (gtk_recent_action_parent_class)->finalize (gobject);
490 }
491
492 static void
493 gtk_recent_action_dispose (GObject *gobject)
494 {
495   GtkRecentAction *action = GTK_RECENT_ACTION (gobject);
496   GtkRecentActionPrivate *priv = action->priv;
497
498   if (priv->current_filter)
499     {
500       g_object_unref (priv->current_filter);
501       priv->current_filter = NULL;
502     }
503
504   G_OBJECT_CLASS (gtk_recent_action_parent_class)->dispose (gobject);
505 }
506
507 static void
508 gtk_recent_action_set_property (GObject      *gobject,
509                                 guint         prop_id,
510                                 const GValue *value,
511                                 GParamSpec   *pspec)
512 {
513   GtkRecentAction *action = GTK_RECENT_ACTION (gobject);
514   GtkRecentActionPrivate *priv = action->priv;
515
516   switch (prop_id)
517     {
518     case PROP_SHOW_NUMBERS:
519       priv->show_numbers = g_value_get_boolean (value);
520       break;
521     case GTK_RECENT_CHOOSER_PROP_SHOW_PRIVATE:
522       priv->show_private = g_value_get_boolean (value);
523       break;
524     case GTK_RECENT_CHOOSER_PROP_SHOW_NOT_FOUND:
525       priv->show_not_found = g_value_get_boolean (value);
526       break;
527     case GTK_RECENT_CHOOSER_PROP_SHOW_TIPS:
528       priv->show_tips = g_value_get_boolean (value);
529       break;
530     case GTK_RECENT_CHOOSER_PROP_SHOW_ICONS:
531       priv->show_icons = g_value_get_boolean (value);
532       break;
533     case GTK_RECENT_CHOOSER_PROP_LIMIT:
534       priv->limit = g_value_get_int (value);
535       break;
536     case GTK_RECENT_CHOOSER_PROP_LOCAL_ONLY:
537       priv->local_only = g_value_get_boolean (value);
538       break;
539     case GTK_RECENT_CHOOSER_PROP_SORT_TYPE:
540       priv->sort_type = g_value_get_enum (value);
541       break;
542     case GTK_RECENT_CHOOSER_PROP_FILTER:
543       set_current_filter (action, g_value_get_object (value));
544       break;
545     case GTK_RECENT_CHOOSER_PROP_SELECT_MULTIPLE:
546       g_warning ("%s: Choosers of type `%s' do not support selecting multiple items.",
547                  G_STRFUNC,
548                  G_OBJECT_TYPE_NAME (gobject));
549       return;
550     case GTK_RECENT_CHOOSER_PROP_RECENT_MANAGER:
551       set_recent_manager (action, g_value_get_object (value));
552       break;
553     default:
554       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
555       return;
556     }
557 }
558
559 static void
560 gtk_recent_action_get_property (GObject    *gobject,
561                                 guint       prop_id,
562                                 GValue     *value,
563                                 GParamSpec *pspec)
564 {
565   GtkRecentAction *action = GTK_RECENT_ACTION (gobject);
566   GtkRecentActionPrivate *priv = action->priv;
567
568   switch (prop_id)
569     {
570     case PROP_SHOW_NUMBERS:
571       g_value_set_boolean (value, priv->show_numbers);
572       break;
573     case GTK_RECENT_CHOOSER_PROP_SHOW_PRIVATE:
574       g_value_set_boolean (value, priv->show_private);
575       break;
576     case GTK_RECENT_CHOOSER_PROP_SHOW_NOT_FOUND:
577       g_value_set_boolean (value, priv->show_not_found);
578       break;
579     case GTK_RECENT_CHOOSER_PROP_SHOW_TIPS:
580       g_value_set_boolean (value, priv->show_tips);
581       break;
582     case GTK_RECENT_CHOOSER_PROP_SHOW_ICONS:
583       g_value_set_boolean (value, priv->show_icons);
584       break;
585     case GTK_RECENT_CHOOSER_PROP_LIMIT:
586       g_value_set_int (value, priv->limit);
587       break;
588     case GTK_RECENT_CHOOSER_PROP_LOCAL_ONLY:
589       g_value_set_boolean (value, priv->local_only);
590       break;
591     case GTK_RECENT_CHOOSER_PROP_SORT_TYPE:
592       g_value_set_enum (value, priv->sort_type);
593       break;
594     case GTK_RECENT_CHOOSER_PROP_FILTER:
595       g_value_set_object (value, priv->current_filter);
596       break;
597     case GTK_RECENT_CHOOSER_PROP_SELECT_MULTIPLE:
598       g_value_set_boolean (value, FALSE);
599       break;
600     default:
601       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
602       break;
603     }
604 }
605
606 static void
607 gtk_recent_action_class_init (GtkRecentActionClass *klass)
608 {
609   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
610   GtkActionClass *action_class = GTK_ACTION_CLASS (klass);
611
612   g_type_class_add_private (klass, sizeof (GtkRecentActionPrivate));
613
614   gobject_class->finalize = gtk_recent_action_finalize;
615   gobject_class->dispose = gtk_recent_action_dispose;
616   gobject_class->set_property = gtk_recent_action_set_property;
617   gobject_class->get_property = gtk_recent_action_get_property;
618
619   action_class->activate = gtk_recent_action_activate;
620   action_class->connect_proxy = gtk_recent_action_connect_proxy;
621   action_class->disconnect_proxy = gtk_recent_action_disconnect_proxy;
622   action_class->create_menu_item = gtk_recent_action_create_menu_item;
623   action_class->create_tool_item = gtk_recent_action_create_tool_item;
624   action_class->create_menu = gtk_recent_action_create_menu;
625   action_class->menu_item_type = GTK_TYPE_IMAGE_MENU_ITEM;
626   action_class->toolbar_item_type = GTK_TYPE_MENU_TOOL_BUTTON;
627
628   _gtk_recent_chooser_install_properties (gobject_class);
629
630   g_object_class_install_property (gobject_class,
631                                    PROP_SHOW_NUMBERS,
632                                    g_param_spec_boolean ("show-numbers",
633                                                          P_("Show Numbers"),
634                                                          P_("Whether the items should be displayed with a number"),
635                                                          FALSE,
636                                                          G_PARAM_READWRITE));
637
638 }
639
640 static void
641 gtk_recent_action_init (GtkRecentAction *action)
642 {
643   GtkRecentActionPrivate *priv;
644
645   action->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (action,
646                                                      GTK_TYPE_RECENT_ACTION,
647                                                      GtkRecentActionPrivate);
648
649   priv->show_numbers = FALSE;
650   priv->show_icons = TRUE;
651   priv->show_tips = FALSE;
652   priv->show_not_found = TRUE;
653   priv->show_private = FALSE;
654   priv->local_only = TRUE;
655
656   priv->limit = FALLBACK_ITEM_LIMIT;
657
658   priv->sort_type = GTK_RECENT_SORT_NONE;
659   priv->sort_func = NULL;
660   priv->sort_data = NULL;
661   priv->data_destroy = NULL;
662
663   priv->current_filter = NULL;
664
665   priv->manager = NULL;
666 }
667
668 /**
669  * gtk_recent_action_new:
670  * @name: a unique name for the action
671  * @label: (allow-none): the label displayed in menu items and on buttons,
672  *   or %NULL
673  * @tooltip: (allow-none): a tooltip for the action, or %NULL
674  * @stock_id: (allow-none): the stock icon to display in widgets representing
675  *   the action, or %NULL
676  *
677  * Creates a new #GtkRecentAction object. To add the action to
678  * a #GtkActionGroup and set the accelerator for the action,
679  * call gtk_action_group_add_action_with_accel().
680  *
681  * Return value: the newly created #GtkRecentAction.
682  *
683  * Since: 2.12
684  */
685 GtkAction *
686 gtk_recent_action_new (const gchar *name,
687                        const gchar *label,
688                        const gchar *tooltip,
689                        const gchar *stock_id)
690 {
691   g_return_val_if_fail (name != NULL, NULL);
692
693   return g_object_new (GTK_TYPE_RECENT_ACTION,
694                        "name", name,
695                        "label", label,
696                        "tooltip", tooltip,
697                        "stock-id", stock_id,
698                        NULL);
699 }
700
701 /**
702  * gtk_recent_action_new_for_manager:
703  * @name: a unique name for the action
704  * @label: (allow-none): the label displayed in menu items and on buttons,
705  *   or %NULL
706  * @tooltip: (allow-none): a tooltip for the action, or %NULL
707  * @stock_id: (allow-none): the stock icon to display in widgets representing
708  *   the action, or %NULL
709  * @manager: (allow-none): a #GtkRecentManager, or %NULL for using the default
710  *   #GtkRecentManager
711  *
712  * Creates a new #GtkRecentAction object. To add the action to
713  * a #GtkActionGroup and set the accelerator for the action,
714  * call gtk_action_group_add_action_with_accel().
715  *
716  * Return value: the newly created #GtkRecentAction
717  * 
718  * Since: 2.12
719  */
720 GtkAction *
721 gtk_recent_action_new_for_manager (const gchar      *name,
722                                    const gchar      *label,
723                                    const gchar      *tooltip,
724                                    const gchar      *stock_id,
725                                    GtkRecentManager *manager)
726 {
727   g_return_val_if_fail (name != NULL, NULL);
728   g_return_val_if_fail (manager == NULL || GTK_IS_RECENT_MANAGER (manager), NULL);
729
730   return g_object_new (GTK_TYPE_RECENT_ACTION,
731                        "name", name,
732                        "label", label,
733                        "tooltip", tooltip,
734                        "stock-id", stock_id,
735                        "recent-manager", manager,
736                        NULL);
737 }
738
739 /**
740  * gtk_recent_action_get_show_numbers:
741  * @action: a #GtkRecentAction
742  *
743  * Returns the value set by gtk_recent_chooser_menu_set_show_numbers().
744  *
745  * Return value: %TRUE if numbers should be shown.
746  *
747  * Since: 2.12
748  */
749 gboolean
750 gtk_recent_action_get_show_numbers (GtkRecentAction *action)
751 {
752   g_return_val_if_fail (GTK_IS_RECENT_ACTION (action), FALSE);
753
754   return action->priv->show_numbers;
755 }
756
757 /**
758  * gtk_recent_action_set_show_numbers:
759  * @action: a #GtkRecentAction
760  * @show_numbers: %TRUE if the shown items should be numbered
761  *
762  * Sets whether a number should be added to the items shown by the
763  * widgets representing @action. The numbers are shown to provide
764  * a unique character for a mnemonic to be used inside the menu item's
765  * label. Only the first ten items get a number to avoid clashes.
766  *
767  * Since: 2.12
768  */
769 void
770 gtk_recent_action_set_show_numbers (GtkRecentAction *action,
771                                     gboolean         show_numbers)
772 {
773   GtkRecentActionPrivate *priv;
774
775   g_return_if_fail (GTK_IS_RECENT_ACTION (action));
776
777   priv = action->priv;
778
779   if (priv->show_numbers != show_numbers)
780     {
781       g_object_ref (action);
782
783       priv->show_numbers = show_numbers;
784
785       g_object_notify (G_OBJECT (action), "show-numbers");
786       g_object_unref (action);
787     }
788 }