[gtk+] GtkContainer: Use the new helpers



commit aeddf5565519dd92f1fe54d68ed147c5478edc2b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Apr 25 19:31:10 2015 -0400

    GtkContainer: Use the new helpers
    
    Instead of issuing g_warning, fill the provided GError.
    This lets us test this error handling, and is the right
    thing to do. Use the new GtkBuilder helpers and
    g_markup_collect_attributes to do so.

 gtk/gtkcontainer.c |  244 ++++++++++++++++++++++++++++++----------------------
 1 files changed, 140 insertions(+), 104 deletions(-)
---
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 3fcc221..8ad3074 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -653,134 +653,164 @@ typedef struct {
   gchar        *child_prop_name;
   gchar        *context;
   gboolean      translatable;
-} PackingPropertiesData;
+} PackingData;
 
 static void
-attributes_start_element (GMarkupParseContext *context,
-                          const gchar         *element_name,
-                          const gchar        **names,
-                          const gchar        **values,
-                          gpointer             user_data,
-                          GError             **error)
+packing_start_element (GMarkupParseContext  *context,
+                       const gchar          *element_name,
+                       const gchar         **names,
+                       const gchar         **values,
+                       gpointer              user_data,
+                       GError              **error)
 {
-  PackingPropertiesData *parser_data = (PackingPropertiesData*)user_data;
-  guint i;
+  PackingData *data = (PackingData*)user_data;
 
   if (strcmp (element_name, "property") == 0)
     {
-      for (i = 0; names[i]; i++)
-        if (strcmp (names[i], "name") == 0)
-          parser_data->child_prop_name = g_strdup (values[i]);
-        else if (strcmp (names[i], "translatable") == 0)
-          {
-            if (!_gtk_builder_boolean_from_string (values[1],
-                                                   &parser_data->translatable,
-                                                   error))
-              return;
-          }
-        else if (strcmp (names[i], "comments") == 0)
-          ; /* for translators */
-        else if (strcmp (names[i], "context") == 0)
-          parser_data->context = g_strdup (values[1]);
-        else
-          g_warning ("Unsupported attribute for GtkContainer Child "
-                     "property: %s\n", names[i]);
+      const gchar *name;
+      gboolean translatable = FALSE;
+      const gchar *ctx = NULL;
+
+      if (!_gtk_builder_check_parent (data->builder, context, "packing", error))
+        return;
+
+      if (!g_markup_collect_attributes (element_name, names, values, error,
+                                        G_MARKUP_COLLECT_STRING, "name", &name,
+                                        G_MARKUP_COLLECT_BOOLEAN|G_MARKUP_COLLECT_OPTIONAL, "translatable", 
&translatable,
+                                        G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "comments", NULL,
+                                        G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "context", &ctx,
+                                        G_MARKUP_COLLECT_INVALID))
+       {
+         _gtk_builder_prefix_error (data->builder, context, error);
+         return;
+       }
+
+     data->child_prop_name = g_strdup (name);
+     data->translatable = translatable;
+     data->context = g_strdup (ctx);
     }
   else if (strcmp (element_name, "packing") == 0)
-    return;
+    {
+      if (!_gtk_builder_check_parent (data->builder, context, "child", error))
+        return;
+
+      if (!g_markup_collect_attributes (element_name, names, values, error,
+                                        G_MARKUP_COLLECT_INVALID, NULL, NULL,
+                                        G_MARKUP_COLLECT_INVALID))
+        _gtk_builder_prefix_error (data->builder, context, error);
+    }
   else
-    g_warning ("Unsupported tag for GtkContainer: %s\n", element_name);
+    {
+      _gtk_builder_error_unhandled_tag (data->builder, context,
+                                        "GtkContainer", element_name,
+                                        error);
+    }
 }
 
 static void
-attributes_text_element (GMarkupParseContext *context,
-                         const gchar         *text,
-                         gsize                text_len,
-                         gpointer             user_data,
-                         GError             **error)
+packing_text_element (GMarkupParseContext  *context,
+                      const gchar          *text,
+                      gsize                 text_len,
+                      gpointer              user_data,
+                      GError              **error)
 {
-  PackingPropertiesData *parser_data = (PackingPropertiesData*)user_data;
+  PackingData *data = (PackingData*)user_data;
 
-  if (parser_data->child_prop_name)
-    g_string_append_len (parser_data->string, text, text_len);
+  if (data->child_prop_name)
+    g_string_append_len (data->string, text, text_len);
 }
 
 static void
-attributes_end_element (GMarkupParseContext *context,
-                       const gchar         *element_name,
-                       gpointer             user_data,
-                       GError             **error)
+packing_end_element (GMarkupParseContext  *context,
+                     const gchar          *element_name,
+                     gpointer              user_data,
+                     GError              **error)
 {
-  PackingPropertiesData *parser_data = (PackingPropertiesData*)user_data;
+  PackingData *data = (PackingData*)user_data;
 
   /* translate the string */
-  if (parser_data->string->len && parser_data->translatable)
+  if (data->string->len && data->translatable)
     {
       const gchar *translated;
       const gchar *domain;
 
-      domain = gtk_builder_get_translation_domain (parser_data->builder);
+      domain = gtk_builder_get_translation_domain (data->builder);
 
       translated = _gtk_builder_parser_translate (domain,
-                                                  parser_data->context,
-                                                  parser_data->string->str);
-      g_string_assign (parser_data->string, translated);
+                                                  data->context,
+                                                  data->string->str);
+      g_string_assign (data->string, translated);
     }
 
-  if (parser_data->child_prop_name)
-    gtk_container_buildable_set_child_property (parser_data->container,
-                                               parser_data->builder,
-                                               parser_data->child,
-                                               parser_data->child_prop_name,
-                                               parser_data->string->str);
+  if (data->child_prop_name)
+    gtk_container_buildable_set_child_property (data->container,
+                                                data->builder,
+                                                data->child,
+                                                data->child_prop_name,
+                                                data->string->str);
 
-  g_string_set_size (parser_data->string, 0);
-  g_free (parser_data->child_prop_name);
-  g_free (parser_data->context);
-  parser_data->child_prop_name = NULL;
-  parser_data->context = NULL;
-  parser_data->translatable = FALSE;
+  g_string_set_size (data->string, 0);
+  g_clear_pointer (&data->child_prop_name, g_free);
+  g_clear_pointer (&data->context, g_free);
+  data->translatable = FALSE;
 }
 
-static const GMarkupParser attributes_parser =
+static const GMarkupParser packing_parser =
   {
-    attributes_start_element,
-    attributes_end_element,
-    attributes_text_element,
+    packing_start_element,
+    packing_end_element,
+    packing_text_element,
   };
 
 typedef struct
   {
     GSList *items;
     GObject *object;
+    GtkBuilder *builder;
   } FocusChainData;
 
 static void
-focus_chain_start_element (GMarkupParseContext *context,
-                           const gchar         *element_name,
-                           const gchar        **names,
-                           const gchar        **values,
-                           gpointer            user_data,
-                           GError            **error)
-{
-  guint i;
+focus_chain_start_element (GMarkupParseContext  *context,
+                           const gchar          *element_name,
+                           const gchar         **names,
+                           const gchar         **values,
+                           gpointer              user_data,
+                           GError              **error)
+{
   FocusChainData *data = (FocusChainData*)user_data;
 
   if (strcmp (element_name, "widget") == 0)
     {
-      for (i = 0; names[i]; i++)
+      const gchar *name;
+
+      if (!_gtk_builder_check_parent (data->builder, context, "focus-chain", error))
+        return;
+
+      if (!g_markup_collect_attributes (element_name, names, values, error,
+                                        G_MARKUP_COLLECT_STRING, "name", &name,
+                                        G_MARKUP_COLLECT_INVALID))
         {
-          if (strcmp (names[i], "name") == 0)
-            data->items = g_slist_prepend (data->items, g_strdup (values[i]));
+          _gtk_builder_prefix_error (data->builder, context, error);
+          return;
         }
+
+      data->items = g_slist_prepend (data->items, g_strdup (name));
     }
   else if (strcmp (element_name, "focus-chain") == 0)
     {
-      return;
+      if (!_gtk_builder_check_parent (data->builder, context, "object", error))
+        return;
+
+      if (!g_markup_collect_attributes (element_name, names, values, error,
+                                        G_MARKUP_COLLECT_INVALID, "", NULL,
+                                        G_MARKUP_COLLECT_INVALID))
+        _gtk_builder_prefix_error (data->builder, context, error);
     }
   else
     {
-      g_warning ("Unsupported type tag for GtkContainer %s\n", element_name);
+      _gtk_builder_error_unhandled_tag (data->builder, context,
+                                        "GtkContainer", element_name,
+                                        error);
     }
 }
 
@@ -795,36 +825,40 @@ gtk_container_buildable_custom_tag_start (GtkBuildable  *buildable,
                                           GObject       *child,
                                           const gchar   *tagname,
                                           GMarkupParser *parser,
-                                          gpointer      *data)
+                                          gpointer      *parser_data)
 {
   if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
-                                                tagname, parser, data))
+                                                tagname, parser, parser_data))
     return TRUE;
 
   if (child && strcmp (tagname, "packing") == 0)
     {
-      PackingPropertiesData *parser_data;
+      PackingData *data;
 
-      parser_data = g_slice_new0 (PackingPropertiesData);
-      parser_data->string = g_string_new ("");
-      parser_data->builder = builder;
-      parser_data->container = GTK_CONTAINER (buildable);
-      parser_data->child = GTK_WIDGET (child);
-      parser_data->child_prop_name = NULL;
+      data = g_slice_new0 (PackingData);
+      data->string = g_string_new ("");
+      data->builder = builder;
+      data->container = GTK_CONTAINER (buildable);
+      data->child = GTK_WIDGET (child);
+      data->child_prop_name = NULL;
+
+      *parser = packing_parser;
+      *parser_data = data;
 
-      *parser = attributes_parser;
-      *data = parser_data;
       return TRUE;
     }
   else if (!child && strcmp (tagname, "focus-chain") == 0)
     {
-      FocusChainData *parser_data;
-      parser_data = g_slice_new0 (FocusChainData);
-      parser_data->items = NULL;
-      parser_data->object = G_OBJECT (buildable);
+      FocusChainData *data;
+
+      data = g_slice_new0 (FocusChainData);
+      data->items = NULL;
+      data->object = G_OBJECT (buildable);
+      data->builder = builder;
 
       *parser = focus_chain_parser;
-      *data = parser_data;
+      *parser_data = data;
+
       return TRUE;
     }
 
@@ -836,19 +870,21 @@ gtk_container_buildable_custom_tag_end (GtkBuildable *buildable,
                                         GtkBuilder   *builder,
                                         GObject      *child,
                                         const gchar  *tagname,
-                                        gpointer     *data)
+                                        gpointer     *parser_data)
 {
   if (strcmp (tagname, "packing") == 0)
     {
-      PackingPropertiesData *parser_data = (PackingPropertiesData*)data;
-      g_string_free (parser_data->string, TRUE);
-      g_slice_free (PackingPropertiesData, parser_data);
+      PackingData *data = (PackingData*)parser_data;
+
+      g_string_free (data->string, TRUE);
+      g_slice_free (PackingData, data);
+
       return;
     }
 
   if (parent_buildable_iface->custom_tag_end)
     parent_buildable_iface->custom_tag_end (buildable, builder,
-                                            child, tagname, data);
+                                            child, tagname, parser_data);
 }
 
 static void
@@ -856,41 +892,41 @@ gtk_container_buildable_custom_finished (GtkBuildable *buildable,
                                          GtkBuilder   *builder,
                                          GObject      *child,
                                          const gchar  *tagname,
-                                         gpointer      data)
+                                         gpointer      parser_data)
 {
    if (strcmp (tagname, "focus-chain") == 0)
     {
-      FocusChainData *parser_data = (FocusChainData*)data;
+      FocusChainData *data = (FocusChainData*)parser_data;
       GSList *l;
       GList *chain;
       GObject *object;
 
       chain = NULL;
-      for (l = parser_data->items; l; l = l->next)
+      for (l = data->items; l; l = l->next)
         {
           object = gtk_builder_get_object (builder, l->data);
           if (!object)
             {
               g_warning ("Unknown object %s specified in focus-chain for %s",
                          (const gchar*)l->data,
-                         gtk_buildable_get_name (GTK_BUILDABLE (parser_data->object)));
+                         gtk_buildable_get_name (GTK_BUILDABLE (data->object)));
               continue;
             }
           chain = g_list_prepend (chain, object);
         }
 
-      gtk_container_set_focus_chain (GTK_CONTAINER (parser_data->object), chain);
+      gtk_container_set_focus_chain (GTK_CONTAINER (data->object), chain);
       g_list_free (chain);
 
-      g_slist_free_full (parser_data->items, g_free);
-      g_slice_free (FocusChainData, parser_data);
+      g_slist_free_full (data->items, g_free);
+      g_slice_free (FocusChainData, data);
 
       return;
     }
 
   if (parent_buildable_iface->custom_finished)
     parent_buildable_iface->custom_finished (buildable, builder,
-                                             child, tagname, data);
+                                             child, tagname, parser_data);
 }
 
 /**


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