From bcd071b5661b1139484f5a98136bbc65a6cb1819 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 29 Jun 2013 20:00:35 -0400 Subject: Add e_table_sort_info_parse_context_push/pop(). New parser implementation that uses GMarkupParser instead of libxml2. --- .../evolution-util/evolution-util-sections.txt | 2 + e-util/e-table-sort-info.c | 210 +++++++++++++++++++++ e-util/e-table-sort-info.h | 6 + 3 files changed, 218 insertions(+) diff --git a/doc/reference/evolution-util/evolution-util-sections.txt b/doc/reference/evolution-util/evolution-util-sections.txt index a5d2330114..146f987bbc 100644 --- a/doc/reference/evolution-util/evolution-util-sections.txt +++ b/doc/reference/evolution-util/evolution-util-sections.txt @@ -3869,6 +3869,8 @@ e_table_sorter_get_type ETableSortInfo ETableSortInfo e_table_sort_info_new +e_table_sort_info_parse_context_push +e_table_sort_info_parse_context_pop e_table_sort_info_ref_specification e_table_sort_info_get_can_group e_table_sort_info_set_can_group diff --git a/e-util/e-table-sort-info.c b/e-util/e-table-sort-info.c index 28e96f710f..e60277b936 100644 --- a/e-util/e-table-sort-info.c +++ b/e-util/e-table-sort-info.c @@ -62,6 +62,166 @@ column_data_clear (ColumnData *data) g_clear_object (&data->column_spec); } +static void +table_sort_info_parser_start_group (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ETableSortInfo *sort_info, + GPtrArray *columns, + GError **error) +{ + const gchar *index_str; + gboolean ascending; + gboolean success; + + success = g_markup_collect_attributes ( + element_name, + attribute_names, + attribute_values, + error, + + G_MARKUP_COLLECT_STRING, + "column", + &index_str, + + G_MARKUP_COLLECT_BOOLEAN | + G_MARKUP_COLLECT_OPTIONAL, + "ascending", + &ascending, + + G_MARKUP_COLLECT_INVALID); + + if (success) { + ETableColumnSpecification *column_spec; + ColumnData column_data; + gint64 index; + + g_return_if_fail (index_str != NULL); + index = g_ascii_strtoll (index_str, NULL, 10); + + g_return_if_fail (index < columns->len); + column_spec = g_ptr_array_index (columns, index); + + column_data.column_spec = g_object_ref (column_spec); + + if (ascending) + column_data.sort_type = GTK_SORT_ASCENDING; + else + column_data.sort_type = GTK_SORT_DESCENDING; + + g_array_append_val (sort_info->priv->groupings, column_data); + } +} + +static void +table_sort_info_parser_start_leaf (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ETableSortInfo *sort_info, + GPtrArray *columns, + GError **error) +{ + const gchar *index_str; + gboolean ascending; + gboolean success; + + success = g_markup_collect_attributes ( + element_name, + attribute_names, + attribute_values, + error, + + G_MARKUP_COLLECT_STRING, + "column", + &index_str, + + G_MARKUP_COLLECT_BOOLEAN | + G_MARKUP_COLLECT_OPTIONAL, + "ascending", + &ascending, + + G_MARKUP_COLLECT_INVALID); + + if (success) { + ETableColumnSpecification *column_spec; + ColumnData column_data; + gint64 index; + + g_return_if_fail (index_str != NULL); + index = g_ascii_strtoll (index_str, NULL, 10); + + g_return_if_fail (index < columns->len); + column_spec = g_ptr_array_index (columns, index); + + column_data.column_spec = g_object_ref (column_spec); + + if (ascending) + column_data.sort_type = GTK_SORT_ASCENDING; + else + column_data.sort_type = GTK_SORT_DESCENDING; + + g_array_append_val (sort_info->priv->sortings, column_data); + } +} + +static void +table_sort_info_parser_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ETableSpecification *specification; + ETableSortInfo *sort_info; + GPtrArray *columns; + + sort_info = E_TABLE_SORT_INFO (user_data); + specification = e_table_sort_info_ref_specification (sort_info); + columns = e_table_specification_ref_columns (specification); + + if (g_str_equal (element_name, "group")) + table_sort_info_parser_start_group ( + context, + element_name, + attribute_names, + attribute_values, + sort_info, + columns, + error); + + if (g_str_equal (element_name, "leaf")) + table_sort_info_parser_start_leaf ( + context, + element_name, + attribute_names, + attribute_values, + sort_info, + columns, + error); + + g_object_unref (specification); + g_ptr_array_unref (columns); +} + +static void +table_sort_info_parser_error (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + g_object_unref (E_TABLE_SORT_INFO (user_data)); +} + +static const GMarkupParser table_sort_info_parser = { + table_sort_info_parser_start_element, + NULL, + NULL, + NULL, + table_sort_info_parser_error +}; + static void table_sort_info_set_specification (ETableSortInfo *sort_info, ETableSpecification *specification) @@ -221,6 +381,56 @@ e_table_sort_info_new (ETableSpecification *specification) "specification", specification, NULL); } +/** + * e_table_sort_info_parse_context_push: + * @context: a #GMarkupParseContext + * @specification: an #ETableSpecification + * + * Creates a new #ETableSortInfo from a segment of XML data being fed to + * @context. Call this function for the appropriate opening tag from the + * start_element callback of a #GMarkupParser, + * then call e_table_sort_info_parse_context_pop() for the corresponding + * closing tag from the end_element callback. + **/ +void +e_table_sort_info_parse_context_push (GMarkupParseContext *context, + ETableSpecification *specification) +{ + g_return_if_fail (context != NULL); + g_return_if_fail (E_IS_TABLE_SPECIFICATION (specification)); + + g_markup_parse_context_push ( + context, &table_sort_info_parser, + e_table_sort_info_new (specification)); +} + +/** + * e_table_sort_info_parse_context_pop: + * @context: a #GMarkupParseContext + * + * Creates a new #ETableSortInfo from a segment of XML data being fed to + * @context. Call e_table_sort_info_parse_context_push() for the appropriate + * opening tag from the start_element callback of a + * #GMarkupParser, then call this function for the corresponding closing tag + * from the end_element callback. + * + * Unreference the newly-created #ETableSortInfo with g_object_unref() when + * finished with it. + * + * Returns: an #ETableSortInfo + **/ +ETableSortInfo * +e_table_sort_info_parse_context_pop (GMarkupParseContext *context) +{ + gpointer user_data; + + g_return_val_if_fail (context != NULL, NULL); + + user_data = g_markup_parse_context_pop (context); + + return E_TABLE_SORT_INFO (user_data); +} + /** * e_table_sort_info_ref_specification: * @sort_info: an #ETableSortInfo diff --git a/e-util/e-table-sort-info.h b/e-util/e-table-sort-info.h index 583feba67a..2c07cbb89b 100644 --- a/e-util/e-table-sort-info.h +++ b/e-util/e-table-sort-info.h @@ -72,6 +72,12 @@ struct _ETableSortInfoClass { GType e_table_sort_info_get_type (void) G_GNUC_CONST; ETableSortInfo *e_table_sort_info_new (struct _ETableSpecification *specification); +void e_table_sort_info_parse_context_push + (GMarkupParseContext *context, + struct _ETableSpecification *specification); +ETableSortInfo * + e_table_sort_info_parse_context_pop + (GMarkupParseContext *context); struct _ETableSpecification * e_table_sort_info_ref_specification (ETableSortInfo *sort_info); -- cgit v1.2.3