g_object_class_install_property (gobject_class,
PROP_NAME,
g_param_spec_string ("name",
- _("Name"),
- _("A name for the action group."),
+ 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",
- _("Sensitive"),
- _("Whether the action group is enabled."),
+ 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",
- _("Visible"),
- _("Whether the action group is visible."),
+ P_("Visible"),
+ P_("Whether the action group is visible."),
TRUE,
G_PARAM_READWRITE));
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->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;
* @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
*/
guint accel_key = 0;
GdkModifierType accel_mods;
GtkStockItem stock_item;
- const gchar *name;
- const gchar *stock_id;
+ gchar *name;
+ gchar *stock_id;
g_object_get (action, "name", &name, "stock_id", &stock_id, NULL);
action_group->private_data->name, "/", name, NULL);
if (accelerator)
+ {
gtk_accelerator_parse (accelerator, &accel_key, &accel_mods);
+ if (accel_key == 0)
+ g_warning ("Unable to parse accelerator '%s' for action '%s'",
+ accelerator, name);
+ }
else if (stock_id && gtk_stock_lookup (stock_id, &stock_item))
{
accel_key = stock_item.keyval;
gtk_accel_map_add_entry (accel_path, accel_key, accel_mods);
gtk_action_set_accel_path (action, accel_path);
- g_free (accel_path);
-
gtk_action_group_add_action (action_group, action);
+
+ g_free (accel_path);
+ g_free (stock_id);
+ g_free (name);
}
/**
/* extra protection to make sure action->name is valid */
g_object_ref (action);
g_hash_table_remove (action_group->private_data->actions, gtk_action_get_name (action));
- g_object_set (G_OBJECT (action), "action_group", NULL, NULL);
g_object_unref (action);
}
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:
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;
entries[i].stock_id);
if (entries[i].callback)
- g_signal_connect_data (action, "activate",
- entries[i].callback,
- user_data, (GClosureNotify)destroy, 0);
+ {
+ 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);
}
+
+ shared_data_unref (shared_data);
}
/**
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++)
{
GtkToggleAction *action;
gtk_toggle_action_set_active (action, entries[i].is_active);
if (entries[i].callback)
- g_signal_connect_data (action, "activate",
- entries[i].callback,
- user_data, (GClosureNotify)destroy, 0);
+ {
+ 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,
GTK_ACTION (action),
entries[i].accelerator);
g_object_unref (action);
}
+
+ shared_data_unref (shared_data);
}
/**
label,
tooltip,
entries[i].stock_id,
- value);
+ entries[i].value);
if (i == 0)
first_action = action;