summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Washington <denisw@src.gnome.org>2011-07-12 20:27:58 +0200
committerDenis Washington <denisw@src.gnome.org>2011-07-12 20:27:58 +0200
commit3e3b8857f825123f605adaeb381795b51cd36455 (patch)
treea3dea901fadddf3f366a1f232fea283510a1f119
parent4fc0c966db7999445e0f0c330435e925bed8b687 (diff)
downloadglade-3e3b8857f825123f605adaeb381795b51cd36455.tar.gz
Properly remove a property binding if the binding source widget is removed
The code is carefully written to resurrect such property bindings if the widget removal is undone.
-rw-r--r--gladeui/glade-property.c92
1 files changed, 82 insertions, 10 deletions
diff --git a/gladeui/glade-property.c b/gladeui/glade-property.c
index d03fb547..a4bd0d36 100644
--- a/gladeui/glade-property.c
+++ b/gladeui/glade-property.c
@@ -108,10 +108,27 @@ struct _GladePropertyPrivate {
* GladeProperty's value is bound to
*/
- gulong binding_handler; /* Signal handler to synchronize
- * the GladeProperty with its binding
- * source (if it is bound)
- */
+ gboolean binding_source_valid; /* TRUE if the property's binding source is
+ * valid, that is, if the binding source widget
+ * is part of the project (we cannot just
+ * set binding_source to NULL if the source widget
+ * is removed as we want to support undo)
+ */
+
+ gulong binding_handler; /* Signal handler to synchronize
+ * the GladeProperty with its binding
+ * source (if it is bound)
+ */
+
+ gulong binding_widget_remove_handler; /* Signal handler to update
+ * binding_source_valid when the
+ * binding source widget is removed
+ */
+
+ gulong binding_widget_add_handler; /* Signal handler to update
+ * binding_source_valid when the
+ * binding source widget is added back
+ */
/* Used only for translatable strings. */
guint i18n_translatable : 1;
@@ -614,7 +631,10 @@ glade_property_init (GladeProperty * property)
property->priv->enabled = TRUE;
property->priv->sensitive = TRUE;
property->priv->binding_source = NULL;
+ property->priv->binding_source_valid = TRUE;
property->priv->binding_handler = 0;
+ property->priv->binding_widget_remove_handler = 0;
+ property->priv->binding_widget_add_handler = 0;
property->priv->i18n_translatable = TRUE;
property->priv->i18n_comment = NULL;
property->priv->sync_tolerance = 1;
@@ -1689,8 +1709,11 @@ GladeProperty *
glade_property_get_binding_source (GladeProperty *property)
{
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
-
- return property->priv->binding_source;
+
+ if (property->priv->binding_source_valid)
+ return property->priv->binding_source;
+ else
+ return NULL;
}
static void
@@ -1698,6 +1721,8 @@ glade_property_binding_source_weak_notify_cb (GladeProperty *property,
GObject *binding_source)
{
property->priv->binding_handler = 0;
+ property->priv->binding_widget_remove_handler = 0;
+ property->priv->binding_widget_add_handler = 0;
g_object_notify_by_pspec (G_OBJECT (property), properties[PROP_BINDING_SOURCE]);
}
@@ -1711,31 +1736,78 @@ glade_property_binding_source_value_changed_cb (GladeProperty *prop,
}
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_valid = !priv->binding_source_valid;
+ g_object_notify_by_pspec (G_OBJECT (property),
+ properties[PROP_BINDING_SOURCE]);
+ }
+}
+
+static void
glade_property_update_binding (GladeProperty *property,
GladeProperty *old_source)
{
GladeProperty *source;
GValue source_val = {0};
- if (property->priv->binding_handler)
- g_signal_handler_disconnect (old_source, property->priv->binding_handler);
+ if (old_source)
+ {
+ GladeWidget *widget = glade_property_get_widget (old_source);
+ GladeProject *project = glade_widget_get_project (widget);
+
+ if (property->priv->binding_handler)
+ g_signal_handler_disconnect (old_source, property->priv->binding_handler);
+
+ if (property->priv->binding_widget_remove_handler)
+ g_signal_handler_disconnect (project,
+ property->priv->binding_widget_remove_handler);
+ if (property->priv->binding_widget_add_handler)
+ g_signal_handler_disconnect (project,
+ property->priv->binding_widget_add_handler);
+ }
+
source = glade_property_get_binding_source (property);
if (source)
{
+ GladeWidget *widget = glade_property_get_widget (source);
+ GladeProject *project = glade_widget_get_project (widget);
+
property->priv->binding_handler =
g_signal_connect (source, "value-changed",
G_CALLBACK (glade_property_binding_source_value_changed_cb),
property);
+ property->priv->binding_widget_remove_handler =
+ g_signal_connect (project, "remove-widget",
+ G_CALLBACK (glade_property_binding_source_widget_cb),
+ property);
+
+ property->priv->binding_widget_add_handler =
+ g_signal_connect (project, "add-widget",
+ G_CALLBACK (glade_property_binding_source_widget_cb),
+ property);
+
+ property->priv->binding_source_valid = TRUE;
+
/* Synchronize the source and target property values once */
glade_property_get_value (source, &source_val);
glade_property_set_value (property, &source_val);
}
else
- property->priv->binding_handler = 0;
-
+ {
+ property->priv->binding_handler = 0;
+ property->priv->binding_widget_remove_handler = 0;
+ property->priv->binding_widget_add_handler = 0;
+ }
}
void