[gtk+] GtkDialog: Use the new helpers



commit 4ee291c8f13c45e6f7579b3639947ff94aa26697
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Apr 25 19:33:52 2015 -0400

    GtkDialog: 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/gtkdialog.c |  194 +++++++++++++++++++++++++++++++-----------------------
 1 files changed, 111 insertions(+), 83 deletions(-)
---
diff --git a/gtk/gtkdialog.c b/gtk/gtkdialog.c
index 21e9004..bc8792e 100644
--- a/gtk/gtkdialog.c
+++ b/gtk/gtkdialog.c
@@ -42,6 +42,7 @@
 #include "gtkbindings.h"
 #include "gtkprivate.h"
 #include "gtkbuildable.h"
+#include "gtkbuilderprivate.h"
 #include "gtksettings.h"
 #include "gtktypebuiltins.h"
 #include "deprecated/gtkstock.h"
@@ -1672,119 +1673,144 @@ typedef struct {
   GtkDialog *dialog;
   GtkBuilder *builder;
   GSList *items;
-  gchar *response;
+  gint response_id;
   gboolean is_default;
-} ActionWidgetsSubParserData;
+  gboolean is_text;
+  GString *string;
+  gboolean in_action_widgets;
+} SubParserData;
 
-static gint
-parse_response_id (const gchar *response_attr)
+static void
+parser_start_element (GMarkupParseContext *context,
+                      const gchar         *element_name,
+                      const gchar        **names,
+                      const gchar        **values,
+                      gpointer             user_data,
+                      GError             **error)
 {
-  int response_id;
-  GEnumClass *enum_class = NULL;
-  GEnumValue *enum_value;
+  SubParserData *data = (SubParserData*)user_data;
+
+  if (strcmp (element_name, "action-widget") == 0)
+    {
+      const gchar *response;
+      gboolean is_default = FALSE;
+      GValue gvalue = G_VALUE_INIT;
 
-  response_id = g_ascii_strtoll (response_attr, NULL, 10);
-  if (response_id != 0)
-    goto out;
+      if (!_gtk_builder_check_parent (data->builder, context, "action-widgets", error))
+        return;
+
+      if (!g_markup_collect_attributes (element_name, names, values, error,
+                                        G_MARKUP_COLLECT_STRING, "response", &response,
+                                        G_MARKUP_COLLECT_BOOLEAN|G_MARKUP_COLLECT_OPTIONAL, "default", 
&is_default,
+                                        G_MARKUP_COLLECT_INVALID))
+        {
+          _gtk_builder_prefix_error (data->builder, context, error);
+          return;
+        }
 
-  enum_class = g_type_class_ref (GTK_TYPE_RESPONSE_TYPE);
-  enum_value = g_enum_get_value_by_nick (enum_class, response_attr);
-  if (enum_value == NULL)
-    goto out;
+      if (!gtk_builder_value_from_string_type (data->builder, GTK_TYPE_RESPONSE_TYPE, response, &gvalue, 
error))
+        {
+          _gtk_builder_prefix_error (data->builder, context, error);
+          return;
+        }
 
-  response_id = enum_value->value;
+      data->response_id = g_value_get_enum (&gvalue);
+      data->is_default = is_default;
+      data->is_text = TRUE;
+      g_string_set_size (data->string, 0);
+    }
+  else if (strcmp (element_name, "action-widgets") == 0)
+    {
+      if (!_gtk_builder_check_parent (data->builder, context, "object", error))
+        return;
 
- out:
-  if (enum_class)
-    g_type_class_unref (enum_class);
+      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);
 
-  return response_id;
+      data->in_action_widgets = TRUE;
+    }
+  else
+    {
+      _gtk_builder_error_unhandled_tag (data->builder, context,
+                                        "GtkDialog", element_name,
+                                        error);
+    }
 }
 
 static void
-attributes_start_element (GMarkupParseContext *context,
-                         const gchar         *element_name,
-                         const gchar        **names,
-                         const gchar        **values,
-                         gpointer             user_data,
-                         GError             **error)
+parser_text_element (GMarkupParseContext *context,
+                     const gchar         *text,
+                     gsize                text_len,
+                     gpointer             user_data,
+                     GError             **error)
 {
-  ActionWidgetsSubParserData *parser_data = (ActionWidgetsSubParserData*)user_data;
-  guint i;
+  SubParserData *data = (SubParserData*)user_data;
 
-  if (strcmp (element_name, "action-widget") == 0)
-    {
-      for (i = 0; names[i]; i++)
-        {
-         if (strcmp (names[i], "response") == 0)
-           parser_data->response = g_strdup (values[i]);
-          else if (strcmp (names[i], "default") == 0)
-            parser_data->is_default = TRUE;
-        }
-    }
-  else if (strcmp (element_name, "action-widgets") == 0)
-    return;
-  else
-    g_warning ("Unsupported tag for GtkDialog: %s\n", element_name);
+  if (data->is_text)
+    g_string_append_len (data->string, text, text_len);
 }
 
 static void
-attributes_text_element (GMarkupParseContext *context,
-                        const gchar         *text,
-                        gsize                text_len,
-                        gpointer             user_data,
-                        GError             **error)
+parser_end_element (GMarkupParseContext  *context,
+                    const gchar          *element_name,
+                    gpointer              user_data,
+                    GError              **error)
 {
-  ActionWidgetsSubParserData *parser_data = (ActionWidgetsSubParserData*)user_data;
-  ActionWidgetInfo *item;
+  SubParserData *data = (SubParserData*)user_data;
 
-  
-  if (!parser_data->response)
-    return;
+  if (data->is_text)
+    {
+      ActionWidgetInfo *item;
 
-  item = g_new (ActionWidgetInfo, 1);
-  item->widget_name = g_strndup (text, text_len);
-  item->response_id = parse_response_id (parser_data->response);
-  g_free (parser_data->response);
-  item->is_default = parser_data->is_default;
-  parser_data->items = g_slist_prepend (parser_data->items, item);
-  parser_data->response = NULL;
-  parser_data->is_default = FALSE;
+      item = g_new (ActionWidgetInfo, 1);
+      item->widget_name = g_strdup (data->string->str);
+      item->response_id = data->response_id;
+      item->is_default = data->is_default;
+
+      data->items = g_slist_prepend (data->items, item);
+      data->is_default = FALSE;
+      data->is_text = FALSE;
+    }
 }
 
-static const GMarkupParser attributes_parser =
+static const GMarkupParser sub_parser =
   {
-    attributes_start_element,
-    NULL,
-    attributes_text_element,
+    parser_start_element,
+    parser_end_element,
+    parser_text_element,
   };
 
 static gboolean
 gtk_dialog_buildable_custom_tag_start (GtkBuildable  *buildable,
-                                      GtkBuilder    *builder,
-                                      GObject       *child,
-                                      const gchar   *tagname,
-                                      GMarkupParser *parser,
-                                      gpointer      *data)
+                                       GtkBuilder    *builder,
+                                       GObject       *child,
+                                       const gchar   *tagname,
+                                       GMarkupParser *parser,
+                                       gpointer      *parser_data)
 {
-  ActionWidgetsSubParserData *parser_data;
+  SubParserData *data;
 
   if (child)
     return FALSE;
 
   if (strcmp (tagname, "action-widgets") == 0)
     {
-      parser_data = g_slice_new0 (ActionWidgetsSubParserData);
-      parser_data->dialog = GTK_DIALOG (buildable);
-      parser_data->items = NULL;
-
-      *parser = attributes_parser;
-      *data = parser_data;
+      data = g_slice_new0 (SubParserData);
+      data->dialog = GTK_DIALOG (buildable);
+      data->builder = builder;
+      data->string = g_string_new ("");
+      data->items = NULL;
+      data->in_action_widgets = FALSE;
+
+      *parser = sub_parser;
+      *parser_data = data;
       return TRUE;
     }
 
   return parent_buildable_iface->custom_tag_start (buildable, builder, child,
-                                                  tagname, parser, data);
+                                                  tagname, parser, parser_data);
 }
 
 static void
@@ -1797,7 +1823,7 @@ gtk_dialog_buildable_custom_finished (GtkBuildable *buildable,
   GtkDialog *dialog = GTK_DIALOG (buildable);
   GtkDialogPrivate *priv = dialog->priv;
   GSList *l;
-  ActionWidgetsSubParserData *parser_data;
+  SubParserData *data;
   GObject *object;
   ResponseData *ad;
   guint signal_id;
@@ -1809,10 +1835,10 @@ gtk_dialog_buildable_custom_finished (GtkBuildable *buildable,
       return;
     }
 
-  parser_data = (ActionWidgetsSubParserData*)user_data;
-  parser_data->items = g_slist_reverse (parser_data->items);
+  data = (SubParserData*)user_data;
+  data->items = g_slist_reverse (data->items);
 
-  for (l = parser_data->items; l; l = l->next)
+  for (l = data->items; l; l = l->next)
     {
       ActionWidgetInfo *item = l->data;
       gboolean is_action;
@@ -1867,8 +1893,10 @@ gtk_dialog_buildable_custom_finished (GtkBuildable *buildable,
       g_free (item->widget_name);
       g_free (item);
     }
-  g_slist_free (parser_data->items);
-  g_slice_free (ActionWidgetsSubParserData, parser_data);
+
+  g_slist_free (data->items);
+  g_string_free (data->string, TRUE);
+  g_slice_free (SubParserData, data);
 
   update_suggested_action (dialog);
 }
@@ -1889,7 +1917,7 @@ gtk_dialog_buildable_add_child (GtkBuildable  *buildable,
       priv->headerbar = GTK_WIDGET (child);
       gtk_window_set_titlebar (GTK_WINDOW (buildable), priv->headerbar);
     }
-  else if (g_strcmp0 (type, "action") == 0)
+  else if (g_str_equal (type, "action"))
     gtk_dialog_add_action_widget (GTK_DIALOG (buildable), GTK_WIDGET (child), GTK_RESPONSE_NONE);
   else
     GTK_BUILDER_WARN_INVALID_CHILD_TYPE (buildable, type);


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