aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-06-30 23:07:02 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-07-02 22:34:10 +0800
commitc337e2af1880b2833b8bd7180c02eac192f9d86b (patch)
tree3c9d576d21f700f844f85bd9d37bf84862b1789e
parent44c74e5e9d5baa0d8856ac601eae4d492b0555a3 (diff)
downloadgsoc2013-evolution-c337e2af1880b2833b8bd7180c02eac192f9d86b.tar
gsoc2013-evolution-c337e2af1880b2833b8bd7180c02eac192f9d86b.tar.gz
gsoc2013-evolution-c337e2af1880b2833b8bd7180c02eac192f9d86b.tar.bz2
gsoc2013-evolution-c337e2af1880b2833b8bd7180c02eac192f9d86b.tar.lz
gsoc2013-evolution-c337e2af1880b2833b8bd7180c02eac192f9d86b.tar.xz
gsoc2013-evolution-c337e2af1880b2833b8bd7180c02eac192f9d86b.tar.zst
gsoc2013-evolution-c337e2af1880b2833b8bd7180c02eac192f9d86b.zip
Reimplement e_table_specification_load_from_string().
New parser implementation that uses GMarkupParser instead of libxml2.
-rw-r--r--e-util/e-table-specification.c390
-rw-r--r--e-util/e-table-specification.h20
2 files changed, 392 insertions, 18 deletions
diff --git a/e-util/e-table-specification.c b/e-util/e-table-specification.c
index 40d4a54d63..ff02d3b08e 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 09b86c3791..bce9c38f6a 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;