]> Pileus Git - ~andy/gtk/blob - gtk/gtkaction.c
[docs] Move documentation to inline comments: GtkAction
[~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_connect_proxy:
964  * @action: the action object
965  * @proxy: the proxy widget
966  *
967  * Connects a widget to an action object as a proxy.  Synchronises 
968  * various properties of the action with the widget (such as label 
969  * text, icon, tooltip, etc), and attaches a callback so that the 
970  * action gets activated when the proxy widget does.
971  *
972  * If the widget is already connected to an action, it is disconnected
973  * first.
974  *
975  * Since: 2.4
976  *
977  * Deprecated: 2.16: Use gtk_activatable_set_related_action() instead.
978  */
979 void
980 gtk_action_connect_proxy (GtkAction *action,
981                           GtkWidget *proxy)
982 {
983   g_return_if_fail (GTK_IS_ACTION (action));
984   g_return_if_fail (GTK_IS_WIDGET (proxy));
985   g_return_if_fail (GTK_IS_ACTIVATABLE (proxy));
986
987   gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (proxy), TRUE);
988
989   gtk_activatable_set_related_action (GTK_ACTIVATABLE (proxy), action);
990 }
991
992 /**
993  * gtk_action_disconnect_proxy:
994  * @action: the action object
995  * @proxy: the proxy widget
996  *
997  * Disconnects a proxy widget from an action.  
998  * Does <emphasis>not</emphasis> destroy the widget, however.
999  *
1000  * Since: 2.4
1001  *
1002  * Deprecated: 2.16: Use gtk_activatable_set_related_action() instead.
1003  */
1004 void
1005 gtk_action_disconnect_proxy (GtkAction *action,
1006                              GtkWidget *proxy)
1007 {
1008   g_return_if_fail (GTK_IS_ACTION (action));
1009   g_return_if_fail (GTK_IS_WIDGET (proxy));
1010
1011   gtk_activatable_set_related_action (GTK_ACTIVATABLE (proxy), NULL);
1012 }
1013
1014 /**
1015  * gtk_action_get_proxies:
1016  * @action: the action object
1017  * 
1018  * Returns the proxy widgets for an action.
1019  * See also gtk_widget_get_action().
1020  *
1021  * Return value: (element-type GtkWidget) (transfer none): a #GSList of proxy widgets. The list is owned by GTK+
1022  * and must not be modified.
1023  *
1024  * Since: 2.4
1025  **/
1026 GSList*
1027 gtk_action_get_proxies (GtkAction *action)
1028 {
1029   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1030
1031   return action->private_data->proxies;
1032 }
1033
1034
1035 /**
1036  * gtk_widget_get_action:
1037  * @widget: a #GtkWidget
1038  *
1039  * Returns the #GtkAction that @widget is a proxy for. 
1040  * See also gtk_action_get_proxies().
1041  *
1042  * Returns: the action that a widget is a proxy for, or
1043  *  %NULL, if it is not attached to an action.
1044  *
1045  * Since: 2.10
1046  *
1047  * Deprecated: 2.16: Use gtk_activatable_get_related_action() instead.
1048  */
1049 GtkAction*
1050 gtk_widget_get_action (GtkWidget *widget)
1051 {
1052   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
1053
1054   if (GTK_IS_ACTIVATABLE (widget))
1055     return gtk_activatable_get_related_action (GTK_ACTIVATABLE (widget));
1056
1057   return NULL;
1058 }
1059
1060 /**
1061  * gtk_action_get_name:
1062  * @action: the action object
1063  * 
1064  * Returns the name of the action.
1065  * 
1066  * Return value: the name of the action. The string belongs to GTK+ and should not
1067  *   be freed.
1068  *
1069  * Since: 2.4
1070  **/
1071 G_CONST_RETURN gchar *
1072 gtk_action_get_name (GtkAction *action)
1073 {
1074   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1075
1076   return action->private_data->name;
1077 }
1078
1079 /**
1080  * gtk_action_is_sensitive:
1081  * @action: the action object
1082  * 
1083  * Returns whether the action is effectively sensitive.
1084  *
1085  * Return value: %TRUE if the action and its associated action group 
1086  * are both sensitive.
1087  *
1088  * Since: 2.4
1089  **/
1090 gboolean
1091 gtk_action_is_sensitive (GtkAction *action)
1092 {
1093   GtkActionPrivate *priv;
1094   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1095
1096   priv = action->private_data;
1097   return priv->sensitive &&
1098     (priv->action_group == NULL ||
1099      gtk_action_group_get_sensitive (priv->action_group));
1100 }
1101
1102 /**
1103  * gtk_action_get_sensitive:
1104  * @action: the action object
1105  * 
1106  * Returns whether the action itself is sensitive. Note that this doesn't 
1107  * necessarily mean effective sensitivity. See gtk_action_is_sensitive() 
1108  * for that.
1109  *
1110  * Return value: %TRUE if the action itself is sensitive.
1111  *
1112  * Since: 2.4
1113  **/
1114 gboolean
1115 gtk_action_get_sensitive (GtkAction *action)
1116 {
1117   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1118
1119   return action->private_data->sensitive;
1120 }
1121
1122 /**
1123  * gtk_action_set_sensitive:
1124  * @action: the action object
1125  * @sensitive: %TRUE to make the action sensitive
1126  * 
1127  * Sets the ::sensitive property of the action to @sensitive. Note that 
1128  * this doesn't necessarily mean effective sensitivity. See 
1129  * gtk_action_is_sensitive() 
1130  * for that.
1131  *
1132  * Since: 2.6
1133  **/
1134 void
1135 gtk_action_set_sensitive (GtkAction *action,
1136                           gboolean   sensitive)
1137 {
1138   g_return_if_fail (GTK_IS_ACTION (action));
1139
1140   sensitive = sensitive != FALSE;
1141   
1142   if (action->private_data->sensitive != sensitive)
1143     {
1144       action->private_data->sensitive = sensitive;
1145
1146       g_object_notify (G_OBJECT (action), "sensitive");
1147     }
1148 }
1149
1150 /**
1151  * gtk_action_is_visible:
1152  * @action: the action object
1153  * 
1154  * Returns whether the action is effectively visible.
1155  *
1156  * Return value: %TRUE if the action and its associated action group 
1157  * are both visible.
1158  *
1159  * Since: 2.4
1160  **/
1161 gboolean
1162 gtk_action_is_visible (GtkAction *action)
1163 {
1164   GtkActionPrivate *priv;
1165   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1166
1167   priv = action->private_data;
1168   return priv->visible &&
1169     (priv->action_group == NULL ||
1170      gtk_action_group_get_visible (priv->action_group));
1171 }
1172
1173 /**
1174  * gtk_action_get_visible:
1175  * @action: the action object
1176  * 
1177  * Returns whether the action itself is visible. Note that this doesn't 
1178  * necessarily mean effective visibility. See gtk_action_is_sensitive() 
1179  * for that.
1180  *
1181  * Return value: %TRUE if the action itself is visible.
1182  *
1183  * Since: 2.4
1184  **/
1185 gboolean
1186 gtk_action_get_visible (GtkAction *action)
1187 {
1188   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1189
1190   return action->private_data->visible;
1191 }
1192
1193 /**
1194  * gtk_action_set_visible:
1195  * @action: the action object
1196  * @visible: %TRUE to make the action visible
1197  * 
1198  * Sets the ::visible property of the action to @visible. Note that 
1199  * this doesn't necessarily mean effective visibility. See 
1200  * gtk_action_is_visible() 
1201  * for that.
1202  *
1203  * Since: 2.6
1204  **/
1205 void
1206 gtk_action_set_visible (GtkAction *action,
1207                         gboolean   visible)
1208 {
1209   g_return_if_fail (GTK_IS_ACTION (action));
1210
1211   visible = visible != FALSE;
1212   
1213   if (action->private_data->visible != visible)
1214     {
1215       action->private_data->visible = visible;
1216
1217       g_object_notify (G_OBJECT (action), "visible");
1218     }
1219 }
1220 /**
1221  * gtk_action_set_is_important:
1222  * @action: the action object
1223  * @is_important: %TRUE to make the action important
1224  *
1225  * Sets whether the action is important, this attribute is used
1226  * primarily by toolbar items to decide whether to show a label
1227  * or not.
1228  *
1229  * Since: 2.16
1230  */
1231 void 
1232 gtk_action_set_is_important (GtkAction *action,
1233                              gboolean   is_important)
1234 {
1235   g_return_if_fail (GTK_IS_ACTION (action));
1236
1237   is_important = is_important != FALSE;
1238   
1239   if (action->private_data->is_important != is_important)
1240     {
1241       action->private_data->is_important = is_important;
1242       
1243       g_object_notify (G_OBJECT (action), "is-important");
1244     }  
1245 }
1246
1247 /**
1248  * gtk_action_get_is_important:
1249  * @action: a #GtkAction
1250  *
1251  * Checks whether @action is important or not
1252  * 
1253  * Returns: whether @action is important
1254  *
1255  * Since: 2.16
1256  */
1257 gboolean 
1258 gtk_action_get_is_important (GtkAction *action)
1259 {
1260   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1261
1262   return action->private_data->is_important;
1263 }
1264
1265 /**
1266  * gtk_action_set_always_show_image:
1267  * @action: a #GtkAction
1268  * @always_show: %TRUE if menuitem proxies should always show their image
1269  *
1270  * Sets whether @action<!-- -->'s menu item proxies will ignore the
1271  * #GtkSettings:gtk-menu-images setting and always show their image, if available.
1272  *
1273  * Use this if the menu item would be useless or hard to use
1274  * without their image.
1275  *
1276  * Since: 2.20
1277  */
1278 void
1279 gtk_action_set_always_show_image (GtkAction *action,
1280                                   gboolean   always_show)
1281 {
1282   GtkActionPrivate *priv;
1283
1284   g_return_if_fail (GTK_IS_ACTION (action));
1285
1286   priv = action->private_data;
1287
1288   always_show = always_show != FALSE;
1289   
1290   if (priv->always_show_image != always_show)
1291     {
1292       priv->always_show_image = always_show;
1293
1294       g_object_notify (G_OBJECT (action), "always-show-image");
1295     }
1296 }
1297
1298 /**
1299  * gtk_action_get_always_show_image:
1300  * @action: a #GtkAction
1301  *
1302  * Returns whether @action<!-- -->'s menu item proxies will ignore the
1303  * #GtkSettings:gtk-menu-images setting and always show their image,
1304  * if available.
1305  *
1306  * Returns: %TRUE if the menu item proxies will always show their image
1307  *
1308  * Since: 2.20
1309  */
1310 gboolean
1311 gtk_action_get_always_show_image  (GtkAction *action)
1312 {
1313   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1314
1315   return action->private_data->always_show_image;
1316 }
1317
1318 /**
1319  * gtk_action_set_label:
1320  * @action: a #GtkAction
1321  * @label: the label text to set
1322  *
1323  * Sets the label of @action.
1324  *
1325  * Since: 2.16
1326  */
1327 void 
1328 gtk_action_set_label (GtkAction   *action,
1329                       const gchar *label)
1330 {
1331   gchar *tmp;
1332   
1333   g_return_if_fail (GTK_IS_ACTION (action));
1334   
1335   tmp = action->private_data->label;
1336   action->private_data->label = g_strdup (label);
1337   g_free (tmp);
1338   action->private_data->label_set = (action->private_data->label != NULL);
1339   /* if label is unset, then use the label from the stock item */
1340   if (!action->private_data->label_set && action->private_data->stock_id)
1341     {
1342       GtkStockItem stock_item;
1343       
1344       if (gtk_stock_lookup (action->private_data->stock_id, &stock_item))
1345         action->private_data->label = g_strdup (stock_item.label);
1346     }
1347
1348   g_object_notify (G_OBJECT (action), "label");
1349   
1350   /* if short_label is unset, set short_label=label */
1351   if (!action->private_data->short_label_set)
1352     {
1353       gtk_action_set_short_label (action, action->private_data->label);
1354       action->private_data->short_label_set = FALSE;
1355     }
1356 }
1357
1358 /**
1359  * gtk_action_get_label:
1360  * @action: a #GtkAction
1361  *
1362  * Gets the label text of @action.
1363  *
1364  * Returns: the label text
1365  *
1366  * Since: 2.16
1367  */
1368 G_CONST_RETURN gchar * 
1369 gtk_action_get_label (GtkAction *action)
1370 {
1371   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1372
1373   return action->private_data->label;
1374 }
1375
1376 /**
1377  * gtk_action_set_short_label:
1378  * @action: a #GtkAction
1379  * @short_label: the label text to set
1380  *
1381  * Sets a shorter label text on @action.
1382  *
1383  * Since: 2.16
1384  */
1385 void 
1386 gtk_action_set_short_label (GtkAction   *action,
1387                             const gchar *short_label)
1388 {
1389   gchar *tmp;
1390
1391   g_return_if_fail (GTK_IS_ACTION (action));
1392
1393   tmp = action->private_data->short_label;
1394   action->private_data->short_label = g_strdup (short_label);
1395   g_free (tmp);
1396   action->private_data->short_label_set = (action->private_data->short_label != NULL);
1397   /* if short_label is unset, then use the value of label */
1398   if (!action->private_data->short_label_set)
1399     action->private_data->short_label = g_strdup (action->private_data->label);
1400
1401   g_object_notify (G_OBJECT (action), "short-label");
1402 }
1403
1404 /**
1405  * gtk_action_get_short_label:
1406  * @action: a #GtkAction
1407  *
1408  * Gets the short label text of @action.
1409  *
1410  * Returns: the short label text.
1411  *
1412  * Since: 2.16
1413  */
1414 G_CONST_RETURN gchar * 
1415 gtk_action_get_short_label (GtkAction *action)
1416 {
1417   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1418
1419   return action->private_data->short_label;
1420 }
1421
1422 /**
1423  * gtk_action_set_visible_horizontal:
1424  * @action: a #GtkAction
1425  * @visible_horizontal: whether the action is visible horizontally
1426  *
1427  * Sets whether @action is visible when horizontal
1428  *
1429  * Since: 2.16
1430  */
1431 void 
1432 gtk_action_set_visible_horizontal (GtkAction *action,
1433                                    gboolean   visible_horizontal)
1434 {
1435   g_return_if_fail (GTK_IS_ACTION (action));
1436
1437   g_return_if_fail (GTK_IS_ACTION (action));
1438
1439   visible_horizontal = visible_horizontal != FALSE;
1440   
1441   if (action->private_data->visible_horizontal != visible_horizontal)
1442     {
1443       action->private_data->visible_horizontal = visible_horizontal;
1444       
1445       g_object_notify (G_OBJECT (action), "visible-horizontal");
1446     }  
1447 }
1448
1449 /**
1450  * gtk_action_get_visible_horizontal:
1451  * @action: a #GtkAction
1452  *
1453  * Checks whether @action is visible when horizontal
1454  * 
1455  * Returns: whether @action is visible when horizontal
1456  *
1457  * Since: 2.16
1458  */
1459 gboolean 
1460 gtk_action_get_visible_horizontal (GtkAction *action)
1461 {
1462   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1463
1464   return action->private_data->visible_horizontal;
1465 }
1466
1467 /**
1468  * gtk_action_set_visible_vertical:
1469  * @action: a #GtkAction
1470  * @visible_vertical: whether the action is visible vertically
1471  *
1472  * Sets whether @action is visible when vertical 
1473  *
1474  * Since: 2.16
1475  */
1476 void 
1477 gtk_action_set_visible_vertical (GtkAction *action,
1478                                  gboolean   visible_vertical)
1479 {
1480   g_return_if_fail (GTK_IS_ACTION (action));
1481
1482   g_return_if_fail (GTK_IS_ACTION (action));
1483
1484   visible_vertical = visible_vertical != FALSE;
1485   
1486   if (action->private_data->visible_vertical != visible_vertical)
1487     {
1488       action->private_data->visible_vertical = visible_vertical;
1489       
1490       g_object_notify (G_OBJECT (action), "visible-vertical");
1491     }  
1492 }
1493
1494 /**
1495  * gtk_action_get_visible_vertical:
1496  * @action: a #GtkAction
1497  *
1498  * Checks whether @action is visible when horizontal
1499  * 
1500  * Returns: whether @action is visible when horizontal
1501  *
1502  * Since: 2.16
1503  */
1504 gboolean 
1505 gtk_action_get_visible_vertical (GtkAction *action)
1506 {
1507   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1508
1509   return action->private_data->visible_vertical;
1510 }
1511
1512 /**
1513  * gtk_action_set_tooltip:
1514  * @action: a #GtkAction
1515  * @tooltip: the tooltip text
1516  *
1517  * Sets the tooltip text on @action
1518  *
1519  * Since: 2.16
1520  */
1521 void 
1522 gtk_action_set_tooltip (GtkAction   *action,
1523                         const gchar *tooltip)
1524 {
1525   gchar *tmp;
1526
1527   g_return_if_fail (GTK_IS_ACTION (action));
1528
1529   tmp = action->private_data->tooltip;
1530   action->private_data->tooltip = g_strdup (tooltip);
1531   g_free (tmp);
1532
1533   g_object_notify (G_OBJECT (action), "tooltip");
1534 }
1535
1536 /**
1537  * gtk_action_get_tooltip:
1538  * @action: a #GtkAction
1539  *
1540  * Gets the tooltip text of @action.
1541  *
1542  * Returns: the tooltip text
1543  *
1544  * Since: 2.16
1545  */
1546 G_CONST_RETURN gchar * 
1547 gtk_action_get_tooltip (GtkAction *action)
1548 {
1549   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1550
1551   return action->private_data->tooltip;
1552 }
1553
1554 /**
1555  * gtk_action_set_stock_id:
1556  * @action: a #GtkAction
1557  * @stock_id: the stock id
1558  *
1559  * Sets the stock id on @action
1560  *
1561  * Since: 2.16
1562  */
1563 void 
1564 gtk_action_set_stock_id (GtkAction   *action,
1565                          const gchar *stock_id)
1566 {
1567   gchar *tmp;
1568
1569   g_return_if_fail (GTK_IS_ACTION (action));
1570
1571   g_return_if_fail (GTK_IS_ACTION (action));
1572
1573   tmp = action->private_data->stock_id;
1574   action->private_data->stock_id = g_strdup (stock_id);
1575   g_free (tmp);
1576
1577   g_object_notify (G_OBJECT (action), "stock-id");
1578   
1579   /* update label and short_label if appropriate */
1580   if (!action->private_data->label_set)
1581     {
1582       GtkStockItem stock_item;
1583       
1584       if (action->private_data->stock_id &&
1585           gtk_stock_lookup (action->private_data->stock_id, &stock_item))
1586         gtk_action_set_label (action, stock_item.label);
1587       else 
1588         gtk_action_set_label (action, NULL);
1589       
1590       action->private_data->label_set = FALSE;
1591     }
1592 }
1593
1594 /**
1595  * gtk_action_get_stock_id:
1596  * @action: a #GtkAction
1597  *
1598  * Gets the stock id of @action.
1599  *
1600  * Returns: the stock id
1601  *
1602  * Since: 2.16
1603  */
1604 G_CONST_RETURN gchar * 
1605 gtk_action_get_stock_id (GtkAction *action)
1606 {
1607   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1608
1609   return action->private_data->stock_id;
1610 }
1611
1612 /**
1613  * gtk_action_set_icon_name:
1614  * @action: a #GtkAction
1615  * @icon_name: the icon name to set
1616  *
1617  * Sets the icon name on @action
1618  *
1619  * Since: 2.16
1620  */
1621 void 
1622 gtk_action_set_icon_name (GtkAction   *action,
1623                           const gchar *icon_name)
1624 {
1625   gchar *tmp;
1626
1627   g_return_if_fail (GTK_IS_ACTION (action));
1628
1629   tmp = action->private_data->icon_name;
1630   action->private_data->icon_name = g_strdup (icon_name);
1631   g_free (tmp);
1632
1633   g_object_notify (G_OBJECT (action), "icon-name");
1634 }
1635
1636 /**
1637  * gtk_action_get_icon_name:
1638  * @action: a #GtkAction
1639  *
1640  * Gets the icon name of @action.
1641  *
1642  * Returns: the icon name
1643  *
1644  * Since: 2.16
1645  */
1646 G_CONST_RETURN gchar * 
1647 gtk_action_get_icon_name (GtkAction *action)
1648 {
1649   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1650
1651   return action->private_data->icon_name;
1652 }
1653
1654 /**
1655  * gtk_action_set_gicon:
1656  * @action: a #GtkAction
1657  * @icon: the #GIcon to set
1658  *
1659  * Sets the icon of @action.
1660  *
1661  * Since: 2.16
1662  */
1663 void
1664 gtk_action_set_gicon (GtkAction *action,
1665                       GIcon     *icon)
1666 {
1667   g_return_if_fail (GTK_IS_ACTION (action));
1668
1669   if (action->private_data->gicon)
1670     g_object_unref (action->private_data->gicon);
1671
1672   action->private_data->gicon = icon;
1673
1674   if (action->private_data->gicon)
1675     g_object_ref (action->private_data->gicon);
1676
1677   g_object_notify (G_OBJECT (action), "gicon");
1678 }
1679
1680 /**
1681  * gtk_action_get_gicon:
1682  * @action: a #GtkAction
1683  *
1684  * Gets the gicon of @action.
1685  *
1686  * Returns: The action's #GIcon if one is set.
1687  *
1688  * Since: 2.16
1689  */
1690 GIcon *
1691 gtk_action_get_gicon (GtkAction *action)
1692 {
1693   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1694
1695   return action->private_data->gicon;
1696 }
1697
1698 /**
1699  * gtk_action_block_activate_from:
1700  * @action: the action object
1701  * @proxy: a proxy widget
1702  *
1703  * Disables calls to the gtk_action_activate()
1704  * function by signals on the given proxy widget.  This is used to
1705  * break notification loops for things like check or radio actions.
1706  *
1707  * This function is intended for use by action implementations.
1708  * 
1709  * Since: 2.4
1710  *
1711  * Deprecated: 2.16: activatables are now responsible for activating the
1712  * action directly so this doesnt apply anymore.
1713  */
1714 void
1715 gtk_action_block_activate_from (GtkAction *action, 
1716                                 GtkWidget *proxy)
1717 {
1718   g_return_if_fail (GTK_IS_ACTION (action));
1719   
1720   g_signal_handlers_block_by_func (proxy, G_CALLBACK (gtk_action_activate),
1721                                    action);
1722
1723   gtk_action_block_activate (action);
1724 }
1725
1726 /**
1727  * gtk_action_unblock_activate_from:
1728  * @action: the action object
1729  * @proxy: a proxy widget
1730  *
1731  * Re-enables calls to the gtk_action_activate()
1732  * function by signals on the given proxy widget.  This undoes the
1733  * blocking done by gtk_action_block_activate_from().
1734  *
1735  * This function is intended for use by action implementations.
1736  * 
1737  * Since: 2.4
1738  *
1739  * Deprecated: 2.16: activatables are now responsible for activating the
1740  * action directly so this doesnt apply anymore.
1741  */
1742 void
1743 gtk_action_unblock_activate_from (GtkAction *action, 
1744                                   GtkWidget *proxy)
1745 {
1746   g_return_if_fail (GTK_IS_ACTION (action));
1747
1748   g_signal_handlers_unblock_by_func (proxy, G_CALLBACK (gtk_action_activate),
1749                                      action);
1750
1751   gtk_action_unblock_activate (action);
1752 }
1753
1754 static void
1755 closure_accel_activate (GClosure     *closure,
1756                         GValue       *return_value,
1757                         guint         n_param_values,
1758                         const GValue *param_values,
1759                         gpointer      invocation_hint,
1760                         gpointer      marshal_data)
1761 {
1762   if (gtk_action_is_sensitive (GTK_ACTION (closure->data)))
1763     {
1764       _gtk_action_emit_activate (GTK_ACTION (closure->data));
1765       
1766       /* we handled the accelerator */
1767       g_value_set_boolean (return_value, TRUE);
1768     }
1769 }
1770
1771 static void
1772 gtk_action_set_action_group (GtkAction      *action,
1773                              GtkActionGroup *action_group)
1774 {
1775   if (action->private_data->action_group == NULL)
1776     g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1777   else
1778     g_return_if_fail (action_group == NULL);
1779
1780   action->private_data->action_group = action_group;
1781 }
1782
1783 /**
1784  * gtk_action_set_accel_path:
1785  * @action: the action object
1786  * @accel_path: the accelerator path
1787  *
1788  * Sets the accel path for this action.  All proxy widgets associated
1789  * with the action will have this accel path, so that their
1790  * accelerators are consistent.
1791  *
1792  * Note that @accel_path string will be stored in a #GQuark. Therefore, if you
1793  * pass a static string, you can save some memory by interning it first with 
1794  * g_intern_static_string().
1795  *
1796  * Since: 2.4
1797  */
1798 void
1799 gtk_action_set_accel_path (GtkAction   *action, 
1800                            const gchar *accel_path)
1801 {
1802   g_return_if_fail (GTK_IS_ACTION (action));
1803
1804   action->private_data->accel_quark = g_quark_from_string (accel_path);
1805 }
1806
1807 /**
1808  * gtk_action_get_accel_path:
1809  * @action: the action object
1810  *
1811  * Returns the accel path for this action.  
1812  *
1813  * Since: 2.6
1814  *
1815  * Returns: the accel path for this action, or %NULL
1816  *   if none is set. The returned string is owned by GTK+ 
1817  *   and must not be freed or modified.
1818  */
1819 G_CONST_RETURN gchar *
1820 gtk_action_get_accel_path (GtkAction *action)
1821 {
1822   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1823
1824   if (action->private_data->accel_quark)
1825     return g_quark_to_string (action->private_data->accel_quark);
1826   else
1827     return NULL;
1828 }
1829
1830 /**
1831  * gtk_action_get_accel_closure:
1832  * @action: the action object
1833  *
1834  * Returns the accel closure for this action.
1835  *
1836  * Since: 2.8
1837  *
1838  * Returns: the accel closure for this action. The returned closure is
1839  *          owned by GTK+ and must not be unreffed or modified.
1840  */
1841 GClosure *
1842 gtk_action_get_accel_closure (GtkAction *action)
1843 {
1844   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1845
1846   return action->private_data->accel_closure;
1847 }
1848
1849
1850 /**
1851  * gtk_action_set_accel_group:
1852  * @action: the action object
1853  * @accel_group: (allow-none): a #GtkAccelGroup or %NULL
1854  *
1855  * Sets the #GtkAccelGroup in which the accelerator for this action
1856  * will be installed.
1857  *
1858  * Since: 2.4
1859  **/
1860 void
1861 gtk_action_set_accel_group (GtkAction     *action,
1862                             GtkAccelGroup *accel_group)
1863 {
1864   g_return_if_fail (GTK_IS_ACTION (action));
1865   g_return_if_fail (accel_group == NULL || GTK_IS_ACCEL_GROUP (accel_group));
1866   
1867   if (accel_group)
1868     g_object_ref (accel_group);
1869   if (action->private_data->accel_group)
1870     g_object_unref (action->private_data->accel_group);
1871
1872   action->private_data->accel_group = accel_group;
1873 }
1874
1875 /**
1876  * gtk_action_connect_accelerator:
1877  * @action: a #GtkAction
1878  * 
1879  * Installs the accelerator for @action if @action has an
1880  * accel path and group. See gtk_action_set_accel_path() and 
1881  * gtk_action_set_accel_group()
1882  *
1883  * Since multiple proxies may independently trigger the installation
1884  * of the accelerator, the @action counts the number of times this
1885  * function has been called and doesn't remove the accelerator until
1886  * gtk_action_disconnect_accelerator() has been called as many times.
1887  *
1888  * Since: 2.4
1889  **/
1890 void 
1891 gtk_action_connect_accelerator (GtkAction *action)
1892 {
1893   g_return_if_fail (GTK_IS_ACTION (action));
1894
1895   if (!action->private_data->accel_quark ||
1896       !action->private_data->accel_group)
1897     return;
1898
1899   if (action->private_data->accel_count == 0)
1900     {
1901       const gchar *accel_path = 
1902         g_quark_to_string (action->private_data->accel_quark);
1903       
1904       gtk_accel_group_connect_by_path (action->private_data->accel_group,
1905                                        accel_path,
1906                                        action->private_data->accel_closure);
1907     }
1908
1909   action->private_data->accel_count++;
1910 }
1911
1912 /**
1913  * gtk_action_disconnect_accelerator:
1914  * @action: a #GtkAction
1915  * 
1916  * Undoes the effect of one call to gtk_action_connect_accelerator().
1917  *
1918  * Since: 2.4
1919  **/
1920 void 
1921 gtk_action_disconnect_accelerator (GtkAction *action)
1922 {
1923   g_return_if_fail (GTK_IS_ACTION (action));
1924
1925   if (!action->private_data->accel_quark ||
1926       !action->private_data->accel_group)
1927     return;
1928
1929   action->private_data->accel_count--;
1930
1931   if (action->private_data->accel_count == 0)
1932     gtk_accel_group_disconnect (action->private_data->accel_group,
1933                                 action->private_data->accel_closure);
1934 }
1935
1936 /**
1937  * gtk_action_create_menu:
1938  * @action: a #GtkAction
1939  *
1940  * If @action provides a #GtkMenu widget as a submenu for the menu
1941  * item or the toolbar item it creates, this function returns an
1942  * instance of that menu.
1943  *
1944  * Return value: the menu item provided by the action, or %NULL.
1945  *
1946  * Since: 2.12
1947  */
1948 GtkWidget *
1949 gtk_action_create_menu (GtkAction *action)
1950 {
1951   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1952
1953   if (GTK_ACTION_GET_CLASS (action)->create_menu)
1954     return GTK_ACTION_GET_CLASS (action)->create_menu (action);
1955
1956   return NULL;
1957 }
1958
1959 #define __GTK_ACTION_C__
1960 #include "gtkaliasdef.c"