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 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 parent_class->finalize (object);
505 gtk_action_group_set_property (GObject *object,
510 GtkActionGroup *self;
511 GtkActionGroupPrivate *private;
514 self = GTK_ACTION_GROUP (object);
515 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
521 private->name = g_value_dup_string (value);
525 gtk_action_group_set_sensitive (self, g_value_get_boolean (value));
528 gtk_action_group_set_visible (self, g_value_get_boolean (value));
531 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
537 gtk_action_group_get_property (GObject *object,
542 GtkActionGroup *self;
543 GtkActionGroupPrivate *private;
545 self = GTK_ACTION_GROUP (object);
546 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
551 g_value_set_string (value, private->name);
554 g_value_set_boolean (value, private->sensitive);
557 g_value_set_boolean (value, private->visible);
560 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
566 gtk_action_group_real_get_action (GtkActionGroup *self,
567 const gchar *action_name)
569 GtkActionGroupPrivate *private;
571 private = GTK_ACTION_GROUP_GET_PRIVATE (self);
573 return g_hash_table_lookup (private->actions, action_name);
577 * gtk_action_group_get_name:
578 * @action_group: the action group
580 * Gets the name of the action group.
582 * Returns: the name of the action group.
586 G_CONST_RETURN gchar *
587 gtk_action_group_get_name (GtkActionGroup *action_group)
589 GtkActionGroupPrivate *private;
591 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
593 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
595 return private->name;
599 * gtk_action_group_get_sensitive:
600 * @action_group: the action group
602 * Returns %TRUE if the group is sensitive. The constituent actions
603 * can only be logically sensitive (see gtk_action_is_sensitive()) if
604 * they are sensitive (see gtk_action_get_sensitive()) and their group
607 * Return value: %TRUE if the group is sensitive.
612 gtk_action_group_get_sensitive (GtkActionGroup *action_group)
614 GtkActionGroupPrivate *private;
616 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
618 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
620 return private->sensitive;
624 cb_set_action_sensitivity (const gchar *name,
627 /* Minor optimization, the action_groups state only affects actions
628 * that are themselves sensitive */
629 g_object_notify (G_OBJECT (action), "sensitive");
634 * gtk_action_group_set_sensitive:
635 * @action_group: the action group
636 * @sensitive: new sensitivity
638 * Changes the sensitivity of @action_group
643 gtk_action_group_set_sensitive (GtkActionGroup *action_group,
646 GtkActionGroupPrivate *private;
648 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
650 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
651 sensitive = sensitive != FALSE;
653 if (private->sensitive != sensitive)
655 private->sensitive = sensitive;
656 g_hash_table_foreach (private->actions,
657 (GHFunc) cb_set_action_sensitivity, NULL);
659 g_object_notify (G_OBJECT (action_group), "sensitive");
664 * gtk_action_group_get_visible:
665 * @action_group: the action group
667 * Returns %TRUE if the group is visible. The constituent actions
668 * can only be logically visible (see gtk_action_is_visible()) if
669 * they are visible (see gtk_action_get_visible()) and their group
672 * Return value: %TRUE if the group is visible.
677 gtk_action_group_get_visible (GtkActionGroup *action_group)
679 GtkActionGroupPrivate *private;
681 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
683 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
685 return private->visible;
689 cb_set_action_visiblity (const gchar *name,
692 /* Minor optimization, the action_groups state only affects actions
693 * that are themselves visible */
694 g_object_notify (G_OBJECT (action), "visible");
698 * gtk_action_group_set_visible:
699 * @action_group: the action group
700 * @visible: new visiblity
702 * Changes the visible of @action_group.
707 gtk_action_group_set_visible (GtkActionGroup *action_group,
710 GtkActionGroupPrivate *private;
712 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
714 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
715 visible = visible != FALSE;
717 if (private->visible != visible)
719 private->visible = visible;
720 g_hash_table_foreach (private->actions,
721 (GHFunc) cb_set_action_visiblity, NULL);
723 g_object_notify (G_OBJECT (action_group), "visible");
728 * gtk_action_group_get_action:
729 * @action_group: the action group
730 * @action_name: the name of the action
732 * Looks up an action in the action group by name.
734 * Returns: (transfer-none): the action, or %NULL if no action by that name exists
739 gtk_action_group_get_action (GtkActionGroup *action_group,
740 const gchar *action_name)
742 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
743 g_return_val_if_fail (GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action != NULL, NULL);
745 return GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action (action_group,
750 check_unique_action (GtkActionGroup *action_group,
751 const gchar *action_name)
753 if (gtk_action_group_get_action (action_group, action_name) != NULL)
755 GtkActionGroupPrivate *private;
757 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
759 g_warning ("Refusing to add non-unique action '%s' to action group '%s'",
769 * gtk_action_group_add_action:
770 * @action_group: the action group
773 * Adds an action object to the action group. Note that this function
774 * does not set up the accel path of the action, which can lead to problems
775 * if a user tries to modify the accelerator of a menuitem associated with
776 * the action. Therefore you must either set the accel path yourself with
777 * gtk_action_set_accel_path(), or use
778 * <literal>gtk_action_group_add_action_with_accel (..., NULL)</literal>.
783 gtk_action_group_add_action (GtkActionGroup *action_group,
786 GtkActionGroupPrivate *private;
789 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
790 g_return_if_fail (GTK_IS_ACTION (action));
792 name = gtk_action_get_name (action);
793 g_return_if_fail (name != NULL);
795 if (!check_unique_action (action_group, name))
798 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
800 g_hash_table_insert (private->actions,
802 g_object_ref (action));
803 g_object_set (action, I_("action-group"), action_group, NULL);
807 * gtk_action_group_add_action_with_accel:
808 * @action_group: the action group
809 * @action: the action to add
810 * @accelerator: (allow-none): the accelerator for the action, in
811 * the format understood by gtk_accelerator_parse(), or "" for no accelerator, or
812 * %NULL to use the stock accelerator
814 * Adds an action object to the action group and sets up the accelerator.
816 * If @accelerator is %NULL, attempts to use the accelerator associated
817 * with the stock_id of the action.
819 * Accel paths are set to
820 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
825 gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
827 const gchar *accelerator)
829 GtkActionGroupPrivate *private;
832 GdkModifierType accel_mods;
835 name = gtk_action_get_name (action);
836 if (!check_unique_action (action_group, name))
839 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
840 accel_path = g_strconcat ("<Actions>/",
841 private->name, "/", name, NULL);
845 if (accelerator[0] == 0)
849 gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
851 g_warning ("Unable to parse accelerator '%s' for action '%s'",
858 GtkStockItem stock_item;
860 g_object_get (action, "stock-id", &stock_id, NULL);
862 if (stock_id && gtk_stock_lookup (stock_id, &stock_item))
864 accel_key = stock_item.keyval;
865 accel_mods = stock_item.modifier;
872 gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
874 gtk_action_set_accel_path (action, accel_path);
875 gtk_action_group_add_action (action_group, action);
881 * gtk_action_group_remove_action:
882 * @action_group: the action group
885 * Removes an action object from the action group.
890 gtk_action_group_remove_action (GtkActionGroup *action_group,
893 GtkActionGroupPrivate *private;
896 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
897 g_return_if_fail (GTK_IS_ACTION (action));
899 name = gtk_action_get_name (action);
900 g_return_if_fail (name != NULL);
902 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
904 g_hash_table_remove (private->actions, name);
908 add_single_action (gpointer key,
912 GList **list = user_data;
914 *list = g_list_prepend (*list, value);
918 * gtk_action_group_list_actions:
919 * @action_group: the action group
921 * Lists the actions in the action group.
923 * Returns: (element-type GtkAction) (transfer container): an allocated list of the action objects in the action group
928 gtk_action_group_list_actions (GtkActionGroup *action_group)
930 GtkActionGroupPrivate *private;
931 GList *actions = NULL;
933 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
935 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
937 g_hash_table_foreach (private->actions, add_single_action, &actions);
939 return g_list_reverse (actions);
944 * gtk_action_group_add_actions:
945 * @action_group: the action group
946 * @entries: an array of action descriptions
947 * @n_entries: the number of entries
948 * @user_data: data to pass to the action callbacks
950 * This is a convenience function to create a number of actions and add them
951 * to the action group.
953 * The "activate" signals of the actions are connected to the callbacks and
954 * their accel paths are set to
955 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
960 gtk_action_group_add_actions (GtkActionGroup *action_group,
961 const GtkActionEntry *entries,
965 gtk_action_group_add_actions_full (action_group,
970 typedef struct _SharedData SharedData;
975 GDestroyNotify destroy;
979 shared_data_unref (gpointer data)
981 SharedData *shared_data = (SharedData *)data;
983 shared_data->ref_count--;
984 if (shared_data->ref_count == 0)
986 if (shared_data->destroy)
987 shared_data->destroy (shared_data->data);
989 g_slice_free (SharedData, shared_data);
995 * gtk_action_group_add_actions_full:
996 * @action_group: the action group
997 * @entries: an array of action descriptions
998 * @n_entries: the number of entries
999 * @user_data: data to pass to the action callbacks
1000 * @destroy: destroy notification callback for @user_data
1002 * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify
1003 * callback for @user_data.
1008 gtk_action_group_add_actions_full (GtkActionGroup *action_group,
1009 const GtkActionEntry *entries,
1012 GDestroyNotify destroy)
1015 /* Keep this in sync with the other
1016 * gtk_action_group_add_..._actions_full() functions.
1019 SharedData *shared_data;
1021 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1023 shared_data = g_slice_new0 (SharedData);
1024 shared_data->ref_count = 1;
1025 shared_data->data = user_data;
1026 shared_data->destroy = destroy;
1028 for (i = 0; i < n_entries; i++)
1032 const gchar *tooltip;
1034 if (!check_unique_action (action_group, entries[i].name))
1037 label = gtk_action_group_translate_string (action_group, entries[i].label);
1038 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1040 action = gtk_action_new (entries[i].name,
1045 if (entries[i].stock_id)
1047 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1048 if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default (),
1049 entries[i].stock_id))
1050 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1053 if (entries[i].callback)
1057 closure = g_cclosure_new (entries[i].callback, user_data, NULL);
1058 g_closure_add_finalize_notifier (closure, shared_data,
1059 (GClosureNotify)shared_data_unref);
1060 shared_data->ref_count++;
1062 g_signal_connect_closure (action, "activate", closure, FALSE);
1065 gtk_action_group_add_action_with_accel (action_group,
1067 entries[i].accelerator);
1068 g_object_unref (action);
1071 shared_data_unref (shared_data);
1075 * gtk_action_group_add_toggle_actions:
1076 * @action_group: the action group
1077 * @entries: an array of toggle action descriptions
1078 * @n_entries: the number of entries
1079 * @user_data: data to pass to the action callbacks
1081 * This is a convenience function to create a number of toggle actions and add them
1082 * to the action group.
1084 * The "activate" signals of the actions are connected to the callbacks and
1085 * their accel paths are set to
1086 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
1091 gtk_action_group_add_toggle_actions (GtkActionGroup *action_group,
1092 const GtkToggleActionEntry *entries,
1096 gtk_action_group_add_toggle_actions_full (action_group,
1103 * gtk_action_group_add_toggle_actions_full:
1104 * @action_group: the action group
1105 * @entries: an array of toggle action descriptions
1106 * @n_entries: the number of entries
1107 * @user_data: data to pass to the action callbacks
1108 * @destroy: destroy notification callback for @user_data
1110 * This variant of gtk_action_group_add_toggle_actions() adds a
1111 * #GDestroyNotify callback for @user_data.
1116 gtk_action_group_add_toggle_actions_full (GtkActionGroup *action_group,
1117 const GtkToggleActionEntry *entries,
1120 GDestroyNotify destroy)
1122 /* Keep this in sync with the other
1123 * gtk_action_group_add_..._actions_full() functions.
1126 SharedData *shared_data;
1128 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1130 shared_data = g_slice_new0 (SharedData);
1131 shared_data->ref_count = 1;
1132 shared_data->data = user_data;
1133 shared_data->destroy = destroy;
1135 for (i = 0; i < n_entries; i++)
1137 GtkToggleAction *action;
1139 const gchar *tooltip;
1141 if (!check_unique_action (action_group, entries[i].name))
1144 label = gtk_action_group_translate_string (action_group, entries[i].label);
1145 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1147 action = gtk_toggle_action_new (entries[i].name,
1152 if (entries[i].stock_id)
1154 if (gtk_icon_factory_lookup_default (entries[i].stock_id))
1155 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1157 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1160 gtk_toggle_action_set_active (action, entries[i].is_active);
1162 if (entries[i].callback)
1166 closure = g_cclosure_new (entries[i].callback, user_data, NULL);
1167 g_closure_add_finalize_notifier (closure, shared_data,
1168 (GClosureNotify)shared_data_unref);
1169 shared_data->ref_count++;
1171 g_signal_connect_closure (action, "activate", closure, FALSE);
1174 gtk_action_group_add_action_with_accel (action_group,
1175 GTK_ACTION (action),
1176 entries[i].accelerator);
1177 g_object_unref (action);
1180 shared_data_unref (shared_data);
1184 * gtk_action_group_add_radio_actions:
1185 * @action_group: the action group
1186 * @entries: an array of radio action descriptions
1187 * @n_entries: the number of entries
1188 * @value: the value of the action to activate initially, or -1 if
1189 * no action should be activated
1190 * @on_change: the callback to connect to the changed signal
1191 * @user_data: data to pass to the action callbacks
1193 * This is a convenience routine to create a group of radio actions and
1194 * add them to the action group.
1196 * The "changed" signal of the first radio action is connected to the
1197 * @on_change callback and the accel paths of the actions are set to
1198 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
1203 gtk_action_group_add_radio_actions (GtkActionGroup *action_group,
1204 const GtkRadioActionEntry *entries,
1207 GCallback on_change,
1210 gtk_action_group_add_radio_actions_full (action_group,
1213 on_change, user_data, NULL);
1217 * gtk_action_group_add_radio_actions_full:
1218 * @action_group: the action group
1219 * @entries: an array of radio action descriptions
1220 * @n_entries: the number of entries
1221 * @value: the value of the action to activate initially, or -1 if
1222 * no action should be activated
1223 * @on_change: the callback to connect to the changed signal
1224 * @user_data: data to pass to the action callbacks
1225 * @destroy: destroy notification callback for @user_data
1227 * This variant of gtk_action_group_add_radio_actions() adds a
1228 * #GDestroyNotify callback for @user_data.
1233 gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group,
1234 const GtkRadioActionEntry *entries,
1237 GCallback on_change,
1239 GDestroyNotify destroy)
1241 /* Keep this in sync with the other
1242 * gtk_action_group_add_..._actions_full() functions.
1245 GSList *group = NULL;
1246 GtkRadioAction *first_action = NULL;
1248 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1250 for (i = 0; i < n_entries; i++)
1252 GtkRadioAction *action;
1254 const gchar *tooltip;
1256 if (!check_unique_action (action_group, entries[i].name))
1259 label = gtk_action_group_translate_string (action_group, entries[i].label);
1260 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1262 action = gtk_radio_action_new (entries[i].name,
1268 if (entries[i].stock_id)
1270 if (gtk_icon_factory_lookup_default (entries[i].stock_id))
1271 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1273 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1277 first_action = action;
1279 gtk_radio_action_set_group (action, group);
1280 group = gtk_radio_action_get_group (action);
1282 if (value == entries[i].value)
1283 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1285 gtk_action_group_add_action_with_accel (action_group,
1286 GTK_ACTION (action),
1287 entries[i].accelerator);
1288 g_object_unref (action);
1291 if (on_change && first_action)
1292 g_signal_connect_data (first_action, "changed",
1293 on_change, user_data,
1294 (GClosureNotify)destroy, 0);
1298 * gtk_action_group_set_translate_func:
1299 * @action_group: a #GtkActionGroup
1300 * @func: a #GtkTranslateFunc
1301 * @data: data to be passed to @func and @notify
1302 * @notify: a #GDestroyNotify function to be called when @action_group is
1303 * destroyed and when the translation function is changed again
1305 * Sets a function to be used for translating the @label and @tooltip of
1306 * #GtkActionGroupEntry<!-- -->s added by gtk_action_group_add_actions().
1308 * If you're using gettext(), it is enough to set the translation domain
1309 * with gtk_action_group_set_translation_domain().
1314 gtk_action_group_set_translate_func (GtkActionGroup *action_group,
1315 GtkTranslateFunc func,
1317 GDestroyNotify notify)
1319 GtkActionGroupPrivate *private;
1321 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1323 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
1325 if (private->translate_notify)
1326 private->translate_notify (private->translate_data);
1328 private->translate_func = func;
1329 private->translate_data = data;
1330 private->translate_notify = notify;
1334 dgettext_swapped (const gchar *msgid,
1335 const gchar *domainname)
1337 /* Pass through g_dgettext if and only if msgid is nonempty. */
1338 if (msgid && *msgid)
1339 return (gchar*) g_dgettext (domainname, msgid);
1341 return (gchar*) msgid;
1345 * gtk_action_group_set_translation_domain:
1346 * @action_group: a #GtkActionGroup
1347 * @domain: the translation domain to use for g_dgettext() calls
1349 * Sets the translation domain and uses g_dgettext() for translating the
1350 * @label and @tooltip of #GtkActionEntry<!-- -->s added by
1351 * gtk_action_group_add_actions().
1353 * If you're not using gettext() for localization, see
1354 * gtk_action_group_set_translate_func().
1359 gtk_action_group_set_translation_domain (GtkActionGroup *action_group,
1360 const gchar *domain)
1362 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1364 gtk_action_group_set_translate_func (action_group,
1365 (GtkTranslateFunc)dgettext_swapped,
1372 * gtk_action_group_translate_string:
1373 * @action_group: a #GtkActionGroup
1376 * Translates a string using the specified translate_func(). This
1377 * is mainly intended for language bindings.
1379 * Returns: the translation of @string
1383 G_CONST_RETURN gchar *
1384 gtk_action_group_translate_string (GtkActionGroup *action_group,
1385 const gchar *string)
1387 GtkActionGroupPrivate *private;
1388 GtkTranslateFunc translate_func;
1389 gpointer translate_data;
1391 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), string);
1396 private = GTK_ACTION_GROUP_GET_PRIVATE (action_group);
1398 translate_func = private->translate_func;
1399 translate_data = private->translate_data;
1402 return translate_func (string, translate_data);
1407 /* Protected for use by GtkAction */
1409 _gtk_action_group_emit_connect_proxy (GtkActionGroup *action_group,
1413 g_signal_emit (action_group, action_group_signals[CONNECT_PROXY], 0,
1418 _gtk_action_group_emit_disconnect_proxy (GtkActionGroup *action_group,
1422 g_signal_emit (action_group, action_group_signals[DISCONNECT_PROXY], 0,
1427 _gtk_action_group_emit_pre_activate (GtkActionGroup *action_group,
1430 g_signal_emit (action_group, action_group_signals[PRE_ACTIVATE], 0, action);
1434 _gtk_action_group_emit_post_activate (GtkActionGroup *action_group,
1437 g_signal_emit (action_group, action_group_signals[POST_ACTIVATE], 0, action);
1440 #define __GTK_ACTION_GROUP_C__
1441 #include "gtkaliasdef.c"