]> Pileus Git - ~andy/gtk/blob - gtk/gtkaction.c
Merge branch 'gtk-2-90'
[~andy/gtk] / gtk / gtkaction.c
1 /*
2  * GTK - The GIMP Toolkit
3  * Copyright (C) 1998, 1999 Red Hat, Inc.
4  * All rights reserved.
5  *
6  * This Library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * 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  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with the Gnome Library; see the file COPYING.LIB.  If not,
18  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /*
23  * Author: James Henstridge <james@daa.com.au>
24  *
25  * Modified by the GTK+ Team and others 2003.  See the AUTHORS
26  * file for a list of people on the GTK+ Team.  See the ChangeLog
27  * files for a list of changes.  These files are distributed with
28  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
29  */
30
31 /**
32  * SECTION:gtkaction
33  * @Short_description: An action which can be triggered by a menu or toolbar item
34  * @Title: GtkAction
35  * @See_also: #GtkActionGroup, #GtkUIManager
36  *
37  * Actions represent operations that the user can be perform, along with
38  * some information how it should be presented in the interface. Each action
39  * provides methods to create icons, menu items and toolbar items
40  * representing itself.
41  *
42  * As well as the callback that is called when the action gets activated,
43  * the following also gets associated with the action:
44  * <itemizedlist>
45  *   <listitem><para>a name (not translated, for path lookup)</para></listitem>
46  *   <listitem><para>a label (translated, for display)</para></listitem>
47  *   <listitem><para>an accelerator</para></listitem>
48  *   <listitem><para>whether label indicates a stock id</para></listitem>
49  *   <listitem><para>a tooltip (optional, translated)</para></listitem>
50  *   <listitem><para>a toolbar label (optional, shorter than label)</para></listitem>
51  * </itemizedlist>
52  * The action will also have some state information:
53  * <itemizedlist>
54  *   <listitem><para>visible (shown/hidden)</para></listitem>
55  *   <listitem><para>sensitive (enabled/disabled)</para></listitem>
56  * </itemizedlist>
57  * Apart from regular actions, there are <link linkend="GtkToggleAction">toggle
58  * actions</link>, which can be toggled between two states and <link
59  * linkend="GtkRadioAction">radio actions</link>, of which only one in a group
60  * can be in the "active" state. Other actions can be implemented as #GtkAction
61  * subclasses.
62  *
63  * Each action can have one or more proxy menu item, toolbar button or
64  * other proxy widgets.  Proxies mirror the state of the action (text
65  * label, tooltip, icon, visible, sensitive, etc), and should change when
66  * the action's state changes. When the proxy is activated, it should
67  * activate its action.
68  */
69
70 #include "config.h"
71
72 #include "gtkaction.h"
73 #include "gtkactiongroup.h"
74 #include "gtkaccellabel.h"
75 #include "gtkbutton.h"
76 #include "gtkiconfactory.h"
77 #include "gtkimage.h"
78 #include "gtkimagemenuitem.h"
79 #include "gtkintl.h"
80 #include "gtklabel.h"
81 #include "gtkmarshalers.h"
82 #include "gtkmenuitem.h"
83 #include "gtkstock.h"
84 #include "gtktearoffmenuitem.h"
85 #include "gtktoolbutton.h"
86 #include "gtktoolbar.h"
87 #include "gtkprivate.h"
88 #include "gtkbuildable.h"
89 #include "gtkactivatable.h"
90 #include "gtkalias.h"
91
92
93 #define GTK_ACTION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ACTION, GtkActionPrivate))
94
95 struct _GtkActionPrivate 
96 {
97   const gchar *name; /* interned */
98   gchar *label;
99   gchar *short_label;
100   gchar *tooltip;
101   gchar *stock_id; /* stock icon */
102   gchar *icon_name; /* themed icon */
103   GIcon *gicon;
104
105   guint sensitive          : 1;
106   guint visible            : 1;
107   guint label_set          : 1; /* these two used so we can set label */
108   guint short_label_set    : 1; /* based on stock id */
109   guint visible_horizontal : 1;
110   guint visible_vertical   : 1;
111   guint is_important       : 1;
112   guint hide_if_empty      : 1;
113   guint visible_overflown  : 1;
114   guint always_show_image  : 1;
115   guint recursion_guard    : 1;
116   guint activate_blocked   : 1;
117
118   /* accelerator */
119   guint          accel_count;
120   GtkAccelGroup *accel_group;
121   GClosure      *accel_closure;
122   GQuark         accel_quark;
123
124   GtkActionGroup *action_group;
125
126   /* list of proxy widgets */
127   GSList *proxies;
128 };
129
130 enum 
131 {
132   ACTIVATE,
133   LAST_SIGNAL
134 };
135
136 enum 
137 {
138   PROP_0,
139   PROP_NAME,
140   PROP_LABEL,
141   PROP_SHORT_LABEL,
142   PROP_TOOLTIP,
143   PROP_STOCK_ID,
144   PROP_ICON_NAME,
145   PROP_GICON,
146   PROP_VISIBLE_HORIZONTAL,
147   PROP_VISIBLE_VERTICAL,
148   PROP_VISIBLE_OVERFLOWN,
149   PROP_IS_IMPORTANT,
150   PROP_HIDE_IF_EMPTY,
151   PROP_SENSITIVE,
152   PROP_VISIBLE,
153   PROP_ACTION_GROUP,
154   PROP_ALWAYS_SHOW_IMAGE
155 };
156
157 /* GtkBuildable */
158 static void gtk_action_buildable_init             (GtkBuildableIface *iface);
159 static void gtk_action_buildable_set_name         (GtkBuildable *buildable,
160                                                    const gchar  *name);
161 static const gchar* gtk_action_buildable_get_name (GtkBuildable *buildable);
162
163 G_DEFINE_TYPE_WITH_CODE (GtkAction, gtk_action, G_TYPE_OBJECT,
164                          G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
165                                                 gtk_action_buildable_init))
166
167 static void gtk_action_finalize     (GObject *object);
168 static void gtk_action_set_property (GObject         *object,
169                                      guint            prop_id,
170                                      const GValue    *value,
171                                      GParamSpec      *pspec);
172 static void gtk_action_get_property (GObject         *object,
173                                      guint            prop_id,
174                                      GValue          *value,
175                                      GParamSpec      *pspec);
176 static void gtk_action_set_action_group (GtkAction      *action,
177                                          GtkActionGroup *action_group);
178
179 static GtkWidget *create_menu_item    (GtkAction *action);
180 static GtkWidget *create_tool_item    (GtkAction *action);
181 static void       connect_proxy       (GtkAction *action,
182                                        GtkWidget *proxy);
183 static void       disconnect_proxy    (GtkAction *action,
184                                        GtkWidget *proxy);
185  
186 static void       closure_accel_activate (GClosure     *closure,
187                                           GValue       *return_value,
188                                           guint         n_param_values,
189                                           const GValue *param_values,
190                                           gpointer      invocation_hint,
191                                           gpointer      marshal_data);
192
193 static guint         action_signals[LAST_SIGNAL] = { 0 };
194
195
196 static void
197 gtk_action_class_init (GtkActionClass *klass)
198 {
199   GObjectClass *gobject_class;
200
201   gobject_class = G_OBJECT_CLASS (klass);
202
203   gobject_class->finalize     = gtk_action_finalize;
204   gobject_class->set_property = gtk_action_set_property;
205   gobject_class->get_property = gtk_action_get_property;
206
207   klass->activate = NULL;
208
209   klass->create_menu_item  = create_menu_item;
210   klass->create_tool_item  = create_tool_item;
211   klass->create_menu       = NULL;
212   klass->menu_item_type    = GTK_TYPE_IMAGE_MENU_ITEM;
213   klass->toolbar_item_type = GTK_TYPE_TOOL_BUTTON;
214   klass->connect_proxy    = connect_proxy;
215   klass->disconnect_proxy = disconnect_proxy;
216
217   g_object_class_install_property (gobject_class,
218                                    PROP_NAME,
219                                    g_param_spec_string ("name",
220                                                         P_("Name"),
221                                                         P_("A unique name for the action."),
222                                                         NULL,
223                                                         GTK_PARAM_READWRITE | 
224                                                         G_PARAM_CONSTRUCT_ONLY));
225
226   /**
227    * GtkAction:label:
228    *
229    * The label used for menu items and buttons that activate
230    * this action. If the label is %NULL, GTK+ uses the stock 
231    * label specified via the stock-id property.
232    *
233    * This is an appearance property and thus only applies if 
234    * #GtkActivatable:use-action-appearance is %TRUE.
235    */
236   g_object_class_install_property (gobject_class,
237                                    PROP_LABEL,
238                                    g_param_spec_string ("label",
239                                                         P_("Label"),
240                                                         P_("The label used for menu items and buttons "
241                                                            "that activate this action."),
242                                                         NULL,
243                                                         GTK_PARAM_READWRITE));
244
245   /**
246    * GtkAction:short-label:
247    *
248    * A shorter label that may be used on toolbar buttons.
249    *
250    * This is an appearance property and thus only applies if 
251    * #GtkActivatable:use-action-appearance is %TRUE.
252    */
253   g_object_class_install_property (gobject_class,
254                                    PROP_SHORT_LABEL,
255                                    g_param_spec_string ("short-label",
256                                                         P_("Short label"),
257                                                         P_("A shorter label that may be used on toolbar buttons."),
258                                                         NULL,
259                                                         GTK_PARAM_READWRITE));
260
261
262   g_object_class_install_property (gobject_class,
263                                    PROP_TOOLTIP,
264                                    g_param_spec_string ("tooltip",
265                                                         P_("Tooltip"),
266                                                         P_("A tooltip for this action."),
267                                                         NULL,
268                                                         GTK_PARAM_READWRITE));
269
270   /**
271    * GtkAction:stock-id:
272    *
273    * The stock icon displayed in widgets representing this action.
274    *
275    * This is an appearance property and thus only applies if 
276    * #GtkActivatable:use-action-appearance is %TRUE.
277    */
278   g_object_class_install_property (gobject_class,
279                                    PROP_STOCK_ID,
280                                    g_param_spec_string ("stock-id",
281                                                         P_("Stock Icon"),
282                                                         P_("The stock icon displayed in widgets representing "
283                                                            "this action."),
284                                                         NULL,
285                                                         GTK_PARAM_READWRITE));
286   /**
287    * GtkAction:gicon:
288    *
289    * The #GIcon displayed in the #GtkAction.
290    *
291    * Note that the stock icon is preferred, if the #GtkAction:stock-id 
292    * property holds the id of an existing stock icon.
293    *
294    * This is an appearance property and thus only applies if 
295    * #GtkActivatable:use-action-appearance is %TRUE.
296    *
297    * Since: 2.16
298    */
299   g_object_class_install_property (gobject_class,
300                                    PROP_GICON,
301                                    g_param_spec_object ("gicon",
302                                                         P_("GIcon"),
303                                                         P_("The GIcon being displayed"),
304                                                         G_TYPE_ICON,
305                                                         GTK_PARAM_READWRITE));                                                  
306   /**
307    * GtkAction:icon-name:
308    *
309    * The name of the icon from the icon theme. 
310    * 
311    * Note that the stock icon is preferred, if the #GtkAction:stock-id 
312    * property holds the id of an existing stock icon, and the #GIcon is
313    * preferred if the #GtkAction:gicon property is set. 
314    *
315    * This is an appearance property and thus only applies if 
316    * #GtkActivatable:use-action-appearance is %TRUE.
317    *
318    * Since: 2.10
319    */
320   g_object_class_install_property (gobject_class,
321                                    PROP_ICON_NAME,
322                                    g_param_spec_string ("icon-name",
323                                                         P_("Icon Name"),
324                                                         P_("The name of the icon from the icon theme"),
325                                                         NULL,
326                                                         GTK_PARAM_READWRITE));
327
328   g_object_class_install_property (gobject_class,
329                                    PROP_VISIBLE_HORIZONTAL,
330                                    g_param_spec_boolean ("visible-horizontal",
331                                                          P_("Visible when horizontal"),
332                                                          P_("Whether the toolbar item is visible when the toolbar "
333                                                             "is in a horizontal orientation."),
334                                                          TRUE,
335                                                          GTK_PARAM_READWRITE));
336   /**
337    * GtkAction:visible-overflown:
338    *
339    * When %TRUE, toolitem proxies for this action are represented in the 
340    * toolbar overflow menu.
341    *
342    * Since: 2.6
343    */
344   g_object_class_install_property (gobject_class,
345                                    PROP_VISIBLE_OVERFLOWN,
346                                    g_param_spec_boolean ("visible-overflown",
347                                                          P_("Visible when overflown"),
348                                                          P_("When TRUE, toolitem proxies for this action "
349                                                             "are represented in the toolbar overflow menu."),
350                                                          TRUE,
351                                                          GTK_PARAM_READWRITE));
352   g_object_class_install_property (gobject_class,
353                                    PROP_VISIBLE_VERTICAL,
354                                    g_param_spec_boolean ("visible-vertical",
355                                                          P_("Visible when vertical"),
356                                                          P_("Whether the toolbar item is visible when the toolbar "
357                                                             "is in a vertical orientation."),
358                                                          TRUE,
359                                                          GTK_PARAM_READWRITE));
360   g_object_class_install_property (gobject_class,
361                                    PROP_IS_IMPORTANT,
362                                    g_param_spec_boolean ("is-important",
363                                                          P_("Is important"),
364                                                          P_("Whether the action is considered important. "
365                                                             "When TRUE, toolitem proxies for this action "
366                                                             "show text in GTK_TOOLBAR_BOTH_HORIZ mode."),
367                                                          FALSE,
368                                                          GTK_PARAM_READWRITE));
369   g_object_class_install_property (gobject_class,
370                                    PROP_HIDE_IF_EMPTY,
371                                    g_param_spec_boolean ("hide-if-empty",
372                                                          P_("Hide if empty"),
373                                                          P_("When TRUE, empty menu proxies for this action are hidden."),
374                                                          TRUE,
375                                                          GTK_PARAM_READWRITE));
376   g_object_class_install_property (gobject_class,
377                                    PROP_SENSITIVE,
378                                    g_param_spec_boolean ("sensitive",
379                                                          P_("Sensitive"),
380                                                          P_("Whether the action is enabled."),
381                                                          TRUE,
382                                                          GTK_PARAM_READWRITE));
383   g_object_class_install_property (gobject_class,
384                                    PROP_VISIBLE,
385                                    g_param_spec_boolean ("visible",
386                                                          P_("Visible"),
387                                                          P_("Whether the action is visible."),
388                                                          TRUE,
389                                                          GTK_PARAM_READWRITE));
390   g_object_class_install_property (gobject_class,
391                                    PROP_ACTION_GROUP,
392                                    g_param_spec_object ("action-group",
393                                                          P_("Action Group"),
394                                                          P_("The GtkActionGroup this GtkAction is associated with, or NULL (for internal use)."),
395                                                          GTK_TYPE_ACTION_GROUP,
396                                                          GTK_PARAM_READWRITE));
397
398   /**
399    * GtkAction:always-show-image:
400    *
401    * If %TRUE, the action's menu item proxies will ignore the #GtkSettings:gtk-menu-images 
402    * setting and always show their image, if available.
403    *
404    * Use this property if the menu item would be useless or hard to use
405    * without their image. 
406    *
407    * Since: 2.20
408    **/
409   g_object_class_install_property (gobject_class,
410                                    PROP_ALWAYS_SHOW_IMAGE,
411                                    g_param_spec_boolean ("always-show-image",
412                                                          P_("Always show image"),
413                                                          P_("Whether the image will always be shown"),
414                                                          FALSE,
415                                                          GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
416
417   /**
418    * GtkAction::activate:
419    * @action: the #GtkAction
420    *
421    * The "activate" signal is emitted when the action is activated.
422    *
423    * Since: 2.4
424    */
425   action_signals[ACTIVATE] =
426     g_signal_new (I_("activate"),
427                   G_OBJECT_CLASS_TYPE (klass),
428                   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
429                   G_STRUCT_OFFSET (GtkActionClass, activate),  NULL, NULL,
430                   g_cclosure_marshal_VOID__VOID,
431                   G_TYPE_NONE, 0);
432
433   g_type_class_add_private (gobject_class, sizeof (GtkActionPrivate));
434 }
435
436
437 static void
438 gtk_action_init (GtkAction *action)
439 {
440   action->private_data = GTK_ACTION_GET_PRIVATE (action);
441
442   action->private_data->name = NULL;
443   action->private_data->label = NULL;
444   action->private_data->short_label = NULL;
445   action->private_data->tooltip = NULL;
446   action->private_data->stock_id = NULL;
447   action->private_data->icon_name = NULL;
448   action->private_data->visible_horizontal = TRUE;
449   action->private_data->visible_vertical   = TRUE;
450   action->private_data->visible_overflown  = TRUE;
451   action->private_data->is_important = FALSE;
452   action->private_data->hide_if_empty = TRUE;
453   action->private_data->always_show_image = FALSE;
454   action->private_data->activate_blocked = FALSE;
455
456   action->private_data->sensitive = TRUE;
457   action->private_data->visible = TRUE;
458
459   action->private_data->label_set = FALSE;
460   action->private_data->short_label_set = FALSE;
461
462   action->private_data->accel_count = 0;
463   action->private_data->accel_group = NULL;
464   action->private_data->accel_quark = 0;
465   action->private_data->accel_closure = 
466     g_closure_new_object (sizeof (GClosure), G_OBJECT (action));
467   g_closure_set_marshal (action->private_data->accel_closure, 
468                          closure_accel_activate);
469   g_closure_ref (action->private_data->accel_closure);
470   g_closure_sink (action->private_data->accel_closure);
471
472   action->private_data->action_group = NULL;
473
474   action->private_data->proxies = NULL;
475   action->private_data->gicon = NULL;  
476 }
477
478 static void
479 gtk_action_buildable_init (GtkBuildableIface *iface)
480 {
481   iface->set_name = gtk_action_buildable_set_name;
482   iface->get_name = gtk_action_buildable_get_name;
483 }
484
485 static void
486 gtk_action_buildable_set_name (GtkBuildable *buildable,
487                                const gchar  *name)
488 {
489   GtkAction *action = GTK_ACTION (buildable);
490
491   action->private_data->name = g_intern_string (name);
492 }
493
494 static const gchar *
495 gtk_action_buildable_get_name (GtkBuildable *buildable)
496 {
497   GtkAction *action = GTK_ACTION (buildable);
498
499   return action->private_data->name;
500 }
501
502 /**
503  * gtk_action_new:
504  * @name: A unique name for the action
505  * @label: (allow-none): the label displayed in menu items and on buttons, or %NULL
506  * @tooltip: (allow-none): a tooltip for the action, or %NULL
507  * @stock_id: the stock icon to display in widgets representing the
508  *   action, or %NULL
509  *
510  * Creates a new #GtkAction object. To add the action to a
511  * #GtkActionGroup and set the accelerator for the action,
512  * call gtk_action_group_add_action_with_accel().
513  * See <xref linkend="XML-UI"/> for information on allowed action
514  * names.
515  *
516  * Return value: a new #GtkAction
517  *
518  * Since: 2.4
519  */
520 GtkAction *
521 gtk_action_new (const gchar *name,
522                 const gchar *label,
523                 const gchar *tooltip,
524                 const gchar *stock_id)
525 {
526   g_return_val_if_fail (name != NULL, NULL);
527
528   return g_object_new (GTK_TYPE_ACTION,
529                        "name", name,
530                        "label", label,
531                        "tooltip", tooltip,
532                        "stock-id", stock_id,
533                        NULL);
534 }
535
536 static void
537 gtk_action_finalize (GObject *object)
538 {
539   GtkAction *action;
540   action = GTK_ACTION (object);
541
542   g_free (action->private_data->label);
543   g_free (action->private_data->short_label);
544   g_free (action->private_data->tooltip);
545   g_free (action->private_data->stock_id);
546   g_free (action->private_data->icon_name);
547   
548   if (action->private_data->gicon)
549     g_object_unref (action->private_data->gicon);
550
551   g_closure_unref (action->private_data->accel_closure);
552   if (action->private_data->accel_group)
553     g_object_unref (action->private_data->accel_group);
554
555   G_OBJECT_CLASS (gtk_action_parent_class)->finalize (object);  
556 }
557
558 static void
559 gtk_action_set_property (GObject         *object,
560                          guint            prop_id,
561                          const GValue    *value,
562                          GParamSpec      *pspec)
563 {
564   GtkAction *action;
565   
566   action = GTK_ACTION (object);
567
568   switch (prop_id)
569     {
570     case PROP_NAME:
571       action->private_data->name = g_intern_string (g_value_get_string (value));
572       break;
573     case PROP_LABEL:
574       gtk_action_set_label (action, g_value_get_string (value));
575       break;
576     case PROP_SHORT_LABEL:
577       gtk_action_set_short_label (action, g_value_get_string (value));
578       break;
579     case PROP_TOOLTIP:
580       gtk_action_set_tooltip (action, g_value_get_string (value));
581       break;
582     case PROP_STOCK_ID:
583       gtk_action_set_stock_id (action, g_value_get_string (value));
584       break;
585     case PROP_GICON:
586       gtk_action_set_gicon (action, g_value_get_object (value));
587       break;
588     case PROP_ICON_NAME:
589       gtk_action_set_icon_name (action, g_value_get_string (value));
590       break;
591     case PROP_VISIBLE_HORIZONTAL:
592       gtk_action_set_visible_horizontal (action, g_value_get_boolean (value));
593       break;
594     case PROP_VISIBLE_VERTICAL:
595       gtk_action_set_visible_vertical (action, g_value_get_boolean (value));
596       break;
597     case PROP_VISIBLE_OVERFLOWN:
598       action->private_data->visible_overflown = g_value_get_boolean (value);
599       break;
600     case PROP_IS_IMPORTANT:
601       gtk_action_set_is_important (action, g_value_get_boolean (value));
602       break;
603     case PROP_HIDE_IF_EMPTY:
604       action->private_data->hide_if_empty = g_value_get_boolean (value);
605       break;
606     case PROP_SENSITIVE:
607       gtk_action_set_sensitive (action, g_value_get_boolean (value));
608       break;
609     case PROP_VISIBLE:
610       gtk_action_set_visible (action, g_value_get_boolean (value));
611       break;
612     case PROP_ACTION_GROUP:
613       gtk_action_set_action_group (action, g_value_get_object (value));
614       break;
615     case PROP_ALWAYS_SHOW_IMAGE:
616       gtk_action_set_always_show_image (action, g_value_get_boolean (value));
617       break;
618     default:
619       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
620       break;
621     }
622 }
623
624 static void
625 gtk_action_get_property (GObject    *object,
626                          guint       prop_id,
627                          GValue     *value,
628                          GParamSpec *pspec)
629 {
630   GtkAction *action;
631
632   action = GTK_ACTION (object);
633
634   switch (prop_id)
635     {
636     case PROP_NAME:
637       g_value_set_static_string (value, action->private_data->name);
638       break;
639     case PROP_LABEL:
640       g_value_set_string (value, action->private_data->label);
641       break;
642     case PROP_SHORT_LABEL:
643       g_value_set_string (value, action->private_data->short_label);
644       break;
645     case PROP_TOOLTIP:
646       g_value_set_string (value, action->private_data->tooltip);
647       break;
648     case PROP_STOCK_ID:
649       g_value_set_string (value, action->private_data->stock_id);
650       break;
651     case PROP_ICON_NAME:
652       g_value_set_string (value, action->private_data->icon_name);
653       break;
654     case PROP_GICON:
655       g_value_set_object (value, action->private_data->gicon);
656       break;
657     case PROP_VISIBLE_HORIZONTAL:
658       g_value_set_boolean (value, action->private_data->visible_horizontal);
659       break;
660     case PROP_VISIBLE_VERTICAL:
661       g_value_set_boolean (value, action->private_data->visible_vertical);
662       break;
663     case PROP_VISIBLE_OVERFLOWN:
664       g_value_set_boolean (value, action->private_data->visible_overflown);
665       break;
666     case PROP_IS_IMPORTANT:
667       g_value_set_boolean (value, action->private_data->is_important);
668       break;
669     case PROP_HIDE_IF_EMPTY:
670       g_value_set_boolean (value, action->private_data->hide_if_empty);
671       break;
672     case PROP_SENSITIVE:
673       g_value_set_boolean (value, action->private_data->sensitive);
674       break;
675     case PROP_VISIBLE:
676       g_value_set_boolean (value, action->private_data->visible);
677       break;
678     case PROP_ACTION_GROUP:
679       g_value_set_object (value, action->private_data->action_group);
680       break;
681     case PROP_ALWAYS_SHOW_IMAGE:
682       g_value_set_boolean (value, action->private_data->always_show_image);
683       break;
684     default:
685       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
686       break;
687     }
688 }
689
690 static GtkWidget *
691 create_menu_item (GtkAction *action)
692 {
693   GType menu_item_type;
694
695   menu_item_type = GTK_ACTION_GET_CLASS (action)->menu_item_type;
696
697   return g_object_new (menu_item_type, NULL);
698 }
699
700 static GtkWidget *
701 create_tool_item (GtkAction *action)
702 {
703   GType toolbar_item_type;
704
705   toolbar_item_type = GTK_ACTION_GET_CLASS (action)->toolbar_item_type;
706
707   return g_object_new (toolbar_item_type, NULL);
708 }
709
710 static void
711 remove_proxy (GtkAction *action,
712               GtkWidget *proxy)
713 {
714   action->private_data->proxies = g_slist_remove (action->private_data->proxies, proxy);
715 }
716
717 static void
718 connect_proxy (GtkAction *action,
719                GtkWidget *proxy)
720 {
721   action->private_data->proxies = g_slist_prepend (action->private_data->proxies, proxy);
722
723   if (action->private_data->action_group)
724     _gtk_action_group_emit_connect_proxy (action->private_data->action_group, action, proxy);
725
726 }
727
728 static void
729 disconnect_proxy (GtkAction *action,
730                   GtkWidget *proxy)
731 {
732   remove_proxy (action, proxy);
733
734   if (action->private_data->action_group)
735     _gtk_action_group_emit_disconnect_proxy (action->private_data->action_group, action, proxy);
736 }
737
738 /**
739  * _gtk_action_sync_menu_visible:
740  * @action: (allow-none): a #GtkAction, or %NULL to determine the action from @proxy
741  * @proxy: a proxy menu item
742  * @empty: whether the submenu attached to @proxy is empty
743  * 
744  * Updates the visibility of @proxy from the visibility of @action
745  * according to the following rules:
746  * <itemizedlist>
747  * <listitem><para>if @action is invisible, @proxy is too
748  * </para></listitem>
749  * <listitem><para>if @empty is %TRUE, hide @proxy unless the "hide-if-empty" 
750  *   property of @action indicates otherwise
751  * </para></listitem>
752  * </itemizedlist>
753  * 
754  * This function is used in the implementation of #GtkUIManager.
755  **/
756 void
757 _gtk_action_sync_menu_visible (GtkAction *action,
758                                GtkWidget *proxy,
759                                gboolean   empty)
760 {
761   gboolean visible = TRUE;
762   gboolean hide_if_empty = TRUE;
763
764   g_return_if_fail (GTK_IS_MENU_ITEM (proxy));
765   g_return_if_fail (action == NULL || GTK_IS_ACTION (action));
766
767   if (action == NULL)
768     action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (proxy));
769
770   if (action)
771     {
772       /* a GtkMenu for a <popup/> doesn't have to have an action */
773       visible = gtk_action_is_visible (action);
774       hide_if_empty = action->private_data->hide_if_empty;
775     }
776
777   if (visible && !(empty && hide_if_empty))
778     gtk_widget_show (proxy);
779   else
780     gtk_widget_hide (proxy);
781 }
782
783 void
784 _gtk_action_emit_activate (GtkAction *action)
785 {
786   GtkActionGroup *group = action->private_data->action_group;
787
788   if (group != NULL) 
789     {
790       g_object_ref (group);
791       _gtk_action_group_emit_pre_activate (group, action);
792     }
793
794     g_signal_emit (action, action_signals[ACTIVATE], 0);
795
796   if (group != NULL) 
797     {
798       _gtk_action_group_emit_post_activate (group, action);
799       g_object_unref (group);
800     }
801 }
802
803 /**
804  * gtk_action_activate:
805  * @action: the action object
806  *
807  * Emits the "activate" signal on the specified action, if it isn't 
808  * insensitive. This gets called by the proxy widgets when they get 
809  * activated.
810  *
811  * It can also be used to manually activate an action.
812  *
813  * Since: 2.4
814  */
815 void
816 gtk_action_activate (GtkAction *action)
817 {
818   g_return_if_fail (GTK_IS_ACTION (action));
819   
820   if (action->private_data->activate_blocked)
821     return;
822
823   if (gtk_action_is_sensitive (action))
824     _gtk_action_emit_activate (action);
825 }
826
827 /**
828  * gtk_action_block_activate:
829  * @action: a #GtkAction
830  *
831  * Disable activation signals from the action 
832  *
833  * This is needed when updating the state of your proxy
834  * #GtkActivatable widget could result in calling gtk_action_activate(),
835  * this is a convenience function to avoid recursing in those
836  * cases (updating toggle state for instance).
837  *
838  * Since: 2.16
839  */
840 void
841 gtk_action_block_activate (GtkAction *action)
842 {
843   g_return_if_fail (GTK_IS_ACTION (action));
844
845   action->private_data->activate_blocked = TRUE;
846 }
847
848 /**
849  * gtk_action_unblock_activate:
850  * @action: a #GtkAction
851  *
852  * Reenable activation signals from the action 
853  *
854  * Since: 2.16
855  */
856 void
857 gtk_action_unblock_activate (GtkAction *action)
858 {
859   g_return_if_fail (GTK_IS_ACTION (action));
860
861   action->private_data->activate_blocked = FALSE;
862 }
863
864 /**
865  * gtk_action_create_icon:
866  * @action: the action object
867  * @icon_size: (type int): the size of the icon that should be created.
868  *
869  * This function is intended for use by action implementations to
870  * create icons displayed in the proxy widgets.
871  *
872  * Returns: a widget that displays the icon for this action.
873  *
874  * Since: 2.4
875  */
876 GtkWidget *
877 gtk_action_create_icon (GtkAction *action, GtkIconSize icon_size)
878 {
879   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
880
881   if (action->private_data->stock_id &&
882       gtk_icon_factory_lookup_default (action->private_data->stock_id))
883     return gtk_image_new_from_stock (action->private_data->stock_id, icon_size);
884   else if (action->private_data->gicon)
885     return gtk_image_new_from_gicon (action->private_data->gicon, icon_size);
886   else if (action->private_data->icon_name)
887     return gtk_image_new_from_icon_name (action->private_data->icon_name, icon_size);
888   else
889     return NULL;
890 }
891
892 /**
893  * gtk_action_create_menu_item:
894  * @action: the action object
895  *
896  * Creates a menu item widget that proxies for the given action.
897  *
898  * Returns: a menu item connected to the action.
899  *
900  * Since: 2.4
901  */
902 GtkWidget *
903 gtk_action_create_menu_item (GtkAction *action)
904 {
905   GtkWidget *menu_item;
906
907   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
908
909   menu_item = GTK_ACTION_GET_CLASS (action)->create_menu_item (action);
910
911   gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (menu_item), TRUE);
912   gtk_activatable_set_related_action (GTK_ACTIVATABLE (menu_item), action);
913
914   return menu_item;
915 }
916
917 /**
918  * gtk_action_create_tool_item:
919  * @action: the action object
920  *
921  * Creates a toolbar item widget that proxies for the given action.
922  *
923  * Returns: a toolbar item connected to the action.
924  *
925  * Since: 2.4
926  */
927 GtkWidget *
928 gtk_action_create_tool_item (GtkAction *action)
929 {
930   GtkWidget *button;
931
932   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
933
934   button = GTK_ACTION_GET_CLASS (action)->create_tool_item (action);
935
936   gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (button), TRUE);
937   gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), action);
938
939   return button;
940 }
941
942 void
943 _gtk_action_add_to_proxy_list (GtkAction     *action,
944                                GtkWidget     *proxy)
945 {
946   g_return_if_fail (GTK_IS_ACTION (action));
947   g_return_if_fail (GTK_IS_WIDGET (proxy));
948  
949   GTK_ACTION_GET_CLASS (action)->connect_proxy (action, proxy);
950 }
951
952 void
953 _gtk_action_remove_from_proxy_list (GtkAction     *action,
954                                     GtkWidget     *proxy)
955 {
956   g_return_if_fail (GTK_IS_ACTION (action));
957   g_return_if_fail (GTK_IS_WIDGET (proxy));
958
959   GTK_ACTION_GET_CLASS (action)->disconnect_proxy (action, proxy);
960 }
961
962 /**
963  * gtk_action_get_proxies:
964  * @action: the action object
965  * 
966  * Returns the proxy widgets for an action.
967  * See also gtk_activatable_get_related_action().
968  *
969  * Return value: (element-type GtkWidget) (transfer none): a #GSList of proxy widgets. The list is owned by GTK+
970  * and must not be modified.
971  *
972  * Since: 2.4
973  **/
974 GSList*
975 gtk_action_get_proxies (GtkAction *action)
976 {
977   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
978
979   return action->private_data->proxies;
980 }
981
982 /**
983  * gtk_action_get_name:
984  * @action: the action object
985  * 
986  * Returns the name of the action.
987  * 
988  * Return value: the name of the action. The string belongs to GTK+ and should not
989  *   be freed.
990  *
991  * Since: 2.4
992  **/
993 G_CONST_RETURN gchar *
994 gtk_action_get_name (GtkAction *action)
995 {
996   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
997
998   return action->private_data->name;
999 }
1000
1001 /**
1002  * gtk_action_is_sensitive:
1003  * @action: the action object
1004  * 
1005  * Returns whether the action is effectively sensitive.
1006  *
1007  * Return value: %TRUE if the action and its associated action group 
1008  * are both sensitive.
1009  *
1010  * Since: 2.4
1011  **/
1012 gboolean
1013 gtk_action_is_sensitive (GtkAction *action)
1014 {
1015   GtkActionPrivate *priv;
1016   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1017
1018   priv = action->private_data;
1019   return priv->sensitive &&
1020     (priv->action_group == NULL ||
1021      gtk_action_group_get_sensitive (priv->action_group));
1022 }
1023
1024 /**
1025  * gtk_action_get_sensitive:
1026  * @action: the action object
1027  * 
1028  * Returns whether the action itself is sensitive. Note that this doesn't 
1029  * necessarily mean effective sensitivity. See gtk_action_is_sensitive() 
1030  * for that.
1031  *
1032  * Return value: %TRUE if the action itself is sensitive.
1033  *
1034  * Since: 2.4
1035  **/
1036 gboolean
1037 gtk_action_get_sensitive (GtkAction *action)
1038 {
1039   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1040
1041   return action->private_data->sensitive;
1042 }
1043
1044 /**
1045  * gtk_action_set_sensitive:
1046  * @action: the action object
1047  * @sensitive: %TRUE to make the action sensitive
1048  * 
1049  * Sets the ::sensitive property of the action to @sensitive. Note that 
1050  * this doesn't necessarily mean effective sensitivity. See 
1051  * gtk_action_is_sensitive() 
1052  * for that.
1053  *
1054  * Since: 2.6
1055  **/
1056 void
1057 gtk_action_set_sensitive (GtkAction *action,
1058                           gboolean   sensitive)
1059 {
1060   g_return_if_fail (GTK_IS_ACTION (action));
1061
1062   sensitive = sensitive != FALSE;
1063   
1064   if (action->private_data->sensitive != sensitive)
1065     {
1066       action->private_data->sensitive = sensitive;
1067
1068       g_object_notify (G_OBJECT (action), "sensitive");
1069     }
1070 }
1071
1072 /**
1073  * gtk_action_is_visible:
1074  * @action: the action object
1075  * 
1076  * Returns whether the action is effectively visible.
1077  *
1078  * Return value: %TRUE if the action and its associated action group 
1079  * are both visible.
1080  *
1081  * Since: 2.4
1082  **/
1083 gboolean
1084 gtk_action_is_visible (GtkAction *action)
1085 {
1086   GtkActionPrivate *priv;
1087   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1088
1089   priv = action->private_data;
1090   return priv->visible &&
1091     (priv->action_group == NULL ||
1092      gtk_action_group_get_visible (priv->action_group));
1093 }
1094
1095 /**
1096  * gtk_action_get_visible:
1097  * @action: the action object
1098  * 
1099  * Returns whether the action itself is visible. Note that this doesn't 
1100  * necessarily mean effective visibility. See gtk_action_is_sensitive() 
1101  * for that.
1102  *
1103  * Return value: %TRUE if the action itself is visible.
1104  *
1105  * Since: 2.4
1106  **/
1107 gboolean
1108 gtk_action_get_visible (GtkAction *action)
1109 {
1110   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1111
1112   return action->private_data->visible;
1113 }
1114
1115 /**
1116  * gtk_action_set_visible:
1117  * @action: the action object
1118  * @visible: %TRUE to make the action visible
1119  * 
1120  * Sets the ::visible property of the action to @visible. Note that 
1121  * this doesn't necessarily mean effective visibility. See 
1122  * gtk_action_is_visible() 
1123  * for that.
1124  *
1125  * Since: 2.6
1126  **/
1127 void
1128 gtk_action_set_visible (GtkAction *action,
1129                         gboolean   visible)
1130 {
1131   g_return_if_fail (GTK_IS_ACTION (action));
1132
1133   visible = visible != FALSE;
1134   
1135   if (action->private_data->visible != visible)
1136     {
1137       action->private_data->visible = visible;
1138
1139       g_object_notify (G_OBJECT (action), "visible");
1140     }
1141 }
1142 /**
1143  * gtk_action_set_is_important:
1144  * @action: the action object
1145  * @is_important: %TRUE to make the action important
1146  *
1147  * Sets whether the action is important, this attribute is used
1148  * primarily by toolbar items to decide whether to show a label
1149  * or not.
1150  *
1151  * Since: 2.16
1152  */
1153 void 
1154 gtk_action_set_is_important (GtkAction *action,
1155                              gboolean   is_important)
1156 {
1157   g_return_if_fail (GTK_IS_ACTION (action));
1158
1159   is_important = is_important != FALSE;
1160   
1161   if (action->private_data->is_important != is_important)
1162     {
1163       action->private_data->is_important = is_important;
1164       
1165       g_object_notify (G_OBJECT (action), "is-important");
1166     }  
1167 }
1168
1169 /**
1170  * gtk_action_get_is_important:
1171  * @action: a #GtkAction
1172  *
1173  * Checks whether @action is important or not
1174  * 
1175  * Returns: whether @action is important
1176  *
1177  * Since: 2.16
1178  */
1179 gboolean 
1180 gtk_action_get_is_important (GtkAction *action)
1181 {
1182   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1183
1184   return action->private_data->is_important;
1185 }
1186
1187 /**
1188  * gtk_action_set_always_show_image:
1189  * @action: a #GtkAction
1190  * @always_show: %TRUE if menuitem proxies should always show their image
1191  *
1192  * Sets whether @action<!-- -->'s menu item proxies will ignore the
1193  * #GtkSettings:gtk-menu-images setting and always show their image, if available.
1194  *
1195  * Use this if the menu item would be useless or hard to use
1196  * without their image.
1197  *
1198  * Since: 2.20
1199  */
1200 void
1201 gtk_action_set_always_show_image (GtkAction *action,
1202                                   gboolean   always_show)
1203 {
1204   GtkActionPrivate *priv;
1205
1206   g_return_if_fail (GTK_IS_ACTION (action));
1207
1208   priv = action->private_data;
1209
1210   always_show = always_show != FALSE;
1211   
1212   if (priv->always_show_image != always_show)
1213     {
1214       priv->always_show_image = always_show;
1215
1216       g_object_notify (G_OBJECT (action), "always-show-image");
1217     }
1218 }
1219
1220 /**
1221  * gtk_action_get_always_show_image:
1222  * @action: a #GtkAction
1223  *
1224  * Returns whether @action<!-- -->'s menu item proxies will ignore the
1225  * #GtkSettings:gtk-menu-images setting and always show their image,
1226  * if available.
1227  *
1228  * Returns: %TRUE if the menu item proxies will always show their image
1229  *
1230  * Since: 2.20
1231  */
1232 gboolean
1233 gtk_action_get_always_show_image  (GtkAction *action)
1234 {
1235   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1236
1237   return action->private_data->always_show_image;
1238 }
1239
1240 /**
1241  * gtk_action_set_label:
1242  * @action: a #GtkAction
1243  * @label: the label text to set
1244  *
1245  * Sets the label of @action.
1246  *
1247  * Since: 2.16
1248  */
1249 void 
1250 gtk_action_set_label (GtkAction   *action,
1251                       const gchar *label)
1252 {
1253   gchar *tmp;
1254   
1255   g_return_if_fail (GTK_IS_ACTION (action));
1256   
1257   tmp = action->private_data->label;
1258   action->private_data->label = g_strdup (label);
1259   g_free (tmp);
1260   action->private_data->label_set = (action->private_data->label != NULL);
1261   /* if label is unset, then use the label from the stock item */
1262   if (!action->private_data->label_set && action->private_data->stock_id)
1263     {
1264       GtkStockItem stock_item;
1265       
1266       if (gtk_stock_lookup (action->private_data->stock_id, &stock_item))
1267         action->private_data->label = g_strdup (stock_item.label);
1268     }
1269
1270   g_object_notify (G_OBJECT (action), "label");
1271   
1272   /* if short_label is unset, set short_label=label */
1273   if (!action->private_data->short_label_set)
1274     {
1275       gtk_action_set_short_label (action, action->private_data->label);
1276       action->private_data->short_label_set = FALSE;
1277     }
1278 }
1279
1280 /**
1281  * gtk_action_get_label:
1282  * @action: a #GtkAction
1283  *
1284  * Gets the label text of @action.
1285  *
1286  * Returns: the label text
1287  *
1288  * Since: 2.16
1289  */
1290 G_CONST_RETURN gchar * 
1291 gtk_action_get_label (GtkAction *action)
1292 {
1293   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1294
1295   return action->private_data->label;
1296 }
1297
1298 /**
1299  * gtk_action_set_short_label:
1300  * @action: a #GtkAction
1301  * @short_label: the label text to set
1302  *
1303  * Sets a shorter label text on @action.
1304  *
1305  * Since: 2.16
1306  */
1307 void 
1308 gtk_action_set_short_label (GtkAction   *action,
1309                             const gchar *short_label)
1310 {
1311   gchar *tmp;
1312
1313   g_return_if_fail (GTK_IS_ACTION (action));
1314
1315   tmp = action->private_data->short_label;
1316   action->private_data->short_label = g_strdup (short_label);
1317   g_free (tmp);
1318   action->private_data->short_label_set = (action->private_data->short_label != NULL);
1319   /* if short_label is unset, then use the value of label */
1320   if (!action->private_data->short_label_set)
1321     action->private_data->short_label = g_strdup (action->private_data->label);
1322
1323   g_object_notify (G_OBJECT (action), "short-label");
1324 }
1325
1326 /**
1327  * gtk_action_get_short_label:
1328  * @action: a #GtkAction
1329  *
1330  * Gets the short label text of @action.
1331  *
1332  * Returns: the short label text.
1333  *
1334  * Since: 2.16
1335  */
1336 G_CONST_RETURN gchar * 
1337 gtk_action_get_short_label (GtkAction *action)
1338 {
1339   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1340
1341   return action->private_data->short_label;
1342 }
1343
1344 /**
1345  * gtk_action_set_visible_horizontal:
1346  * @action: a #GtkAction
1347  * @visible_horizontal: whether the action is visible horizontally
1348  *
1349  * Sets whether @action is visible when horizontal
1350  *
1351  * Since: 2.16
1352  */
1353 void 
1354 gtk_action_set_visible_horizontal (GtkAction *action,
1355                                    gboolean   visible_horizontal)
1356 {
1357   g_return_if_fail (GTK_IS_ACTION (action));
1358
1359   g_return_if_fail (GTK_IS_ACTION (action));
1360
1361   visible_horizontal = visible_horizontal != FALSE;
1362   
1363   if (action->private_data->visible_horizontal != visible_horizontal)
1364     {
1365       action->private_data->visible_horizontal = visible_horizontal;
1366       
1367       g_object_notify (G_OBJECT (action), "visible-horizontal");
1368     }  
1369 }
1370
1371 /**
1372  * gtk_action_get_visible_horizontal:
1373  * @action: a #GtkAction
1374  *
1375  * Checks whether @action is visible when horizontal
1376  * 
1377  * Returns: whether @action is visible when horizontal
1378  *
1379  * Since: 2.16
1380  */
1381 gboolean 
1382 gtk_action_get_visible_horizontal (GtkAction *action)
1383 {
1384   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1385
1386   return action->private_data->visible_horizontal;
1387 }
1388
1389 /**
1390  * gtk_action_set_visible_vertical:
1391  * @action: a #GtkAction
1392  * @visible_vertical: whether the action is visible vertically
1393  *
1394  * Sets whether @action is visible when vertical 
1395  *
1396  * Since: 2.16
1397  */
1398 void 
1399 gtk_action_set_visible_vertical (GtkAction *action,
1400                                  gboolean   visible_vertical)
1401 {
1402   g_return_if_fail (GTK_IS_ACTION (action));
1403
1404   g_return_if_fail (GTK_IS_ACTION (action));
1405
1406   visible_vertical = visible_vertical != FALSE;
1407   
1408   if (action->private_data->visible_vertical != visible_vertical)
1409     {
1410       action->private_data->visible_vertical = visible_vertical;
1411       
1412       g_object_notify (G_OBJECT (action), "visible-vertical");
1413     }  
1414 }
1415
1416 /**
1417  * gtk_action_get_visible_vertical:
1418  * @action: a #GtkAction
1419  *
1420  * Checks whether @action is visible when horizontal
1421  * 
1422  * Returns: whether @action is visible when horizontal
1423  *
1424  * Since: 2.16
1425  */
1426 gboolean 
1427 gtk_action_get_visible_vertical (GtkAction *action)
1428 {
1429   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1430
1431   return action->private_data->visible_vertical;
1432 }
1433
1434 /**
1435  * gtk_action_set_tooltip:
1436  * @action: a #GtkAction
1437  * @tooltip: the tooltip text
1438  *
1439  * Sets the tooltip text on @action
1440  *
1441  * Since: 2.16
1442  */
1443 void 
1444 gtk_action_set_tooltip (GtkAction   *action,
1445                         const gchar *tooltip)
1446 {
1447   gchar *tmp;
1448
1449   g_return_if_fail (GTK_IS_ACTION (action));
1450
1451   tmp = action->private_data->tooltip;
1452   action->private_data->tooltip = g_strdup (tooltip);
1453   g_free (tmp);
1454
1455   g_object_notify (G_OBJECT (action), "tooltip");
1456 }
1457
1458 /**
1459  * gtk_action_get_tooltip:
1460  * @action: a #GtkAction
1461  *
1462  * Gets the tooltip text of @action.
1463  *
1464  * Returns: the tooltip text
1465  *
1466  * Since: 2.16
1467  */
1468 G_CONST_RETURN gchar * 
1469 gtk_action_get_tooltip (GtkAction *action)
1470 {
1471   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1472
1473   return action->private_data->tooltip;
1474 }
1475
1476 /**
1477  * gtk_action_set_stock_id:
1478  * @action: a #GtkAction
1479  * @stock_id: the stock id
1480  *
1481  * Sets the stock id on @action
1482  *
1483  * Since: 2.16
1484  */
1485 void 
1486 gtk_action_set_stock_id (GtkAction   *action,
1487                          const gchar *stock_id)
1488 {
1489   gchar *tmp;
1490
1491   g_return_if_fail (GTK_IS_ACTION (action));
1492
1493   g_return_if_fail (GTK_IS_ACTION (action));
1494
1495   tmp = action->private_data->stock_id;
1496   action->private_data->stock_id = g_strdup (stock_id);
1497   g_free (tmp);
1498
1499   g_object_notify (G_OBJECT (action), "stock-id");
1500   
1501   /* update label and short_label if appropriate */
1502   if (!action->private_data->label_set)
1503     {
1504       GtkStockItem stock_item;
1505       
1506       if (action->private_data->stock_id &&
1507           gtk_stock_lookup (action->private_data->stock_id, &stock_item))
1508         gtk_action_set_label (action, stock_item.label);
1509       else 
1510         gtk_action_set_label (action, NULL);
1511       
1512       action->private_data->label_set = FALSE;
1513     }
1514 }
1515
1516 /**
1517  * gtk_action_get_stock_id:
1518  * @action: a #GtkAction
1519  *
1520  * Gets the stock id of @action.
1521  *
1522  * Returns: the stock id
1523  *
1524  * Since: 2.16
1525  */
1526 G_CONST_RETURN gchar * 
1527 gtk_action_get_stock_id (GtkAction *action)
1528 {
1529   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1530
1531   return action->private_data->stock_id;
1532 }
1533
1534 /**
1535  * gtk_action_set_icon_name:
1536  * @action: a #GtkAction
1537  * @icon_name: the icon name to set
1538  *
1539  * Sets the icon name on @action
1540  *
1541  * Since: 2.16
1542  */
1543 void 
1544 gtk_action_set_icon_name (GtkAction   *action,
1545                           const gchar *icon_name)
1546 {
1547   gchar *tmp;
1548
1549   g_return_if_fail (GTK_IS_ACTION (action));
1550
1551   tmp = action->private_data->icon_name;
1552   action->private_data->icon_name = g_strdup (icon_name);
1553   g_free (tmp);
1554
1555   g_object_notify (G_OBJECT (action), "icon-name");
1556 }
1557
1558 /**
1559  * gtk_action_get_icon_name:
1560  * @action: a #GtkAction
1561  *
1562  * Gets the icon name of @action.
1563  *
1564  * Returns: the icon name
1565  *
1566  * Since: 2.16
1567  */
1568 G_CONST_RETURN gchar * 
1569 gtk_action_get_icon_name (GtkAction *action)
1570 {
1571   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1572
1573   return action->private_data->icon_name;
1574 }
1575
1576 /**
1577  * gtk_action_set_gicon:
1578  * @action: a #GtkAction
1579  * @icon: the #GIcon to set
1580  *
1581  * Sets the icon of @action.
1582  *
1583  * Since: 2.16
1584  */
1585 void
1586 gtk_action_set_gicon (GtkAction *action,
1587                       GIcon     *icon)
1588 {
1589   g_return_if_fail (GTK_IS_ACTION (action));
1590
1591   if (action->private_data->gicon)
1592     g_object_unref (action->private_data->gicon);
1593
1594   action->private_data->gicon = icon;
1595
1596   if (action->private_data->gicon)
1597     g_object_ref (action->private_data->gicon);
1598
1599   g_object_notify (G_OBJECT (action), "gicon");
1600 }
1601
1602 /**
1603  * gtk_action_get_gicon:
1604  * @action: a #GtkAction
1605  *
1606  * Gets the gicon of @action.
1607  *
1608  * Returns: The action's #GIcon if one is set.
1609  *
1610  * Since: 2.16
1611  */
1612 GIcon *
1613 gtk_action_get_gicon (GtkAction *action)
1614 {
1615   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1616
1617   return action->private_data->gicon;
1618 }
1619
1620 static void
1621 closure_accel_activate (GClosure     *closure,
1622                         GValue       *return_value,
1623                         guint         n_param_values,
1624                         const GValue *param_values,
1625                         gpointer      invocation_hint,
1626                         gpointer      marshal_data)
1627 {
1628   if (gtk_action_is_sensitive (GTK_ACTION (closure->data)))
1629     {
1630       _gtk_action_emit_activate (GTK_ACTION (closure->data));
1631       
1632       /* we handled the accelerator */
1633       g_value_set_boolean (return_value, TRUE);
1634     }
1635 }
1636
1637 static void
1638 gtk_action_set_action_group (GtkAction      *action,
1639                              GtkActionGroup *action_group)
1640 {
1641   if (action->private_data->action_group == NULL)
1642     g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1643   else
1644     g_return_if_fail (action_group == NULL);
1645
1646   action->private_data->action_group = action_group;
1647 }
1648
1649 /**
1650  * gtk_action_set_accel_path:
1651  * @action: the action object
1652  * @accel_path: the accelerator path
1653  *
1654  * Sets the accel path for this action.  All proxy widgets associated
1655  * with the action will have this accel path, so that their
1656  * accelerators are consistent.
1657  *
1658  * Note that @accel_path string will be stored in a #GQuark. Therefore, if you
1659  * pass a static string, you can save some memory by interning it first with 
1660  * g_intern_static_string().
1661  *
1662  * Since: 2.4
1663  */
1664 void
1665 gtk_action_set_accel_path (GtkAction   *action, 
1666                            const gchar *accel_path)
1667 {
1668   g_return_if_fail (GTK_IS_ACTION (action));
1669
1670   action->private_data->accel_quark = g_quark_from_string (accel_path);
1671 }
1672
1673 /**
1674  * gtk_action_get_accel_path:
1675  * @action: the action object
1676  *
1677  * Returns the accel path for this action.  
1678  *
1679  * Since: 2.6
1680  *
1681  * Returns: the accel path for this action, or %NULL
1682  *   if none is set. The returned string is owned by GTK+ 
1683  *   and must not be freed or modified.
1684  */
1685 G_CONST_RETURN gchar *
1686 gtk_action_get_accel_path (GtkAction *action)
1687 {
1688   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1689
1690   if (action->private_data->accel_quark)
1691     return g_quark_to_string (action->private_data->accel_quark);
1692   else
1693     return NULL;
1694 }
1695
1696 /**
1697  * gtk_action_get_accel_closure:
1698  * @action: the action object
1699  *
1700  * Returns the accel closure for this action.
1701  *
1702  * Since: 2.8
1703  *
1704  * Returns: the accel closure for this action. The returned closure is
1705  *          owned by GTK+ and must not be unreffed or modified.
1706  */
1707 GClosure *
1708 gtk_action_get_accel_closure (GtkAction *action)
1709 {
1710   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1711
1712   return action->private_data->accel_closure;
1713 }
1714
1715
1716 /**
1717  * gtk_action_set_accel_group:
1718  * @action: the action object
1719  * @accel_group: (allow-none): a #GtkAccelGroup or %NULL
1720  *
1721  * Sets the #GtkAccelGroup in which the accelerator for this action
1722  * will be installed.
1723  *
1724  * Since: 2.4
1725  **/
1726 void
1727 gtk_action_set_accel_group (GtkAction     *action,
1728                             GtkAccelGroup *accel_group)
1729 {
1730   g_return_if_fail (GTK_IS_ACTION (action));
1731   g_return_if_fail (accel_group == NULL || GTK_IS_ACCEL_GROUP (accel_group));
1732   
1733   if (accel_group)
1734     g_object_ref (accel_group);
1735   if (action->private_data->accel_group)
1736     g_object_unref (action->private_data->accel_group);
1737
1738   action->private_data->accel_group = accel_group;
1739 }
1740
1741 /**
1742  * gtk_action_connect_accelerator:
1743  * @action: a #GtkAction
1744  * 
1745  * Installs the accelerator for @action if @action has an
1746  * accel path and group. See gtk_action_set_accel_path() and 
1747  * gtk_action_set_accel_group()
1748  *
1749  * Since multiple proxies may independently trigger the installation
1750  * of the accelerator, the @action counts the number of times this
1751  * function has been called and doesn't remove the accelerator until
1752  * gtk_action_disconnect_accelerator() has been called as many times.
1753  *
1754  * Since: 2.4
1755  **/
1756 void 
1757 gtk_action_connect_accelerator (GtkAction *action)
1758 {
1759   g_return_if_fail (GTK_IS_ACTION (action));
1760
1761   if (!action->private_data->accel_quark ||
1762       !action->private_data->accel_group)
1763     return;
1764
1765   if (action->private_data->accel_count == 0)
1766     {
1767       const gchar *accel_path = 
1768         g_quark_to_string (action->private_data->accel_quark);
1769       
1770       gtk_accel_group_connect_by_path (action->private_data->accel_group,
1771                                        accel_path,
1772                                        action->private_data->accel_closure);
1773     }
1774
1775   action->private_data->accel_count++;
1776 }
1777
1778 /**
1779  * gtk_action_disconnect_accelerator:
1780  * @action: a #GtkAction
1781  * 
1782  * Undoes the effect of one call to gtk_action_connect_accelerator().
1783  *
1784  * Since: 2.4
1785  **/
1786 void 
1787 gtk_action_disconnect_accelerator (GtkAction *action)
1788 {
1789   g_return_if_fail (GTK_IS_ACTION (action));
1790
1791   if (!action->private_data->accel_quark ||
1792       !action->private_data->accel_group)
1793     return;
1794
1795   action->private_data->accel_count--;
1796
1797   if (action->private_data->accel_count == 0)
1798     gtk_accel_group_disconnect (action->private_data->accel_group,
1799                                 action->private_data->accel_closure);
1800 }
1801
1802 /**
1803  * gtk_action_create_menu:
1804  * @action: a #GtkAction
1805  *
1806  * If @action provides a #GtkMenu widget as a submenu for the menu
1807  * item or the toolbar item it creates, this function returns an
1808  * instance of that menu.
1809  *
1810  * Return value: the menu item provided by the action, or %NULL.
1811  *
1812  * Since: 2.12
1813  */
1814 GtkWidget *
1815 gtk_action_create_menu (GtkAction *action)
1816 {
1817   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1818
1819   if (GTK_ACTION_GET_CLASS (action)->create_menu)
1820     return GTK_ACTION_GET_CLASS (action)->create_menu (action);
1821
1822   return NULL;
1823 }
1824
1825 #define __GTK_ACTION_C__
1826 #include "gtkaliasdef.c"