builder: Add gtk_builder_lookup_object()

... and use it. This function looks up an object like
gtk_builder_get_object() but generates an error on failure.

Unlike the evil function _gtk_builder_lookup_object() which also
generates an error but hides it for later lookup.

Use this to avoid continuing applying properties when an error was
encountered.
This commit is contained in:
Benjamin Otte 2019-11-25 07:40:28 +01:00
parent 552db7cb08
commit 512c4c13a6
3 changed files with 64 additions and 19 deletions

View File

@ -996,11 +996,13 @@ _gtk_builder_add_signals (GtkBuilder *builder,
g_slist_copy (signals));
}
static void
gtk_builder_apply_delayed_properties (GtkBuilder *builder)
static gboolean
gtk_builder_apply_delayed_properties (GtkBuilder *builder,
GError **error)
{
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
GSList *l, *props;
gboolean result = TRUE;
/* take the list over from the builder->priv.
*
@ -1015,18 +1017,25 @@ gtk_builder_apply_delayed_properties (GtkBuilder *builder)
DelayedProperty *property = l->data;
GObject *object, *obj;
object = g_hash_table_lookup (priv->objects, property->object);
g_assert (object != NULL);
if (result)
{
object = g_hash_table_lookup (priv->objects, property->object);
g_assert (object != NULL);
obj = _gtk_builder_lookup_object (builder, property->value, property->line, property->col);
if (obj)
g_object_set (object, property->pspec->name, obj, NULL);
obj = gtk_builder_lookup_object (builder, property->value, property->line, property->col, error);
if (obj)
g_object_set (object, property->pspec->name, obj, NULL);
else
result = FALSE;
}
g_free (property->value);
g_free (property->object);
g_slice_free (DelayedProperty, property);
}
g_slist_free (props);
return result;
}
static inline void
@ -1040,28 +1049,37 @@ free_binding_info (gpointer data,
g_slice_free (BindingInfo, data);
}
static inline void
gtk_builder_create_bindings (GtkBuilder *builder)
static inline gboolean
gtk_builder_create_bindings (GtkBuilder *builder,
GError **error)
{
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
GSList *l;
gboolean result = TRUE;
for (l = priv->bindings; l; l = l->next)
{
BindingInfo *info = l->data;
GObject *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);
if (result)
{
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
result = FALSE;
}
free_binding_info (info, NULL);
}
g_slist_free (priv->bindings);
priv->bindings = NULL;
return result;
}
/**
@ -1755,9 +1773,9 @@ gboolean
_gtk_builder_finish (GtkBuilder *builder,
GError **error)
{
gtk_builder_apply_delayed_properties (builder);
gtk_builder_create_bindings (builder);
return gtk_builder_connect_signals (builder, error);
return gtk_builder_apply_delayed_properties (builder, error)
&& gtk_builder_create_bindings (builder, error)
&& gtk_builder_connect_signals (builder, error);
}
/**
@ -2983,6 +3001,28 @@ _gtk_builder_check_parent (GtkBuilder *builder,
return FALSE;
}
GObject *
gtk_builder_lookup_object (GtkBuilder *builder,
const gchar *name,
gint line,
gint col,
GError **error)
{
GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder);
GObject *obj;
obj = g_hash_table_lookup (priv->objects, name);
if (obj == NULL)
{
g_set_error (error,
GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_ID,
"%s:%d:%d Object with ID %s not found",
priv->filename, line, col, name);
}
return obj;
}
/*< private >
* @builder: a #GtkBuilder
* @name: object name to look up

View File

@ -1594,10 +1594,10 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
if (!gtk_buildable_parse_context_parse (&data.ctx, buffer, length, error))
goto out;
if (!_gtk_builder_finish (builder, error))
if (_gtk_builder_lookup_failed (builder, error))
goto out;
if (_gtk_builder_lookup_failed (builder, error))
if (!_gtk_builder_finish (builder, error))
goto out;
/* Custom parser_finished */

View File

@ -222,6 +222,11 @@ gboolean _gtk_builder_check_parent (GtkBuilder *builder,
GtkBuildableParseContext *context,
const gchar *parent_name,
GError **error);
GObject *gtk_builder_lookup_object (GtkBuilder *builder,
const gchar *name,
gint line,
gint col,
GError **error);
GObject *_gtk_builder_lookup_object (GtkBuilder *builder,
const gchar *name,
gint line,