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