]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkactiongroup.c
Use _gtk_action_emit_activate() instead of directly emitting the activate
[~andy/gtk] / gtk / gtkactiongroup.c
index 4c3ef728e197d5fb0ef1107231ad9b1a5362fe23..f265bd2c298a2007ca3a2e4efaa65426519914cb 100644 (file)
@@ -130,23 +130,23 @@ gtk_action_group_class_init (GtkActionGroupClass *klass)
   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));
 
@@ -246,6 +246,14 @@ gtk_action_group_class_init (GtkActionGroupClass *klass)
   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)
 {
@@ -255,7 +263,7 @@ 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;
@@ -517,7 +525,12 @@ gtk_action_group_get_action (GtkActionGroup *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
  */
@@ -562,8 +575,8 @@ gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
   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);
 
@@ -571,7 +584,12 @@ gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
                            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;
@@ -582,9 +600,11 @@ gtk_action_group_add_action_with_accel (GtkActionGroup *action_group,
     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);
 }
 
 /**
@@ -607,7 +627,6 @@ gtk_action_group_remove_action (GtkActionGroup *action_group,
   /* 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);
 }
 
@@ -670,6 +689,29 @@ gtk_action_group_add_actions (GtkActionGroup *action_group,
                                     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:
@@ -698,12 +740,18 @@ gtk_action_group_add_actions_full (GtkActionGroup *action_group,
   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;
@@ -727,15 +775,24 @@ gtk_action_group_add_actions_full (GtkActionGroup *action_group,
                               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);
 }
 
 /**
@@ -792,12 +849,18 @@ gtk_action_group_add_toggle_actions_full (GtkActionGroup       *action_group,
   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;
@@ -823,15 +886,24 @@ gtk_action_group_add_toggle_actions_full (GtkActionGroup       *action_group,
       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);
 }
 
 /**
@@ -927,7 +999,7 @@ gtk_action_group_add_radio_actions_full (GtkActionGroup      *action_group,
                                     label,
                                     tooltip,
                                     entries[i].stock_id,
-                                    value);
+                                    entries[i].value);
 
       if (i == 0) 
        first_action = action;