#include <config.h>
#include "gtkactiongroup.h"
+#include "gtkstock.h"
#include "gtktoggleaction.h"
#include "gtkradioaction.h"
#include "gtkaccelmap.h"
+#include "gtkmarshalers.h"
#include "gtkintl.h"
#define GTK_ACTION_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ACTION_GROUP, GtkActionGroupPrivate))
struct _GtkActionGroupPrivate
{
gchar *name;
+ gboolean sensitive;
+ gboolean visible;
GHashTable *actions;
GtkTranslateFunc translate_func;
GtkDestroyNotify translate_notify;
};
-static void gtk_action_group_init (GtkActionGroup *self);
-static void gtk_action_group_class_init (GtkActionGroupClass *class);
+enum
+{
+ CONNECT_PROXY,
+ DISCONNECT_PROXY,
+ PRE_ACTIVATE,
+ POST_ACTIVATE,
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_0,
+ PROP_NAME,
+ PROP_SENSITIVE,
+ PROP_VISIBLE
+};
+
+static void gtk_action_group_init (GtkActionGroup *self);
+static void gtk_action_group_class_init (GtkActionGroupClass *class);
+static void gtk_action_group_finalize (GObject *object);
+static void gtk_action_group_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_action_group_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static GtkAction *gtk_action_group_real_get_action (GtkActionGroup *self,
+ const gchar *name);
+
GType
gtk_action_group_get_type (void)
}
static GObjectClass *parent_class = NULL;
-static void gtk_action_group_finalize (GObject *object);
-static GtkAction *gtk_action_group_real_get_action (GtkActionGroup *self,
- const gchar *name);
+static guint action_group_signals[LAST_SIGNAL] = { 0 };
static void
gtk_action_group_class_init (GtkActionGroupClass *klass)
parent_class = g_type_class_peek_parent (klass);
gobject_class->finalize = gtk_action_group_finalize;
+ gobject_class->set_property = gtk_action_group_set_property;
+ gobject_class->get_property = gtk_action_group_get_property;
klass->get_action = gtk_action_group_real_get_action;
+ g_object_class_install_property (gobject_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ P_("Name"),
+ P_("A name for the action group."),
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (gobject_class,
+ PROP_SENSITIVE,
+ g_param_spec_boolean ("sensitive",
+ P_("Sensitive"),
+ P_("Whether the action group is enabled."),
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_VISIBLE,
+ g_param_spec_boolean ("visible",
+ P_("Visible"),
+ P_("Whether the action group is visible."),
+ TRUE,
+ G_PARAM_READWRITE));
+
+ /**
+ * GtkGroupAction::connect-proxy:
+ * @action_group: the group
+ * @action: the action
+ * @proxy: the proxy
+ *
+ * The connect_proxy signal is emitted after connecting a proxy to
+ * an action in the group. Note that the proxy may have been connected
+ * to a different action before.
+ *
+ * This is intended for simple customizations for which a custom action
+ * class would be too clumsy, e.g. showing tooltips for menuitems in the
+ * statusbar.
+ *
+ * #GtkUIManager proxies the signal and provides global notification
+ * just before any action is connected to a proxy, which is probably more
+ * convenient to use.
+ *
+ * Since: 2.4
+ */
+ action_group_signals[CONNECT_PROXY] =
+ g_signal_new ("connect_proxy",
+ G_OBJECT_CLASS_TYPE (klass),
+ 0, 0, NULL, NULL,
+ _gtk_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_ACTION, GTK_TYPE_WIDGET);
+
+ /**
+ * GtkAction::disconnect-proxy:
+ * @action_group: the group
+ * @action: the action
+ * @proxy: the proxy
+ *
+ * The disconnect_proxy signal is emitted after disconnecting a proxy
+ * from an action in the group.
+ *
+ * #GtkUIManager proxies the signal and provides global notification
+ * just before any action is connected to a proxy, which is probably more
+ * convenient to use.
+ *
+ * Since: 2.4
+ */
+ action_group_signals[DISCONNECT_PROXY] =
+ g_signal_new ("disconnect_proxy",
+ G_OBJECT_CLASS_TYPE (klass),
+ 0, 0, NULL, NULL,
+ _gtk_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_ACTION, GTK_TYPE_WIDGET);
+
+ /**
+ * GtkActionGroup::pre_activate:
+ * @action_group: the group
+ * @action: the action
+ *
+ * The pre_activate signal is emitted just before the @action in the
+ * @action_group is activated
+ *
+ * This is intended for #GtkUIManager to proxy the signal and provide global
+ * notification just before any action is activated.
+ *
+ * Since: 2.4
+ */
+ action_group_signals[PRE_ACTIVATE] =
+ g_signal_new ("pre_activate",
+ G_OBJECT_CLASS_TYPE (klass),
+ 0, 0, NULL, NULL,
+ _gtk_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_ACTION);
+
+ /**
+ * GtkActionGroup::post_activate:
+ * @action_group: the group
+ * @action: the action
+ *
+ * The post_activate signal is emitted just after the @action in the
+ * @action_group is activated
+ *
+ * This is intended for #GtkUIManager to proxy the signal and provide global
+ * notification just after any action is activated.
+ *
+ * Since: 2.4
+ */
+ action_group_signals[POST_ACTIVATE] =
+ g_signal_new ("post_activate",
+ G_OBJECT_CLASS_TYPE (klass),
+ 0, 0, NULL, NULL,
+ _gtk_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_ACTION);
+
g_type_class_add_private (gobject_class, sizeof (GtkActionGroupPrivate));
}
+
+static void
+remove_action (GtkAction *action)
+{
+ g_object_set (action, "action_group", NULL, NULL);
+ g_object_unref (action);
+}
+
static void
gtk_action_group_init (GtkActionGroup *self)
{
self->private_data = GTK_ACTION_GROUP_GET_PRIVATE (self);
self->private_data->name = NULL;
+ self->private_data->sensitive = TRUE;
+ self->private_data->visible = TRUE;
self->private_data->actions = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
+ (GDestroyNotify) remove_action);
self->private_data->translate_func = NULL;
self->private_data->translate_data = NULL;
self->private_data->translate_notify = NULL;
/**
* gtk_action_group_new:
- * @name: the name of the action group
+ * @name: the name of the action group.
*
- * Creates a new #GtkActionGroup object.
+ * Creates a new #GtkActionGroup object. The name of the action group
+ * is used when associating <link linkend="Action-Accel">keybindings</link>
+ * with the actions.
*
* Returns: the new #GtkActionGroup
*
(* parent_class->finalize) (object);
}
+static void
+gtk_action_group_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkActionGroup *self;
+ gchar *tmp;
+
+ self = GTK_ACTION_GROUP (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ tmp = self->private_data->name;
+ self->private_data->name = g_value_dup_string (value);
+ g_free (tmp);
+ break;
+ case PROP_SENSITIVE:
+ gtk_action_group_set_sensitive (self, g_value_get_boolean (value));
+ break;
+ case PROP_VISIBLE:
+ gtk_action_group_set_visible (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_action_group_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkActionGroup *self;
+
+ self = GTK_ACTION_GROUP (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, self->private_data->name);
+ break;
+ case PROP_SENSITIVE:
+ g_value_set_boolean (value, self->private_data->sensitive);
+ break;
+ case PROP_VISIBLE:
+ g_value_set_boolean (value, self->private_data->visible);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
static GtkAction *
gtk_action_group_real_get_action (GtkActionGroup *self,
const gchar *action_name)
return action_group->private_data->name;
}
+/**
+ * gtk_action_group_get_sensitive:
+ * @action_group: the action group
+ *
+ * Returns %TRUE if the group is sensitive. The constituent actions
+ * can only be logically sensitive (see gtk_action_is_sensitive()) if
+ * they are sensitive (see gtk_action_get_sensitive()) and their group
+ * is sensitive.
+ *
+ * Return value: %TRUE if the group is sensitive.
+ *
+ * Since: 2.4
+ */
+gboolean
+gtk_action_group_get_sensitive (GtkActionGroup *action_group)
+{
+ g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
+
+ return action_group->private_data->sensitive;
+}
+
+static void
+cb_set_action_sensitivity (const gchar *name, GtkAction *action)
+{
+ /* Minor optimization, the action_groups state only effects actions that are
+ * themselves sensitive */
+ if (gtk_action_get_sensitive (action))
+ g_object_notify (G_OBJECT (action), "sensitive");
+}
+
+/**
+ * gtk_action_group_set_sensitive:
+ * @action_group: the action group
+ * @sensitive: new sensitivity
+ *
+ * Changes the sensitivity of @action_group
+ *
+ * Since: 2.4
+ */
+void
+gtk_action_group_set_sensitive (GtkActionGroup *action_group, gboolean sensitive)
+{
+ g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+ if (action_group->private_data->sensitive ^ sensitive)
+ {
+ action_group->private_data->sensitive = sensitive;
+ g_hash_table_foreach (action_group->private_data->actions,
+ (GHFunc) cb_set_action_sensitivity, NULL);
+ }
+}
+
+/**
+ * gtk_action_group_get_visible:
+ * @action_group: the action group
+ *
+ * Returns %TRUE if the group is visible. The constituent actions
+ * can only be logically visible (see gtk_action_is_visible()) if
+ * they are visible (see gtk_action_get_visible()) and their group
+ * is visible.
+ *
+ * Return value: %TRUE if the group is sensitive.
+ *
+ * Since: 2.4
+ */
+gboolean
+gtk_action_group_get_visible (GtkActionGroup *action_group)
+{
+ g_return_val_if_fail (GTK_IS_ACTION_GROUP (action_group), FALSE);
+
+ return action_group->private_data->visible;
+}
+
+static void
+cb_set_action_visiblity (const gchar *name, GtkAction *action)
+{
+ /* Minor optimization, the action_groups state only effects actions that are
+ * themselves sensitive */
+ if (gtk_action_get_visible (action))
+ g_object_notify (G_OBJECT (action), "visible");
+}
+
+/**
+ * gtk_action_group_set_visible:
+ * @action_group: the action group
+ * @visible: new visiblity
+ *
+ * Changes the visible of @action_group.
+ *
+ * Since: 2.4
+ */
+void
+gtk_action_group_set_visible (GtkActionGroup *action_group, gboolean visible)
+{
+ g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+ if (action_group->private_data->visible ^ visible)
+ {
+ action_group->private_data->visible = visible;
+ g_hash_table_foreach (action_group->private_data->actions,
+ (GHFunc) cb_set_action_visiblity, NULL);
+ }
+}
+
/**
* gtk_action_group_get_action:
* @action_group: the action group
* @action_group: the action group
* @action: an action
*
- * Adds an action object to the action group.
+ * Adds an action object to the action group. Note that this function
+ * does not set up the accel path of the action, which can lead to problems
+ * if a user tries to modify the accelerator of a menuitem associated with
+ * the action. Therefore you must either set the accel path yourself with
+ * gtk_action_set_accel_path(), or use
+ * <literal>gtk_action_group_add_action_with_accel (..., NULL)</literal>.
*
* Since: 2.4
*/
g_hash_table_insert (action_group->private_data->actions,
g_strdup (gtk_action_get_name (action)),
g_object_ref (action));
+ g_object_set (G_OBJECT (action), "action_group", action_group, NULL);
+}
+
+/**
+ * gtk_action_group_add_action_with_accel:
+ * @action_group: the action group
+ * @action: the action to add
+ * @accelerator: the accelerator for the action, in
+ * the format understood by gtk_accelerator_parse(), or %NULL to use the
+ * stock accelerator
+ *
+ * Adds an action object to the action group and sets up the accelerator.
+ *
+ * If @accelerator is %NULL, attempts to use the accelerator associated
+ * with the stock_id of the action.
+ *
+ * Accel paths are set to
+ * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
+ *
+ * Since: 2.4
+ */
+void
+gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
+ GtkAction *action,
+ const gchar *accelerator)
+{
+ gchar *accel_path;
+ guint accel_key = 0;
+ GdkModifierType accel_mods;
+ GtkStockItem stock_item;
+ gchar *name;
+ gchar *stock_id;
+
+ g_object_get (action, "name", &name, "stock_id", &stock_id, NULL);
+
+ accel_path = g_strconcat ("<Actions>/",
+ action_group->private_data->name, "/", name, NULL);
+
+ if (accelerator)
+ gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
+ else if (stock_id && gtk_stock_lookup (stock_id, &stock_item))
+ {
+ accel_key = stock_item.keyval;
+ accel_mods = stock_item.modifier;
+ }
+
+ if (accel_key)
+ gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
+
+ gtk_action_set_accel_path (action, accel_path);
+ gtk_action_group_add_action (action_group, action);
+
+ g_free (accel_path);
+ g_free (stock_id);
+ g_free (name);
}
/**
- * gtk_action_group_removes_action:
+ * gtk_action_group_remove_action:
* @action_group: the action group
* @action: an action
*
* @action_group: the action group
* @entries: an array of action descriptions
* @n_entries: the number of entries
+ * @user_data: data to pass to the action callbacks
+ *
+ * This is a convenience function to create a number of actions and add them
+ * to the action group.
+ *
+ * The "activate" signals of the actions are connected to the callbacks and
+ * their accel paths are set to
+ * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
+ *
+ * Since: 2.4
+ */
+void
+gtk_action_group_add_actions (GtkActionGroup *action_group,
+ GtkActionEntry *entries,
+ guint n_entries,
+ gpointer user_data)
+{
+ gtk_action_group_add_actions_full (action_group,
+ entries, n_entries,
+ user_data, NULL);
+}
+
+typedef struct _SharedData SharedData;
+
+struct _SharedData {
+ guint ref_count;
+ gpointer data;
+ GDestroyNotify destroy;
+};
+
+static void
+shared_data_unref (gpointer data)
+{
+ SharedData *shared_data = (SharedData *)data;
+
+ shared_data->ref_count--;
+ if (shared_data->ref_count == 0)
+ {
+ if (shared_data->destroy)
+ (*shared_data->destroy) (shared_data->data);
+
+ g_free (shared_data);
+ }
+}
+
+
+/**
+ * gtk_action_group_add_actions_full:
+ * @action_group: the action group
+ * @entries: an array of action descriptions
+ * @n_entries: the number of entries
+ * @user_data: data to pass to the action callbacks
+ * @destroy: destroy notification callback for @user_data
*
- * This is a convenience routine to create a number of actions and add
- * them to the action group. Each member of the array describes an
- * action to create.
+ * This variant of gtk_action_group_add_actions() adds a #GDestroyNotify
+ * callback for @user_data.
*
* Since: 2.4
*/
void
-gtk_action_group_add_actions (GtkActionGroup *action_group,
- GtkActionGroupEntry *entries,
- guint n_entries)
+gtk_action_group_add_actions_full (GtkActionGroup *action_group,
+ GtkActionEntry *entries,
+ guint n_entries,
+ gpointer user_data,
+ GDestroyNotify destroy)
{
+
+ /* Keep this in sync with the other
+ * gtk_action_group_add_..._actions_full() functions.
+ */
guint i;
GtkTranslateFunc translate_func;
gpointer translate_data;
+ SharedData *shared_data;
g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
translate_func = action_group->private_data->translate_func;
translate_data = action_group->private_data->translate_data;
+ shared_data = g_new0 (SharedData, 1);
+ shared_data->ref_count = 1;
+ shared_data->data = user_data;
+ shared_data->destroy = destroy;
+
for (i = 0; i < n_entries; i++)
{
GtkAction *action;
- GType action_type;
- gchar *accel_path;
- gchar *label;
- gchar *tooltip;
-
- switch (entries[i].entry_type) {
- case GTK_ACTION_NORMAL:
- action_type = GTK_TYPE_ACTION;
- break;
- case GTK_ACTION_TOGGLE:
- action_type = GTK_TYPE_TOGGLE_ACTION;
- break;
- case GTK_ACTION_RADIO:
- action_type = GTK_TYPE_RADIO_ACTION;
- break;
- default:
- g_warning ("unsupported action type");
- action_type = GTK_TYPE_ACTION;
- }
+ const gchar *label;
+ const gchar *tooltip;
if (translate_func)
{
tooltip = entries[i].tooltip;
}
- action = g_object_new (action_type,
- "name", entries[i].name,
- "label", label,
- "tooltip", tooltip,
- "stock_id", entries[i].stock_id,
- NULL);
+ action = gtk_action_new (entries[i].name,
+ label,
+ tooltip,
+ entries[i].stock_id);
- if (entries[i].entry_type == GTK_ACTION_RADIO &&
- entries[i].extra_data != NULL)
+ if (entries[i].callback)
{
- GtkAction *radio_action;
- GSList *group;
-
- radio_action =
- gtk_action_group_get_action (GTK_ACTION_GROUP (action_group),
- entries[i].extra_data);
- if (radio_action)
- {
- group = gtk_radio_action_get_group (GTK_RADIO_ACTION (radio_action));
- gtk_radio_action_set_group (GTK_RADIO_ACTION (action), group);
- }
- else
- g_warning (G_STRLOC " could not look up `%s'", entries[i].extra_data);
+ GClosure *closure;
+
+ closure = g_cclosure_new (entries[i].callback, user_data, NULL);
+ g_closure_add_finalize_notifier (closure, shared_data,
+ (GClosureNotify)shared_data_unref);
+ shared_data->ref_count++;
+
+ g_signal_connect_closure (action, "activate", closure, FALSE);
}
+
+ gtk_action_group_add_action_with_accel (action_group,
+ action,
+ entries[i].accelerator);
+ g_object_unref (action);
+ }
- if (entries[i].callback)
- g_signal_connect (action, "activate",
- entries[i].callback, entries[i].user_data);
+ shared_data_unref (shared_data);
+}
+
+/**
+ * gtk_action_group_add_toggle_actions:
+ * @action_group: the action group
+ * @entries: an array of toggle action descriptions
+ * @n_entries: the number of entries
+ * @user_data: data to pass to the action callbacks
+ *
+ * This is a convenience function to create a number of toggle actions and add them
+ * to the action group.
+ *
+ * The "activate" signals of the actions are connected to the callbacks and
+ * their accel paths are set to
+ * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
+ *
+ * Since: 2.4
+ */
+void
+gtk_action_group_add_toggle_actions (GtkActionGroup *action_group,
+ GtkToggleActionEntry *entries,
+ guint n_entries,
+ gpointer user_data)
+{
+ gtk_action_group_add_toggle_actions_full (action_group,
+ entries, n_entries,
+ user_data, NULL);
+}
+
+
+/**
+ * gtk_action_group_add_toggle_actions_full:
+ * @action_group: the action group
+ * @entries: an array of toggle action descriptions
+ * @n_entries: the number of entries
+ * @user_data: data to pass to the action callbacks
+ * @destroy: destroy notification callback for @user_data
+ *
+ * This variant of gtk_action_group_add_toggle_actions() adds a
+ * #GDestroyNotify callback for @user_data.
+ *
+ * Since: 2.4
+ */
+void
+gtk_action_group_add_toggle_actions_full (GtkActionGroup *action_group,
+ GtkToggleActionEntry *entries,
+ guint n_entries,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ /* Keep this in sync with the other
+ * gtk_action_group_add_..._actions_full() functions.
+ */
+ guint i;
+ GtkTranslateFunc translate_func;
+ gpointer translate_data;
+ SharedData *shared_data;
- /* set the accel path for the menu item */
- accel_path = g_strconcat ("<Actions>/", action_group->private_data->name, "/",
- entries[i].name, NULL);
- if (entries[i].accelerator)
+ g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+ translate_func = action_group->private_data->translate_func;
+ translate_data = action_group->private_data->translate_data;
+
+ shared_data = g_new0 (SharedData, 1);
+ shared_data->ref_count = 1;
+ shared_data->data = user_data;
+ shared_data->destroy = destroy;
+
+ for (i = 0; i < n_entries; i++)
+ {
+ GtkToggleAction *action;
+ const gchar *label;
+ const gchar *tooltip;
+
+ if (translate_func)
+ {
+ label = translate_func (entries[i].label, translate_data);
+ tooltip = translate_func (entries[i].tooltip, translate_data);
+ }
+ else
+ {
+ label = entries[i].label;
+ tooltip = entries[i].tooltip;
+ }
+
+ action = gtk_toggle_action_new (entries[i].name,
+ label,
+ tooltip,
+ entries[i].stock_id);
+
+ gtk_toggle_action_set_active (action, entries[i].is_active);
+
+ if (entries[i].callback)
{
- guint accel_key = 0;
- GdkModifierType accel_mods;
+ GClosure *closure;
+
+ closure = g_cclosure_new (entries[i].callback, user_data, NULL);
+ g_closure_add_finalize_notifier (closure, shared_data,
+ (GClosureNotify)shared_data_unref);
+ shared_data->ref_count++;
- gtk_accelerator_parse (entries[i].accelerator, &accel_key,
- &accel_mods);
- if (accel_key)
- gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
+ g_signal_connect_closure (action, "activate", closure, FALSE);
}
+
+ gtk_action_group_add_action_with_accel (action_group,
+ GTK_ACTION (action),
+ entries[i].accelerator);
+ g_object_unref (action);
+ }
+
+ shared_data_unref (shared_data);
+}
+
+/**
+ * gtk_action_group_add_radio_actions:
+ * @action_group: the action group
+ * @entries: an array of radio action descriptions
+ * @n_entries: the number of entries
+ * @value: the value of the action to activate initially, or -1 if
+ * no action should be activated
+ * @on_change: the callback to connect to the changed signal
+ * @user_data: data to pass to the action callbacks
+ *
+ * This is a convenience routine to create a group of radio actions and
+ * add them to the action group.
+ *
+ * The "changed" signal of the first radio action is connected to the
+ * @on_change callback and the accel paths of the actions are set to
+ * <literal><Actions>/<replaceable>group-name</replaceable>/<replaceable>action-name</replaceable></literal>.
+ *
+ * Since: 2.4
+ **/
+void
+gtk_action_group_add_radio_actions (GtkActionGroup *action_group,
+ GtkRadioActionEntry *entries,
+ guint n_entries,
+ gint value,
+ GCallback on_change,
+ gpointer user_data)
+{
+ gtk_action_group_add_radio_actions_full (action_group,
+ entries, n_entries,
+ value,
+ on_change, user_data, NULL);
+}
+
+/**
+ * gtk_action_group_add_radio_actions_full:
+ * @action_group: the action group
+ * @entries: an array of radio action descriptions
+ * @n_entries: the number of entries
+ * @value: the value of the action to activate initially, or -1 if
+ * no action should be activated
+ * @on_change: the callback to connect to the changed signal
+ * @user_data: data to pass to the action callbacks
+ * @destroy: destroy notification callback for @user_data
+ *
+ * This variant of gtk_action_group_add_radio_actions() adds a
+ * #GDestroyNotify callback for @user_data.
+ *
+ * Since: 2.4
+ **/
+void
+gtk_action_group_add_radio_actions_full (GtkActionGroup *action_group,
+ GtkRadioActionEntry *entries,
+ guint n_entries,
+ gint value,
+ GCallback on_change,
+ gpointer user_data,
+ GDestroyNotify destroy)
+{
+ /* Keep this in sync with the other
+ * gtk_action_group_add_..._actions_full() functions.
+ */
+ guint i;
+ GtkTranslateFunc translate_func;
+ gpointer translate_data;
+ GSList *group = NULL;
+ GtkRadioAction *first_action = NULL;
+
+ g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+ translate_func = action_group->private_data->translate_func;
+ translate_data = action_group->private_data->translate_data;
+
+ for (i = 0; i < n_entries; i++)
+ {
+ GtkRadioAction *action;
+ const gchar *label;
+ const gchar *tooltip;
- gtk_action_set_accel_path (action, accel_path);
- g_free (accel_path);
+ if (translate_func)
+ {
+ label = translate_func (entries[i].label, translate_data);
+ tooltip = translate_func (entries[i].tooltip, translate_data);
+ }
+ else
+ {
+ label = entries[i].label;
+ tooltip = entries[i].tooltip;
+ }
+
+ action = gtk_radio_action_new (entries[i].name,
+ label,
+ tooltip,
+ entries[i].stock_id,
+ entries[i].value);
- gtk_action_group_add_action (action_group, action);
+ if (i == 0)
+ first_action = action;
+
+ gtk_radio_action_set_group (action, group);
+ group = gtk_radio_action_get_group (action);
+
+ if (value == entries[i].value)
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
+
+ gtk_action_group_add_action_with_accel (action_group,
+ GTK_ACTION (action),
+ entries[i].accelerator);
g_object_unref (action);
}
+
+ if (on_change && first_action)
+ g_signal_connect_data (first_action, "changed",
+ on_change, user_data,
+ (GClosureNotify)destroy, 0);
}
/**
* @domain: the translation domain to use for dgettext() calls
*
* Sets the translation domain and uses dgettext() for translating the
- * @label and @tooltip of #GtkActionGroupEntry<!-- -->s added by
+ * @label and @tooltip of #GtkActionEntry<!-- -->s added by
* gtk_action_group_add_actions().
*
* If you're not using gettext() for localization, see
g_strdup (domain),
g_free);
}
+
+/* Protected for use by GtkAction */
+void
+_gtk_action_group_emit_connect_proxy (GtkActionGroup *action_group,
+ GtkAction *action,
+ GtkWidget *proxy)
+{
+ g_signal_emit (action_group, action_group_signals[CONNECT_PROXY], 0,
+ action, proxy);
+}
+
+void
+_gtk_action_group_emit_disconnect_proxy (GtkActionGroup *action_group,
+ GtkAction *action,
+ GtkWidget *proxy)
+{
+ g_signal_emit (action_group, action_group_signals[DISCONNECT_PROXY], 0,
+ action, proxy);
+}
+
+void
+_gtk_action_group_emit_pre_activate (GtkActionGroup *action_group,
+ GtkAction *action)
+{
+ g_signal_emit (action_group, action_group_signals[PRE_ACTIVATE], 0, action);
+}
+
+void
+_gtk_action_group_emit_post_activate (GtkActionGroup *action_group,
+ GtkAction *action)
+{
+ g_signal_emit (action_group, action_group_signals[POST_ACTIVATE], 0, action);
+}