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