summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjell.ahlstedt@bredband.net>2014-07-21 15:34:55 +0200
committerKjell Ahlstedt <kjell.ahlstedt@bredband.net>2014-07-21 15:34:55 +0200
commit08da2fbbb763b81fd6f1e3074aaaf83694c012ed (patch)
tree62324950aa3de5319073edfaf458f8343a80e58e
parent0417e5faae6be7a887ba3e15df481a97c71b4645 (diff)
downloadglibmm-08da2fbbb763b81fd6f1e3074aaaf83694c012ed.tar.gz
Make custom interface properties instance data
* glib/glibmm/class.cc: Copy the default values of the interface properties to the class's iface_properties_quark. * glib/glibmm/property.cc: custom_set_property_callback(): Copy the default values to object-specific data. custom_get_property_callback(): Get object-specific value if it exists, else class-specific default value. Bug #732746.
-rw-r--r--glib/glibmm/class.cc3
-rw-r--r--glib/glibmm/property.cc45
2 files changed, 46 insertions, 2 deletions
diff --git a/glib/glibmm/class.cc b/glib/glibmm/class.cc
index 6107c5cf..217d02e7 100644
--- a/glib/glibmm/class.cc
+++ b/glib/glibmm/class.cc
@@ -214,10 +214,13 @@ void Class::custom_class_init_function(void* g_class, void* class_data)
const gchar* prop_name = g_param_spec_get_name(iface_props[p]);
// Override only properties which have not been overridden in a base class.
+ // Store the default values belonging to the class.
+ // They are copied to an object in custom_set_property_callback() in property.cc.
if (!g_object_class_find_property(gobject_class, prop_name))
{
GValue* g_value = g_new0(GValue, 1);
g_value_init(g_value, iface_props[p]->value_type);
+ g_param_value_set_default(iface_props[p], g_value);
props->push_back(g_value);
g_object_class_override_property(gobject_class, props->size(), prop_name);
diff --git a/glib/glibmm/property.cc b/glib/glibmm/property.cc
index 30f367fb..4cf054f9 100644
--- a/glib/glibmm/property.cc
+++ b/glib/glibmm/property.cc
@@ -98,6 +98,23 @@ Glib::PropertyBase& property_from_id(Glib::ObjectBase& object, unsigned int prop
return *static_cast<Glib::PropertyBase*>(prop_ptr);
}
+// Delete the interface property values when an object of a custom type is finalized.
+void destroy_notify_obj_iface_props(void* data)
+{
+ Glib::Class::iface_properties_type* obj_iface_props =
+ static_cast<Glib::Class::iface_properties_type*>(data);
+
+ if (obj_iface_props)
+ {
+ for (Glib::Class::iface_properties_type::size_type i = 0; i < obj_iface_props->size(); i++)
+ {
+ g_value_unset((*obj_iface_props)[i]);
+ g_free((*obj_iface_props)[i]);
+ }
+ delete obj_iface_props;
+ }
+}
+
} // anonymous namespace
@@ -122,7 +139,13 @@ void custom_get_property_callback(GObject* object, unsigned int property_id,
if (property_id <= iface_props_size)
{
- g_value_copy((*iface_props)[property_id - 1], value);
+ // Get the object's property value if there is one, else the class's default value.
+ Class::iface_properties_type* obj_iface_props = static_cast<Class::iface_properties_type*>(
+ g_object_get_qdata(object, Class::iface_properties_quark));
+ if (obj_iface_props)
+ g_value_copy((*obj_iface_props)[property_id - 1], value);
+ else
+ g_value_copy((*iface_props)[property_id - 1], value);
}
else
{
@@ -157,7 +180,25 @@ void custom_set_property_callback(GObject* object, unsigned int property_id,
if (property_id <= iface_props_size)
{
- g_value_copy(value, (*iface_props)[property_id - 1]);
+ // If the object does not have interface property values,
+ // copy the class's default values to the object.
+ Class::iface_properties_type* obj_iface_props = static_cast<Class::iface_properties_type*>(
+ g_object_get_qdata(object, Class::iface_properties_quark));
+ if (!obj_iface_props)
+ {
+ obj_iface_props = new Class::iface_properties_type();
+ g_object_set_qdata_full(object, Class::iface_properties_quark, obj_iface_props,
+ destroy_notify_obj_iface_props);
+ for (Class::iface_properties_type::size_type p = 0; p < iface_props_size; ++p)
+ {
+ GValue* g_value = g_new0(GValue, 1);
+ g_value_init(g_value, G_VALUE_TYPE((*iface_props)[p]));
+ g_value_copy((*iface_props)[p], g_value);
+ obj_iface_props->push_back(g_value);
+ }
+ }
+
+ g_value_copy(value, (*obj_iface_props)[property_id - 1]);
g_object_notify_by_pspec(object, param_spec);
}
else