[glib/wip/gproperty-2: 52/57] gobject: Add wrappers for overriding GProperty default values



commit d778ffd6fa068e76c52f0762455509cc869a74e3
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Jun 19 23:25:51 2013 +0100

    gobject: Add wrappers for overriding GProperty default values
    
    We need convenience API for sub-classes that wish to override the
    default value of a property installed by one of their parents.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=648526

 gobject/gobject.c        |   90 ++++++++++++++++++++++++++++++++++++++++++++++
 gobject/gobject.h        |    9 +++++
 gobject/tests/property.c |   80 +++++++++++++++++++++++++++++++++++++---
 3 files changed, 173 insertions(+), 6 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 74ba167..8b011c4 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -892,6 +892,96 @@ g_object_class_override_property (GObjectClass *oclass,
 }
 
 /**
+ * g_object_class_override_property_default_value:
+ * @oclass: a #GObjectClass
+ * @property_name: the name of the property
+ * @value: the new default value of the property
+ *
+ * Overrides the default value of @property_name on the class @oclass.
+ *
+ * Since: 2.38
+ */
+void
+g_object_class_override_property_default_value (GObjectClass *oclass,
+                                                const gchar  *property_name,
+                                                const GValue *value)
+{
+  GParamSpec *pspec;
+
+  g_return_if_fail (G_IS_OBJECT_CLASS (oclass));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (value != NULL);
+
+  pspec = g_object_class_find_property (oclass, property_name);
+  if (!G_IS_PROPERTY (pspec))
+    {
+      g_critical ("The property %s::%s is not a GProperty, and its default "
+                  "value cannot be overridden",
+                  G_OBJECT_CLASS_NAME (oclass),
+                  property_name);
+      return;
+    }
+
+  g_property_override_default_value (G_PROPERTY (pspec),
+                                     G_OBJECT_CLASS_TYPE (oclass),
+                                     value);
+}
+
+/**
+ * g_object_class_override_property_default_value:
+ * @oclass: a #GObjectClass
+ * @property_name: the name of the property
+ * @...: the new default value of the property
+ *
+ * Overrides the default value of @property_name on the class @oclass.
+ *
+ * Since: 2.38
+ */
+void
+g_object_class_override_property_default (GObjectClass *oclass,
+                                          const gchar  *property_name,
+                                          ...)
+{
+  GValue value = G_VALUE_INIT;
+  gchar *error = NULL;
+  GParamSpec *pspec;
+  va_list args;
+
+  g_return_if_fail (G_IS_OBJECT_CLASS (oclass));
+  g_return_if_fail (property_name != NULL);
+
+  pspec = g_object_class_find_property (oclass, property_name);
+  if (!G_IS_PROPERTY (pspec))
+    {
+      g_critical ("The property %s::%s is not a GProperty, and its default "
+                  "value cannot be overridden",
+                  G_OBJECT_CLASS_NAME (oclass),
+                  property_name);
+      return;
+    }
+
+  va_start (args, property_name);
+
+  G_VALUE_COLLECT_INIT (&value, pspec->value_type, args, 0, &error);
+  if (error)
+    {
+      g_warning ("%s: %s", G_STRFUNC, error);
+      g_free (error);
+      g_value_unset (&value);
+      va_end (args);
+      return;
+    }
+
+  va_end (args);
+
+  g_property_override_default_value (G_PROPERTY (pspec),
+                                     G_OBJECT_CLASS_TYPE (oclass),
+                                     &value);
+
+  g_value_unset (&value);
+}
+
+/**
  * g_object_class_list_properties:
  * @oclass: a #GObjectClass
  * @n_properties: (out): return location for the length of the returned array
diff --git a/gobject/gobject.h b/gobject/gobject.h
index 03a9629..df3147f 100644
--- a/gobject/gobject.h
+++ b/gobject/gobject.h
@@ -412,6 +412,15 @@ GLIB_AVAILABLE_IN_ALL
 GParamSpec**g_object_interface_list_properties  (gpointer     g_iface,
                                                 guint       *n_properties_p);
 
+GLIB_AVAILABLE_IN_2_38
+void        g_object_class_override_property_default (GObjectClass *oclass,
+                                                      const gchar  *property_name,
+                                                      ...);
+GLIB_AVAILABLE_IN_2_38
+void        g_object_class_override_property_default_value (GObjectClass *oclass,
+                                                            const gchar  *property_name,
+                                                            const GValue *value);
+
 GLIB_AVAILABLE_IN_ALL
 GType       g_object_get_type                 (void) G_GNUC_CONST;
 GLIB_AVAILABLE_IN_ALL
diff --git a/gobject/tests/property.c b/gobject/tests/property.c
index 8e421a4..477e0a1 100644
--- a/gobject/tests/property.c
+++ b/gobject/tests/property.c
@@ -75,6 +75,9 @@ test_object_finalize (GObject *gobject)
 
   g_free (priv->string_val);
 
+  if (priv->enum_val_set)
+    g_assert (priv->enum_val != TEST_ENUM_UNSET);
+
   if (priv->enum_val != TEST_ENUM_UNSET)
     g_assert (priv->enum_val_set);
 
@@ -147,7 +150,7 @@ test_object_class_init (TestObjectClass *klass)
                                                    NULL,
                                                    G_PROPERTY_READWRITE,
                                                    G_PROPERTY_DEFAULT (TEST_ENUM_UNSET)
-                                                   g_property_set_prerequisite (g_property, 
test_enum_get_type ());)
+                                                   G_PROPERTY_PREREQUISITE (test_enum_get_type ()))
                        G_DEFINE_PROPERTY (TestObject,
                                           boolean,
                                           enum_val_set,
@@ -164,10 +167,6 @@ test_object_class_init (TestObjectClass *klass)
 static void
 test_object_init (TestObject *self)
 {
-  TestObjectPrivate *priv = test_object_get_private (self);
-
-  g_assert (priv->enum_val == TEST_ENUM_UNSET);
-  g_assert (!priv->enum_val_set);
 }
 
 G_DECLARE_PROPERTY_GET_SET (TestObject, test_object, gboolean, bool_val)
@@ -182,6 +181,48 @@ G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, float, height)
 G_DEFINE_PROPERTY_GET_SET (TestObject, test_object, TestEnum, enum_val)
 G_DEFINE_PROPERTY_INDIRECT_GET (TestObject, test_object, gboolean, enum_val_set)
 
+typedef struct {
+  TestObject parent_instance;
+} TestDerived;
+
+typedef struct {
+  TestObjectClass parent_class;
+} TestDerivedClass;
+
+GType test_derived_get_type (void);
+
+G_DEFINE_TYPE (TestDerived, test_derived, test_object_get_type ())
+
+static void
+test_derived_constructed (GObject *gobject)
+{
+  TestObject *self = (TestObject *) gobject;
+  TestObjectPrivate *priv = test_object_get_instance_private (self);
+
+  g_assert (priv->enum_val == TEST_ENUM_TWO);
+  g_assert (priv->enum_val_set);
+
+  /* do not chain up, or we trigger the assert */
+}
+
+static void
+test_derived_class_init (TestDerivedClass *klass)
+{
+  G_OBJECT_CLASS (klass)->constructed = test_derived_constructed;
+
+  g_object_class_override_property_default (G_OBJECT_CLASS (klass),
+                                            "enum-val",
+                                            TEST_ENUM_TWO);
+  g_object_class_override_property_default (G_OBJECT_CLASS (klass),
+                                            "with-default",
+                                            128);
+}
+
+static void
+test_derived_init (TestDerived *self)
+{
+}
+
 /* test units start here */
 
 static void
@@ -284,9 +325,10 @@ gproperty_explicit_set (void)
 static void
 gproperty_default_init (void)
 {
-  TestObject *obj = g_object_new (test_object_get_type (), NULL);
+  TestObject *obj;
   guint8 with_default = 0;
 
+  obj = g_object_new (test_object_get_type (), NULL);
   g_object_get (obj, "with-default", &with_default, NULL);
   g_assert_cmpint (with_default, ==, 255);
 
@@ -300,6 +342,31 @@ gproperty_default_init (void)
 }
 
 static void
+gproperty_default_override (void)
+{
+  TestObject *obj;
+  guint8 with_default = 0;
+
+  if (g_test_verbose ())
+    g_print ("*** Base type ***\n");
+
+  obj = g_object_new (test_object_get_type (), NULL);
+  g_object_get (obj, "with-default", &with_default, NULL);
+  g_assert_cmpint (with_default, ==, 255);
+
+  g_object_unref (obj);
+
+  if (g_test_verbose ())
+    g_print ("*** Derived type ***\n");
+
+  obj = g_object_new (test_derived_get_type (), NULL);
+  g_object_get (obj, "with-default", &with_default, NULL);
+  g_assert_cmpint (with_default, ==, 128);
+
+  g_object_unref (obj);
+}
+
+static void
 gproperty_accessors_get_set (void)
 {
   TestObject *obj = g_object_new (test_object_get_type (), NULL);
@@ -334,6 +401,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/gproperty/object-get", gproperty_object_get);
   g_test_add_func ("/gproperty/explicit-set", gproperty_explicit_set);
   g_test_add_func ("/gproperty/default/init", gproperty_default_init);
+  g_test_add_func ("/gproperty/default/override", gproperty_default_override);
   g_test_add_func ("/gproperty/accessors/get-set", gproperty_accessors_get_set);
 
   return g_test_run ();


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