]> Pileus Git - ~andy/gtk/blob - gtk/gtkaction.c
Add gtk_action_[sg]et_always_show_image()
[~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: the action object
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:
1262  *
1263  * Returns whether @action<!-- -->'s menu item proxies will ignore the
1264  * #GtkSettings:gtk-menu-images setting and always show their image, if available.
1265  *
1266  * Returns: %TRUE if the menu item proxies will always show their image
1267  *
1268  * Since: 2.20
1269  */
1270 gboolean
1271 gtk_action_get_always_show_image  (GtkAction *action)
1272 {
1273   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1274
1275   return action->private_data->always_show_image;
1276 }
1277
1278 /**
1279  * gtk_action_set_label:
1280  * @action: a #GtkAction
1281  * @label: the label text to set
1282  *
1283  * Sets the label of @action.
1284  *
1285  * Since: 2.16
1286  */
1287 void 
1288 gtk_action_set_label (GtkAction   *action,
1289                       const gchar *label)
1290 {
1291   gchar *tmp;
1292   
1293   g_return_if_fail (GTK_IS_ACTION (action));
1294   
1295   tmp = action->private_data->label;
1296   action->private_data->label = g_strdup (label);
1297   g_free (tmp);
1298   action->private_data->label_set = (action->private_data->label != NULL);
1299   /* if label is unset, then use the label from the stock item */
1300   if (!action->private_data->label_set && action->private_data->stock_id)
1301     {
1302       GtkStockItem stock_item;
1303       
1304       if (gtk_stock_lookup (action->private_data->stock_id, &stock_item))
1305         action->private_data->label = g_strdup (stock_item.label);
1306     }
1307
1308   g_object_notify (G_OBJECT (action), "label");
1309   
1310   /* if short_label is unset, set short_label=label */
1311   if (!action->private_data->short_label_set)
1312     {
1313       gtk_action_set_short_label (action, action->private_data->label);
1314       action->private_data->short_label_set = FALSE;
1315     }
1316 }
1317
1318 /**
1319  * gtk_action_get_label:
1320  * @action: a #GtkAction
1321  *
1322  * Gets the label text of @action.
1323  *
1324  * Returns: the label text
1325  *
1326  * Since: 2.16
1327  */
1328 G_CONST_RETURN gchar * 
1329 gtk_action_get_label (GtkAction *action)
1330 {
1331   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1332
1333   return action->private_data->label;
1334 }
1335
1336 /**
1337  * gtk_action_set_short_label:
1338  * @action: a #GtkAction
1339  * @short_label: the label text to set
1340  *
1341  * Sets a shorter label text on @action.
1342  *
1343  * Since: 2.16
1344  */
1345 void 
1346 gtk_action_set_short_label (GtkAction   *action,
1347                             const gchar *short_label)
1348 {
1349   gchar *tmp;
1350
1351   g_return_if_fail (GTK_IS_ACTION (action));
1352
1353   tmp = action->private_data->short_label;
1354   action->private_data->short_label = g_strdup (short_label);
1355   g_free (tmp);
1356   action->private_data->short_label_set = (action->private_data->short_label != NULL);
1357   /* if short_label is unset, then use the value of label */
1358   if (!action->private_data->short_label_set)
1359     action->private_data->short_label = g_strdup (action->private_data->label);
1360
1361   g_object_notify (G_OBJECT (action), "short-label");
1362 }
1363
1364 /**
1365  * gtk_action_get_short_label:
1366  * @action: a #GtkAction
1367  *
1368  * Gets the short label text of @action.
1369  *
1370  * Returns: the short label text.
1371  *
1372  * Since: 2.16
1373  */
1374 G_CONST_RETURN gchar * 
1375 gtk_action_get_short_label (GtkAction *action)
1376 {
1377   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1378
1379   return action->private_data->short_label;
1380 }
1381
1382 /**
1383  * gtk_action_set_visible_horizontal:
1384  * @action: a #GtkAction
1385  * @visible_horizontal: whether the action is visible horizontally
1386  *
1387  * Sets whether @action is visible when horizontal
1388  *
1389  * Since: 2.16
1390  */
1391 void 
1392 gtk_action_set_visible_horizontal (GtkAction *action,
1393                                    gboolean   visible_horizontal)
1394 {
1395   g_return_if_fail (GTK_IS_ACTION (action));
1396
1397   g_return_if_fail (GTK_IS_ACTION (action));
1398
1399   visible_horizontal = visible_horizontal != FALSE;
1400   
1401   if (action->private_data->visible_horizontal != visible_horizontal)
1402     {
1403       action->private_data->visible_horizontal = visible_horizontal;
1404       
1405       g_object_notify (G_OBJECT (action), "visible-horizontal");
1406     }  
1407 }
1408
1409 /**
1410  * gtk_action_get_visible_horizontal:
1411  * @action: a #GtkAction
1412  *
1413  * Checks whether @action is visible when horizontal
1414  * 
1415  * Returns: whether @action is visible when horizontal
1416  *
1417  * Since: 2.16
1418  */
1419 gboolean 
1420 gtk_action_get_visible_horizontal (GtkAction *action)
1421 {
1422   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1423
1424   return action->private_data->visible_horizontal;
1425 }
1426
1427 /**
1428  * gtk_action_set_visible_vertical:
1429  * @action: a #GtkAction
1430  * @visible_vertical: whether the action is visible vertically
1431  *
1432  * Sets whether @action is visible when vertical 
1433  *
1434  * Since: 2.16
1435  */
1436 void 
1437 gtk_action_set_visible_vertical (GtkAction *action,
1438                                  gboolean   visible_vertical)
1439 {
1440   g_return_if_fail (GTK_IS_ACTION (action));
1441
1442   g_return_if_fail (GTK_IS_ACTION (action));
1443
1444   visible_vertical = visible_vertical != FALSE;
1445   
1446   if (action->private_data->visible_vertical != visible_vertical)
1447     {
1448       action->private_data->visible_vertical = visible_vertical;
1449       
1450       g_object_notify (G_OBJECT (action), "visible-vertical");
1451     }  
1452 }
1453
1454 /**
1455  * gtk_action_get_visible_vertical:
1456  * @action: a #GtkAction
1457  *
1458  * Checks whether @action is visible when horizontal
1459  * 
1460  * Returns: whether @action is visible when horizontal
1461  *
1462  * Since: 2.16
1463  */
1464 gboolean 
1465 gtk_action_get_visible_vertical (GtkAction *action)
1466 {
1467   g_return_val_if_fail (GTK_IS_ACTION (action), FALSE);
1468
1469   return action->private_data->visible_vertical;
1470 }
1471
1472 /**
1473  * gtk_action_set_tooltip:
1474  * @action: a #GtkAction
1475  * @tooltip: the tooltip text
1476  *
1477  * Sets the tooltip text on @action
1478  *
1479  * Since: 2.16
1480  */
1481 void 
1482 gtk_action_set_tooltip (GtkAction   *action,
1483                         const gchar *tooltip)
1484 {
1485   gchar *tmp;
1486
1487   g_return_if_fail (GTK_IS_ACTION (action));
1488
1489   tmp = action->private_data->tooltip;
1490   action->private_data->tooltip = g_strdup (tooltip);
1491   g_free (tmp);
1492
1493   g_object_notify (G_OBJECT (action), "tooltip");
1494 }
1495
1496 /**
1497  * gtk_action_get_tooltip:
1498  * @action: a #GtkAction
1499  *
1500  * Gets the tooltip text of @action.
1501  *
1502  * Returns: the tooltip text
1503  *
1504  * Since: 2.16
1505  */
1506 G_CONST_RETURN gchar * 
1507 gtk_action_get_tooltip (GtkAction *action)
1508 {
1509   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1510
1511   return action->private_data->tooltip;
1512 }
1513
1514 /**
1515  * gtk_action_set_stock_id:
1516  * @action: a #GtkAction
1517  * @stock_id: the stock id
1518  *
1519  * Sets the stock id on @action
1520  *
1521  * Since: 2.16
1522  */
1523 void 
1524 gtk_action_set_stock_id (GtkAction   *action,
1525                          const gchar *stock_id)
1526 {
1527   gchar *tmp;
1528
1529   g_return_if_fail (GTK_IS_ACTION (action));
1530
1531   g_return_if_fail (GTK_IS_ACTION (action));
1532
1533   tmp = action->private_data->stock_id;
1534   action->private_data->stock_id = g_strdup (stock_id);
1535   g_free (tmp);
1536
1537   g_object_notify (G_OBJECT (action), "stock-id");
1538   
1539   /* update label and short_label if appropriate */
1540   if (!action->private_data->label_set)
1541     {
1542       GtkStockItem stock_item;
1543       
1544       if (action->private_data->stock_id &&
1545           gtk_stock_lookup (action->private_data->stock_id, &stock_item))
1546         gtk_action_set_label (action, stock_item.label);
1547       else 
1548         gtk_action_set_label (action, NULL);
1549       
1550       action->private_data->label_set = FALSE;
1551     }
1552 }
1553
1554 /**
1555  * gtk_action_get_stock_id:
1556  * @action: a #GtkAction
1557  *
1558  * Gets the stock id of @action.
1559  *
1560  * Returns: the stock id
1561  *
1562  * Since: 2.16
1563  */
1564 G_CONST_RETURN gchar * 
1565 gtk_action_get_stock_id (GtkAction *action)
1566 {
1567   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1568
1569   return action->private_data->stock_id;
1570 }
1571
1572 /**
1573  * gtk_action_set_icon_name:
1574  * @action: a #GtkAction
1575  * @icon_name: the icon name to set
1576  *
1577  * Sets the icon name on @action
1578  *
1579  * Since: 2.16
1580  */
1581 void 
1582 gtk_action_set_icon_name (GtkAction   *action,
1583                           const gchar *icon_name)
1584 {
1585   gchar *tmp;
1586
1587   g_return_if_fail (GTK_IS_ACTION (action));
1588
1589   tmp = action->private_data->icon_name;
1590   action->private_data->icon_name = g_strdup (icon_name);
1591   g_free (tmp);
1592
1593   g_object_notify (G_OBJECT (action), "icon-name");
1594 }
1595
1596 /**
1597  * gtk_action_get_icon_name:
1598  * @action: a #GtkAction
1599  *
1600  * Gets the icon name of @action.
1601  *
1602  * Returns: the icon name
1603  *
1604  * Since: 2.16
1605  */
1606 G_CONST_RETURN gchar * 
1607 gtk_action_get_icon_name (GtkAction *action)
1608 {
1609   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1610
1611   return action->private_data->icon_name;
1612 }
1613
1614 /**
1615  * gtk_action_set_gicon:
1616  * @action: a #GtkAction
1617  * @icon: the #GIcon to set
1618  *
1619  * Sets the icon of @action.
1620  *
1621  * Since: 2.16
1622  */
1623 void
1624 gtk_action_set_gicon (GtkAction *action,
1625                       GIcon     *icon)
1626 {
1627   g_return_if_fail (GTK_IS_ACTION (action));
1628
1629   if (action->private_data->gicon)
1630     g_object_unref (action->private_data->gicon);
1631
1632   action->private_data->gicon = icon;
1633
1634   if (action->private_data->gicon)
1635     g_object_ref (action->private_data->gicon);
1636
1637   g_object_notify (G_OBJECT (action), "gicon");
1638 }
1639
1640 /**
1641  * gtk_action_get_gicon:
1642  * @action: a #GtkAction
1643  *
1644  * Gets the gicon of @action.
1645  *
1646  * Returns: The action's #GIcon if one is set.
1647  *
1648  * Since: 2.16
1649  */
1650 GIcon *
1651 gtk_action_get_gicon (GtkAction *action)
1652 {
1653   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1654
1655   return action->private_data->gicon;
1656 }
1657
1658 /**
1659  * gtk_action_block_activate_from:
1660  * @action: the action object
1661  * @proxy: a proxy widget
1662  *
1663  * Disables calls to the gtk_action_activate()
1664  * function by signals on the given proxy widget.  This is used to
1665  * break notification loops for things like check or radio actions.
1666  *
1667  * This function is intended for use by action implementations.
1668  * 
1669  * Since: 2.4
1670  *
1671  * Deprecated: 2.16: activatables are now responsible for activating the
1672  * action directly so this doesnt apply anymore.
1673  */
1674 void
1675 gtk_action_block_activate_from (GtkAction *action, 
1676                                 GtkWidget *proxy)
1677 {
1678   g_return_if_fail (GTK_IS_ACTION (action));
1679   
1680   g_signal_handlers_block_by_func (proxy, G_CALLBACK (gtk_action_activate),
1681                                    action);
1682
1683   gtk_action_block_activate (action);
1684 }
1685
1686 /**
1687  * gtk_action_unblock_activate_from:
1688  * @action: the action object
1689  * @proxy: a proxy widget
1690  *
1691  * Re-enables calls to the gtk_action_activate()
1692  * function by signals on the given proxy widget.  This undoes the
1693  * blocking done by gtk_action_block_activate_from().
1694  *
1695  * This function is intended for use by action implementations.
1696  * 
1697  * Since: 2.4
1698  *
1699  * Deprecated: 2.16: activatables are now responsible for activating the
1700  * action directly so this doesnt apply anymore.
1701  */
1702 void
1703 gtk_action_unblock_activate_from (GtkAction *action, 
1704                                   GtkWidget *proxy)
1705 {
1706   g_return_if_fail (GTK_IS_ACTION (action));
1707
1708   g_signal_handlers_unblock_by_func (proxy, G_CALLBACK (gtk_action_activate),
1709                                      action);
1710
1711   gtk_action_unblock_activate (action);
1712 }
1713
1714 static void
1715 closure_accel_activate (GClosure     *closure,
1716                         GValue       *return_value,
1717                         guint         n_param_values,
1718                         const GValue *param_values,
1719                         gpointer      invocation_hint,
1720                         gpointer      marshal_data)
1721 {
1722   if (gtk_action_is_sensitive (GTK_ACTION (closure->data)))
1723     {
1724       _gtk_action_emit_activate (GTK_ACTION (closure->data));
1725       
1726       /* we handled the accelerator */
1727       g_value_set_boolean (return_value, TRUE);
1728     }
1729 }
1730
1731 static void
1732 gtk_action_set_action_group (GtkAction      *action,
1733                              GtkActionGroup *action_group)
1734 {
1735   if (action->private_data->action_group == NULL)
1736     g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1737   else
1738     g_return_if_fail (action_group == NULL);
1739
1740   action->private_data->action_group = action_group;
1741 }
1742
1743 /**
1744  * gtk_action_set_accel_path:
1745  * @action: the action object
1746  * @accel_path: the accelerator path
1747  *
1748  * Sets the accel path for this action.  All proxy widgets associated
1749  * with the action will have this accel path, so that their
1750  * accelerators are consistent.
1751  *
1752  * Note that @accel_path string will be stored in a #GQuark. Therefore, if you
1753  * pass a static string, you can save some memory by interning it first with 
1754  * g_intern_static_string().
1755  *
1756  * Since: 2.4
1757  */
1758 void
1759 gtk_action_set_accel_path (GtkAction   *action, 
1760                            const gchar *accel_path)
1761 {
1762   g_return_if_fail (GTK_IS_ACTION (action));
1763
1764   action->private_data->accel_quark = g_quark_from_string (accel_path);
1765 }
1766
1767 /**
1768  * gtk_action_get_accel_path:
1769  * @action: the action object
1770  *
1771  * Returns the accel path for this action.  
1772  *
1773  * Since: 2.6
1774  *
1775  * Returns: the accel path for this action, or %NULL
1776  *   if none is set. The returned string is owned by GTK+ 
1777  *   and must not be freed or modified.
1778  */
1779 G_CONST_RETURN gchar *
1780 gtk_action_get_accel_path (GtkAction *action)
1781 {
1782   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1783
1784   if (action->private_data->accel_quark)
1785     return g_quark_to_string (action->private_data->accel_quark);
1786   else
1787     return NULL;
1788 }
1789
1790 /**
1791  * gtk_action_get_accel_closure:
1792  * @action: the action object
1793  *
1794  * Returns the accel closure for this action.
1795  *
1796  * Since: 2.8
1797  *
1798  * Returns: the accel closure for this action. The returned closure is
1799  *          owned by GTK+ and must not be unreffed or modified.
1800  */
1801 GClosure *
1802 gtk_action_get_accel_closure (GtkAction *action)
1803 {
1804   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1805
1806   return action->private_data->accel_closure;
1807 }
1808
1809
1810 /**
1811  * gtk_action_set_accel_group:
1812  * @action: the action object
1813  * @accel_group: a #GtkAccelGroup or %NULL
1814  * 
1815  * Sets the #GtkAccelGroup in which the accelerator for this action
1816  * will be installed.
1817  *
1818  * Since: 2.4
1819  **/
1820 void
1821 gtk_action_set_accel_group (GtkAction     *action,
1822                             GtkAccelGroup *accel_group)
1823 {
1824   g_return_if_fail (GTK_IS_ACTION (action));
1825   g_return_if_fail (accel_group == NULL || GTK_IS_ACCEL_GROUP (accel_group));
1826   
1827   if (accel_group)
1828     g_object_ref (accel_group);
1829   if (action->private_data->accel_group)
1830     g_object_unref (action->private_data->accel_group);
1831
1832   action->private_data->accel_group = accel_group;
1833 }
1834
1835 /**
1836  * gtk_action_connect_accelerator:
1837  * @action: a #GtkAction
1838  * 
1839  * Installs the accelerator for @action if @action has an
1840  * accel path and group. See gtk_action_set_accel_path() and 
1841  * gtk_action_set_accel_group()
1842  *
1843  * Since multiple proxies may independently trigger the installation
1844  * of the accelerator, the @action counts the number of times this
1845  * function has been called and doesn't remove the accelerator until
1846  * gtk_action_disconnect_accelerator() has been called as many times.
1847  *
1848  * Since: 2.4
1849  **/
1850 void 
1851 gtk_action_connect_accelerator (GtkAction *action)
1852 {
1853   g_return_if_fail (GTK_IS_ACTION (action));
1854
1855   if (!action->private_data->accel_quark ||
1856       !action->private_data->accel_group)
1857     return;
1858
1859   if (action->private_data->accel_count == 0)
1860     {
1861       const gchar *accel_path = 
1862         g_quark_to_string (action->private_data->accel_quark);
1863       
1864       gtk_accel_group_connect_by_path (action->private_data->accel_group,
1865                                        accel_path,
1866                                        action->private_data->accel_closure);
1867     }
1868
1869   action->private_data->accel_count++;
1870 }
1871
1872 /**
1873  * gtk_action_disconnect_accelerator:
1874  * @action: a #GtkAction
1875  * 
1876  * Undoes the effect of one call to gtk_action_connect_accelerator().
1877  *
1878  * Since: 2.4
1879  **/
1880 void 
1881 gtk_action_disconnect_accelerator (GtkAction *action)
1882 {
1883   g_return_if_fail (GTK_IS_ACTION (action));
1884
1885   if (!action->private_data->accel_quark ||
1886       !action->private_data->accel_group)
1887     return;
1888
1889   action->private_data->accel_count--;
1890
1891   if (action->private_data->accel_count == 0)
1892     gtk_accel_group_disconnect (action->private_data->accel_group,
1893                                 action->private_data->accel_closure);
1894 }
1895
1896 /**
1897  * gtk_action_create_menu:
1898  * @action: a #GtkAction
1899  *
1900  * If @action provides a #GtkMenu widget as a submenu for the menu
1901  * item or the toolbar item it creates, this function returns an
1902  * instance of that menu.
1903  *
1904  * Return value: the menu item provided by the action, or %NULL.
1905  *
1906  * Since: 2.12
1907  */
1908 GtkWidget *
1909 gtk_action_create_menu (GtkAction *action)
1910 {
1911   g_return_val_if_fail (GTK_IS_ACTION (action), NULL);
1912
1913   if (GTK_ACTION_GET_CLASS (action)->create_menu)
1914     return GTK_ACTION_GET_CLASS (action)->create_menu (action);
1915
1916   return NULL;
1917 }
1918
1919 #define __GTK_ACTION_C__
1920 #include "gtkaliasdef.c"