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 GtkDestroyNotify 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 self->private_data = GTK_ACTION_GROUP_GET_PRIVATE (self);
297 self->private_data->name = NULL;
298 self->private_data->sensitive = TRUE;
299 self->private_data->visible = TRUE;
300 self->private_data->actions = g_hash_table_new_full (g_str_hash, g_str_equal,
302 (GDestroyNotify) remove_action);
303 self->private_data->translate_func = NULL;
304 self->private_data->translate_data = NULL;
305 self->private_data->translate_notify = NULL;
309 gtk_action_group_buildable_init (GtkBuildableIface *iface)
311 iface->add_child = gtk_action_group_buildable_add_child;
312 iface->set_name = gtk_action_group_buildable_set_name;
313 iface->get_name = gtk_action_group_buildable_get_name;
314 iface->custom_tag_start = gtk_action_group_buildable_custom_tag_start;
315 iface->custom_tag_end = gtk_action_group_buildable_custom_tag_end;
319 gtk_action_group_buildable_add_child (GtkBuildable *buildable,
324 gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (buildable),
325 GTK_ACTION (child), NULL);
329 gtk_action_group_buildable_set_name (GtkBuildable *buildable,
332 GtkActionGroup *self = GTK_ACTION_GROUP (buildable);
333 self->private_data->name = g_strdup (name);
337 gtk_action_group_buildable_get_name (GtkBuildable *buildable)
339 GtkActionGroup *self = GTK_ACTION_GROUP (buildable);
340 return self->private_data->name;
347 } AcceleratorParserData;
350 accelerator_start_element (GMarkupParseContext *context,
351 const gchar *element_name,
353 const gchar **values,
360 AcceleratorParserData *parser_data = (AcceleratorParserData*)user_data;
362 if (strcmp (element_name, "accelerator") != 0)
363 g_warning ("Unknown <accelerator> tag: %s", element_name);
365 for (i = 0; names[i]; i++)
367 if (strcmp (names[i], "key") == 0)
368 key = gdk_keyval_from_name (values[i]);
369 else if (strcmp (names[i], "modifiers") == 0)
371 if (!_gtk_builder_flags_from_string (GDK_TYPE_MODIFIER_TYPE,
381 g_warning ("<accelerator> requires a key attribute");
384 parser_data->key = key;
385 parser_data->modifiers = (guint)modifiers;
388 static const GMarkupParser accelerator_parser =
390 accelerator_start_element
394 gtk_action_group_buildable_custom_tag_start (GtkBuildable *buildable,
397 const gchar *tagname,
398 GMarkupParser *parser,
401 AcceleratorParserData *parser_data;
403 if (child && strcmp (tagname, "accelerator") == 0)
405 parser_data = g_slice_new0 (AcceleratorParserData);
406 parser_data->child = child;
407 *user_data = parser_data;
408 *parser = accelerator_parser;
416 gtk_action_group_buildable_custom_tag_end (GtkBuildable *buildable,
419 const gchar *tagname,
422 AcceleratorParserData *data;
424 if (strcmp (tagname, "accelerator") == 0)
426 GtkActionGroup *action_group;
430 data = (AcceleratorParserData*)user_data;
431 action_group = GTK_ACTION_GROUP (buildable);
432 action = GTK_ACTION (child);
434 accel_path = g_strconcat ("<Actions>/",
435 action_group->private_data->name, "/",
436 gtk_action_get_name (action), NULL);
438 if (gtk_accel_map_lookup_entry (accel_path, NULL))
439 gtk_accel_map_change_entry (accel_path, data->key, data->modifiers, TRUE);
441 gtk_accel_map_add_entry (accel_path, data->key, data->modifiers);
443 gtk_action_set_accel_path (action, accel_path);
446 g_slice_free (AcceleratorParserData, data);
451 * gtk_action_group_new:
452 * @name: the name of the action group.
454 * Creates a new #GtkActionGroup object. The name of the action group
455 * is used when associating <link linkend="Action-Accel">keybindings</link>
458 * Returns: the new #GtkActionGroup
463 gtk_action_group_new (const gchar *name)
465 GtkActionGroup *self;
467 self = g_object_new (GTK_TYPE_ACTION_GROUP, NULL);
468 self->private_data->name = g_strdup (name);
474 gtk_action_group_finalize (GObject *object)
476 GtkActionGroup *self;
478 self = GTK_ACTION_GROUP (object);
480 g_free (self->private_data->name);
481 self->private_data->name = NULL;
483 g_hash_table_destroy (self->private_data->actions);
484 self->private_data->actions = NULL;
486 if (self->private_data->translate_notify)
487 self->private_data->translate_notify (self->private_data->translate_data);
489 if (parent_class->finalize)
490 (* parent_class->finalize) (object);
494 gtk_action_group_set_property (GObject *object,
499 GtkActionGroup *self;
502 self = GTK_ACTION_GROUP (object);
507 tmp = self->private_data->name;
508 self->private_data->name = g_value_dup_string (value);
512 gtk_action_group_set_sensitive (self, g_value_get_boolean (value));
515 gtk_action_group_set_visible (self, g_value_get_boolean (value));
518 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
524 gtk_action_group_get_property (GObject *object,
529 GtkActionGroup *self;
531 self = GTK_ACTION_GROUP (object);
536 g_value_set_string (value, self->private_data->name);
539 g_value_set_boolean (value, self->private_data->sensitive);
542 g_value_set_boolean (value, self->private_data->visible);
545 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
551 gtk_action_group_real_get_action (GtkActionGroup *self,
552 const gchar *action_name)
554 return g_hash_table_lookup (self->private_data->actions, action_name);
558 * gtk_action_group_get_name:
559 * @action_group: the action group
561 * Gets the name of the action group.
563 * Returns: the name of the action group.
567 G_CONST_RETURN gchar *
568 gtk_action_group_get_name (GtkActionGroup *action_group)
570 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
572 return action_group->private_data->name;
576 * gtk_action_group_get_sensitive:
577 * @action_group: the action group
579 * Returns %TRUE if the group is sensitive. The constituent actions
580 * can only be logically sensitive (see gtk_action_is_sensitive()) if
581 * they are sensitive (see gtk_action_get_sensitive()) and their group
584 * Return value: %TRUE if the group is sensitive.
589 gtk_action_group_get_sensitive (GtkActionGroup *action_group)
591 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
593 return action_group->private_data->sensitive;
597 cb_set_action_sensitivity (const gchar *name,
600 /* Minor optimization, the action_groups state only affects actions
601 * that are themselves sensitive */
602 if (gtk_action_get_sensitive (action))
603 _gtk_action_sync_sensitive (action);
607 * gtk_action_group_set_sensitive:
608 * @action_group: the action group
609 * @sensitive: new sensitivity
611 * Changes the sensitivity of @action_group
616 gtk_action_group_set_sensitive (GtkActionGroup *action_group,
619 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
621 sensitive = sensitive != FALSE;
623 if (action_group->private_data->sensitive != sensitive)
625 action_group->private_data->sensitive = sensitive;
626 g_hash_table_foreach (action_group->private_data->actions,
627 (GHFunc) cb_set_action_sensitivity, NULL);
629 g_object_notify (G_OBJECT (action_group), "sensitive");
634 * gtk_action_group_get_visible:
635 * @action_group: the action group
637 * Returns %TRUE if the group is visible. The constituent actions
638 * can only be logically visible (see gtk_action_is_visible()) if
639 * they are visible (see gtk_action_get_visible()) and their group
642 * Return value: %TRUE if the group is visible.
647 gtk_action_group_get_visible (GtkActionGroup *action_group)
649 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
651 return action_group->private_data->visible;
655 cb_set_action_visiblity (const gchar *name,
658 /* Minor optimization, the action_groups state only affects actions
659 * that are themselves visible */
660 if (gtk_action_get_visible (action))
661 _gtk_action_sync_visible (action);
665 * gtk_action_group_set_visible:
666 * @action_group: the action group
667 * @visible: new visiblity
669 * Changes the visible of @action_group.
674 gtk_action_group_set_visible (GtkActionGroup *action_group,
677 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
679 visible = visible != FALSE;
681 if (action_group->private_data->visible != visible)
683 action_group->private_data->visible = visible;
684 g_hash_table_foreach (action_group->private_data->actions,
685 (GHFunc) cb_set_action_visiblity, NULL);
687 g_object_notify (G_OBJECT (action_group), "visible");
692 * gtk_action_group_get_action:
693 * @action_group: the action group
694 * @action_name: the name of the action
696 * Looks up an action in the action group by name.
698 * Returns: the action, or %NULL if no action by that name exists
703 gtk_action_group_get_action (GtkActionGroup *action_group,
704 const gchar *action_name)
706 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
707 g_return_val_if_fail (GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action != NULL, NULL);
709 return (* GTK_ACTION_GROUP_GET_CLASS (action_group)->get_action)
710 (action_group, action_name);
714 check_unique_action (GtkActionGroup *action_group,
715 const gchar *action_name)
717 if (gtk_action_group_get_action (action_group, action_name) != NULL)
719 g_warning ("Refusing to add non-unique action '%s' to action group '%s'",
721 action_group->private_data->name);
729 * gtk_action_group_add_action:
730 * @action_group: the action group
733 * Adds an action object to the action group. Note that this function
734 * does not set up the accel path of the action, which can lead to problems
735 * if a user tries to modify the accelerator of a menuitem associated with
736 * the action. Therefore you must either set the accel path yourself with
737 * gtk_action_set_accel_path(), or use
738 * <literal>gtk_action_group_add_action_with_accel (..., NULL)</literal>.
743 gtk_action_group_add_action (GtkActionGroup *action_group,
748 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
749 g_return_if_fail (GTK_IS_ACTION (action));
751 name = gtk_action_get_name (action);
752 g_return_if_fail (name != NULL);
754 if (!check_unique_action (action_group, name))
757 g_hash_table_insert (action_group->private_data->actions,
759 g_object_ref (action));
760 g_object_set (action, I_("action-group"), action_group, NULL);
764 * gtk_action_group_add_action_with_accel:
765 * @action_group: the action group
766 * @action: the action to add
767 * @accelerator: the accelerator for the action, in
768 * the format understood by gtk_accelerator_parse(), or "" for no accelerator, or
769 * %NULL to use the stock accelerator
771 * Adds an action object to the action group and sets up the accelerator.
773 * If @accelerator is %NULL, attempts to use the accelerator associated
774 * with the stock_id of the action.
776 * Accel paths are set to
777 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
782 gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
784 const gchar *accelerator)
788 GdkModifierType accel_mods;
791 name = gtk_action_get_name (action);
792 if (!check_unique_action (action_group, name))
795 accel_path = g_strconcat ("<Actions>/",
796 action_group->private_data->name, "/", name, NULL);
800 if (accelerator[0] == 0)
804 gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
806 g_warning ("Unable to parse accelerator '%s' for action '%s'",
813 GtkStockItem stock_item;
815 g_object_get (action, "stock-id", &stock_id, NULL);
817 if (stock_id && gtk_stock_lookup (stock_id, &stock_item))
819 accel_key = stock_item.keyval;
820 accel_mods = stock_item.modifier;
827 gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
829 gtk_action_set_accel_path (action, accel_path);
830 gtk_action_group_add_action (action_group, action);
836 * gtk_action_group_remove_action:
837 * @action_group: the action group
840 * Removes an action object from the action group.
845 gtk_action_group_remove_action (GtkActionGroup *action_group,
850 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
851 g_return_if_fail (GTK_IS_ACTION (action));
853 name = gtk_action_get_name (action);
854 g_return_if_fail (name != NULL);
856 g_hash_table_remove (action_group->private_data->actions, name);
860 add_single_action (gpointer key,
864 GList **list = user_data;
866 *list = g_list_prepend (*list, value);
870 * gtk_action_group_list_actions:
871 * @action_group: the action group
873 * Lists the actions in the action group.
875 * Returns: an allocated list of the action objects in the action group
880 gtk_action_group_list_actions (GtkActionGroup *action_group)
882 GList *actions = NULL;
883 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), NULL);
885 g_hash_table_foreach (action_group->private_data->actions, add_single_action, &actions);
887 return g_list_reverse (actions);
892 * gtk_action_group_add_actions:
893 * @action_group: the action group
894 * @entries: an array of action descriptions
895 * @n_entries: the number of entries
896 * @user_data: data to pass to the action callbacks
898 * This is a convenience function to create a number of actions and add them
899 * to the action group.
901 * The "activate" signals of the actions are connected to the callbacks and
902 * their accel paths are set to
903 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
908 gtk_action_group_add_actions (GtkActionGroup *action_group,
909 const GtkActionEntry *entries,
913 gtk_action_group_add_actions_full (action_group,
918 typedef struct _SharedData SharedData;
923 GDestroyNotify destroy;
927 shared_data_unref (gpointer data)
929 SharedData *shared_data = (SharedData *)data;
931 shared_data->ref_count--;
932 if (shared_data->ref_count == 0)
934 if (shared_data->destroy)
935 (*shared_data->destroy) (shared_data->data);
937 g_slice_free (SharedData, shared_data);
943 * gtk_action_group_add_actions_full:
944 * @action_group: the action group
945 * @entries: an array of action descriptions
946 * @n_entries: the number of entries
947 * @user_data: data to pass to the action callbacks
948 * @destroy: destroy notification callback for @user_data
950 * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify
951 * callback for @user_data.
956 gtk_action_group_add_actions_full (GtkActionGroup *action_group,
957 const GtkActionEntry *entries,
960 GDestroyNotify destroy)
963 /* Keep this in sync with the other
964 * gtk_action_group_add_..._actions_full() functions.
967 SharedData *shared_data;
969 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
971 shared_data = g_slice_new0 (SharedData);
972 shared_data->ref_count = 1;
973 shared_data->data = user_data;
974 shared_data->destroy = destroy;
976 for (i = 0; i < n_entries; i++)
980 const gchar *tooltip;
982 if (!check_unique_action (action_group, entries[i].name))
985 label = gtk_action_group_translate_string (action_group, entries[i].label);
986 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
988 action = gtk_action_new (entries[i].name,
993 if (entries[i].stock_id)
995 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
996 if (gtk_icon_theme_has_icon (gtk_icon_theme_get_default (),
997 entries[i].stock_id))
998 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1001 if (entries[i].callback)
1005 closure = g_cclosure_new (entries[i].callback, user_data, NULL);
1006 g_closure_add_finalize_notifier (closure, shared_data,
1007 (GClosureNotify)shared_data_unref);
1008 shared_data->ref_count++;
1010 g_signal_connect_closure (action, "activate", closure, FALSE);
1013 gtk_action_group_add_action_with_accel (action_group,
1015 entries[i].accelerator);
1016 g_object_unref (action);
1019 shared_data_unref (shared_data);
1023 * gtk_action_group_add_toggle_actions:
1024 * @action_group: the action group
1025 * @entries: an array of toggle action descriptions
1026 * @n_entries: the number of entries
1027 * @user_data: data to pass to the action callbacks
1029 * This is a convenience function to create a number of toggle actions and add them
1030 * to the action group.
1032 * The "activate" signals of the actions are connected to the callbacks and
1033 * their accel paths are set to
1034 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
1039 gtk_action_group_add_toggle_actions (GtkActionGroup *action_group,
1040 const GtkToggleActionEntry *entries,
1044 gtk_action_group_add_toggle_actions_full (action_group,
1051 * gtk_action_group_add_toggle_actions_full:
1052 * @action_group: the action group
1053 * @entries: an array of toggle action descriptions
1054 * @n_entries: the number of entries
1055 * @user_data: data to pass to the action callbacks
1056 * @destroy: destroy notification callback for @user_data
1058 * This variant of gtk_action_group_add_toggle_actions() adds a
1059 * #GDestroyNotify callback for @user_data.
1064 gtk_action_group_add_toggle_actions_full (GtkActionGroup *action_group,
1065 const GtkToggleActionEntry *entries,
1068 GDestroyNotify destroy)
1070 /* Keep this in sync with the other
1071 * gtk_action_group_add_..._actions_full() functions.
1074 SharedData *shared_data;
1076 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1078 shared_data = g_slice_new0 (SharedData);
1079 shared_data->ref_count = 1;
1080 shared_data->data = user_data;
1081 shared_data->destroy = destroy;
1083 for (i = 0; i < n_entries; i++)
1085 GtkToggleAction *action;
1087 const gchar *tooltip;
1089 if (!check_unique_action (action_group, entries[i].name))
1092 label = gtk_action_group_translate_string (action_group, entries[i].label);
1093 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1095 action = gtk_toggle_action_new (entries[i].name,
1100 if (entries[i].stock_id)
1102 if (gtk_icon_factory_lookup_default (entries[i].stock_id))
1103 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1105 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1108 gtk_toggle_action_set_active (action, entries[i].is_active);
1110 if (entries[i].callback)
1114 closure = g_cclosure_new (entries[i].callback, user_data, NULL);
1115 g_closure_add_finalize_notifier (closure, shared_data,
1116 (GClosureNotify)shared_data_unref);
1117 shared_data->ref_count++;
1119 g_signal_connect_closure (action, "activate", closure, FALSE);
1122 gtk_action_group_add_action_with_accel (action_group,
1123 GTK_ACTION (action),
1124 entries[i].accelerator);
1125 g_object_unref (action);
1128 shared_data_unref (shared_data);
1132 * gtk_action_group_add_radio_actions:
1133 * @action_group: the action group
1134 * @entries: an array of radio action descriptions
1135 * @n_entries: the number of entries
1136 * @value: the value of the action to activate initially, or -1 if
1137 * no action should be activated
1138 * @on_change: the callback to connect to the changed signal
1139 * @user_data: data to pass to the action callbacks
1141 * This is a convenience routine to create a group of radio actions and
1142 * add them to the action group.
1144 * The "changed" signal of the first radio action is connected to the
1145 * @on_change callback and the accel paths of the actions are set to
1146 * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
1151 gtk_action_group_add_radio_actions (GtkActionGroup *action_group,
1152 const GtkRadioActionEntry *entries,
1155 GCallback on_change,
1158 gtk_action_group_add_radio_actions_full (action_group,
1161 on_change, user_data, NULL);
1165 * gtk_action_group_add_radio_actions_full:
1166 * @action_group: the action group
1167 * @entries: an array of radio action descriptions
1168 * @n_entries: the number of entries
1169 * @value: the value of the action to activate initially, or -1 if
1170 * no action should be activated
1171 * @on_change: the callback to connect to the changed signal
1172 * @user_data: data to pass to the action callbacks
1173 * @destroy: destroy notification callback for @user_data
1175 * This variant of gtk_action_group_add_radio_actions() adds a
1176 * #GDestroyNotify callback for @user_data.
1181 gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group,
1182 const GtkRadioActionEntry *entries,
1185 GCallback on_change,
1187 GDestroyNotify destroy)
1189 /* Keep this in sync with the other
1190 * gtk_action_group_add_..._actions_full() functions.
1193 GSList *group = NULL;
1194 GtkRadioAction *first_action = NULL;
1196 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1198 for (i = 0; i < n_entries; i++)
1200 GtkRadioAction *action;
1202 const gchar *tooltip;
1204 if (!check_unique_action (action_group, entries[i].name))
1207 label = gtk_action_group_translate_string (action_group, entries[i].label);
1208 tooltip = gtk_action_group_translate_string (action_group, entries[i].tooltip);
1210 action = gtk_radio_action_new (entries[i].name,
1216 if (entries[i].stock_id)
1218 if (gtk_icon_factory_lookup_default (entries[i].stock_id))
1219 g_object_set (action, "stock-id", entries[i].stock_id, NULL);
1221 g_object_set (action, "icon-name", entries[i].stock_id, NULL);
1225 first_action = action;
1227 gtk_radio_action_set_group (action, group);
1228 group = gtk_radio_action_get_group (action);
1230 if (value == entries[i].value)
1231 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1233 gtk_action_group_add_action_with_accel (action_group,
1234 GTK_ACTION (action),
1235 entries[i].accelerator);
1236 g_object_unref (action);
1239 if (on_change && first_action)
1240 g_signal_connect_data (first_action, "changed",
1241 on_change, user_data,
1242 (GClosureNotify)destroy, 0);
1246 * gtk_action_group_set_translate_func:
1247 * @action_group: a #GtkActionGroup
1248 * @func: a #GtkTranslateFunc
1249 * @data: data to be passed to @func and @notify
1250 * @notify: a #GtkDestroyNotify function to be called when @action_group is
1251 * destroyed and when the translation function is changed again
1253 * Sets a function to be used for translating the @label and @tooltip of
1254 * #GtkActionGroupEntry<!-- -->s added by gtk_action_group_add_actions().
1256 * If you're using gettext(), it is enough to set the translation domain
1257 * with gtk_action_group_set_translation_domain().
1262 gtk_action_group_set_translate_func (GtkActionGroup *action_group,
1263 GtkTranslateFunc func,
1265 GtkDestroyNotify notify)
1267 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1269 if (action_group->private_data->translate_notify)
1270 action_group->private_data->translate_notify (action_group->private_data->translate_data);
1272 action_group->private_data->translate_func = func;
1273 action_group->private_data->translate_data = data;
1274 action_group->private_data->translate_notify = notify;
1278 dgettext_swapped (const gchar *msgid,
1279 const gchar *domainname)
1281 /* Pass through dgettext if and only if msgid is nonempty. */
1282 if (msgid && *msgid)
1283 return dgettext (domainname, msgid);
1285 return (gchar*) msgid;
1289 * gtk_action_group_set_translation_domain:
1290 * @action_group: a #GtkActionGroup
1291 * @domain: the translation domain to use for dgettext() calls
1293 * Sets the translation domain and uses dgettext() for translating the
1294 * @label and @tooltip of #GtkActionEntry<!-- -->s added by
1295 * gtk_action_group_add_actions().
1297 * If you're not using gettext() for localization, see
1298 * gtk_action_group_set_translate_func().
1303 gtk_action_group_set_translation_domain (GtkActionGroup *action_group,
1304 const gchar *domain)
1306 g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
1308 gtk_action_group_set_translate_func (action_group,
1309 (GtkTranslateFunc)dgettext_swapped,
1316 * gtk_action_group_translate_string:
1317 * @action_group: a #GtkActionGroup
1320 * Translates a string using the specified translate_func(). This
1321 * is mainly intended for language bindings.
1323 * Returns: the translation of @string
1327 G_CONST_RETURN gchar *
1328 gtk_action_group_translate_string (GtkActionGroup *action_group,
1329 const gchar *string)
1331 GtkTranslateFunc translate_func;
1332 gpointer translate_data;
1334 g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), string);
1339 translate_func = action_group->private_data->translate_func;
1340 translate_data = action_group->private_data->translate_data;
1343 return translate_func (string, translate_data);
1348 /* Protected for use by GtkAction */
1350 _gtk_action_group_emit_connect_proxy (GtkActionGroup *action_group,
1354 g_signal_emit (action_group, action_group_signals[CONNECT_PROXY], 0,
1359 _gtk_action_group_emit_disconnect_proxy (GtkActionGroup *action_group,
1363 g_signal_emit (action_group, action_group_signals[DISCONNECT_PROXY], 0,
1368 _gtk_action_group_emit_pre_activate (GtkActionGroup *action_group,
1371 g_signal_emit (action_group, action_group_signals[PRE_ACTIVATE], 0, action);
1375 _gtk_action_group_emit_post_activate (GtkActionGroup *action_group,
1378 g_signal_emit (action_group, action_group_signals[POST_ACTIVATE], 0, action);
1381 #define __GTK_ACTION_GROUP_C__
1382 #include "gtkaliasdef.c"