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
This commit is contained in:
Emmanuele Bassi
2013-06-19 23:25:51 +01:00
parent e783b3883e
commit d778ffd6fa
3 changed files with 173 additions and 6 deletions

View File

@@ -891,6 +891,96 @@ g_object_class_override_property (GObjectClass *oclass,
g_object_class_install_property (oclass, property_id, new);
}
/**
* 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

View File

@@ -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

View File

@@ -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);
@@ -299,6 +341,31 @@ gproperty_default_init (void)
g_object_unref (obj);
}
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)
{
@@ -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 ();