]> Pileus Git - ~andy/gtk/commitdiff
pasted rich text should not be affected by tags that are active at the
authorMichael Natterer <mitch@imendio.com>
Mon, 10 Apr 2006 20:18:31 +0000 (20:18 +0000)
committerMichael Natterer <mitch@src.gnome.org>
Mon, 10 Apr 2006 20:18:31 +0000 (20:18 +0000)
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.

ChangeLog
ChangeLog.pre-2-10
gtk/gtktextbufferrichtext.c

index 01bfa8b40315184af5d13e9c3e74ad97a7f4c2f2..9c76485e7c1b0197fa75c0323dfc5e4ebf372117 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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.
+
 2006-04-11  Anders Carlsson  <andersca@imendio.com>
 
         * gdk/gdkinternals.h:
index 01bfa8b40315184af5d13e9c3e74ad97a7f4c2f2..9c76485e7c1b0197fa75c0323dfc5e4ebf372117 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2006-04-11  Anders Carlsson  <andersca@imendio.com>
 
         * gdk/gdkinternals.h:
index 12cb00b3b8b2338391a81fca141cdf4d7e634cb3..e2bf690c81d0c6e19bc17ed13444d28264ac2a3f 100644 (file)
@@ -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;
         }
     }