summaryrefslogtreecommitdiff
path: root/gtk/gtktextbufferrichtext.c
diff options
context:
space:
mode:
authorMichael Natterer <mitch@imendio.com>2006-04-10 20:18:31 +0000
committerMichael Natterer <mitch@src.gnome.org>2006-04-10 20:18:31 +0000
commit99722bec2c80eac906c3ddf87f791613ba2add26 (patch)
tree62aaff3c8b81740764b99829cb8b1f4147c3b8fc /gtk/gtktextbufferrichtext.c
parent47257b075b408826831fb295a0b210b1c32d09e8 (diff)
downloadgtk+-99722bec2c80eac906c3ddf87f791613ba2add26.tar.gz
pasted rich text should not be affected by tags that are active at the
2006-04-10 Michael Natterer <mitch@imendio.com> * gtk/gtktextbufferrichtext.c (gtk_text_buffer_deserialize): pasted rich text should not be affected by tags that are active at the insertion point. Therefore, remove and remember all active tags, and re-apply them left and right of the inserted text after pasting. Fixes bug #337653.
Diffstat (limited to 'gtk/gtktextbufferrichtext.c')
-rw-r--r--gtk/gtktextbufferrichtext.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/gtk/gtktextbufferrichtext.c b/gtk/gtktextbufferrichtext.c
index 12cb00b3b8..e2bf690c81 100644
--- a/gtk/gtktextbufferrichtext.c
+++ b/gtk/gtktextbufferrichtext.c
@@ -567,6 +567,78 @@ gtk_text_buffer_deserialize (GtkTextBuffer *register_buffer,
{
GtkTextBufferDeserializeFunc function = fmt->function;
gboolean success;
+ GSList *split_tags;
+ GSList *list;
+ GtkTextMark *left_end = NULL;
+ GtkTextMark *right_start = NULL;
+ GSList *left_start_list = NULL;
+ GSList *right_end_list = NULL;
+
+ /* We don't want the tags that are effective at the insertion
+ * point to affect the pasted text, therefore we remove and
+ * remember them, so they can be re-applied left and right of
+ * the inserted text after pasting
+ */
+ split_tags = gtk_text_iter_get_tags (iter);
+
+ list = split_tags;
+ while (list)
+ {
+ GtkTextTag *tag = list->data;
+
+ list = g_slist_next (list);
+
+ /* If a tag begins at the insertion point, ignore it
+ * because it doesn't affect the pasted text
+ */
+ if (gtk_text_iter_begins_tag (iter, tag))
+ split_tags = g_slist_remove (split_tags, tag);
+ }
+
+ if (split_tags)
+ {
+ /* Need to remember text marks, because text iters
+ * don't survive pasting
+ */
+ left_end = gtk_text_buffer_create_mark (content_buffer,
+ NULL, iter, TRUE);
+ right_start = gtk_text_buffer_create_mark (content_buffer,
+ NULL, iter, FALSE);
+
+ for (list = split_tags; list; list = g_slist_next (list))
+ {
+ GtkTextTag *tag = list->data;
+ GtkTextIter *backward_toggle = gtk_text_iter_copy (iter);
+ GtkTextIter *forward_toggle = gtk_text_iter_copy (iter);
+ GtkTextMark *left_start = NULL;
+ GtkTextMark *right_end = NULL;
+
+ gtk_text_iter_backward_to_tag_toggle (backward_toggle, tag);
+ left_start = gtk_text_buffer_create_mark (content_buffer,
+ NULL,
+ backward_toggle,
+ FALSE);
+
+ gtk_text_iter_forward_to_tag_toggle (forward_toggle, tag);
+ right_end = gtk_text_buffer_create_mark (content_buffer,
+ NULL,
+ forward_toggle,
+ TRUE);
+
+ left_start_list = g_slist_prepend (left_start_list, left_start);
+ right_end_list = g_slist_prepend (right_end_list, right_end);
+
+ gtk_text_buffer_remove_tag (content_buffer, tag,
+ backward_toggle,
+ forward_toggle);
+
+ gtk_text_iter_free (forward_toggle);
+ gtk_text_iter_free (backward_toggle);
+ }
+
+ left_start_list = g_slist_reverse (left_start_list);
+ right_end_list = g_slist_reverse (right_end_list);
+ }
success = function (register_buffer, content_buffer,
iter, data, length,
@@ -579,6 +651,57 @@ gtk_text_buffer_deserialize (GtkTextBuffer *register_buffer,
_("Unknown error when trying to deserialize %s"),
gdk_atom_name (format));
+ if (split_tags)
+ {
+ GSList *left_list;
+ GSList *right_list;
+ GtkTextIter left_e;
+ GtkTextIter right_s;
+
+ /* Turn the remembered marks back into iters so they
+ * can by used to re-apply the remembered tags
+ */
+ gtk_text_buffer_get_iter_at_mark (content_buffer,
+ &left_e, left_end);
+ gtk_text_buffer_get_iter_at_mark (content_buffer,
+ &right_s, right_start);
+
+ for (list = split_tags,
+ left_list = left_start_list,
+ right_list = right_end_list;
+ list && left_list && right_list;
+ list = g_slist_next (list),
+ left_list = g_slist_next (left_list),
+ right_list = g_slist_next (right_list))
+ {
+ GtkTextTag *tag = list->data;
+ GtkTextMark *left_start = left_list->data;
+ GtkTextMark *right_end = right_list->data;
+ GtkTextIter left_s;
+ GtkTextIter right_e;
+
+ gtk_text_buffer_get_iter_at_mark (content_buffer,
+ &left_s, left_start);
+ gtk_text_buffer_get_iter_at_mark (content_buffer,
+ &right_e, right_end);
+
+ gtk_text_buffer_apply_tag (content_buffer, tag,
+ &left_s, &left_e);
+ gtk_text_buffer_apply_tag (content_buffer, tag,
+ &right_s, &right_e);
+
+ gtk_text_buffer_delete_mark (content_buffer, left_start);
+ gtk_text_buffer_delete_mark (content_buffer, right_end);
+ }
+
+ gtk_text_buffer_delete_mark (content_buffer, left_end);
+ gtk_text_buffer_delete_mark (content_buffer, right_start);
+
+ g_slist_free (split_tags);
+ g_slist_free (left_start_list);
+ g_slist_free (right_end_list);
+ }
+
return success;
}
}