[evolution] Reimplement e_table_specification_load_from_string().



commit c337e2af1880b2833b8bd7180c02eac192f9d86b
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sun Jun 30 11:07:02 2013 -0400

    Reimplement e_table_specification_load_from_string().
    
    New parser implementation that uses GMarkupParser instead of libxml2.

 e-util/e-table-specification.c |  390 +++++++++++++++++++++++++++++++++++++++-
 e-util/e-table-specification.h |   20 +-
 2 files changed, 392 insertions(+), 18 deletions(-)
---
diff --git a/e-util/e-table-specification.c b/e-util/e-table-specification.c
index 40d4a54..ff02d3b 100644
--- a/e-util/e-table-specification.c
+++ b/e-util/e-table-specification.c
@@ -43,6 +43,368 @@ G_DEFINE_TYPE (
        G_TYPE_OBJECT)
 
 static void
+table_specification_start_specification (GMarkupParseContext *context,
+                                         const gchar *element_name,
+                                         const gchar **attribute_names,
+                                         const gchar **attribute_values,
+                                         ETableSpecification *specification,
+                                         GError **error)
+{
+       const gchar *cursor_mode = NULL;
+       const gchar *selection_mode = NULL;
+       gboolean fallback_draw_grid = FALSE;
+       gboolean missing;
+
+       g_free (specification->click_to_add_message);
+       specification->click_to_add_message = NULL;
+
+       g_free (specification->domain);
+       specification->domain = NULL;
+
+       /* Use G_MARKUP_COLLECT_TRISTATE to identify
+        * missing attributes that default to TRUE. */
+       g_markup_collect_attributes (
+               element_name,
+               attribute_names,
+               attribute_values,
+               error,
+
+               G_MARKUP_COLLECT_TRISTATE,
+               "alternating-row-colors",
+               &specification->alternating_row_colors,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "no-headers",
+               &specification->no_headers,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "click-to-add",
+               &specification->click_to_add,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "click-to-add-end",
+               &specification->click_to_add_end,
+
+               G_MARKUP_COLLECT_TRISTATE,
+               "horizontal-draw-grid",
+               &specification->horizontal_draw_grid,
+
+               G_MARKUP_COLLECT_TRISTATE,
+               "vertical-draw-grid",
+               &specification->vertical_draw_grid,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "draw-grid",
+               &fallback_draw_grid,
+
+               G_MARKUP_COLLECT_TRISTATE,
+               "draw-focus",
+               &specification->draw_focus,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "horizontal-scrolling",
+               &specification->horizontal_scrolling,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "horizontal-resize",
+               &specification->horizontal_resize,
+
+               G_MARKUP_COLLECT_TRISTATE,
+               "allow-grouping",
+               &specification->allow_grouping,
+
+               G_MARKUP_COLLECT_STRING |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "selection-mode",
+               &selection_mode,
+
+               G_MARKUP_COLLECT_STRING |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "cursor-mode",
+               &cursor_mode,
+
+               G_MARKUP_COLLECT_STRDUP |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "_click-to-add-message",
+               &specification->click_to_add_message,
+
+               G_MARKUP_COLLECT_STRDUP |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "gettext-domain",
+               &specification->domain,
+
+               G_MARKUP_COLLECT_INVALID);
+
+       /* Additional tweaks. */
+
+       missing =
+               (specification->alternating_row_colors != TRUE) &&
+               (specification->alternating_row_colors != FALSE);
+       if (missing)
+               specification->alternating_row_colors = TRUE;
+
+       if (!specification->click_to_add)
+               specification->click_to_add_end = FALSE;
+
+       missing =
+               (specification->horizontal_draw_grid != TRUE) &&
+               (specification->horizontal_draw_grid != FALSE);
+       if (missing)
+               specification->horizontal_draw_grid = fallback_draw_grid;
+
+       missing =
+               (specification->vertical_draw_grid != TRUE) &&
+               (specification->vertical_draw_grid != FALSE);
+       if (missing)
+               specification->vertical_draw_grid = fallback_draw_grid;
+
+       missing =
+               (specification->draw_focus != TRUE) &&
+               (specification->draw_focus != FALSE);
+       if (missing)
+               specification->draw_focus = TRUE;
+
+       missing =
+               (specification->allow_grouping != TRUE) &&
+               (specification->allow_grouping != FALSE);
+       if (missing)
+               specification->allow_grouping = TRUE;
+
+       if (selection_mode == NULL)  /* attribute missing */
+               specification->selection_mode = GTK_SELECTION_MULTIPLE;
+       else if (g_ascii_strcasecmp (selection_mode, "single") == 0)
+               specification->selection_mode = GTK_SELECTION_SINGLE;
+       else if (g_ascii_strcasecmp (selection_mode, "browse") == 0)
+               specification->selection_mode = GTK_SELECTION_BROWSE;
+       else if (g_ascii_strcasecmp (selection_mode, "extended") == 0)
+               specification->selection_mode = GTK_SELECTION_MULTIPLE;
+       else  /* unrecognized attribute value */
+               specification->selection_mode = GTK_SELECTION_MULTIPLE;
+
+       if (cursor_mode == NULL)  /* attribute missing */
+               specification->cursor_mode = E_CURSOR_SIMPLE;
+       else if (g_ascii_strcasecmp (cursor_mode, "line") == 0)
+               specification->cursor_mode = E_CURSOR_LINE;
+       else if (g_ascii_strcasecmp (cursor_mode, "spreadsheet") == 0)
+               specification->cursor_mode = E_CURSOR_SPREADSHEET;
+       else  /* unrecognized attribute value */
+               specification->cursor_mode = E_CURSOR_SIMPLE;
+
+       if (specification->domain != NULL && *specification->domain == '\0') {
+               g_free (specification->domain);
+               specification->domain = NULL;
+       }
+}
+
+static void
+table_specification_start_column (GMarkupParseContext *context,
+                                  const gchar *element_name,
+                                  const gchar **attribute_names,
+                                  const gchar **attribute_values,
+                                  GPtrArray *columns,
+                                  GError **error)
+{
+       ETableColumnSpecification *column_spec;
+       const gchar *model_col_str = NULL;
+       const gchar *compare_col_str = NULL;
+       const gchar *expansion_str = NULL;
+       const gchar *minimum_width_str = NULL;
+       const gchar *priority_str = NULL;
+       gint64 int_value;
+       gboolean missing;
+
+       column_spec = e_table_column_specification_new ();
+
+       /* Use G_MARKUP_COLLECT_TRISTATE to identify
+        * missing attributes that default to TRUE. */
+       g_markup_collect_attributes (
+               element_name,
+               attribute_names,
+               attribute_values,
+               error,
+
+               G_MARKUP_COLLECT_STRING |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "model_col",
+               &model_col_str,
+
+               G_MARKUP_COLLECT_STRING |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "compare_col",
+               &compare_col_str,
+
+               G_MARKUP_COLLECT_STRDUP |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "_title",
+               &column_spec->title,
+
+               G_MARKUP_COLLECT_STRDUP |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "pixbuf",
+               &column_spec->pixbuf,
+
+               G_MARKUP_COLLECT_STRING |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "expansion",
+               &expansion_str,
+
+               G_MARKUP_COLLECT_STRING |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "minimum_width",
+               &minimum_width_str,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "resizable",
+               &column_spec->resizable,
+
+               G_MARKUP_COLLECT_BOOLEAN |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "disabled",
+               &column_spec->disabled,
+
+               G_MARKUP_COLLECT_STRDUP |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "cell",
+               &column_spec->cell,
+
+               G_MARKUP_COLLECT_STRDUP |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "compare",
+               &column_spec->compare,
+
+               G_MARKUP_COLLECT_STRDUP |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "search",
+               &column_spec->search,
+
+               G_MARKUP_COLLECT_TRISTATE,
+               "sortable",
+               &column_spec->sortable,
+
+               G_MARKUP_COLLECT_STRING |
+               G_MARKUP_COLLECT_OPTIONAL,
+               "priority",
+               &priority_str,
+
+               G_MARKUP_COLLECT_INVALID);
+
+       /* Additional tweaks. */
+
+       if (model_col_str != NULL) {
+               int_value = g_ascii_strtoll (model_col_str, NULL, 10);
+               column_spec->model_col = (gint) int_value;
+               column_spec->compare_col = (gint) int_value;
+       }
+
+       if (compare_col_str != NULL) {
+               int_value = g_ascii_strtoll (compare_col_str, NULL, 10);
+               column_spec->compare_col = (gint) int_value;
+       }
+
+       if (column_spec->title == NULL)
+               column_spec->title = g_strdup ("");
+
+       if (expansion_str != NULL)
+               column_spec->expansion = g_ascii_strtod (expansion_str, NULL);
+
+       if (minimum_width_str != NULL) {
+               int_value = g_ascii_strtoll (minimum_width_str, NULL, 10);
+               column_spec->minimum_width = (gint) int_value;
+       }
+
+       if (priority_str != NULL) {
+               int_value = g_ascii_strtoll (priority_str, NULL, 10);
+               column_spec->priority = (gint) int_value;
+       }
+
+       missing =
+               (column_spec->sortable != TRUE) &&
+               (column_spec->sortable != FALSE);
+       if (missing)
+               column_spec->sortable = TRUE;
+
+       g_ptr_array_add (columns, g_object_ref (column_spec));
+
+       g_object_unref (column_spec);
+}
+
+static void
+table_specification_start_element (GMarkupParseContext *context,
+                                   const gchar *element_name,
+                                   const gchar **attribute_names,
+                                   const gchar **attribute_values,
+                                   gpointer user_data,
+                                   GError **error)
+{
+       ETableSpecification *specification;
+       GPtrArray *columns;
+
+       specification = E_TABLE_SPECIFICATION (user_data);
+       columns = e_table_specification_ref_columns (specification);
+
+       if (g_str_equal (element_name, "ETableSpecification"))
+               table_specification_start_specification (
+                       context,
+                       element_name,
+                       attribute_names,
+                       attribute_values,
+                       specification,
+                       error);
+
+       if (g_str_equal (element_name, "ETableColumn"))
+               table_specification_start_column (
+                       context,
+                       element_name,
+                       attribute_names,
+                       attribute_values,
+                       columns,
+                       error);
+
+       if (g_str_equal (element_name, "ETableState"))
+               e_table_state_parse_context_push (context, specification);
+
+       g_ptr_array_unref (columns);
+}
+
+static void
+table_specification_end_element (GMarkupParseContext *context,
+                                 const gchar *element_name,
+                                 gpointer user_data,
+                                 GError **error)
+{
+       ETableSpecification *specification;
+
+       specification = E_TABLE_SPECIFICATION (user_data);
+
+       if (g_str_equal (element_name, "ETableState")) {
+               ETableState *state;
+
+               state = e_table_state_parse_context_pop (context);
+               g_return_if_fail (E_IS_TABLE_STATE (state));
+
+               g_clear_object (&specification->state);
+               specification->state = g_object_ref (state);
+
+               g_object_unref (state);
+       }
+}
+
+static const GMarkupParser table_specification_parser = {
+       table_specification_start_element,
+       table_specification_end_element,
+       NULL,
+       NULL,
+       NULL
+};
+
+static void
 table_specification_dispose (GObject *object)
 {
        ETableSpecification *specification;
@@ -229,19 +591,31 @@ gboolean
 e_table_specification_load_from_string (ETableSpecification *specification,
                                         const gchar *xml)
 {
-       xmlDoc *doc;
+       GMarkupParseContext *context;
        gboolean success = FALSE;
 
        g_return_val_if_fail (E_IS_TABLE_SPECIFICATION (specification), FALSE);
        g_return_val_if_fail (xml != NULL, FALSE);
 
-       doc = xmlParseMemory ((gchar *) xml, strlen (xml));
-       if (doc != NULL) {
-               xmlNode *node = xmlDocGetRootElement (doc);
-               e_table_specification_load_from_node (specification, node);
-               xmlFreeDoc (doc);
-               success = TRUE;
-       }
+       g_ptr_array_set_size (specification->priv->columns, 0);
+       g_clear_object (&specification->state);
+
+       context = g_markup_parse_context_new (
+               &table_specification_parser, 0,
+               g_object_ref (specification),
+               (GDestroyNotify) g_object_unref);
+
+       if (g_markup_parse_context_parse (context, xml, -1, NULL))
+               success = g_markup_parse_context_end_parse (context, NULL);
+
+       g_markup_parse_context_free (context);
+
+       if (specification->state == NULL)
+               specification->state = e_table_state_vanilla (specification);
+
+       e_table_sort_info_set_can_group (
+               specification->state->sort_info,
+               specification->allow_grouping);
 
        return success;
 }
diff --git a/e-util/e-table-specification.h b/e-util/e-table-specification.h
index 09b86c3..bce9c38 100644
--- a/e-util/e-table-specification.h
+++ b/e-util/e-table-specification.h
@@ -61,16 +61,16 @@ struct _ETableSpecification {
 
        ETableState *state;
 
-       guint alternating_row_colors : 1;
-       guint no_headers : 1;
-       guint click_to_add : 1;
-       guint click_to_add_end : 1;
-       guint horizontal_draw_grid : 1;
-       guint vertical_draw_grid : 1;
-       guint draw_focus : 1;
-       guint horizontal_scrolling : 1;
-       guint horizontal_resize : 1;
-       guint allow_grouping : 1;
+       gboolean alternating_row_colors;
+       gboolean no_headers;
+       gboolean click_to_add;
+       gboolean click_to_add_end;
+       gboolean horizontal_draw_grid;
+       gboolean vertical_draw_grid;
+       gboolean draw_focus;
+       gboolean horizontal_scrolling;
+       gboolean horizontal_resize;
+       gboolean allow_grouping;
        GtkSelectionMode selection_mode;
        ECursorMode cursor_mode;
 


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