diff options
author | Michael Natterer <mitch@imendio.com> | 2006-08-28 16:14:42 +0000 |
---|---|---|
committer | Michael Natterer <mitch@src.gnome.org> | 2006-08-28 16:14:42 +0000 |
commit | 0fa6144940197ff150e232a53c2da515296e12b0 (patch) | |
tree | da6f63e9be0c6925e3515d3f1c0e364422ee7c39 /gtk/gtktextbufferserialize.c | |
parent | 21ac0b0b4045ebedfcf1c6a8dc527a3f5d20c372 (diff) | |
download | gtk+-0fa6144940197ff150e232a53c2da515296e12b0.tar.gz |
don't write out </apply_tag> for tags that have already been closed by the
2006-08-28 Michael Natterer <mitch@imendio.com>
* gtk/gtktextbufferserialize.c (serialize_text): don't write out
</apply_tag> for tags that have already been closed by the logic
which turns overlapping spans into XML-able trees. Fixes broken
XML when there are overlapping tags in the buffer. Also free two
leaked GLists and did some cleanup.
* tests/Makefile.am
* tests/testrichtext.c: new test which creates randomly tagged
GtkTextBuffers and serializes/deserializes them.
Diffstat (limited to 'gtk/gtktextbufferserialize.c')
-rw-r--r-- | gtk/gtktextbufferserialize.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/gtk/gtktextbufferserialize.c b/gtk/gtktextbufferserialize.c index 66eb18d63e..cacf6c61d1 100644 --- a/gtk/gtktextbufferserialize.c +++ b/gtk/gtktextbufferserialize.c @@ -434,14 +434,13 @@ serialize_text (GtkTextBuffer *buffer, { GtkTextIter iter, old_iter; GSList *tag_list, *new_tag_list; - GQueue *active_tags; - int i; + GSList *active_tags; g_string_append (context->text_str, "<text>"); iter = context->start; tag_list = NULL; - active_tags = g_queue_new (); + active_tags = NULL; do { @@ -453,29 +452,33 @@ serialize_text (GtkTextBuffer *buffer, find_list_delta (tag_list, new_tag_list, &added, &removed); /* Handle removed tags */ - tmp = removed; - while (tmp) + for (tmp = removed; tmp; tmp = tmp->next) { GtkTextTag *tag = tmp->data; - g_string_append (context->text_str, "</apply_tag>"); - - /* We might need to drop some of the tags and re-add them afterwards */ - while (g_queue_peek_head (active_tags) != tag && - !g_queue_is_empty (active_tags)) - { - added = g_list_prepend (added, g_queue_pop_head (active_tags)); - g_string_append_printf (context->text_str, "</apply_tag>"); - } + /* Only close the tag if we didn't close it before (by using + * the stack logic in the while() loop below) + */ + if (g_slist_find (active_tags, tag)) + { + g_string_append (context->text_str, "</apply_tag>"); - g_queue_pop_head (active_tags); + /* Drop all tags that were opened after this one (which are + * above this on in the stack) + */ + while (active_tags->data != tag) + { + added = g_list_prepend (added, active_tags->data); + active_tags = g_slist_remove (active_tags, active_tags->data); + g_string_append_printf (context->text_str, "</apply_tag>"); + } - tmp = tmp->next; + active_tags = g_slist_remove (active_tags, active_tags->data); + } } /* Handle added tags */ - tmp = added; - while (tmp) + for (tmp = added; tmp; tmp = tmp->next) { GtkTextTag *tag = tmp->data; gchar *tag_name; @@ -505,14 +508,16 @@ serialize_text (GtkTextBuffer *buffer, g_string_append_printf (context->text_str, "<apply_tag id=\"%d\">", GPOINTER_TO_INT (tag_id)); } - g_queue_push_head (active_tags, tag); - tmp = tmp->next; + active_tags = g_slist_prepend (active_tags, tag); } g_slist_free (tag_list); tag_list = new_tag_list; + g_list_free (added); + g_list_free (removed); + old_iter = iter; /* Now try to go to either the next tag toggle, or if a pixbuf appears */ @@ -570,10 +575,10 @@ serialize_text (GtkTextBuffer *buffer, while (!gtk_text_iter_equal (&iter, &context->end)); /* Close any open tags */ - for (i = 0; i < g_queue_get_length (active_tags); i++) { + for (tag_list = active_tags; tag_list; tag_list = tag_list->next) g_string_append (context->text_str, "</apply_tag>"); - } - g_queue_free (active_tags); + + g_slist_free (active_tags); g_string_append (context->text_str, "</text>\n</text_view_markup>\n"); } |