[glade/gbinding] Cleaned up the GladeProperty binding code
- From: Denis Washington <denisw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade/gbinding] Cleaned up the GladeProperty binding code
- Date: Wed, 10 Aug 2011 19:51:02 +0000 (UTC)
commit 9e8c883bfe8a43c8358da45de031a88846b1ee5c
Author: Denis Washington <denisw src gnome org>
Date: Wed Aug 10 21:50:09 2011 +0200
Cleaned up the GladeProperty binding code
gladeui/glade-property.c | 216 ++++++++++++++++++++++++++--------------------
1 files changed, 122 insertions(+), 94 deletions(-)
---
diff --git a/gladeui/glade-property.c b/gladeui/glade-property.c
index 76606ce..1d02a31 100644
--- a/gladeui/glade-property.c
+++ b/gladeui/glade-property.c
@@ -109,18 +109,20 @@ struct _GladePropertyPrivate {
*/
/* Binding source validility flags */
- gboolean binding_source_alive;
- gboolean binding_source_enabled;
- gboolean binding_source_sensitive;
+ gboolean binding_source_valid; /* Indicates whether the binding source
+ * is belongs to a widget that is currently
+ * part of the project (becomes FALSE if
+ * the binding source widget is removed)
+ */
gchar *binding_transform_func; /* the transformation function for
* the property's binding
*/
- gulong binding_handler; /* Signal handler to synchronize
- * the GladeProperty with its binding
- * source (if it is bound)
- */
+ gulong binding_value_handler; /* Signal handler to synchronize
+ * the GladeProperty with its
+ * binding source (if it is bound)
+ */
gulong binding_enabled_handler; /* Signal handler to keeep
* binding_source_enabled
@@ -657,7 +659,7 @@ glade_property_init (GladeProperty * property)
property->priv->sensitive = TRUE;
property->priv->binding_source = NULL;
property->priv->binding_transform_func = NULL;
- property->priv->binding_handler = 0;
+ property->priv->binding_value_handler = 0;
property->priv->binding_enabled_handler = 0;
property->priv->binding_sensitive_handler = 0;
property->priv->binding_widget_remove_handler = 0;
@@ -1758,17 +1760,33 @@ glade_property_get_state (GladeProperty *property)
return property->priv->state;
}
+static gboolean
+glade_property_binding_source_valid (GladeProperty *binding_source)
+{
+ GladeWidget *source_widget;
+
+ if (!binding_source)
+ return FALSE;
+
+ source_widget = glade_property_get_widget (binding_source);
+
+ if (!glade_property_get_enabled (binding_source) ||
+ !glade_property_get_sensitive (binding_source) ||
+ !glade_widget_in_project (source_widget))
+ return FALSE;
+
+ return TRUE;
+}
+
GladeProperty *
glade_property_get_binding_source (GladeProperty *property)
{
+ GladeProperty *source;
+
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
- if (property->priv->binding_source_alive &&
- property->priv->binding_source_enabled &&
- property->priv->binding_source_sensitive)
- return property->priv->binding_source;
- else
- return NULL;
+ source = property->priv->binding_source;
+ return (glade_property_binding_source_valid (source)) ? source : NULL;
}
static void
@@ -1776,26 +1794,11 @@ glade_property_binding_source_weak_notify_cb (GladeProperty *property,
GObject *binding_source)
{
property->priv->binding_source = NULL;
- property->priv->binding_handler = 0;
+ property->priv->binding_value_handler = 0;
glade_property_remove_binding_source (property);
}
static void
-glade_property_binding_source_widget_cb (GladeProject *project,
- GladeWidget *widget,
- GladeProperty *property)
-{
- GladePropertyPrivate *priv = property->priv;
-
- if (widget == glade_property_get_widget (priv->binding_source))
- {
- priv->binding_source_alive = !priv->binding_source_alive;
- g_object_notify_by_pspec (G_OBJECT (property),
- properties[PROP_BINDING_SOURCE]);
- }
-}
-
-static void
glade_property_remove_binding_source (GladeProperty *property)
{
GladeProperty *old_source;
@@ -1805,15 +1808,19 @@ glade_property_remove_binding_source (GladeProperty *property)
if ((old_source = property->priv->binding_source) != NULL)
g_object_weak_unref (G_OBJECT (old_source),
(GWeakNotify) glade_property_binding_source_weak_notify_cb,
- property);
+ property);
- if (property->priv->binding_handler > 0)
- g_signal_handler_disconnect (old_source, property->priv->binding_handler);
+ if (property->priv->binding_value_handler > 0)
+ g_signal_handler_disconnect (old_source, property->priv->binding_value_handler);
if (property->priv->binding_enabled_handler > 0)
g_signal_handler_disconnect (old_source, property->priv->binding_enabled_handler);
if (property->priv->binding_sensitive_handler > 0)
g_signal_handler_disconnect (old_source, property->priv->binding_sensitive_handler);
+ property->priv->binding_value_handler = 0;
+ property->priv->binding_enabled_handler = 0;
+ property->priv->binding_sensitive_handler = 0;
+
/* The property's widget might be currently finalized and have
* its project set to NULL, so prefer to query the binding source
* widget for it.
@@ -1838,24 +1845,16 @@ glade_property_remove_binding_source (GladeProperty *property)
if (property->priv->binding_widget_remove_handler > 0)
g_signal_handler_disconnect (project,
property->priv->binding_widget_remove_handler);
-
if (property->priv->binding_widget_add_handler > 0)
g_signal_handler_disconnect (project,
property->priv->binding_widget_add_handler);
-}
-static void
-glade_property_binding_source_valid_notify_cb (GladeProperty *source,
- GParamSpec *pspec,
- GladeProperty *property)
-{
- /* Rebind if the source property's "enabled" or
- "sensitive" state changes */
- glade_property_set_binding_source (property, source);
+ property->priv->binding_widget_remove_handler = 0;
+ property->priv->binding_widget_add_handler = 0;
}
static void
-glade_property_binding_source_value_changed_cb (GladeProperty *prop,
+glade_property_binding_source_value_changed_cb (GladeProperty *source,
GValue *old_value,
GValue *new_value,
GladeProperty *property)
@@ -1863,17 +1862,62 @@ glade_property_binding_source_value_changed_cb (GladeProperty *prop,
glade_property_set_value (property, new_value);
}
+static void
+glade_property_binding_source_notify_enabled_sensitive_cb (GladeProperty *source,
+ GParamSpec *pspec,
+ GladeProperty *property)
+{
+ if (glade_property_binding_source_valid (source))
+ {
+ GValue source_val = {0};
+
+ glade_property_get_value (source, &source_val);
+ glade_property_set_value (property, &source_val);
+ }
+ else
+ glade_property_reset (property);
+
+ g_object_notify_by_pspec (G_OBJECT (property),
+ properties[PROP_BINDING_SOURCE]);
+}
+
+static void
+glade_property_binding_source_widget_cb (GladeProject *project,
+ GladeWidget *widget,
+ GladeProperty *property)
+{
+ if (widget == glade_property_get_widget (property->priv->binding_source))
+ g_object_notify_by_pspec (G_OBJECT (property),
+ properties[PROP_BINDING_SOURCE]);
+}
+
void
glade_property_set_binding_source (GladeProperty *property,
GladeProperty *binding_source)
{
GladeProperty *old_source;
- GValue source_val = {0};
-
+
g_return_if_fail (GLADE_IS_PROPERTY (property));
g_return_if_fail (!binding_source || GLADE_IS_PROPERTY (binding_source));
+ if (binding_source)
+ {
+ GladePropertyClass *prop_pclass = glade_property_get_class (property);
+ GladePropertyClass *source_pclass = glade_property_get_class (binding_source);
+ GParamSpec *prop_pspec = glade_property_class_get_pspec (prop_pclass);
+ GParamSpec *source_pspec = glade_property_class_get_pspec (source_pclass);
+
+ g_return_if_fail (source_pspec->flags | G_PARAM_READABLE);
+ g_return_if_fail (prop_pspec->flags | G_PARAM_WRITABLE);
+ g_return_if_fail (glade_property_binding_source_valid (binding_source));
+
+ if (property->priv->binding_transform_func)
+ g_return_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (source_pspec),
+ G_PARAM_SPEC_TYPE (prop_pspec)));
+ }
+
old_source = glade_property_get_binding_source (property);
+
glade_property_remove_binding_source (property);
property->priv->binding_source = binding_source;
@@ -1882,28 +1926,48 @@ glade_property_set_binding_source (GladeProperty *property,
GladeWidget *widget = glade_property_get_widget (binding_source);
GladeProject *project = glade_widget_get_project (widget);
GClosure *closure;
-
+
g_object_weak_ref (G_OBJECT (binding_source),
(GWeakNotify) glade_property_binding_source_weak_notify_cb,
property);
+ /* Synchronize the source and target property values if there
+ * is no transformation function; if there is, the best thing we
+ * can do is to reset the target property to the default value
+ * (the source and target property types might not be compatible)
+ */
+ if (glade_property_get_binding_transform_func (property))
+ glade_property_reset (property);
+ else
+ {
+ GValue source_val = {0};
+
+ property->priv->binding_value_handler =
+ g_signal_connect (binding_source, "value-changed",
+ G_CALLBACK (glade_property_binding_source_value_changed_cb),
+ property);
+
+ glade_property_get_value (binding_source, &source_val);
+ glade_property_set_value (property, &source_val);
+ }
+
property->priv->binding_enabled_handler =
g_signal_connect (binding_source, "notify::enabled",
- G_CALLBACK (glade_property_binding_source_valid_notify_cb),
+ G_CALLBACK (glade_property_binding_source_notify_enabled_sensitive_cb),
property);
property->priv->binding_sensitive_handler =
g_signal_connect (binding_source, "notify::sensitive",
- G_CALLBACK (glade_property_binding_source_valid_notify_cb),
+ G_CALLBACK (glade_property_binding_source_notify_enabled_sensitive_cb),
property);
- /* To be called when the binding source widget is deleted */
+ /* To be called when the binding source widget is deleted / re-added */
closure =
g_cclosure_new (G_CALLBACK (glade_property_binding_source_widget_cb),
G_OBJECT (property), NULL);
- /* Don't call when binding source is freed (see FIXME in
- * glade_property_remove_binding_source() for why this is
+ /* Don't call after the binding source has been freed (see FIXME
+ * in glade_property_remove_binding_source() for why this is
* needed)
*/
g_object_watch_closure (G_OBJECT (binding_source), closure);
@@ -1913,38 +1977,6 @@ glade_property_set_binding_source (GladeProperty *property,
property->priv->binding_widget_add_handler =
g_signal_connect_closure (project, "add-widget", closure, FALSE);
-
- property->priv->binding_source_alive = TRUE;
- property->priv->binding_source_enabled = glade_property_get_enabled (binding_source);
- property->priv->binding_source_sensitive = glade_property_get_sensitive (binding_source);
-
- /* Synchronize the source and target property values if there
- * is no transformation function; if there is, the best thing we
- * can do is to reset the target property to the default value
- * (the source and target property types might not be compatible)
- */
- if (glade_property_get_binding_transform_func (property) ||
- !property->priv->binding_source_enabled ||
- !property->priv->binding_source_sensitive)
- glade_property_reset (property);
- else
- {
- property->priv->binding_handler =
- g_signal_connect (binding_source, "value-changed",
- G_CALLBACK (glade_property_binding_source_value_changed_cb),
- property);
-
- glade_property_get_value (binding_source, &source_val);
- glade_property_set_value (property, &source_val);
- }
- }
- else
- {
- property->priv->binding_handler = 0;
- property->priv->binding_enabled_handler = 0;
- property->priv->binding_sensitive_handler = 0;
- property->priv->binding_widget_remove_handler = 0;
- property->priv->binding_widget_add_handler = 0;
}
if (binding_source != old_source)
@@ -1957,9 +1989,7 @@ glade_property_get_binding_transform_func (GladeProperty *property)
{
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
- if (property->priv->binding_source_alive &&
- property->priv->binding_source_enabled &&
- property->priv->binding_source_sensitive)
+ if (glade_property_get_binding_source (property))
return property->priv->binding_transform_func;
else
return NULL;
@@ -1972,16 +2002,14 @@ glade_property_set_binding_transform_func (GladeProperty *property,
g_return_if_fail (GLADE_IS_PROPERTY (property));
g_free (property->priv->binding_transform_func);
- if (transform_func)
- property->priv->binding_transform_func = g_strdup (transform_func);
- else
- property->priv->binding_transform_func = NULL;
+ property->priv->binding_transform_func = (transform_func)
+ ? g_strdup (transform_func)
+ : NULL;
/* Call glade_property_set_binding_source() to adjust to the new
* transformation function setting */
- glade_property_set_binding_source (property,
- glade_property_get_binding_source (property));
-
+ glade_property_set_binding_source (property, property->priv->binding_source);
+
g_object_notify_by_pspec (G_OBJECT (property),
properties[PROP_BINDING_TRANSFORM_FUNC]);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]