2 * GTK - The GIMP Toolkit
3 * Copyright (C) 1998, 1999 Red Hat, Inc.
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.
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.
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.
23 * Author: James Henstridge <james@daa.com.au>
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/.
34 #include "gtkactiongroup.h"
35 #include "gtkbuildable.h"
36 #include "gtkiconfactory.h"
37 #include "gtkicontheme.h"
39 #include "gtktoggleaction.h"
40 #include "gtkradioaction.h"
41 #include "gtkaccelmap.h"
42 #include "gtkmarshalers.h"
43 #include "gtkbuilderprivate.h"
44 #include "gtkprivate.h"
48 #define GTK_ACTION_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ACTION_GROUP, GtkActionGroupPrivate))
50 struct _GtkActionGroupPrivate
57 GtkTranslateFunc translate_func;
58 gpointer translate_data;
59 GDestroyNotify translate_notify;
79 static void gtk_action_group_init (GtkActionGroup *self);
80 static void gtk_action_group_class_init (GtkActionGroupClass *class);
81 static void gtk_action_group_finalize (GObject *object);
82 static void gtk_action_group_set_property (GObject *object,
86 static void gtk_action_group_get_property (GObject *object,
90 static GtkAction *gtk_action_group_real_get_action (GtkActionGroup *self,
94 static void gtk_action_group_buildable_init (GtkBuildableIface *iface);
95 static void gtk_action_group_buildable_add_child (GtkBuildable *buildable,
99 static void gtk_action_group_buildable_set_name (GtkBuildable *buildable,
101 static const gchar* gtk_action_group_buildable_get_name (GtkBuildable *buildable);
102 static gboolean gtk_action_group_buildable_custom_tag_start (GtkBuildable *buildable,
105 const gchar *tagname,
106 GMarkupParser *parser,
108 static void gtk_action_group_buildable_custom_tag_end (GtkBuildable *buildable,
111 const gchar *tagname,
112 gpointer *user_data);
115 gtk_action_group_get_type (void)
117 static GType type = 0;
121 const GTypeInfo type_info =
123 sizeof (GtkActionGroupClass),
124 NULL, /* base_init */
125 NULL, /* base_finalize */
126 (GClassInitFunc) gtk_action_group_class_init,
127 NULL, /* class_finalize */
128 NULL, /* class_data */
129 sizeof (GtkActionGroup),
131 (GInstanceInitFunc) gtk_action_group_init,
134 static const GInterfaceInfo buildable_info =
136 (GInterfaceInitFunc) gtk_action_group_buildable_init,
141 type = g_type_register_static (G_TYPE_OBJECT, I_("GtkActionGroup"),
144 g_type_add_interface_static (type,
151 static GObjectClass *parent_class = NULL;
152 static guint action_group_signals[LAST_SIGNAL] = { 0 };
155 gtk_action_group_class_init (GtkActionGroupClass *klass)
157 GObjectClass *gobject_class;
159 gobject_class = G_OBJECT_CLASS (klass);
160 parent_class = g_type_class_peek_parent (klass);
162 gobject_class->finalize = gtk_action_group_finalize;
163 gobject_class->set_property = gtk_action_group_set_property;
164 gobject_class->get_property = gtk_action_group_get_property;
165 klass->get_action = gtk_action_group_real_get_action;
167 g_object_class_install_property (gobject_class,
169 g_param_spec_string ("name",
171 P_("A name for the action group."),
173 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
174 g_object_class_install_property (gobject_class,
176 g_param_spec_boolean ("sensitive",
178 P_("Whether the action group is enabled."),
180 GTK_PARAM_READWRITE));
181 g_object_class_install_property (gobject_class,
183 g_param_spec_boolean ("visible",
185 P_("Whether the action group is visible."),
187 GTK_PARAM_READWRITE));
190 * GtkActionGroup::connect-proxy:
191 * @action_group: the group
192 * @action: the action
195 * The connect_proxy signal is emitted after connecting a proxy to
196 * an action in the group. Note that the proxy may have been connected
197 * to a different action before.
199 * This is intended for simple customizations for which a custom action
200 * class would be too clumsy, e.g. showing tooltips for menuitems in the
203 * #GtkUIManager proxies the signal and provides global notification
204 * just before any action is connected to a proxy, which is probably more
209 action_group_signals[CONNECT_PROXY] =
210 g_signal_new (I_("connect_proxy"),
211 G_OBJECT_CLASS_TYPE (klass),
213 _gtk_marshal_VOID__OBJECT_OBJECT,
215 GTK_TYPE_ACTION, GTK_TYPE_WIDGET);
218 * GtkActionGroup::disconnect-proxy:
219 * @action_group: the group
220 * @action: the action
223 * The disconnect_proxy signal is emitted after disconnecting a proxy
224 * from an action in the group.
226 * #GtkUIManager proxies the signal and provides global notification
227 * just before any action is connected to a proxy, which is probably more
232 action_group_signals[DISCONNECT_PROXY] =
233 g_signal_new (I_("disconnect_proxy"),
234 G_OBJECT_CLASS_TYPE (klass),
236 _gtk_marshal_VOID__OBJECT_OBJECT,
238 GTK_TYPE_ACTION, GTK_TYPE_WIDGET);
241 * GtkActionGroup::pre-activate:
242 * @action_group: the group
243 * @action: the action
245 * The pre_activate signal is emitted just before the @action in the
246 * @action_group is activated
248 * This is intended for #GtkUIManager to proxy the signal and provide global
249 * notification just before any action is activated.
253 action_group_signals[PRE_ACTIVATE] =
254 g_signal_new (I_("pre_activate"),
255 G_OBJECT_CLASS_TYPE (klass),
257 _gtk_marshal_VOID__OBJECT,
262 * GtkActionGroup::post-activate:
263 * @action_group: the group
264 * @action: the action
266 * The post_activate signal is emitted just after the @action in the
267 * @action_group is activated
269 * This is intended for #GtkUIManager to proxy the signal and provide global
270 * notification just after any action is activated.
274 action_group_signals[POST_ACTIVATE] =
275 g_signal_new (I_("post_activate"),
276 G_OBJECT_CLASS_TYPE (klass),
278 _gtk_marshal_VOID__OBJECT,
282 g_type_class_add_private (gobject_class, sizeof (GtkActionGroupPrivate));
287 remove_action (GtkAction *action)
289 g_object_set (action, I_("action-group"), NULL, NULL);
290 g_object_unref (action);
294 gtk_action_group_init (GtkActionGroup *self)
296 GtkActionGroupPrivate *private;
298 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
300 private->name = NULL;
301 private->sensitive = TRUE;
302 private->visible = TRUE;
303 private->actions = g_hash_table_new_full (g_str_hash, g_str_equal,
305 (GDestroyNotify) remove_action);
306 private->translate_func = NULL;
307 private->translate_data = NULL;
308 private->translate_notify = NULL;
312 gtk_action_group_buildable_init (GtkBuildableIface *iface)
314 iface->add_child = gtk_action_group_buildable_add_child;
315 iface->set_name = gtk_action_group_buildable_set_name;
316 iface->get_name = gtk_action_group_buildable_get_name;
317 iface->custom_tag_start = gtk_action_group_buildable_custom_tag_start;
318 iface->custom_tag_end = gtk_action_group_buildable_custom_tag_end;
322 gtk_action_group_buildable_add_child (GtkBuildable *buildable,
327 gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (buildable),
328 GTK_ACTION (child), NULL);
332 gtk_action_group_buildable_set_name (GtkBuildable *buildable,
335 GtkActionGroup *self = GTK_ACTION_GROUP (buildable);
336 GtkActionGroupPrivate *private = GTK_ACTION_GROUP_GET_PRIVATE (self);
338 private->name = g_strdup (name);
342 gtk_action_group_buildable_get_name (GtkBuildable *buildable)
344 GtkActionGroup *self = GTK_ACTION_GROUP (buildable);
345 GtkActionGroupPrivate *private = GTK_ACTION_GROUP_GET_PRIVATE (self);
346 return private->name;
352 GdkModifierType modifiers;
353 } AcceleratorParserData;
356 accelerator_start_element (GMarkupParseContext *context,
357 const gchar *element_name,
359 const gchar **values,
365 GdkModifierType modifiers = 0;
366 AcceleratorParserData *parser_data = (AcceleratorParserData*)user_data;
368 if (strcmp (element_name, "accelerator") != 0)
369 g_warning ("Unknown <accelerator> tag: %s", element_name);
371 for (i = 0; names[i]; i++)
373 if (strcmp (names[i], "key") == 0)
374 key = gdk_keyval_from_name (values[i]);
375 else if (strcmp (names[i], "modifiers") == 0)
377 if (!_gtk_builder_flags_from_string (GDK_TYPE_MODIFIER_TYPE,
387 g_warning ("<accelerator> requires a key attribute");
390 parser_data->key = key;
391 parser_data->modifiers = modifiers;
394 static const GMarkupParser accelerator_parser =
396 accelerator_start_element
400 gtk_action_group_buildable_custom_tag_start (GtkBuildable *buildable,
403 const gchar *tagname,
404 GMarkupParser *parser,
407 AcceleratorParserData *parser_data;
409 if (child && strcmp (tagname, "accelerator") == 0)
411 parser_data = g_slice_new0 (AcceleratorParserData);
412 parser_data->child = child;
413 *user_data = parser_data;
414 *parser = accelerator_parser;
422 gtk_action_group_buildable_custom_tag_end (GtkBuildable *buildable,
425 const gchar *tagname,
428 AcceleratorParserData *data;
430 if (strcmp (tagname, "accelerator") == 0)
432 GtkActionGroup *action_group;
433 GtkActionGroupPrivate *private;
437 data = (AcceleratorParserData*)user_data;
438 action_group = GTK_ACTION_GROUP (buildable);
439 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
440 action = GTK_ACTION (child);
442 accel_path = g_strconcat ("<Actions>/",
444 gtk_action_get_name (action), NULL);
446 if (gtk_accel_map_lookup_entry (accel_path, NULL))
447 gtk_accel_map_change_entry (accel_path, data->key, data->modifiers, TRUE);
449 gtk_accel_map_add_entry (accel_path, data->key, data->modifiers);
451 gtk_action_set_accel_path (action, accel_path);
454 g_slice_free (AcceleratorParserData, data);
459 * gtk_action_group_new:
460 * @name: the name of the action group.
462 * Creates a new #GtkActionGroup object. The name of the action group
463 * is used when associating <link linkend="Action-Accel">keybindings</link>
466 * Returns: the new #GtkActionGroup
471 gtk_action_group_new (const gchar *name)
473 GtkActionGroup *self;
474 GtkActionGroupPrivate *private;
476 self = g_object_new (GTK_TYPE_ACTION_GROUP, NULL);
477 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
478 private->name = g_strdup (name);
484 gtk_action_group_finalize (GObject *object)
486 GtkActionGroup *self;
487 GtkActionGroupPrivate *private;
489 self = GTK_ACTION_GROUP (object);
490 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
492 g_free (private->name);
493 private->name = NULL;
495 g_hash_table_destroy (private->actions);
496 private->actions = NULL;
498 if (private->translate_notify)
499 private->translate_notify (private->translate_data);
501 if (parent_class->finalize)
502 (* parent_class->finalize) (object);
506 gtk_action_group_set_property (GObject *object,
511 GtkActionGroup *self;
512 GtkActionGroupPrivate *private;
515 self = GTK_ACTION_GROUP (object);
516 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
522 private->name = g_value_dup_string (value);
526 gtk_action_group_set_sensitive (self, g_value_get_boolean (value));
529 gtk_action_group_set_visible (self, g_value_get_boolean (value));
532 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
538 gtk_action_group_get_property (GObject *object,
543 GtkActionGroup *self;
544 GtkActionGroupPrivate *private;
546 self = GTK_ACTION_GROUP (object);
547 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
552 g_value_set_string (value, private->name);
555 g_value_set_boolean (value, private->sensitive);
558 g_value_set_boolean (value, private->visible);
561 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
567 gtk_action_group_real_get_action (GtkActionGroup *self,
568 const gchar *action_name)
570 GtkActionGroupPrivate *private;
572 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
574 return g_hash_table_lookup (private->actions, action_name);
578 * gtk_action_group_get_name:
579 * @action_group: the action group
581 * Gets the name of the action group.
583 * Returns: the name of the action group.
587 G_CONST_RETURN gchar *
588 gtk_action_group_get_name (GtkActionGroup *action_group)
590 GtkActionGroupPrivate *private;
592 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
594 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
596 return private->name;
600 * gtk_action_group_get_sensitive:
601 * @action_group: the action group
603 * Returns %TRUE if the group is sensitive. The constituent actions
604 * can only be logically sensitive (see gtk_action_is_sensitive()) if
605 * they are sensitive (see gtk_action_get_sensitive()) and their group
608 * Return value: %TRUE if the group is sensitive.
613 gtk_action_group_get_sensitive (GtkActionGroup *action_group)
615 GtkActionGroupPrivate *private;
617 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
619 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
621 return private->sensitive;
625 cb_set_action_sensitivity (const gchar *name,
628 /* Minor optimization, the action_groups state only affects actions
629 * that are themselves sensitive */
630 if (gtk_action_get_sensitive (action))
631 _gtk_action_sync_sensitive (action);
635 * gtk_action_group_set_sensitive:
636 * @action_group: the action group
637 * @sensitive: new sensitivity
639 * Changes the sensitivity of @action_group
644 gtk_action_group_set_sensitive (GtkActionGroup *action_group,
647 GtkActionGroupPrivate *private;
649 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
651 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
652 sensitive = sensitive != FALSE;
654 if (private->sensitive != sensitive)
656 private->sensitive = sensitive;
657 g_hash_table_foreach (private->actions,
658 (GHFunc) cb_set_action_sensitivity, NULL);
660 g_object_notify (G_OBJECT (action_group), "sensitive");
665 * gtk_action_group_get_visible:
666 * @action_group: the action group
668 * Returns %TRUE if the group is visible. The constituent actions
669 * can only be logically visible (see gtk_action_is_visible()) if
670 * they are visible (see gtk_action_get_visible()) and their group
673 * Return value: %TRUE if the group is visible.
678 gtk_action_group_get_visible (GtkActionGroup *action_group)
680 GtkActionGroupPrivate *private;
682 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
684 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
686 return private->visible;
690 cb_set_action_visiblity (const gchar *name,
693 /* Minor optimization, the action_groups state only affects actions
694 * that are themselves visible */
695 if (gtk_action_get_visible (action))
696 _gtk_action_sync_visible (action);
700 * gtk_action_group_set_visible:
701 * @action_group: the action group
702 * @visible: new visiblity
704 * Changes the visible of @action_group.
709 gtk_action_group_set_visible (GtkActionGroup *action_group,
712 GtkActionGroupPrivate *private;
714 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
716 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
717 visible = visible != FALSE;
719 if (private->visible != visible)
721 private->visible = visible;
722 g_hash_table_foreach (private->actions,
723 (GHFunc) cb_set_action_visiblity, NULL);
725 g_object_notify (G_OBJECT (action_group), "visible");
730 * gtk_action_group_get_action:
731 * @action_group: the action group
732 * @action_name: the name of the action
734 * Looks up an action in the action group by name.
736 * Returns: the action, or %NULL if no action by that name exists
741 gtk_action_group_get_action (GtkActionGroup *action_group,
742 const gchar *action_name)
744 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
745 g_return_val_if_fail (GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action != NULL, NULL);
747 return (* GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action)
748 (action_group, action_name);
752 check_unique_action (GtkActionGroup *action_group,
753 const gchar *action_name)
755 if (gtk_action_group_get_action (action_group, action_name) != NULL)
757 GtkActionGroupPrivate *private;
759 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
761 g_warning ("Refusing to add non-unique action '%s' to action group '%s'",
771 * gtk_action_group_add_action:
772 * @action_group: the action group
775 * Adds an action object to the action group. Note that this function
776 * does not set up the accel path of the action, which can lead to problems
777 * if a user tries to modify the accelerator of a menuitem associated with
778 * the action. Therefore you must either set the accel path yourself with
779 * gtk_action_set_accel_path(), or use
780 * <literal>gtk_action_group_add_action_with_accel (..., NULL)</literal>.
785 gtk_action_group_add_action (GtkActionGroup *action_group,
788 GtkActionGroupPrivate *private;
791 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
792 g_return_if_fail (GTK_IS_ACTION (action));
794 name = gtk_action_get_name (action);
795 g_return_if_fail (name != NULL);
797 if (!check_unique_action (action_group, name))
800 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
802 g_hash_table_insert (private->actions,
804 g_object_ref (action));
805 g_object_set (action, I_("action-group"), action_group, NULL);
809 * gtk_action_group_add_action_with_accel:
810 * @action_group: the action group
811 * @action: the action to add
812 * @accelerator: the accelerator for the action, in
813 * the format understood by gtk_accelerator_parse(), or "" for no accelerator, or
814 * %NULL to use the stock accelerator
816 * Adds an action object to the action group and sets up the accelerator.
818 * If @accelerator is %NULL, attempts to use the accelerator associated
819 * with the stock_id of the action.
821 * Accel paths are set to
822 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
827 gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
829 const gchar *accelerator)
831 GtkActionGroupPrivate *private;
834 GdkModifierType accel_mods;
837 name = gtk_action_get_name (action);
838 if (!check_unique_action (action_group, name))
841 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
842 accel_path = g_strconcat ("<Actions>/",
843 private->name, "/", name, NULL);
847 if (accelerator[0] == 0)
851 gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
853 g_warning ("Unable to parse accelerator '%s' for action '%s'",
860 GtkStockItem stock_item;
862 g_object_get (action, "stock-id", &stock_id, NULL);
864 if (stock_id && gtk_stock_lookup (stock_id, &stock_item))
866 accel_key = stock_item.keyval;
867 accel_mods = stock_item.modifier;
874 gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
876 gtk_action_set_accel_path (action, accel_path);
877 gtk_action_group_add_action (action_group, action);
883 * gtk_action_group_remove_action:
884 * @action_group: the action group
887 * Removes an action object from the action group.
892 gtk_action_group_remove_action (GtkActionGroup *action_group,
895 GtkActionGroupPrivate *private;
898 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
899 g_return_if_fail (GTK_IS_ACTION (action));
901 name = gtk_action_get_name (action);
902 g_return_if_fail (name != NULL);
904 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
906 g_hash_table_remove (private->actions, name);
910 add_single_action (gpointer key,
914 GList **list = user_data;
916 *list = g_list_prepend (*list, value);
920 * gtk_action_group_list_actions:
921 * @action_group: the action group
923 * Lists the actions in the action group.
925 * Returns: an allocated list of the action objects in the action group
930 gtk_action_group_list_actions (GtkActionGroup *action_group)
932 GtkActionGroupPrivate *private;
933 GList *actions = NULL;
935 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
937 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
939 g_hash_table_foreach (private->actions, add_single_action, &actions);
941 return g_list_reverse (actions);
946 * gtk_action_group_add_actions:
947 * @action_group: the action group
948 * @entries: an array of action descriptions
949 * @n_entries: the number of entries
950 * @user_data: data to pass to the action callbacks
952 * This is a convenience function to create a number of actions and add them
953 * to the action group.
955 * The "activate" signals of the actions are connected to the callbacks and
956 * their accel paths are set to
957 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
962 gtk_action_group_add_actions (GtkActionGroup *action_group,
963 const GtkActionEntry *entries,
967 gtk_action_group_add_actions_full (action_group,
972 typedef struct _SharedData SharedData;
977 GDestroyNotify destroy;
981 shared_data_unref (gpointer data)
983 SharedData *shared_data = (SharedData *)data;
985 shared_data->ref_count--;
986 if (shared_data->ref_count == 0)
988 if (shared_data->destroy)
989 (*shared_data->destroy) (shared_data->data);
991 g_slice_free (SharedData, shared_data);
997 * gtk_action_group_add_actions_full:
998 * @action_group: the action group
999 * @entries: an array of action descriptions
1000 * @n_entries: the number of entries
1001 * @user_data: data to pass to the action callbacks
1002 * @destroy: destroy notification callback for @user_data
1004 * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify
1005 * callback for @user_data.
1010 gtk_action_group_add_actions_full (GtkActionGroup *action_group,
1011 const GtkActionEntry *entries,
1014 GDestroyNotify destroy)
1017 /* Keep this in sync with the other
1018 * gtk_action_group_add_..._actions_full() functions.
1021 SharedData *shared_data;
1023 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1025 shared_data = g_slice_new0 (SharedData);
1026 shared_data->ref_count = 1;
1027 shared_data->data = user_data;
1028 shared_data->destroy = destroy;
1030 for (i = 0; i < n_entries; i++)
1034 const gchar *tooltip;
1036 if (!check_unique_action (action_group, entries[i].name))
1039 label = gtk_action_group_translate_string (action_group, entries[i].label);
1040 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1042 action = gtk_action_new (entries[i].name,
1047 if (entries[i].stock_id)
1049 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1050 if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default (),
1051 entries[i].stock_id))
1052 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1055 if (entries[i].callback)
1059 closure = g_cclosure_new (entries[i].callback, user_data, NULL);
1060 g_closure_add_finalize_notifier (closure, shared_data,
1061 (GClosureNotify)shared_data_unref);
1062 shared_data->ref_count++;
1064 g_signal_connect_closure (action, "activate", closure, FALSE);
1067 gtk_action_group_add_action_with_accel (action_group,
1069 entries[i].accelerator);
1070 g_object_unref (action);
1073 shared_data_unref (shared_data);
1077 * gtk_action_group_add_toggle_actions:
1078 * @action_group: the action group
1079 * @entries: an array of toggle action descriptions
1080 * @n_entries: the number of entries
1081 * @user_data: data to pass to the action callbacks
1083 * This is a convenience function to create a number of toggle actions and add them
1084 * to the action group.
1086 * The "activate" signals of the actions are connected to the callbacks and
1087 * their accel paths are set to
1088 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
1093 gtk_action_group_add_toggle_actions (GtkActionGroup *action_group,
1094 const GtkToggleActionEntry *entries,
1098 gtk_action_group_add_toggle_actions_full (action_group,
1105 * gtk_action_group_add_toggle_actions_full:
1106 * @action_group: the action group
1107 * @entries: an array of toggle action descriptions
1108 * @n_entries: the number of entries
1109 * @user_data: data to pass to the action callbacks
1110 * @destroy: destroy notification callback for @user_data
1112 * This variant of gtk_action_group_add_toggle_actions() adds a
1113 * #GDestroyNotify callback for @user_data.
1118 gtk_action_group_add_toggle_actions_full (GtkActionGroup *action_group,
1119 const GtkToggleActionEntry *entries,
1122 GDestroyNotify destroy)
1124 /* Keep this in sync with the other
1125 * gtk_action_group_add_..._actions_full() functions.
1128 SharedData *shared_data;
1130 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1132 shared_data = g_slice_new0 (SharedData);
1133 shared_data->ref_count = 1;
1134 shared_data->data = user_data;
1135 shared_data->destroy = destroy;
1137 for (i = 0; i < n_entries; i++)
1139 GtkToggleAction *action;
1141 const gchar *tooltip;
1143 if (!check_unique_action (action_group, entries[i].name))
1146 label = gtk_action_group_translate_string (action_group, entries[i].label);
1147 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1149 action = gtk_toggle_action_new (entries[i].name,
1154 if (entries[i].stock_id)
1156 if (gtk_icon_factory_lookup_default (entries[i].stock_id))
1157 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1159 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1162 gtk_toggle_action_set_active (action, entries[i].is_active);
1164 if (entries[i].callback)
1168 closure = g_cclosure_new (entries[i].callback, user_data, NULL);
1169 g_closure_add_finalize_notifier (closure, shared_data,
1170 (GClosureNotify)shared_data_unref);
1171 shared_data->ref_count++;
1173 g_signal_connect_closure (action, "activate", closure, FALSE);
1176 gtk_action_group_add_action_with_accel (action_group,
1177 GTK_ACTION (action),
1178 entries[i].accelerator);
1179 g_object_unref (action);
1182 shared_data_unref (shared_data);
1186 * gtk_action_group_add_radio_actions:
1187 * @action_group: the action group
1188 * @entries: an array of radio action descriptions
1189 * @n_entries: the number of entries
1190 * @value: the value of the action to activate initially, or -1 if
1191 * no action should be activated
1192 * @on_change: the callback to connect to the changed signal
1193 * @user_data: data to pass to the action callbacks
1195 * This is a convenience routine to create a group of radio actions and
1196 * add them to the action group.
1198 * The "changed" signal of the first radio action is connected to the
1199 * @on_change callback and the accel paths of the actions are set to
1200 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
1205 gtk_action_group_add_radio_actions (GtkActionGroup *action_group,
1206 const GtkRadioActionEntry *entries,
1209 GCallback on_change,
1212 gtk_action_group_add_radio_actions_full (action_group,
1215 on_change, user_data, NULL);
1219 * gtk_action_group_add_radio_actions_full:
1220 * @action_group: the action group
1221 * @entries: an array of radio action descriptions
1222 * @n_entries: the number of entries
1223 * @value: the value of the action to activate initially, or -1 if
1224 * no action should be activated
1225 * @on_change: the callback to connect to the changed signal
1226 * @user_data: data to pass to the action callbacks
1227 * @destroy: destroy notification callback for @user_data
1229 * This variant of gtk_action_group_add_radio_actions() adds a
1230 * #GDestroyNotify callback for @user_data.
1235 gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group,
1236 const GtkRadioActionEntry *entries,
1239 GCallback on_change,
1241 GDestroyNotify destroy)
1243 /* Keep this in sync with the other
1244 * gtk_action_group_add_..._actions_full() functions.
1247 GSList *group = NULL;
1248 GtkRadioAction *first_action = NULL;
1250 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1252 for (i = 0; i < n_entries; i++)
1254 GtkRadioAction *action;
1256 const gchar *tooltip;
1258 if (!check_unique_action (action_group, entries[i].name))
1261 label = gtk_action_group_translate_string (action_group, entries[i].label);
1262 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1264 action = gtk_radio_action_new (entries[i].name,
1270 if (entries[i].stock_id)
1272 if (gtk_icon_factory_lookup_default (entries[i].stock_id))
1273 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1275 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1279 first_action = action;
1281 gtk_radio_action_set_group (action, group);
1282 group = gtk_radio_action_get_group (action);
1284 if (value == entries[i].value)
1285 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1287 gtk_action_group_add_action_with_accel (action_group,
1288 GTK_ACTION (action),
1289 entries[i].accelerator);
1290 g_object_unref (action);
1293 if (on_change && first_action)
1294 g_signal_connect_data (first_action, "changed",
1295 on_change, user_data,
1296 (GClosureNotify)destroy, 0);
1300 * gtk_action_group_set_translate_func:
1301 * @action_group: a #GtkActionGroup
1302 * @func: a #GtkTranslateFunc
1303 * @data: data to be passed to @func and @notify
1304 * @notify: a #GDestroyNotify function to be called when @action_group is
1305 * destroyed and when the translation function is changed again
1307 * Sets a function to be used for translating the @label and @tooltip of
1308 * #GtkActionGroupEntry<!-- -->s added by gtk_action_group_add_actions().
1310 * If you're using gettext(), it is enough to set the translation domain
1311 * with gtk_action_group_set_translation_domain().
1316 gtk_action_group_set_translate_func (GtkActionGroup *action_group,
1317 GtkTranslateFunc func,
1319 GDestroyNotify notify)
1321 GtkActionGroupPrivate *private;
1323 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1325 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
1327 if (private->translate_notify)
1328 private->translate_notify (private->translate_data);
1330 private->translate_func = func;
1331 private->translate_data = data;
1332 private->translate_notify = notify;
1336 dgettext_swapped (const gchar *msgid,
1337 const gchar *domainname)
1339 /* Pass through g_dgettext if and only if msgid is nonempty. */
1340 if (msgid && *msgid)
1341 return (gchar*) g_dgettext (domainname, msgid);
1343 return (gchar*) msgid;
1347 * gtk_action_group_set_translation_domain:
1348 * @action_group: a #GtkActionGroup
1349 * @domain: the translation domain to use for g_dgettext() calls
1351 * Sets the translation domain and uses g_dgettext() for translating the
1352 * @label and @tooltip of #GtkActionEntry<!-- -->s added by
1353 * gtk_action_group_add_actions().
1355 * If you're not using gettext() for localization, see
1356 * gtk_action_group_set_translate_func().
1361 gtk_action_group_set_translation_domain (GtkActionGroup *action_group,
1362 const gchar *domain)
1364 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1366 gtk_action_group_set_translate_func (action_group,
1367 (GtkTranslateFunc)dgettext_swapped,
1374 * gtk_action_group_translate_string:
1375 * @action_group: a #GtkActionGroup
1378 * Translates a string using the specified translate_func(). This
1379 * is mainly intended for language bindings.
1381 * Returns: the translation of @string
1385 G_CONST_RETURN gchar *
1386 gtk_action_group_translate_string (GtkActionGroup *action_group,
1387 const gchar *string)
1389 GtkActionGroupPrivate *private;
1390 GtkTranslateFunc translate_func;
1391 gpointer translate_data;
1393 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), string);
1398 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
1400 translate_func = private->translate_func;
1401 translate_data = private->translate_data;
1404 return translate_func (string, translate_data);
1409 /* Protected for use by GtkAction */
1411 _gtk_action_group_emit_connect_proxy (GtkActionGroup *action_group,
1415 g_signal_emit (action_group, action_group_signals[CONNECT_PROXY], 0,
1420 _gtk_action_group_emit_disconnect_proxy (GtkActionGroup *action_group,
1424 g_signal_emit (action_group, action_group_signals[DISCONNECT_PROXY], 0,
1429 _gtk_action_group_emit_pre_activate (GtkActionGroup *action_group,
1432 g_signal_emit (action_group, action_group_signals[PRE_ACTIVATE], 0, action);
1436 _gtk_action_group_emit_post_activate (GtkActionGroup *action_group,
1439 g_signal_emit (action_group, action_group_signals[POST_ACTIVATE], 0, action);
1442 #define __GTK_ACTION_GROUP_C__
1443 #include "gtkaliasdef.c"