[gtk/wip/otte/builder: 38/41] builder: Add gtk_builder_lookup_object()



commit 512c4c13a6098001148f2cabc8b692c182bd97bb
Author: Benjamin Otte <otte redhat com>
Date:   Mon Nov 25 07:40:28 2019 +0100

    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.

 gtk/gtkbuilder.c        | 74 +++++++++++++++++++++++++++++++++++++------------
 gtk/gtkbuilderparser.c  |  4 +--
 gtk/gtkbuilderprivate.h |  5 ++++
 3 files changed, 64 insertions(+), 19 deletions(-)
---
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index 8f6935c696..cafbe4e5f6 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -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
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index 0597fd6ab6..64e95fbfce 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -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 */
diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h
index 0e72efe273..49833ae9d5 100644
--- a/gtk/gtkbuilderprivate.h
+++ b/gtk/gtkbuilderprivate.h
@@ -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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]