From d58500b3180492cc9396fdf8dcbf61b29f7f7464 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 29 Apr 2015 15:19:31 -0400 Subject: [PATCH] GtkBuilder: Report more lookup failures as GError Report failures to lookup objects for property values and bindings via GError too, and provide location information while doing so. https://bugzilla.gnome.org/show_bug.cgi?id=748234 --- gtk/gtkbuilder.c | 40 +++++++++++++++++++++++++++++++-------- gtk/gtkbuilderparser.c | 42 +++++++++++------------------------------ gtk/gtkbuilderprivate.h | 6 ++++++ 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c index 60b3b9a696..521159a8ec 100644 --- a/gtk/gtkbuilder.c +++ b/gtk/gtkbuilder.c @@ -445,6 +445,8 @@ typedef struct gchar *object; GParamSpec *pspec; gchar *value; + gint line; + gint col; } DelayedProperty; static void @@ -496,6 +498,8 @@ gtk_builder_get_parameters (GtkBuilder *builder, property->pspec = prop->pspec; property->object = g_strdup (object_name); property->value = g_strdup (prop->data); + property->line = prop->line; + property->col = prop->col; builder->priv->delayed_properties = g_slist_prepend (builder->priv->delayed_properties, property); continue; @@ -899,12 +903,9 @@ gtk_builder_apply_delayed_properties (GtkBuilder *builder) object = g_hash_table_lookup (builder->priv->objects, property->object); g_assert (object != NULL); - obj = g_hash_table_lookup (builder->priv->objects, property->value); + obj = _gtk_builder_lookup_object (builder, property->value, property->line, property->col); if (obj) g_object_set (object, property->pspec->name, obj, NULL); - else - g_warning ("No object called: %s", property->value); - g_free (property->value); g_free (property->object); @@ -933,13 +934,11 @@ gtk_builder_create_bindings (GtkBuilder *builder) BindingInfo *info = l->data; GObject *source; - if ((source = gtk_builder_get_object (builder, info->source))) + source = _gtk_builder_lookup_object (builder, info->source, info->line, info->col); + if (source) g_object_bind_property (source, info->source_property, info->target, info->target_pspec->name, info->flags); - else - g_warning ("Could not find source object '%s' to bind property '%s'", - info->source, info->source_property); free_binding_info (info, NULL); } @@ -2746,3 +2745,28 @@ _gtk_builder_lookup_object (GtkBuilder *builder, return obj; } + +/*< private > + * _gtk_builder_lookup_failed: + * @GtkBuilder: a #GtkBuilder + * @error: return location for error + * + * Finds whether any object lookups have failed. + * + * Returns: %TRUE if @error has been set + */ +gboolean +_gtk_builder_lookup_failed (GtkBuilder *builder, + GError **error) +{ + GError *lookup_error; + + lookup_error = (GError*) g_object_steal_data (G_OBJECT (builder), "lookup-error"); + if (lookup_error) + { + g_propagate_error (error, lookup_error); + return TRUE; + } + + return FALSE; +} diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c index d90038a434..845d805f70 100644 --- a/gtk/gtkbuilderparser.c +++ b/gtk/gtkbuilderparser.c @@ -700,6 +700,7 @@ parse_property (ParserData *data, binfo->source = g_strdup (bind_source); binfo->source_property = g_strdup (bind_property); binfo->flags = bind_flags; + g_markup_parse_context_get_position (data->ctx, &binfo->line, &binfo->col); object_info->bindings = g_slist_prepend (object_info->bindings, binfo); } @@ -720,6 +721,7 @@ parse_property (ParserData *data, state_push (data, info); info->tag.name = element_name; + g_markup_parse_context_get_position (data->ctx, &info->line, &info->col); } static void @@ -941,8 +943,6 @@ subparser_end (GMarkupParseContext *context, ParserData *data, GError **error) { - GError *lookup_error; - if (data->subparser->parser->end_element) data->subparser->parser->end_element (context, element_name, data->subparser->data, error); @@ -953,8 +953,6 @@ subparser_end (GMarkupParseContext *context, if (strcmp (data->subparser->start, element_name) != 0) return; - g_object_set_data (G_OBJECT (data->builder), "lookup-error", NULL); - gtk_buildable_custom_tag_end (GTK_BUILDABLE (data->subparser->object), data->builder, data->subparser->child, @@ -962,12 +960,8 @@ subparser_end (GMarkupParseContext *context, data->subparser->data); g_free (data->subparser->parser); - lookup_error = (GError*) g_object_steal_data (G_OBJECT (data->builder), "lookup-error"); - if (lookup_error) - { - g_propagate_error (error, lookup_error); - return; - } + if (_gtk_builder_lookup_failed (data->builder, error)) + return; if (GTK_BUILDABLE_GET_IFACE (data->subparser->object)->custom_finished) data->custom_finalizers = g_slist_prepend (data->custom_finalizers, @@ -1352,7 +1346,7 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder, const gchar* domain; ParserData *data; GSList *l; - + /* Store the original domain so that interface domain attribute can be * applied for the builder and the original domain can be restored after * parsing has finished. This allows subparsers to translate elements with @@ -1393,28 +1387,22 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder, goto out; _gtk_builder_finish (builder); + if (_gtk_builder_lookup_failed (builder, error)) + goto out; /* Custom parser_finished */ data->custom_finalizers = g_slist_reverse (data->custom_finalizers); for (l = data->custom_finalizers; l; l = l->next) { SubParser *sub = (SubParser*)l->data; - GError *lookup_error; - - g_object_set_data (G_OBJECT (builder), "lookup-error", NULL); gtk_buildable_custom_finished (GTK_BUILDABLE (sub->object), builder, sub->child, sub->tagname, sub->data); - - lookup_error = (GError*) g_object_steal_data (G_OBJECT (builder), "lookup-error"); - if (lookup_error) - { - g_propagate_error (error, lookup_error); - goto out; - } + if (_gtk_builder_lookup_failed (builder, error)) + goto out; } /* Common parser_finished, for all created objects */ @@ -1422,18 +1410,10 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder, for (l = data->finalizers; l; l = l->next) { GtkBuildable *buildable = (GtkBuildable*)l->data; - GError *lookup_error; - - g_object_set_data (G_OBJECT (builder), "lookup-error", NULL); gtk_buildable_parser_finished (GTK_BUILDABLE (buildable), builder); - - lookup_error = (GError*) g_object_steal_data (G_OBJECT (builder), "lookup-error"); - if (lookup_error) - { - g_propagate_error (error, lookup_error); - goto out; - } + if (_gtk_builder_lookup_failed (builder, error)) + goto out; } out: diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h index ee457c1871..2a539eb392 100644 --- a/gtk/gtkbuilderprivate.h +++ b/gtk/gtkbuilderprivate.h @@ -66,6 +66,8 @@ typedef struct { gboolean translatable:1; gboolean bound:1; gchar *context; + gint line; + gint col; } PropertyInfo; typedef struct { @@ -85,6 +87,8 @@ typedef struct gchar *source; gchar *source_property; GBindingFlags flags; + gint line; + gint col; } BindingInfo; typedef struct { @@ -201,6 +205,8 @@ GObject * _gtk_builder_lookup_object (GtkBuilder *builder, const gchar *name, gint line, gint col); +gboolean _gtk_builder_lookup_failed (GtkBuilder *builder, + GError **error); #endif /* __GTK_BUILDER_PRIVATE_H__ */