[glib] GActionGroup is now an interface



commit 6cd62920bbb8ed42c7381bb56deca820515500f9
Author: Ryan Lortie <desrt desrt ca>
Date:   Mon Aug 30 17:31:06 2010 +0200

    GActionGroup is now an interface
    
     - make GAction.get_state() return a reference
     - fix some leaks/warnings in the tests
     - fix signal propagation in GSimpleActionGroup

 gio/gaction.c            |    9 +++--
 gio/gactiongroup.c       |   46 +++++++++++++----------
 gio/gactiongroup.h       |   43 ++++------------------
 gio/gsimpleactiongroup.c |   89 +++++++++++++++++----------------------------
 gio/gsimpleactiongroup.h |    8 +---
 gio/tests/actions.c      |   21 +++++++----
 6 files changed, 90 insertions(+), 126 deletions(-)
---
diff --git a/gio/gaction.c b/gio/gaction.c
index e7c5f00..3b3b642 100644
--- a/gio/gaction.c
+++ b/gio/gaction.c
@@ -195,7 +195,7 @@ g_action_get_property (GObject    *object,
       break;
 
     case PROP_STATE:
-      g_value_set_variant (value, g_action_get_state (action));
+      g_value_take_variant (value, g_action_get_state (action));
       break;
 
     default:
@@ -398,7 +398,10 @@ g_action_set_state (GAction  *action,
  * action is stateful then the type of the return value is the type
  * given by g_action_get_state_type().
  *
- * Returns: (allow-none) (transfer none): the current state of the action
+ * The return value should be released with g_variant_unref() when it is
+ * no longer required.
+ *
+ * Returns: (allow-none): the current state of the action
  *
  * Since: 2.26
  **/
@@ -407,7 +410,7 @@ g_action_get_state (GAction *action)
 {
   g_return_val_if_fail (G_IS_ACTION (action), NULL);
 
-  return action->priv->state;
+  return action->priv->state ? g_variant_ref (action->priv->state) : NULL;
 }
 
 /**
diff --git a/gio/gactiongroup.c b/gio/gactiongroup.c
index 253d51b..e162475 100644
--- a/gio/gactiongroup.c
+++ b/gio/gactiongroup.c
@@ -48,7 +48,7 @@
  * on individual actions.
  **/
 
-G_DEFINE_ABSTRACT_TYPE (GActionGroup, g_action_group, G_TYPE_OBJECT)
+G_DEFINE_INTERFACE (GActionGroup, g_action_group, G_TYPE_OBJECT)
 
 enum
 {
@@ -62,12 +62,7 @@ enum
 static guint g_action_group_signals[NR_SIGNALS];
 
 static void
-g_action_group_init (GActionGroup *action_group)
-{
-}
-
-static void
-g_action_group_class_init (GActionGroupClass *class)
+g_action_group_default_init (GActionGroupInterface *class)
 {
   /**
    * GActionGroup::action-added:
@@ -83,7 +78,7 @@ g_action_group_class_init (GActionGroupClass *class)
     g_signal_new (I_("action-added"),
                   G_TYPE_ACTION_GROUP,
                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
-                  G_STRUCT_OFFSET (GActionGroupClass, action_added),
+                  G_STRUCT_OFFSET (GActionGroupInterface, action_added),
                   NULL, NULL,
                   g_cclosure_marshal_VOID__STRING,
                   G_TYPE_NONE, 1,
@@ -104,7 +99,7 @@ g_action_group_class_init (GActionGroupClass *class)
     g_signal_new (I_("action-removed"),
                   G_TYPE_ACTION_GROUP,
                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
-                  G_STRUCT_OFFSET (GActionGroupClass, action_removed),
+                  G_STRUCT_OFFSET (GActionGroupInterface, action_removed),
                   NULL, NULL,
                   g_cclosure_marshal_VOID__STRING,
                   G_TYPE_NONE, 1,
@@ -125,7 +120,8 @@ g_action_group_class_init (GActionGroupClass *class)
     g_signal_new (I_("action-enabled-changed"),
                   G_TYPE_ACTION_GROUP,
                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
-                  G_STRUCT_OFFSET (GActionGroupClass, action_enabled_changed),
+                  G_STRUCT_OFFSET (GActionGroupInterface,
+                                   action_enabled_changed),
                   NULL, NULL,
                   _gio_marshal_VOID__STRING_BOOLEAN,
                   G_TYPE_NONE, 2,
@@ -146,7 +142,8 @@ g_action_group_class_init (GActionGroupClass *class)
     g_signal_new (I_("action-state-changed"),
                   G_TYPE_ACTION_GROUP,
                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
-                  G_STRUCT_OFFSET (GActionGroupClass, action_state_changed),
+                  G_STRUCT_OFFSET (GActionGroupInterface,
+                                   action_state_changed),
                   NULL, NULL,
                   _gio_marshal_VOID__STRING_VARIANT,
                   G_TYPE_NONE, 2,
@@ -172,7 +169,8 @@ g_action_group_list_actions (GActionGroup *action_group)
 {
   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
 
-  return G_ACTION_GROUP_GET_CLASS (action_group)->list_actions (action_group);
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->list_actions (action_group);
 }
 
 /**
@@ -192,7 +190,8 @@ g_action_group_has_action (GActionGroup *action_group,
 {
   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
 
-  return G_ACTION_GROUP_GET_CLASS (action_group)->has_action (action_group, action_name);
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->has_action (action_group, action_name);
 }
 
 /**
@@ -224,7 +223,8 @@ g_action_group_get_parameter_type (GActionGroup *action_group,
 {
   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
 
-  return G_ACTION_GROUP_GET_CLASS (action_group)->get_parameter_type (action_group, action_name);
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_parameter_type (action_group, action_name);
 }
 
 /**
@@ -258,7 +258,8 @@ g_action_group_get_state_type (GActionGroup *action_group,
 {
   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
 
-  return G_ACTION_GROUP_GET_CLASS (action_group)->get_state_type (action_group, action_name);
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_state_type (action_group, action_name);
 }
 
 /**
@@ -295,7 +296,8 @@ g_action_group_get_state_hint (GActionGroup *action_group,
 {
   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
 
-  return G_ACTION_GROUP_GET_CLASS (action_group)->get_state_hint (action_group, action_name);
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_state_hint (action_group, action_name);
 }
 
 /**
@@ -318,7 +320,8 @@ g_action_group_get_enabled (GActionGroup *action_group,
 {
   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), FALSE);
 
-  return G_ACTION_GROUP_GET_CLASS (action_group)->get_enabled (action_group, action_name);
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_enabled (action_group, action_name);
 }
 
 /**
@@ -345,7 +348,8 @@ g_action_group_get_state (GActionGroup *action_group,
 {
   g_return_val_if_fail (G_IS_ACTION_GROUP (action_group), NULL);
 
-  return G_ACTION_GROUP_GET_CLASS (action_group)->get_state (action_group, action_name);
+  return G_ACTION_GROUP_GET_IFACE (action_group)
+    ->get_state (action_group, action_name);
 }
 
 /**
@@ -377,7 +381,8 @@ g_action_group_set_state (GActionGroup *action_group,
   g_return_if_fail (action_name != NULL);
   g_return_if_fail (value != NULL);
 
-  G_ACTION_GROUP_GET_CLASS (action_group)->set_state (action_group, action_name, value);
+  G_ACTION_GROUP_GET_IFACE (action_group)
+    ->set_state (action_group, action_name, value);
 }
 
 /**
@@ -403,7 +408,8 @@ g_action_group_activate (GActionGroup *action_group,
   g_return_if_fail (G_IS_ACTION_GROUP (action_group));
   g_return_if_fail (action_name != NULL);
 
-  G_ACTION_GROUP_GET_CLASS (action_group)->activate (action_group, action_name, parameter);
+  G_ACTION_GROUP_GET_IFACE (action_group)
+    ->activate (action_group, action_name, parameter);
 }
 
 /**
diff --git a/gio/gactiongroup.h b/gio/gactiongroup.h
index e0f7a2d..590e9ae 100644
--- a/gio/gactiongroup.h
+++ b/gio/gactiongroup.h
@@ -33,33 +33,15 @@ G_BEGIN_DECLS
 #define G_TYPE_ACTION_GROUP                                 (g_action_group_get_type ())
 #define G_ACTION_GROUP(inst)                                (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
                                                              G_TYPE_ACTION_GROUP, GActionGroup))
-#define G_ACTION_GROUP_CLASS(class)                         (G_TYPE_CHECK_CLASS_CAST ((class),                       \
-                                                             G_TYPE_ACTION_GROUP, GActionGroupClass))
-#define G_IS_ACTION_GROUP(inst)                             (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_ACTION_GROUP))
-#define G_IS_ACTION_GROUP_CLASS(class)                      (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_ACTION_GROUP))
-#define G_ACTION_GROUP_GET_CLASS(inst)                      (G_TYPE_INSTANCE_GET_CLASS ((inst),                      \
-                                                             G_TYPE_ACTION_GROUP, GActionGroupClass))
+#define G_IS_ACTION_GROUP(inst)                             (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
+                                                             G_TYPE_ACTION_GROUP))
+#define G_ACTION_GROUP_GET_IFACE(inst)                      (G_TYPE_INSTANCE_GET_INTERFACE ((inst),                  \
+                                                             G_TYPE_ACTION_GROUP, GActionGroupInterface))
 
-typedef struct _GActionGroupPrivate                         GActionGroupPrivate;
-typedef struct _GActionGroupClass                           GActionGroupClass;
+typedef struct _GActionGroupInterface                       GActionGroupInterface;
 
 /**
- * GActionGroup:
- *
- * The #GActionGroup structure contains private data and should only be accessed using the provided API.
- *
- * Since: 2.26
- */
-struct _GActionGroup
-{
-  /*< private >*/
-  GObject parent_instance;
-
-  GActionGroupPrivate *priv;
-};
-
-/**
- * GActionGroupClass:
+ * GActionGroupInterface:
  * @has_action: the virtual function pointer for g_action_group_has_action()
  * @list_actions: the virtual function pointer for g_action_group_list_actions()
  * @get_parameter_type: the virtual function pointer for g_action_group_get_parameter_type()
@@ -78,12 +60,10 @@ struct _GActionGroup
  *
  * Since: 2.26
  */
-struct _GActionGroupClass
+struct _GActionGroupInterface
 {
-  /*< private >*/
-  GObjectClass parent_class;
+  GTypeInterface g_iface;
 
-  /*< public >*/
   /* virtual functions */
   gboolean              (* has_action)              (GActionGroup  *action_group,
                                                      const gchar   *action_name);
@@ -113,10 +93,6 @@ struct _GActionGroupClass
                                                      const gchar   *action_name,
                                                      GVariant      *parameter);
 
-  /*< private >*/
-  gpointer vtable_padding[6];
-
-  /*< public >*/
   /* signals */
   void                  (* action_added)            (GActionGroup  *action_group,
                                                      const gchar   *action_name);
@@ -128,9 +104,6 @@ struct _GActionGroupClass
   void                  (* action_state_changed)    (GActionGroup   *action_group,
                                                      const gchar    *action_name,
                                                      GVariant       *value);
-
-  /*< private >*/
-  gpointer signal_padding[6];
 };
 
 GType                   g_action_group_get_type                         (void) G_GNUC_CONST;
diff --git a/gio/gsimpleactiongroup.c b/gio/gsimpleactiongroup.c
index dc3451d..dd17022 100644
--- a/gio/gsimpleactiongroup.c
+++ b/gio/gsimpleactiongroup.c
@@ -36,7 +36,11 @@ struct _GSimpleActionGroupPrivate
   GHashTable *table;  /* string -> GAction */
 };
 
-G_DEFINE_TYPE (GSimpleActionGroup, g_simple_action_group, G_TYPE_ACTION_GROUP)
+static void g_simple_action_group_iface_init (GActionGroupInterface *);
+G_DEFINE_TYPE_WITH_CODE (GSimpleActionGroup,
+  g_simple_action_group, G_TYPE_OBJECT,
+  G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
+    g_simple_action_group_iface_init))
 
 static gchar **
 g_simple_action_group_list_actions (GActionGroup *group)
@@ -176,23 +180,27 @@ g_simple_action_group_activate (GActionGroup *group,
 }
 
 static void
-action_enabled_changed (GAction  *action,
-                        gboolean  enabled,
-                        gpointer  user_data)
+action_enabled_notify (GAction     *action,
+                       GParamSpec  *pspec,
+                       gpointer     user_data)
 {
   g_action_group_action_enabled_changed (user_data,
                                          g_action_get_name (action),
-                                         enabled);
+                                         g_action_get_enabled (action));
 }
 
 static void
-action_state_changed (GAction  *action,
-                      GVariant *value,
-                      gpointer  user_data)
+action_state_notify (GAction    *action,
+                     GParamSpec *pspec,
+                     gpointer    user_data)
 {
+  GVariant *value;
+
+  value = g_action_get_state (action);
   g_action_group_action_state_changed (user_data,
                                        g_action_get_name (action),
                                        value);
+  g_variant_unref (value);
 }
 
 static void
@@ -200,9 +208,9 @@ g_simple_action_group_disconnect (gpointer key,
                                   gpointer value,
                                   gpointer user_data)
 {
-  g_signal_handlers_disconnect_by_func (value, action_enabled_changed,
+  g_signal_handlers_disconnect_by_func (value, action_enabled_notify,
                                         user_data);
-  g_signal_handlers_disconnect_by_func (value, action_state_changed,
+  g_signal_handlers_disconnect_by_func (value, action_state_notify,
                                         user_data);
 }
 
@@ -233,24 +241,27 @@ g_simple_action_group_init (GSimpleActionGroup *simple)
 static void
 g_simple_action_group_class_init (GSimpleActionGroupClass *class)
 {
-  GActionGroupClass *group_class = G_ACTION_GROUP_CLASS (class);
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
   object_class->finalize = g_simple_action_group_finalize;
 
-  group_class->list_actions = g_simple_action_group_list_actions;
-  group_class->has_action = g_simple_action_group_has_action;
-  group_class->get_parameter_type = g_simple_action_group_get_parameter_type;
-  group_class->get_state_type = g_simple_action_group_get_state_type;
-  group_class->get_state_hint = g_simple_action_group_get_state_hint;
-  group_class->get_enabled = g_simple_action_group_get_enabled;
-  group_class->get_state = g_simple_action_group_get_state;
-  group_class->set_state = g_simple_action_group_set_state;
-  group_class->activate = g_simple_action_group_activate;
-
   g_type_class_add_private (class, sizeof (GSimpleActionGroupPrivate));
 }
 
+static void
+g_simple_action_group_iface_init (GActionGroupInterface *iface)
+{
+  iface->list_actions = g_simple_action_group_list_actions;
+  iface->has_action = g_simple_action_group_has_action;
+  iface->get_parameter_type = g_simple_action_group_get_parameter_type;
+  iface->get_state_type = g_simple_action_group_get_state_type;
+  iface->get_state_hint = g_simple_action_group_get_state_hint;
+  iface->get_enabled = g_simple_action_group_get_enabled;
+  iface->get_state = g_simple_action_group_get_state;
+  iface->set_state = g_simple_action_group_set_state;
+  iface->activate = g_simple_action_group_activate;
+}
+
 /**
  * g_simple_action_group_new:
  *
@@ -325,11 +336,11 @@ g_simple_action_group_insert (GSimpleActionGroup *simple,
         }
 
       g_signal_connect (action, "notify::enabled",
-                        G_CALLBACK (action_enabled_changed), simple);
+                        G_CALLBACK (action_enabled_notify), simple);
 
       if (g_action_get_state_type (action) != NULL)
         g_signal_connect (action, "notify::state",
-                          G_CALLBACK (action_state_changed), simple);
+                          G_CALLBACK (action_state_notify), simple);
 
       g_hash_table_insert (simple->priv->table,
                            g_strdup (action_name),
@@ -367,35 +378,3 @@ g_simple_action_group_remove (GSimpleActionGroup *simple,
       g_hash_table_remove (simple->priv->table, action_name);
     }
 }
-
-/**
- * g_simple_action_group_set_enabled:
- * @simple: a #GSimpleActionGroup
- * @action_name: the name of an action
- * @enabled: if the action should be enabled
- *
- * Sets an action in the group as being enabled or not.
- *
- * This is a convenience function, equivalent to calling
- * g_simple_action_group_lookup() and using g_action_set_enabled() on
- * the result.
- *
- * If no action named @action_name exists then this function does
- * nothing.
- *
- * Since: 2.26
- **/
-void
-g_simple_action_group_set_enabled (GSimpleActionGroup *simple,
-                                   const gchar        *action_name,
-                                   gboolean            enabled)
-{
-  GAction *action;
-
-  g_return_if_fail (G_IS_SIMPLE_ACTION_GROUP (simple));
-
-  action = g_hash_table_lookup (simple->priv->table, action_name);
-
-  if (action != NULL)
-    g_action_set_enabled (action, enabled);
-}
diff --git a/gio/gsimpleactiongroup.h b/gio/gsimpleactiongroup.h
index 2637a47..14d60c4 100644
--- a/gio/gsimpleactiongroup.h
+++ b/gio/gsimpleactiongroup.h
@@ -55,7 +55,7 @@ typedef struct _GSimpleActionGroupClass                     GSimpleActionGroupCl
 struct _GSimpleActionGroup
 {
   /*< private >*/
-  GActionGroup parent_instance;
+  GObject parent_instance;
 
   GSimpleActionGroupPrivate *priv;
 };
@@ -63,7 +63,7 @@ struct _GSimpleActionGroup
 struct _GSimpleActionGroupClass
 {
   /*< private >*/
-  GActionGroupClass parent_class;
+  GObjectClass parent_class;
 
   /*< private >*/
   gpointer padding[12];
@@ -82,10 +82,6 @@ void                    g_simple_action_group_insert                    (GSimple
 void                    g_simple_action_group_remove                    (GSimpleActionGroup *simple,
                                                                          const gchar        *action_name);
 
-void                    g_simple_action_group_set_enabled               (GSimpleActionGroup *simple,
-                                                                         const gchar        *action_name,
-                                                                         gboolean            enabled);
-
 G_END_DECLS
 
 #endif /* __G_SIMPLE_ACTION_GROUP_H__ */
diff --git a/gio/tests/actions.c b/gio/tests/actions.c
index 6e68bb4..9da72bc 100644
--- a/gio/tests/actions.c
+++ b/gio/tests/actions.c
@@ -50,6 +50,7 @@ test_basic (void)
   g_assert (enabled);
   g_assert (state_type == NULL);
   g_assert (state == NULL);
+  g_free (name);
 
   g_signal_connect (action, "activate", G_CALLBACK (activate), &a);
   g_assert (!a.did_run);
@@ -99,7 +100,7 @@ test_basic (void)
 }
 
 static gboolean
-strv_has_string (const gchar **haystack,
+strv_has_string (gchar       **haystack,
                  const gchar  *needle)
 {
   guint n;
@@ -113,7 +114,7 @@ strv_has_string (const gchar **haystack,
 }
 
 static gboolean
-strv_set_equal (const gchar **strv, ...)
+strv_set_equal (gchar **strv, ...)
 {
   gint count;
   va_list list;
@@ -190,12 +191,15 @@ test_simple_group (void)
   state = g_action_group_get_state (G_ACTION_GROUP (group), "bar");
   g_assert (g_variant_type_equal (g_variant_get_type (state), G_VARIANT_TYPE_STRING));
   g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi");
+  g_variant_unref (state);
 
   g_action_group_set_state (G_ACTION_GROUP (group), "bar", g_variant_new_string ("boo"));
   state = g_action_group_get_state (G_ACTION_GROUP (group), "bar");
   g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "boo");
+  g_variant_unref (state);
 
-  g_simple_action_group_set_enabled (group, "bar", FALSE);
+  action = g_simple_action_group_lookup (group, "bar");
+  g_action_set_enabled (action, FALSE);
   g_assert (!g_action_group_get_enabled (G_ACTION_GROUP (group), "bar"));
 
   g_simple_action_group_remove (group, "bar");
@@ -212,6 +216,7 @@ test_simple_group (void)
 static void
 test_stateful (void)
 {
+  GVariant *state;
   GAction *action;
 
   action = g_action_new_stateful ("foo", NULL, g_variant_new_string ("hihi"));
@@ -220,8 +225,9 @@ test_stateful (void)
   g_assert (g_action_get_state_hint (action) == NULL);
   g_assert (g_variant_type_equal (g_action_get_state_type (action),
                                   G_VARIANT_TYPE_STRING));
-  g_assert_cmpstr (g_variant_get_string (g_action_get_state (action), NULL),
-                   ==, "hihi");
+  state = g_action_get_state (action);
+  g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi");
+  g_variant_unref (state);
 
   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
     {
@@ -231,8 +237,9 @@ test_stateful (void)
   g_test_trap_assert_failed ();
 
   g_action_set_state (action, g_variant_new_string ("hello"));
-  g_assert_cmpstr (g_variant_get_string (g_action_get_state (action), NULL),
-                   ==, "hello");
+  state = g_action_get_state (action);
+  g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hello");
+  g_variant_unref (state);
 
   g_object_unref (action);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]