diff --git a/demos/gtk-demo/listview_clocks.c b/demos/gtk-demo/listview_clocks.c index b463839051..25d8c2e340 100644 --- a/demos/gtk-demo/listview_clocks.c +++ b/demos/gtk-demo/listview_clocks.c @@ -401,7 +401,7 @@ setup_listitem_cb (GtkListItemFactory *factory, "location"); /* Now create the label and bind the expression to it. */ location_label = gtk_label_new (NULL); - gtk_expression_bind (expression, location_label, "label"); + gtk_expression_bind (expression, location_label, location_label, "label"); gtk_container_add (GTK_CONTAINER (box), location_label); @@ -411,7 +411,7 @@ setup_listitem_cb (GtkListItemFactory *factory, expression = gtk_expression_ref (clock_expression); /* Now create the widget and bind the expression to it. */ picture = gtk_picture_new (); - gtk_expression_bind (expression, picture, "paintable"); + gtk_expression_bind (expression, picture, picture, "paintable"); gtk_container_add (GTK_CONTAINER (box), picture); @@ -430,7 +430,7 @@ setup_listitem_cb (GtkListItemFactory *factory, NULL, NULL); /* Now create the label and bind the expression to it. */ time_label = gtk_label_new (NULL); - gtk_expression_bind (expression, time_label, "label"); + gtk_expression_bind (expression, time_label, time_label, "label"); gtk_container_add (GTK_CONTAINER (box), time_label); gtk_expression_unref (clock_expression); diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c index 518b046110..c5df7b5c9d 100644 --- a/gtk/gtkbuilder.c +++ b/gtk/gtkbuilder.c @@ -1055,11 +1055,13 @@ gtk_builder_create_bindings (GtkBuilder *builder, BindingInfo *info = l->data; GObject *source; - source = _gtk_builder_lookup_object (builder, info->source, info->line, info->col); + source = gtk_builder_lookup_object (builder, info->source, info->line, info->col, error); if (source) g_object_bind_property (source, info->source_property, info->target, info->target_pspec->name, info->flags); + else + error = NULL; _free_binding_info (info, NULL); } @@ -1067,17 +1069,39 @@ gtk_builder_create_bindings (GtkBuilder *builder, { BindingExpressionInfo *info = l->data; GtkExpression *expression; + GObject *object; - expression = expression_info_construct (builder, info->expr, error); - if (expression == NULL) + if (info->object_name) { - g_prefix_error (error, "%s:%d:%d: ", priv->filename, info->line, info->col); - error = NULL; - result = FALSE; + object = gtk_builder_lookup_object (builder, info->object_name, info->line, info->col, error); + if (object == NULL) + { + error = NULL; + result = FALSE; + } + } + else if (priv->current_object) + { + object = priv->current_object; } else { - gtk_expression_bind (expression, info->target, info->target_pspec->name); + object = info->target; + } + + if (object) + { + expression = expression_info_construct (builder, info->expr, error); + if (expression == NULL) + { + g_prefix_error (error, "%s:%d:%d: ", priv->filename, info->line, info->col); + error = NULL; + result = FALSE; + } + else + { + gtk_expression_bind (expression, info->target, object, info->target_pspec->name); + } } free_binding_expression_info (info); diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c index e0f305dbc4..4bdb0af82b 100644 --- a/gtk/gtkbuilderparser.c +++ b/gtk/gtkbuilderparser.c @@ -954,7 +954,8 @@ parse_binding (ParserData *data, GError **error) { BindingExpressionInfo *info; - const gchar *name = NULL; + const char *name = NULL; + const char *object_name = NULL; ObjectInfo *object_info; GParamSpec *pspec = NULL; @@ -969,6 +970,7 @@ parse_binding (ParserData *data, if (!g_markup_collect_attributes (element_name, names, values, error, G_MARKUP_COLLECT_STRING, "name", &name, + G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "object", &object_name, G_MARKUP_COLLECT_INVALID)) { _gtk_builder_prefix_error (data->builder, &data->ctx, error); @@ -1013,6 +1015,7 @@ parse_binding (ParserData *data, info->tag_type = TAG_BINDING_EXPRESSION; info->target = NULL; info->target_pspec = pspec; + info->object_name = g_strdup (object_name); gtk_buildable_parse_context_get_position (&data->ctx, &info->line, &info->col); state_push (data, info); @@ -1506,6 +1509,7 @@ free_binding_expression_info (BindingExpressionInfo *info) { if (info->expr) free_expression_info (info->expr); + g_free (info->object_name); g_slice_free (BindingExpressionInfo, info); } diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h index a5e1f22861..8e690e0c88 100644 --- a/gtk/gtkbuilderprivate.h +++ b/gtk/gtkbuilderprivate.h @@ -133,6 +133,7 @@ typedef struct guint tag_type; GObject *target; GParamSpec *target_pspec; + char *object_name; ExpressionInfo *expr; gint line; gint col; diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c index 493d29da9d..19e3a4341c 100644 --- a/gtk/gtkexpression.c +++ b/gtk/gtkexpression.c @@ -1333,6 +1333,8 @@ gtk_expression_bind_notify (gpointer data) * gtk_expression_bind: * @self: (transfer full): a #GtkExpression * @object: (transfer none) (type GObject): the object to bind + * @this_: (transfer none) (type GObject): the this argument for + * the evaluation of @self * @property: name of the property to bind to * * Bind @object's property named @property to @self. @@ -1353,6 +1355,7 @@ gtk_expression_bind_notify (gpointer data) GtkExpressionWatch * gtk_expression_bind (GtkExpression *self, gpointer object, + gpointer this_, const char *property) { GtkExpressionBind *bind; @@ -1384,7 +1387,7 @@ gtk_expression_bind (GtkExpression *self, bind->object = object; bind->pspec = pspec; bind->watch = gtk_expression_watch (self, - object, + this_, gtk_expression_bind_notify, bind, gtk_expression_bind_free); diff --git a/gtk/gtkexpression.h b/gtk/gtkexpression.h index bac7762561..d7916be716 100644 --- a/gtk/gtkexpression.h +++ b/gtk/gtkexpression.h @@ -59,6 +59,7 @@ GtkExpressionWatch * gtk_expression_watch (GtkExpression GDK_AVAILABLE_IN_ALL GtkExpressionWatch * gtk_expression_bind (GtkExpression *self, gpointer object, + gpointer this_, const char * property); GDK_AVAILABLE_IN_ALL