1 /* GTK - The GIMP Toolkit
2 * gtktextbuffer.c Copyright (C) 2000 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include "gtkclipboard.h"
32 #include "gtkinvisible.h"
33 #include "gtksignal.h"
34 #include "gtktextbuffer.h"
35 #include "gtktextbtree.h"
36 #include "gtktextiterprivate.h"
39 typedef struct _ClipboardRequest ClipboardRequest;
41 struct _ClipboardRequest
43 GtkTextBuffer *buffer;
45 gboolean default_editable;
46 gboolean is_clipboard;
47 gboolean replace_selection;
76 TARGET_TEXT_BUFFER_CONTENTS
79 static void gtk_text_buffer_init (GtkTextBuffer *tkxt_buffer);
80 static void gtk_text_buffer_class_init (GtkTextBufferClass *klass);
81 static void gtk_text_buffer_finalize (GObject *object);
84 static void gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer);
85 static void gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
89 static void gtk_text_buffer_real_insert_pixbuf (GtkTextBuffer *buffer,
92 static void gtk_text_buffer_real_insert_anchor (GtkTextBuffer *buffer,
94 GtkTextChildAnchor *anchor);
95 static void gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
98 static void gtk_text_buffer_real_apply_tag (GtkTextBuffer *buffer,
100 const GtkTextIter *start_char,
101 const GtkTextIter *end_char);
102 static void gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
104 const GtkTextIter *start_char,
105 const GtkTextIter *end_char);
106 static void gtk_text_buffer_real_changed (GtkTextBuffer *buffer);
108 static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
109 static void free_log_attr_cache (GtkTextLogAttrCache *cache);
111 static GtkObjectClass *parent_class = NULL;
112 static guint signals[LAST_SIGNAL] = { 0 };
115 gtk_text_buffer_get_type (void)
117 static GType our_type = 0;
121 static const GTypeInfo our_info =
123 sizeof (GtkTextBufferClass),
124 (GBaseInitFunc) NULL,
125 (GBaseFinalizeFunc) NULL,
126 (GClassInitFunc) gtk_text_buffer_class_init,
127 NULL, /* class_finalize */
128 NULL, /* class_data */
129 sizeof (GtkTextBuffer),
131 (GInstanceInitFunc) gtk_text_buffer_init
134 our_type = g_type_register_static (G_TYPE_OBJECT,
144 gtk_text_buffer_class_init (GtkTextBufferClass *klass)
146 GObjectClass *object_class = G_OBJECT_CLASS (klass);
148 parent_class = g_type_class_peek_parent (klass);
150 object_class->finalize = gtk_text_buffer_finalize;
152 klass->insert_text = gtk_text_buffer_real_insert_text;
153 klass->insert_pixbuf = gtk_text_buffer_real_insert_pixbuf;
154 klass->insert_child_anchor = gtk_text_buffer_real_insert_anchor;
155 klass->delete_range = gtk_text_buffer_real_delete_range;
156 klass->apply_tag = gtk_text_buffer_real_apply_tag;
157 klass->remove_tag = gtk_text_buffer_real_remove_tag;
158 klass->changed = gtk_text_buffer_real_changed;
160 signals[INSERT_TEXT] =
161 g_signal_newc ("insert_text",
162 G_OBJECT_CLASS_TYPE (object_class),
164 G_STRUCT_OFFSET (GtkTextBufferClass, insert_text),
166 gtk_marshal_VOID__BOXED_STRING_INT,
169 GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
170 GTK_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
173 signals[INSERT_PIXBUF] =
174 g_signal_newc ("insert_pixbuf",
175 G_OBJECT_CLASS_TYPE (object_class),
177 G_STRUCT_OFFSET (GtkTextBufferClass, insert_pixbuf),
179 gtk_marshal_VOID__BOXED_OBJECT,
182 GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
185 signals[INSERT_CHILD_ANCHOR] =
186 g_signal_newc ("insert_child_anchor",
187 G_OBJECT_CLASS_TYPE (object_class),
189 G_STRUCT_OFFSET (GtkTextBufferClass, insert_child_anchor),
191 gtk_marshal_VOID__BOXED_OBJECT,
194 GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
195 GTK_TYPE_TEXT_CHILD_ANCHOR);
197 signals[DELETE_RANGE] =
198 g_signal_newc ("delete_range",
199 G_OBJECT_CLASS_TYPE (object_class),
201 G_STRUCT_OFFSET (GtkTextBufferClass, delete_range),
203 gtk_marshal_VOID__BOXED_BOXED,
206 GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
207 GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
210 g_signal_newc ("changed",
211 G_OBJECT_CLASS_TYPE (object_class),
213 G_STRUCT_OFFSET (GtkTextBufferClass, changed),
215 gtk_marshal_VOID__VOID,
219 signals[MODIFIED_CHANGED] =
220 g_signal_newc ("modified_changed",
221 G_OBJECT_CLASS_TYPE (object_class),
223 G_STRUCT_OFFSET (GtkTextBufferClass, modified_changed),
225 gtk_marshal_VOID__VOID,
230 g_signal_newc ("mark_set",
231 G_OBJECT_CLASS_TYPE (object_class),
233 G_STRUCT_OFFSET (GtkTextBufferClass, mark_set),
235 gtk_marshal_VOID__BOXED_OBJECT,
241 signals[MARK_DELETED] =
242 g_signal_newc ("mark_deleted",
243 G_OBJECT_CLASS_TYPE (object_class),
245 G_STRUCT_OFFSET (GtkTextBufferClass, mark_deleted),
247 gtk_marshal_VOID__OBJECT,
253 g_signal_newc ("apply_tag",
254 G_OBJECT_CLASS_TYPE (object_class),
256 G_STRUCT_OFFSET (GtkTextBufferClass, apply_tag),
258 gtk_marshal_VOID__OBJECT_BOXED_BOXED,
265 signals[REMOVE_TAG] =
266 g_signal_newc ("remove_tag",
267 G_OBJECT_CLASS_TYPE (object_class),
269 G_STRUCT_OFFSET (GtkTextBufferClass, remove_tag),
271 gtk_marshal_VOID__OBJECT_BOXED_BOXED,
278 signals[BEGIN_USER_ACTION] =
279 g_signal_newc ("begin_user_action",
280 G_OBJECT_CLASS_TYPE (object_class),
282 G_STRUCT_OFFSET (GtkTextBufferClass, begin_user_action),
284 gtk_marshal_VOID__VOID,
288 signals[END_USER_ACTION] =
289 g_signal_newc ("end_user_action",
290 G_OBJECT_CLASS_TYPE (object_class),
292 G_STRUCT_OFFSET (GtkTextBufferClass, end_user_action),
294 gtk_marshal_VOID__VOID,
300 gtk_text_buffer_init (GtkTextBuffer *buffer)
302 buffer->clipboard_contents = NULL;
306 * gtk_text_buffer_new:
307 * @table: a tag table, or NULL to create a new one
309 * Creates a new text buffer.
311 * Return value: a new text buffer
314 gtk_text_buffer_new (GtkTextTagTable *table)
316 GtkTextBuffer *text_buffer;
318 text_buffer = GTK_TEXT_BUFFER (g_object_new (gtk_text_buffer_get_type (), NULL));
322 text_buffer->tag_table = table;
324 g_object_ref (G_OBJECT (text_buffer->tag_table));
327 g_object_ref (G_OBJECT (text_buffer));
333 gtk_text_buffer_finalize (GObject *object)
335 GtkTextBuffer *buffer;
337 buffer = GTK_TEXT_BUFFER (object);
339 if (buffer->clipboard_contents)
341 g_object_unref (G_OBJECT (buffer->clipboard_contents));
342 buffer->clipboard_contents = NULL;
345 if (buffer->tag_table)
347 g_object_unref (G_OBJECT (buffer->tag_table));
348 buffer->tag_table = NULL;
353 _gtk_text_btree_unref (buffer->btree);
354 buffer->btree = NULL;
357 if (buffer->log_attr_cache)
358 free_log_attr_cache (buffer->log_attr_cache);
360 buffer->log_attr_cache = NULL;
362 G_OBJECT_CLASS (parent_class)->finalize (object);
365 static GtkTextTagTable*
366 get_table (GtkTextBuffer *buffer)
368 if (buffer->tag_table == NULL)
369 buffer->tag_table = gtk_text_tag_table_new ();
371 return buffer->tag_table;
375 get_btree (GtkTextBuffer *buffer)
377 if (buffer->btree == NULL)
378 buffer->btree = _gtk_text_btree_new (gtk_text_buffer_get_tag_table (buffer),
381 return buffer->btree;
385 _gtk_text_buffer_get_btree (GtkTextBuffer *buffer)
387 return get_btree (buffer);
391 * gtk_text_buffer_get_tag_table:
392 * @buffer: a #GtkTextBuffer
394 * Get the #GtkTextTagTable associated with this buffer.
396 * Return value: the buffer's tag table
399 gtk_text_buffer_get_tag_table (GtkTextBuffer *buffer)
401 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
403 return get_table (buffer);
407 * gtk_text_buffer_set_text:
408 * @buffer: a #GtkTextBuffer
409 * @text: UTF-8 text to insert
410 * @len: length of @text in bytes
412 * Deletes current contents of @buffer, and inserts @text instead. If
413 * @text doesn't end with a newline, a newline is added;
414 * #GtkTextBuffer contents must always end with a newline. If @text
415 * ends with a newline, the new buffer contents will be exactly
416 * @text. If @len is -1, @text must be nul-terminated.
419 gtk_text_buffer_set_text (GtkTextBuffer *buffer,
423 GtkTextIter start, end;
425 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
426 g_return_if_fail (text != NULL);
431 /* Chop newline, since the buffer will already have one
434 if (len > 0 && text[len-1] == '\n')
437 gtk_text_buffer_get_bounds (buffer, &start, &end);
439 gtk_text_buffer_delete (buffer, &start, &end);
443 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
444 gtk_text_buffer_insert (buffer, &start, text, len);
454 gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
459 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
460 g_return_if_fail (iter != NULL);
462 _gtk_text_btree_insert (iter, text, len);
464 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
468 gtk_text_buffer_emit_insert (GtkTextBuffer *buffer,
473 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
474 g_return_if_fail (iter != NULL);
475 g_return_if_fail (text != NULL);
480 g_assert (g_utf8_validate (text, len, NULL));
484 g_signal_emit (G_OBJECT (buffer), signals[INSERT_TEXT], 0,
490 * gtk_text_buffer_insert:
491 * @buffer: a #GtkTextBuffer
492 * @iter: a position in the buffer
493 * @text: UTF-8 format text to insert
494 * @len: length of text in bytes, or -1
496 * Inserts @len bytes of @text at position @iter. If @len is -1,
497 * @text must be nul-terminated and will be inserted in its
498 * entirety. Emits the "insert_text" signal; insertion actually occurs
499 * in the default handler for the signal. @iter is invalidated when
500 * insertion occurs (because the buffer contents change), but the
501 * default signal handler revalidates it to point to the end of the
506 gtk_text_buffer_insert (GtkTextBuffer *buffer,
511 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
512 g_return_if_fail (iter != NULL);
513 g_return_if_fail (text != NULL);
515 gtk_text_buffer_emit_insert (buffer, iter, text, len);
519 * gtk_text_buffer_insert_at_cursor:
520 * @buffer: a #GtkTextBuffer
521 * @text: some text in UTF-8 format
522 * @len: length of text, in bytes
524 * Simply calls gtk_text_buffer_insert (), using the current
525 * cursor position as the insertion point.
528 gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buffer,
534 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
535 g_return_if_fail (text != NULL);
537 gtk_text_buffer_get_iter_at_mark (buffer, &iter,
538 gtk_text_buffer_get_mark (buffer,
541 gtk_text_buffer_insert (buffer, &iter, text, len);
545 * gtk_text_buffer_insert_interactive:
546 * @buffer: a #GtkTextBuffer
547 * @iter: a position in @buffer
548 * @text: some UTF-8 text
549 * @len: length of text in bytes, or -1
550 * @default_editable: default editability of buffer
552 * Like gtk_text_buffer_insert (), but the insertion will not occur if
553 * @iter is at a non-editable location in the buffer. Usually you
554 * want to prevent insertions at ineditable locations if the insertion
555 * results from a user action (is interactive).
557 * @default_editable indicates the editability of text that doesn't
558 * have a tag affecting editability applied to it. Typically the
559 * result of gtk_text_view_get_editable() is appropriate here.
561 * Return value: whether text was actually inserted
564 gtk_text_buffer_insert_interactive (GtkTextBuffer *buffer,
568 gboolean default_editable)
570 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
571 g_return_val_if_fail (text != NULL, FALSE);
573 if (gtk_text_iter_editable (iter, default_editable))
575 gtk_text_buffer_begin_user_action (buffer);
576 gtk_text_buffer_emit_insert (buffer, iter, text, len);
577 gtk_text_buffer_end_user_action (buffer);
585 * gtk_text_buffer_insert_interactive_at_cursor:
586 * @buffer: a #GtkTextBuffer
587 * @text: text in UTF-8 format
588 * @len: length of text in bytes, or -1
589 * @default_editable: default editability of buffer
591 * Calls gtk_text_buffer_insert_interactive () at the cursor
594 * @default_editable indicates the editability of text that doesn't
595 * have a tag affecting editability applied to it. Typically the
596 * result of gtk_text_view_get_editable() is appropriate here.
598 * Return value: whether text was actually inserted
601 gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
604 gboolean default_editable)
608 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
609 g_return_val_if_fail (text != NULL, FALSE);
611 gtk_text_buffer_get_iter_at_mark (buffer, &iter,
612 gtk_text_buffer_get_mark (buffer,
615 return gtk_text_buffer_insert_interactive (buffer, &iter, text, len,
620 possibly_not_text (gunichar ch,
623 return ch == GTK_TEXT_UNKNOWN_CHAR;
627 insert_text_range (GtkTextBuffer *buffer,
629 const GtkTextIter *orig_start,
630 const GtkTextIter *orig_end,
631 gboolean interactive)
635 text = gtk_text_iter_get_text (orig_start, orig_end);
637 gtk_text_buffer_emit_insert (buffer, iter, text, -1);
642 typedef struct _Range Range;
645 GtkTextBuffer *buffer;
646 GtkTextMark *start_mark;
647 GtkTextMark *end_mark;
648 GtkTextMark *whole_end_mark;
649 GtkTextIter *range_start;
650 GtkTextIter *range_end;
651 GtkTextIter *whole_end;
655 save_range (GtkTextIter *range_start,
656 GtkTextIter *range_end,
657 GtkTextIter *whole_end)
661 r = g_new (Range, 1);
663 r->buffer = gtk_text_iter_get_buffer (range_start);
664 g_object_ref (G_OBJECT (r->buffer));
667 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
672 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
678 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
683 r->range_start = range_start;
684 r->range_end = range_end;
685 r->whole_end = whole_end;
691 restore_range (Range *r)
693 gtk_text_buffer_get_iter_at_mark (r->buffer,
697 gtk_text_buffer_get_iter_at_mark (r->buffer,
701 gtk_text_buffer_get_iter_at_mark (r->buffer,
705 gtk_text_buffer_delete_mark (r->buffer, r->start_mark);
706 gtk_text_buffer_delete_mark (r->buffer, r->end_mark);
707 gtk_text_buffer_delete_mark (r->buffer, r->whole_end_mark);
709 g_object_unref (G_OBJECT (r->buffer));
714 insert_range_untagged (GtkTextBuffer *buffer,
716 const GtkTextIter *orig_start,
717 const GtkTextIter *orig_end,
718 gboolean interactive)
720 GtkTextIter range_start;
721 GtkTextIter range_end;
722 GtkTextIter start, end;
723 GtkTextBuffer *src_buffer;
726 if (gtk_text_iter_equal (orig_start, orig_end))
732 src_buffer = gtk_text_iter_get_buffer (&start);
739 if (gtk_text_iter_equal (&range_start, &range_end))
741 /* Figure out how to move forward */
743 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
745 if (gtk_text_iter_equal (&range_end, &end))
747 /* nothing left to do */
750 else if (gtk_text_iter_get_char (&range_end) == GTK_TEXT_UNKNOWN_CHAR)
752 GdkPixbuf *pixbuf = NULL;
753 GtkTextChildAnchor *anchor = NULL;
754 pixbuf = gtk_text_iter_get_pixbuf (&range_end);
755 anchor = gtk_text_iter_get_child_anchor (&range_end);
759 r = save_range (&range_start,
763 gtk_text_buffer_insert_pixbuf (buffer,
770 gtk_text_iter_forward_char (&range_end);
772 range_start = range_end;
776 /* Just skip anchors */
778 gtk_text_iter_forward_char (&range_end);
779 range_start = range_end;
783 /* The GTK_TEXT_UNKNOWN_CHAR was in a text segment, so
786 gtk_text_iter_forward_find_char (&range_end,
787 possibly_not_text, NULL,
790 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
795 /* Text segment starts here, so forward search to
796 * find its possible endpoint
798 gtk_text_iter_forward_find_char (&range_end,
799 possibly_not_text, NULL,
802 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
807 r = save_range (&range_start,
811 insert_text_range (buffer,
820 range_start = range_end;
826 gtk_text_buffer_real_insert_range (GtkTextBuffer *buffer,
828 const GtkTextIter *orig_start,
829 const GtkTextIter *orig_end,
830 gboolean interactive)
832 /* Find each range of uniformly-tagged text, insert it,
833 * then apply the tags.
835 GtkTextIter start = *orig_start;
836 GtkTextIter end = *orig_end;
837 GtkTextIter range_start;
838 GtkTextIter range_end;
839 GtkTextBuffer *src_buffer;
842 if (gtk_text_iter_equal (orig_start, orig_end))
846 gtk_text_buffer_begin_user_action (buffer);
848 src_buffer = gtk_text_iter_get_buffer (orig_start);
850 gtk_text_iter_reorder (&start, &end);
858 GtkTextIter start_iter;
862 if (gtk_text_iter_equal (&range_start, &end))
863 break; /* All done */
865 g_assert (gtk_text_iter_compare (&range_start, &end) < 0);
867 gtk_text_iter_forward_to_tag_toggle (&range_end, NULL);
869 g_assert (!gtk_text_iter_equal (&range_start, &range_end));
871 /* Clamp to the end iterator */
872 if (gtk_text_iter_compare (&range_end, &end) > 0)
875 /* We have a range with unique tags; insert it, and
878 start_offset = gtk_text_iter_get_offset (iter);
880 r = save_range (&range_start, &range_end, &end);
882 insert_range_untagged (buffer, iter, &range_start, &range_end, interactive);
887 gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start_offset);
889 tags = gtk_text_iter_get_tags (&range_start);
891 while (tmp_list != NULL)
893 gtk_text_buffer_apply_tag (buffer,
898 tmp_list = g_slist_next (tmp_list);
902 range_start = range_end;
906 gtk_text_buffer_end_user_action (buffer);
910 * gtk_text_buffer_insert_range:
911 * @buffer: a #GtkTextBuffer
912 * @iter: a position in @buffer
913 * @start: a position in a #GtkTextBuffer
914 * @end: another position in the same buffer as @start
916 * Copies text, tags, and pixbufs between @start and @end (the order
917 * of @start and @end doesn't matter) and inserts the copy at @iter.
918 * Used instead of simply getting/inserting text because it preserves
919 * images and tags. If @start and @end are in a different buffer from
920 * @buffer, the two buffers must share the same tag table.
922 * Implemented via emissions of the insert_text and apply_tag signals,
926 gtk_text_buffer_insert_range (GtkTextBuffer *buffer,
928 const GtkTextIter *start,
929 const GtkTextIter *end)
931 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
932 g_return_if_fail (iter != NULL);
933 g_return_if_fail (start != NULL);
934 g_return_if_fail (end != NULL);
935 g_return_if_fail (gtk_text_iter_get_buffer (start) ==
936 gtk_text_iter_get_buffer (end));
937 g_return_if_fail (gtk_text_iter_get_buffer (start)->tag_table ==
940 gtk_text_buffer_real_insert_range (buffer, iter, start, end, FALSE);
944 * gtk_text_buffer_insert_range_interactive:
945 * @buffer: a #GtkTextBuffer
946 * @iter: a position in @buffer
947 * @start: a position in a #GtkTextBuffer
948 * @end: another position in the same buffer as @start
949 * @default_editable: default editability of the buffer
951 * Same as gtk_text_buffer_insert_range(), but does nothing if the
952 * insertion point isn't editable. The @default_editable parameter
953 * indicates whether the text is editable at @iter if no tags
954 * enclosing @iter affect editability. Typically the result of
955 * gtk_text_view_get_editable() is appropriate here.
957 * Returns: whether an insertion was possible at @iter
960 gtk_text_buffer_insert_range_interactive (GtkTextBuffer *buffer,
962 const GtkTextIter *start,
963 const GtkTextIter *end,
964 gboolean default_editable)
966 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
967 g_return_val_if_fail (iter != NULL, FALSE);
968 g_return_val_if_fail (start != NULL, FALSE);
969 g_return_val_if_fail (end != NULL, FALSE);
970 g_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
971 gtk_text_iter_get_buffer (end), FALSE);
972 g_return_val_if_fail (gtk_text_iter_get_buffer (start)->tag_table ==
973 buffer->tag_table, FALSE);
976 if (gtk_text_iter_editable (iter, default_editable))
978 gtk_text_buffer_real_insert_range (buffer, iter, start, end, TRUE);
986 * gtk_text_buffer_insert_with_tags:
987 * @buffer: a #GtkTextBuffer
988 * @iter: an iterator in @buffer
990 * @len: length of @text, or -1
991 * @first_tag: first tag to apply to @text
992 * @Varargs: NULL-terminated list of tags to apply
994 * Inserts @text into @buffer at @iter, applying the list of tags to
995 * the newly-inserted text. The last tag specified must be NULL to
996 * terminate the list. Equivalent to calling gtk_text_buffer_insert (),
997 * then gtk_text_buffer_apply_tag () on the inserted text;
998 * gtk_text_buffer_insert_with_tags () is just a convenience function.
1001 gtk_text_buffer_insert_with_tags (GtkTextBuffer *buffer,
1005 GtkTextTag *first_tag,
1013 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1014 g_return_if_fail (iter != NULL);
1015 g_return_if_fail (text != NULL);
1017 start_offset = gtk_text_iter_get_offset (iter);
1019 gtk_text_buffer_insert (buffer, iter, text, len);
1021 if (first_tag == NULL)
1024 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1026 va_start (args, first_tag);
1030 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
1032 tag = va_arg (args, GtkTextTag*);
1039 * gtk_text_buffer_insert_with_tags_by_name:
1040 * @buffer: a #GtkTextBuffer
1041 * @iter: position in @buffer
1043 * @len: length of @text, or -1
1044 * @first_tag_name: name of a tag to apply to @text
1045 * @Varargs: more tag names
1047 * Same as gtk_text_buffer_insert_with_tags (), but allows you
1048 * to pass in tag names instead of tag objects.
1051 gtk_text_buffer_insert_with_tags_by_name (GtkTextBuffer *buffer,
1055 const gchar *first_tag_name,
1061 const gchar *tag_name;
1063 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1064 g_return_if_fail (iter != NULL);
1065 g_return_if_fail (text != NULL);
1067 start_offset = gtk_text_iter_get_offset (iter);
1069 gtk_text_buffer_insert (buffer, iter, text, len);
1071 if (first_tag_name == NULL)
1074 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1076 va_start (args, first_tag_name);
1077 tag_name = first_tag_name;
1082 tag = gtk_text_tag_table_lookup (buffer->tag_table,
1087 g_warning ("%s: no tag with name '%s'!", G_STRLOC, tag_name);
1091 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
1093 tag_name = va_arg (args, const gchar*);
1105 gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
1109 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1110 g_return_if_fail (start != NULL);
1111 g_return_if_fail (end != NULL);
1113 _gtk_text_btree_delete (start, end);
1115 /* may have deleted the selection... */
1116 gtk_text_buffer_update_primary_selection (buffer);
1118 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1122 gtk_text_buffer_emit_delete (GtkTextBuffer *buffer,
1126 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1127 g_return_if_fail (start != NULL);
1128 g_return_if_fail (end != NULL);
1130 if (gtk_text_iter_equal (start, end))
1133 gtk_text_iter_reorder (start, end);
1135 /* Somewhat annoyingly, if you try to delete the final newline
1136 * the BTree will put it back; which means you can't deduce the
1137 * final contents of the buffer purely by monitoring insert/delete
1138 * signals on the buffer. But if you delete the final newline, any
1139 * tags on the newline will go away, oddly. See comment in
1140 * gtktextbtree.c. This is all sort of annoying, but really hard
1143 g_signal_emit (G_OBJECT (buffer),
1144 signals[DELETE_RANGE],
1150 * gtk_text_buffer_delete:
1151 * @buffer: a #GtkTextBuffer
1152 * @start: a position in @buffer
1153 * @end: another position in @buffer
1155 * Deletes text between @start and @end. The order of @start and @end
1156 * is not actually relevant; gtk_text_buffer_delete () will reorder
1157 * them. This function actually emits the "delete_range" signal, and
1158 * the default handler of that signal deletes the text. Because the
1159 * buffer is modified, all outstanding iterators become invalid after
1160 * calling this function; however, the @start and @end will be
1161 * re-initialized to point to the location where text was deleted.
1163 * Note that the final newline in the buffer may not be deleted; a
1164 * #GtkTextBuffer always contains at least one newline. You can
1165 * safely include the final newline in the range [@start,@end) but it
1166 * won't be affected by the deletion.
1170 gtk_text_buffer_delete (GtkTextBuffer *buffer,
1174 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1175 g_return_if_fail (start != NULL);
1176 g_return_if_fail (end != NULL);
1178 gtk_text_buffer_emit_delete (buffer, start, end);
1182 * gtk_text_buffer_delete_interactive:
1183 * @buffer: a #GtkTextBuffer
1184 * @start_iter: start of range to delete
1185 * @end_iter: end of range
1186 * @default_editable: whether the buffer is editable by default
1188 * Deletes all <emphasis>editable</emphasis> text in the given range.
1189 * Calls gtk_text_buffer_delete () for each editable sub-range of
1190 * [@start,@end). @start and @end are revalidated to point to
1191 * the location of the last deleted range, or left untouched if
1192 * no text was deleted.
1194 * Return value: whether some text was actually deleted
1197 gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
1198 GtkTextIter *start_iter,
1199 GtkTextIter *end_iter,
1200 gboolean default_editable)
1202 GtkTextMark *end_mark;
1203 GtkTextMark *start_mark;
1205 gboolean current_state;
1206 gboolean deleted_stuff = FALSE;
1208 /* Delete all editable text in the range start_iter, end_iter */
1210 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1211 g_return_val_if_fail (start_iter != NULL, FALSE);
1212 g_return_val_if_fail (end_iter != NULL, FALSE);
1214 gtk_text_buffer_begin_user_action (buffer);
1216 gtk_text_iter_reorder (start_iter, end_iter);
1218 start_mark = gtk_text_buffer_create_mark (buffer, NULL,
1220 end_mark = gtk_text_buffer_create_mark (buffer, NULL,
1224 current_state = gtk_text_iter_editable (&iter, default_editable);
1229 gboolean done = FALSE;
1232 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
1234 gtk_text_buffer_get_iter_at_mark (buffer, &end, end_mark);
1236 if (gtk_text_iter_compare (&iter, &end) >= 0)
1239 iter = end; /* clamp to the last boundary */
1242 new_state = gtk_text_iter_editable (&iter, default_editable);
1244 if (current_state == new_state)
1250 /* We're ending an editable region. Delete said region. */
1253 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
1255 gtk_text_buffer_emit_delete (buffer, &start, &iter);
1257 deleted_stuff = TRUE;
1259 /* revalidate user's iterators. */
1260 *start_iter = start;
1270 if (current_state && !new_state)
1272 /* End of an editable region. Delete it. */
1275 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
1277 gtk_text_buffer_emit_delete (buffer, &start, &iter);
1279 current_state = FALSE;
1280 deleted_stuff = TRUE;
1282 /* revalidate user's iterators. */
1283 *start_iter = start;
1288 /* We are at the start of an editable region. We won't be deleting
1289 * the previous region. Move start mark to start of this region.
1292 g_assert (!current_state && new_state);
1294 gtk_text_buffer_move_mark (buffer, start_mark,
1298 current_state = TRUE;
1306 gtk_text_buffer_delete_mark (buffer, start_mark);
1307 gtk_text_buffer_delete_mark (buffer, end_mark);
1309 gtk_text_buffer_end_user_action (buffer);
1311 return deleted_stuff;
1315 * Extracting textual buffer contents
1319 * gtk_text_buffer_get_text:
1320 * @buffer: a #GtkTextBuffer
1321 * @start: start of a range
1322 * @end: end of a range
1323 * @include_hidden_chars: whether to include invisible text
1325 * Returns the text in the range [@start,@end). Excludes undisplayed
1326 * text (text marked with tags that set the invisibility attribute) if
1327 * @include_hidden_chars is FALSE. Does not include characters
1328 * representing embedded images, so byte and character indexes into
1329 * the returned string do <emphasis>not</emphasis> correspond to byte
1330 * and character indexes into the buffer. Contrast with
1331 * gtk_text_buffer_get_slice ().
1333 * Return value: an allocated UTF-8 string
1336 gtk_text_buffer_get_text (GtkTextBuffer *buffer,
1337 const GtkTextIter *start,
1338 const GtkTextIter *end,
1339 gboolean include_hidden_chars)
1341 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1342 g_return_val_if_fail (start != NULL, NULL);
1343 g_return_val_if_fail (end != NULL, NULL);
1345 if (include_hidden_chars)
1346 return gtk_text_iter_get_text (start, end);
1348 return gtk_text_iter_get_visible_text (start, end);
1352 * gtk_text_buffer_get_slice:
1353 * @buffer: a #GtkTextBuffer
1354 * @start: start of a range
1355 * @end: end of a range
1356 * @include_hidden_chars: whether to include invisible text
1358 * Returns the text in the range [@start,@end). Excludes undisplayed
1359 * text (text marked with tags that set the invisibility attribute) if
1360 * @include_hidden_chars is FALSE. The returned string includes a
1361 * 0xFFFC character whenever the buffer contains
1362 * embedded images, so byte and character indexes into
1363 * the returned string <emphasis>do</emphasis> correspond to byte
1364 * and character indexes into the buffer. Contrast with
1365 * gtk_text_buffer_get_text (). Note that 0xFFFC can occur in normal
1366 * text as well, so it is not a reliable indicator that a pixbuf or
1367 * widget is in the buffer.
1369 * Return value: an allocated UTF-8 string
1372 gtk_text_buffer_get_slice (GtkTextBuffer *buffer,
1373 const GtkTextIter *start,
1374 const GtkTextIter *end,
1375 gboolean include_hidden_chars)
1377 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1378 g_return_val_if_fail (start != NULL, NULL);
1379 g_return_val_if_fail (end != NULL, NULL);
1381 if (include_hidden_chars)
1382 return gtk_text_iter_get_slice (start, end);
1384 return gtk_text_iter_get_visible_slice (start, end);
1392 gtk_text_buffer_real_insert_pixbuf (GtkTextBuffer *buffer,
1396 _gtk_text_btree_insert_pixbuf (iter, pixbuf);
1398 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1402 * gtk_text_buffer_insert_pixbuf:
1403 * @buffer: a #GtkTextBuffer
1404 * @iter: location to insert the pixbuf
1405 * @pixbuf: a #GdkPixbuf
1407 * Inserts an image into the text buffer at @iter. The image will be
1408 * counted as one character in character counts, and when obtaining
1409 * the buffer contents as a string, will be represented by the Unicode
1410 * "object replacement character" 0xFFFC. Note that the "slice"
1411 * variants for obtaining portions of the buffer as a string include
1412 * this character for pixbufs, but the "text" variants do
1413 * not. e.g. see gtk_text_buffer_get_slice() and
1414 * gtk_text_buffer_get_text().
1418 gtk_text_buffer_insert_pixbuf (GtkTextBuffer *buffer,
1422 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1423 g_return_if_fail (iter != NULL);
1424 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
1426 g_signal_emit (G_OBJECT (buffer), signals[INSERT_PIXBUF], 0,
1436 gtk_text_buffer_real_insert_anchor (GtkTextBuffer *buffer,
1438 GtkTextChildAnchor *anchor)
1440 _gtk_text_btree_insert_child_anchor (iter, anchor);
1442 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1446 * gtk_text_buffer_insert_child_anchor:
1447 * @buffer: a #GtkTextBuffer
1448 * @iter: location to insert the anchor
1449 * @anchor: a #GtkTextChildAnchor
1451 * Inserts a child widget anchor into the text buffer at @iter. The
1452 * anchor will be counted as one character in character counts, and
1453 * when obtaining the buffer contents as a string, will be represented
1454 * by the Unicode "object replacement character" 0xFFFC. Note that the
1455 * "slice" variants for obtaining portions of the buffer as a string
1456 * include this character for pixbufs, but the "text" variants do
1457 * not. e.g. see gtk_text_buffer_get_slice() and
1458 * gtk_text_buffer_get_text(). Consider
1459 * gtk_text_buffer_create_child_anchor() as a more convenient
1460 * alternative to this function. The buffer will add a reference to
1461 * the anchor, so you can unref it after insertion.
1465 gtk_text_buffer_insert_child_anchor (GtkTextBuffer *buffer,
1467 GtkTextChildAnchor *anchor)
1469 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1470 g_return_if_fail (iter != NULL);
1471 g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor));
1473 g_signal_emit (G_OBJECT (buffer), signals[INSERT_CHILD_ANCHOR], 0,
1479 * gtk_text_buffer_create_child_anchor:
1480 * @buffer: a #GtkTextBuffer
1481 * @iter: location in the buffer
1483 * This is a convenience function which simply creates a child anchor
1484 * with gtk_text_child_anchor_new() and inserts it into the buffer
1485 * with gtk_text_buffer_insert_child_anchor().
1487 * Return value: the created child anchor
1490 gtk_text_buffer_create_child_anchor (GtkTextBuffer *buffer,
1493 GtkTextChildAnchor *anchor;
1495 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1496 g_return_val_if_fail (iter != NULL, NULL);
1498 anchor = gtk_text_child_anchor_new ();
1500 gtk_text_buffer_insert_child_anchor (buffer, iter, anchor);
1502 g_object_unref (G_OBJECT (anchor));
1512 gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
1513 const GtkTextIter *location,
1516 /* IMO this should NOT work like insert_text and delete_range,
1517 where the real action happens in the default handler.
1519 The reason is that the default handler would be _required_,
1520 i.e. the whole widget would start breaking and segfaulting
1521 if the default handler didn't get run. So you can't really
1522 override the default handler or stop the emission; that is,
1523 this signal is purely for notification, and not to allow users
1524 to modify the default behavior. */
1526 g_object_ref (G_OBJECT (mark));
1528 g_signal_emit (G_OBJECT (buffer),
1534 g_object_unref (G_OBJECT (mark));
1538 * gtk_text_buffer_set_mark:
1539 * @buffer: a #GtkTextBuffer
1540 * @mark_name: name of the mark
1541 * @iter: location for the mark.
1542 * @left_gravity: if the mark is created by this function, gravity for the new
1544 * @should_exist: if %TRUE, warn if the mark does not exist, and return
1547 * Move the mark to the given position, if not @should_exist, create the mark.
1549 * Return value: mark
1552 gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
1553 GtkTextMark *existing_mark,
1554 const gchar *mark_name,
1555 const GtkTextIter *iter,
1556 gboolean left_gravity,
1557 gboolean should_exist)
1559 GtkTextIter location;
1562 mark = _gtk_text_btree_set_mark (get_btree (buffer),
1569 if (_gtk_text_btree_mark_is_insert (get_btree (buffer), mark) ||
1570 _gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
1572 gtk_text_buffer_update_primary_selection (buffer);
1575 _gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1579 gtk_text_buffer_mark_set (buffer, &location, mark);
1585 * gtk_text_buffer_create_mark:
1586 * @buffer: a #GtkTextBuffer
1587 * @mark_name: name for mark, or %NULL
1588 * @where: location to place mark
1589 * @left_gravity: whether the mark has left gravity
1591 * Creates a mark at position @where. If @mark_name is %NULL, the mark
1592 * is anonymous; otherwise, the mark can be retrieved by name using
1593 * gtk_text_buffer_get_mark (). If a mark has left gravity, and text is
1594 * inserted at the mark's current location, the mark will be moved to
1595 * the left of the newly-inserted text. If the mark has right gravity
1596 * (@left_gravity = %FALSE), the mark will end up on the right of
1597 * newly-inserted text. The standard left-to-right cursor is a mark
1598 * with right gravity (when you type, the cursor stays on the right
1599 * side of the text you're typing).
1601 * The caller of this function does <emphasis>not</emphasis> own a reference
1602 * to the returned #GtkTextMark, so you can ignore the return value
1603 * if you like. Marks are owned by the buffer and go away when the
1606 * Emits the "mark_set" signal as notification of the mark's initial
1609 * Return value: the new #GtkTextMark object
1612 gtk_text_buffer_create_mark (GtkTextBuffer *buffer,
1613 const gchar *mark_name,
1614 const GtkTextIter *where,
1615 gboolean left_gravity)
1617 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1619 return gtk_text_buffer_set_mark (buffer, NULL, mark_name, where,
1620 left_gravity, FALSE);
1624 * gtk_text_buffer_move_mark:
1625 * @buffer: a #GtkTextBuffer
1626 * @mark: a #GtkTextMark
1627 * @where: new location for @mark in @buffer
1629 * Moves @mark to the new location @where. Emits the "mark_set" signal
1630 * as notification of the move.
1633 gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
1635 const GtkTextIter *where)
1637 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1638 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1639 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1641 gtk_text_buffer_set_mark (buffer, mark, NULL, where, FALSE, TRUE);
1645 * gtk_text_buffer_get_iter_at_mark:
1646 * @buffer: a #GtkTextBuffer
1647 * @iter: iterator to initialize
1648 * @mark: a #GtkTextMark in @buffer
1650 * Initializes @iter with the current position of @mark.
1653 gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
1657 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1658 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1659 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1661 _gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1667 * gtk_text_buffer_delete_mark:
1668 * @buffer: a #GtkTextBuffer
1669 * @mark: a #GtkTextMark in @buffer
1671 * Deletes @mark, so that it's no longer located anywhere in the
1672 * buffer. Removes the reference the buffer holds to the mark, so if
1673 * you haven't called g_object_ref () on the mark, it will be freed. Even
1674 * if the mark isn't freed, most operations on @mark become
1675 * invalid. There is no way to undelete a
1676 * mark. gtk_text_mark_get_deleted () will return TRUE after this
1677 * function has been called on a mark; gtk_text_mark_get_deleted ()
1678 * indicates that a mark no longer belongs to a buffer. The "mark_deleted"
1679 * signal will be emitted as notification after the mark is deleted.
1682 gtk_text_buffer_delete_mark (GtkTextBuffer *buffer,
1685 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1686 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1687 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1689 g_object_ref (G_OBJECT (mark));
1691 _gtk_text_btree_remove_mark (get_btree (buffer), mark);
1693 /* See rationale above for MARK_SET on why we emit this after
1694 * removing the mark, rather than removing the mark in a default
1697 g_signal_emit (G_OBJECT (buffer), signals[MARK_DELETED],
1701 g_object_unref (G_OBJECT (mark));
1705 * gtk_text_buffer_get_mark:
1706 * @buffer: a #GtkTextBuffer
1707 * @name: a mark name
1709 * Returns the mark named @name in buffer @buffer, or NULL if no such
1710 * mark exists in the buffer.
1712 * Return value: a #GtkTextMark, or NULL
1715 gtk_text_buffer_get_mark (GtkTextBuffer *buffer,
1720 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1721 g_return_val_if_fail (name != NULL, NULL);
1723 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1730 * gtk_text_buffer_move_mark_by_name:
1731 * @buffer: a #GtkTextBuffer
1732 * @name: name of a mark
1733 * @where: new location for mark
1735 * Moves the mark named @name (which must exist) to location @where.
1736 * See gtk_text_buffer_move_mark () for details.
1739 gtk_text_buffer_move_mark_by_name (GtkTextBuffer *buffer,
1741 const GtkTextIter *where)
1745 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1746 g_return_if_fail (name != NULL);
1748 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1752 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1756 gtk_text_buffer_move_mark (buffer, mark, where);
1760 * gtk_text_buffer_delete_mark_by_name:
1761 * @buffer: a #GtkTextBuffer
1762 * @name: name of a mark in @buffer
1764 * Deletes the mark named @name; the mark must exist. See
1765 * gtk_text_buffer_delete_mark () for details.
1768 gtk_text_buffer_delete_mark_by_name (GtkTextBuffer *buffer,
1773 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1774 g_return_if_fail (name != NULL);
1776 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1780 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1784 gtk_text_buffer_delete_mark (buffer, mark);
1788 * gtk_text_buffer_get_insert:
1789 * @buffer: a #GtkTextBuffer
1791 * Returns the mark that represents the cursor (insertion point).
1792 * Equivalent to calling gtk_text_buffer_get_mark () to get the mark
1793 * name "insert," but very slightly more efficient, and involves less
1796 * Return value: insertion point mark
1799 gtk_text_buffer_get_insert (GtkTextBuffer *buffer)
1801 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1803 /* FIXME use struct member in btree */
1804 return gtk_text_buffer_get_mark (buffer, "insert");
1808 * gtk_text_buffer_get_selection_bound:
1809 * @buffer: a #GtkTextBuffer
1811 * Returns the mark that represents the selection bound. Equivalent
1812 * to calling gtk_text_buffer_get_mark () to get the mark name
1813 * "selection_bound," but very slightly more efficient, and involves
1816 * The currently-selected text in @buffer is the region between the
1817 * "selection_bound" and "insert" marks. If "selection_bound" and
1818 * "insert" are in the same place, then there is no current selection.
1819 * gtk_text_buffer_get_selection_bounds () is another convenient function
1820 * for handling the selection, if you just want to know whether there's a
1821 * selection and what its bounds are.
1823 * Return value: selection bound mark
1826 gtk_text_buffer_get_selection_bound (GtkTextBuffer *buffer)
1828 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1830 /* FIXME use struct member in btree */
1831 return gtk_text_buffer_get_mark (buffer, "selection_bound");
1835 gtk_text_buffer_get_iter_at_child_anchor (GtkTextBuffer *buffer,
1837 GtkTextChildAnchor *anchor)
1839 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1840 g_return_if_fail (iter != NULL);
1841 g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor));
1842 g_return_if_fail (!gtk_text_child_anchor_get_deleted (anchor));
1844 _gtk_text_btree_get_iter_at_child_anchor (get_btree (buffer),
1850 * gtk_text_buffer_place_cursor:
1851 * @buffer: a #GtkTextBuffer
1852 * @where: where to put the cursor
1854 * This function moves the "insert" and "selection_bound" marks
1855 * simultaneously. If you move them to the same place in two steps
1856 * with gtk_text_buffer_move_mark (), you will temporarily select a
1857 * region in between their old and new locations, which can be pretty
1858 * inefficient since the temporarily-selected region will force stuff
1859 * to be recalculated. This function moves them as a unit, which can
1863 gtk_text_buffer_place_cursor (GtkTextBuffer *buffer,
1864 const GtkTextIter *where)
1868 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1872 if (gtk_text_iter_is_end (&real))
1873 gtk_text_iter_backward_char (&real);
1875 _gtk_text_btree_place_cursor (get_btree (buffer), &real);
1876 gtk_text_buffer_mark_set (buffer, &real,
1877 gtk_text_buffer_get_mark (buffer,
1879 gtk_text_buffer_mark_set (buffer, &real,
1880 gtk_text_buffer_get_mark (buffer,
1881 "selection_bound"));
1889 * gtk_text_buffer_create_tag:
1890 * @buffer: a #GtkTextBuffer
1891 * @tag_name: name of the new tag, or %NULL
1892 * @first_property_name: name of first property to set, or %NULL
1893 * @Varargs: %NULL-terminated list of property names and values
1896 * Creates a tag and adds it to the tag table for @buffer.
1897 * Equivalent to calling gtk_text_tag_new () and then adding the
1898 * tag to the buffer's tag table. The returned tag has its refcount
1899 * incremented, as if you'd called gtk_text_tag_new ().
1901 * If @tag_name is %NULL, the tag is anonymous.
1903 * The @first_property_name argument and subsequent arguments are a list
1904 * of properties to set on the tag, as with g_object_set().
1906 * Return value: a new tag
1909 gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
1910 const gchar *tag_name,
1911 const gchar *first_property_name,
1917 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1919 tag = gtk_text_tag_new (tag_name);
1921 gtk_text_tag_table_add (get_table (buffer), tag);
1923 if (first_property_name)
1925 va_start (list, first_property_name);
1926 g_object_set_valist (G_OBJECT (tag), first_property_name, list);
1934 gtk_text_buffer_real_apply_tag (GtkTextBuffer *buffer,
1936 const GtkTextIter *start,
1937 const GtkTextIter *end)
1939 _gtk_text_btree_tag (start, end, tag, TRUE);
1943 gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
1945 const GtkTextIter *start,
1946 const GtkTextIter *end)
1948 _gtk_text_btree_tag (start, end, tag, FALSE);
1952 gtk_text_buffer_real_changed (GtkTextBuffer *buffer)
1954 gtk_text_buffer_set_modified (buffer, TRUE);
1958 gtk_text_buffer_emit_tag (GtkTextBuffer *buffer,
1961 const GtkTextIter *start,
1962 const GtkTextIter *end)
1964 GtkTextIter start_tmp = *start;
1965 GtkTextIter end_tmp = *end;
1967 g_return_if_fail (tag != NULL);
1969 gtk_text_iter_reorder (&start_tmp, &end_tmp);
1972 g_signal_emit (G_OBJECT (buffer), signals[APPLY_TAG],
1974 tag, &start_tmp, &end_tmp);
1976 g_signal_emit (G_OBJECT (buffer), signals[REMOVE_TAG],
1978 tag, &start_tmp, &end_tmp);
1983 * gtk_text_buffer_apply_tag:
1984 * @buffer: a #GtkTextBuffer
1985 * @tag: a #GtkTextTag
1986 * @start: one bound of range to be tagged
1987 * @end: other bound of range to be tagged
1989 * Emits the "apply_tag" signal on @buffer. The default
1990 * handler for the signal applies @tag to the given range.
1991 * @start and @end do not have to be in order.
1995 gtk_text_buffer_apply_tag (GtkTextBuffer *buffer,
1997 const GtkTextIter *start,
1998 const GtkTextIter *end)
2000 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2001 g_return_if_fail (GTK_IS_TEXT_TAG (tag));
2002 g_return_if_fail (start != NULL);
2003 g_return_if_fail (end != NULL);
2005 gtk_text_buffer_emit_tag (buffer, tag, TRUE, start, end);
2009 * gtk_text_buffer_remove_tag:
2010 * @buffer: a #GtkTextBuffer
2011 * @tag: a #GtkTextTag
2012 * @start: one bound of range to be untagged
2013 * @end: other bound of range to be untagged
2015 * Emits the "remove_tag" signal. The default handler for the signal
2016 * removes all occurrences of @tag from the given range. @start and
2017 * @end don't have to be in order.
2021 gtk_text_buffer_remove_tag (GtkTextBuffer *buffer,
2023 const GtkTextIter *start,
2024 const GtkTextIter *end)
2027 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2028 g_return_if_fail (GTK_IS_TEXT_TAG (tag));
2029 g_return_if_fail (start != NULL);
2030 g_return_if_fail (end != NULL);
2032 gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
2037 * gtk_text_buffer_apply_tag_by_name:
2038 * @buffer: a #GtkTextBuffer
2039 * @name: name of a named #GtkTextTag
2040 * @start: one bound of range to be tagged
2041 * @end: other bound of range to be tagged
2043 * Calls gtk_text_tag_table_lookup() on the buffer's tag table to
2044 * get a #GtkTextTag, then calls gtk_text_buffer_apply_tag().
2048 gtk_text_buffer_apply_tag_by_name (GtkTextBuffer *buffer,
2050 const GtkTextIter *start,
2051 const GtkTextIter *end)
2055 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2056 g_return_if_fail (name != NULL);
2057 g_return_if_fail (start != NULL);
2058 g_return_if_fail (end != NULL);
2060 tag = gtk_text_tag_table_lookup (get_table (buffer),
2065 g_warning ("Unknown tag `%s'", name);
2069 gtk_text_buffer_emit_tag (buffer, tag, TRUE, start, end);
2073 * gtk_text_buffer_remove_tag_by_name:
2074 * @buffer: a #GtkTextBuffer
2075 * @name: name of a #GtkTextTag
2076 * @start: one bound of range to be untagged
2077 * @end: other bound of range to be untagged
2079 * Calls gtk_text_tag_table_lookup() on the buffer's tag table to
2080 * get a #GtkTextTag, then calls gtk_text_buffer_remove_tag().
2085 gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
2087 const GtkTextIter *start,
2088 const GtkTextIter *end)
2092 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2093 g_return_if_fail (name != NULL);
2094 g_return_if_fail (start != NULL);
2095 g_return_if_fail (end != NULL);
2097 tag = gtk_text_tag_table_lookup (get_table (buffer),
2102 g_warning ("Unknown tag `%s'", name);
2106 gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
2111 * Obtain various iterators
2115 * gtk_text_buffer_get_iter_at_line_offset:
2116 * @buffer: a #GtkTextBuffer
2117 * @iter: iterator to initialize
2118 * @line_number: line number counting from 0
2119 * @char_offset: char offset from start of line
2121 * Obtains an iterator pointing to @char_offset within the given
2122 * line. The @char_offset must exist, offsets off the end of the line
2123 * are not allowed. Note <emphasis>characters</emphasis>, not bytes;
2124 * UTF-8 may encode one character as multiple bytes.
2128 gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
2133 g_return_if_fail (iter != NULL);
2134 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2136 _gtk_text_btree_get_iter_at_line_char (get_btree (buffer),
2137 iter, line_number, char_offset);
2141 * gtk_text_buffer_get_iter_at_line_index:
2142 * @buffer: a #GtkTextBuffer
2143 * @iter: iterator to initialize
2144 * @line_number: line number counting from 0
2145 * @byte_index: byte index from start of line
2147 * Obtains an iterator pointing to @byte_index within the given line.
2148 * @byte_index must be the start of a UTF-8 character, and must not be
2149 * beyond the end of the line. Note <emphasis>bytes</emphasis>, not
2150 * characters; UTF-8 may encode one character as multiple bytes.
2154 gtk_text_buffer_get_iter_at_line_index (GtkTextBuffer *buffer,
2159 g_return_if_fail (iter != NULL);
2160 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2162 _gtk_text_btree_get_iter_at_line_byte (get_btree (buffer),
2163 iter, line_number, byte_index);
2167 * gtk_text_buffer_get_iter_at_line:
2168 * @buffer: a #GtkTextBuffer
2169 * @iter: iterator to initialize
2170 * @line_number: line number counting from 0
2172 * Initializes @iter to the start of the given line.
2175 gtk_text_buffer_get_iter_at_line (GtkTextBuffer *buffer,
2179 g_return_if_fail (iter != NULL);
2180 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2182 gtk_text_buffer_get_iter_at_line_offset (buffer, iter, line_number, 0);
2186 * gtk_text_buffer_get_iter_at_offset:
2187 * @buffer: a #GtkTextBuffer
2188 * @iter: iterator to initialize
2189 * @char_offset: char offset from start of buffer, counting from 0
2191 * Initializes @iter to a position @char_offset chars from the start
2192 * of the entire buffer.
2196 gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer,
2200 g_return_if_fail (iter != NULL);
2201 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2203 _gtk_text_btree_get_iter_at_char (get_btree (buffer), iter, char_offset);
2207 * gtk_text_buffer_get_end_iter:
2208 * @buffer: a #GtkTextBuffer
2209 * @iter: iterator to initialize
2211 * Initializes @iter with the "end iterator," one past the last valid
2212 * character in the text buffer. If dereferenced with
2213 * gtk_text_iter_get_char(), the end iterator has a character value of
2214 * 0. The entire buffer lies in the range from the first position in
2215 * the buffer (call gtk_text_buffer_get_iter_at_offset() to get
2216 * character position 0) to the end iterator.
2220 gtk_text_buffer_get_end_iter (GtkTextBuffer *buffer,
2223 g_return_if_fail (iter != NULL);
2224 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2226 _gtk_text_btree_get_end_iter (get_btree (buffer), iter);
2230 * gtk_text_buffer_get_bounds:
2231 * @buffer: a #GtkTextBuffer
2232 * @start: iterator to initialize with first position in the buffer
2233 * @end: iterator to initialize with the end iterator
2235 * Retrieves the first and last iterators in the buffer, i.e. the
2236 * entire buffer lies within the range [@start,@end).
2240 gtk_text_buffer_get_bounds (GtkTextBuffer *buffer,
2244 g_return_if_fail (start != NULL);
2245 g_return_if_fail (end != NULL);
2246 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2248 _gtk_text_btree_get_iter_at_char (get_btree (buffer), start, 0);
2249 _gtk_text_btree_get_end_iter (get_btree (buffer), end);
2257 * gtk_text_buffer_get_modified:
2258 * @buffer: a #GtkTextBuffer
2260 * Indicates whether the buffer has been modified since the last call
2261 * to gtk_text_buffer_set_modified() set the modification flag to
2262 * %FALSE. Used for example to enable a "save" function in a text
2265 * Return value: %TRUE if the buffer has been modified
2268 gtk_text_buffer_get_modified (GtkTextBuffer *buffer)
2270 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2272 return buffer->modified;
2276 * gtk_text_buffer_set_modified:
2277 * @buffer: a #GtkTextBuffer
2278 * @setting: modification flag setting
2280 * Used to keep track of whether the buffer has been modified since the
2281 * last time it was saved. Whenever the buffer is saved to disk, call
2282 * gtk_text_buffer_set_modified (@buffer, FALSE). When the buffer is modified,
2283 * it will automatically toggled on the modified bit again. When the modified
2284 * bit flips, the buffer emits a "modified_changed" signal.
2288 gtk_text_buffer_set_modified (GtkTextBuffer *buffer,
2291 gboolean fixed_setting;
2293 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2295 fixed_setting = setting != FALSE;
2297 if (buffer->modified == fixed_setting)
2301 buffer->modified = fixed_setting;
2302 g_signal_emit (G_OBJECT (buffer), signals[MODIFIED_CHANGED], 0);
2308 * Assorted other stuff
2312 * gtk_text_buffer_get_line_count:
2313 * @buffer: a #GtkTextBuffer
2315 * Obtains the number of lines in the buffer. This value is cached, so
2316 * the function is very fast.
2318 * Return value: number of lines in the buffer
2321 gtk_text_buffer_get_line_count (GtkTextBuffer *buffer)
2323 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
2325 return _gtk_text_btree_line_count (get_btree (buffer));
2329 * gtk_text_buffer_get_char_count:
2330 * @buffer: a #GtkTextBuffer
2332 * Gets the number of characters in the buffer; note that characters
2333 * and bytes are not the same, you can't e.g. expect the contents of
2334 * the buffer in string form to be this many bytes long. The character
2335 * count is cached, so this function is very fast.
2337 * Return value: number of characters in the buffer
2340 gtk_text_buffer_get_char_count (GtkTextBuffer *buffer)
2342 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
2344 return _gtk_text_btree_char_count (get_btree (buffer));
2347 /* Called when we lose the primary selection.
2350 clipboard_clear_selection_cb (GtkClipboard *clipboard,
2353 /* Move selection_bound to the insertion point */
2355 GtkTextIter selection_bound;
2356 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2358 gtk_text_buffer_get_iter_at_mark (buffer, &insert,
2359 gtk_text_buffer_get_mark (buffer, "insert"));
2360 gtk_text_buffer_get_iter_at_mark (buffer, &selection_bound,
2361 gtk_text_buffer_get_mark (buffer, "selection_bound"));
2363 if (!gtk_text_iter_equal (&insert, &selection_bound))
2364 gtk_text_buffer_move_mark (buffer,
2365 gtk_text_buffer_get_mark (buffer, "selection_bound"),
2369 /* Called when we have the primary selection and someone else wants our
2370 * data in order to paste it.
2373 clipboard_get_selection_cb (GtkClipboard *clipboard,
2374 GtkSelectionData *selection_data,
2378 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2379 GtkTextIter start, end;
2381 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2383 if (selection_data->target ==
2384 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2386 /* Provide the address of the buffer; this will only be
2387 * used within-process
2389 gtk_selection_data_set (selection_data,
2390 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2399 str = gtk_text_iter_get_visible_text (&start, &end);
2400 gtk_selection_data_set_text (selection_data, str);
2406 /* Provide cut/copied data */
2408 clipboard_get_contents_cb (GtkClipboard *clipboard,
2409 GtkSelectionData *selection_data,
2413 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2414 GtkTextBuffer *contents = buffer->clipboard_contents;
2416 if (selection_data->target ==
2417 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2419 /* Provide the address of the clipboard buffer; this will only
2420 * be used within-process. OK to supply a NULL value for contents.
2422 gtk_selection_data_set (selection_data,
2423 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2430 /* Just provide text from the clipboard buffer */
2431 if (buffer->clipboard_contents)
2434 GtkTextIter start, end;
2436 gtk_text_buffer_get_bounds (contents, &start, &end);
2437 /* strip off the trailing newline, it isn't part of the text that was cut */
2438 gtk_text_iter_backward_char (&end);
2440 str = gtk_text_iter_get_visible_text (&start, &end);
2441 gtk_selection_data_set_text (selection_data, str);
2446 gtk_selection_data_set_text (selection_data, "");
2453 clipboard_clear_contents_cb (GtkClipboard *clipboard,
2456 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2458 if (buffer->clipboard_contents)
2460 g_object_unref (G_OBJECT (buffer->clipboard_contents));
2461 buffer->clipboard_contents = NULL;
2466 get_paste_point (GtkTextBuffer *buffer,
2468 gboolean clear_afterward)
2470 GtkTextIter insert_point;
2471 GtkTextMark *paste_point_override;
2473 paste_point_override = gtk_text_buffer_get_mark (buffer,
2474 "gtk_paste_point_override");
2476 if (paste_point_override != NULL)
2478 gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
2479 paste_point_override);
2480 if (clear_afterward)
2481 gtk_text_buffer_delete_mark (buffer,
2482 gtk_text_buffer_get_mark (buffer,
2483 "gtk_paste_point_override"));
2487 gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
2488 gtk_text_buffer_get_mark (buffer,
2492 *iter = insert_point;
2496 pre_paste_prep (ClipboardRequest *request_data,
2497 GtkTextIter *insert_point)
2499 GtkTextBuffer *buffer = request_data->buffer;
2501 get_paste_point (buffer, insert_point, TRUE);
2503 /* If we're going to replace the selection, we insert before it to
2504 * avoid messing it up, then we delete the selection after inserting.
2506 if (request_data->replace_selection)
2508 GtkTextIter start, end;
2510 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2511 *insert_point = start;
2516 post_paste_cleanup (ClipboardRequest *request_data)
2518 if (request_data->replace_selection)
2520 GtkTextIter start, end;
2522 if (gtk_text_buffer_get_selection_bounds (request_data->buffer,
2525 if (request_data->interactive)
2526 gtk_text_buffer_delete_interactive (request_data->buffer,
2529 request_data->default_editable);
2531 gtk_text_buffer_delete (request_data->buffer, &start, &end);
2536 /* Called when we request a paste and receive the text data
2539 clipboard_text_received (GtkClipboard *clipboard,
2543 ClipboardRequest *request_data = data;
2544 GtkTextBuffer *buffer = request_data->buffer;
2548 GtkTextIter insert_point;
2550 pre_paste_prep (request_data, &insert_point);
2552 if (request_data->interactive)
2553 gtk_text_buffer_insert_interactive (buffer, &insert_point,
2554 str, -1, request_data->default_editable);
2556 gtk_text_buffer_insert (buffer, &insert_point,
2559 post_paste_cleanup (request_data);
2562 g_object_unref (G_OBJECT (buffer));
2563 g_free (request_data);
2566 static GtkTextBuffer*
2567 selection_data_get_buffer (GtkSelectionData *selection_data,
2568 ClipboardRequest *request_data)
2571 GtkTextBuffer *src_buffer = NULL;
2573 /* If we can get the owner, the selection is in-process */
2574 owner = gdk_selection_owner_get (selection_data->selection);
2579 if (selection_data->type != gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2582 if (selection_data->length != sizeof (src_buffer))
2585 memcpy (&src_buffer, selection_data->data, sizeof (src_buffer));
2587 if (src_buffer == NULL)
2590 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (src_buffer), NULL);
2592 if (gtk_text_buffer_get_tag_table (src_buffer) !=
2593 gtk_text_buffer_get_tag_table (request_data->buffer))
2600 /* These are pretty handy functions; maybe something like them
2601 * should be in the public API. Also, there are other places in this
2602 * file where they could be used.
2605 save_iter (const GtkTextIter *iter,
2606 gboolean left_gravity)
2608 return gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (iter),
2615 restore_iter (const GtkTextIter *iter,
2618 gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (save_id),
2619 (GtkTextIter*) iter,
2621 gtk_text_buffer_delete_mark (gtk_text_mark_get_buffer (save_id),
2627 paste_from_buffer (ClipboardRequest *request_data,
2628 GtkTextBuffer *src_buffer,
2629 const GtkTextIter *start,
2630 const GtkTextIter *end)
2632 GtkTextIter insert_point;
2634 /* We're about to emit a bunch of signals, so be safe */
2635 g_object_ref (G_OBJECT (src_buffer));
2637 pre_paste_prep (request_data, &insert_point);
2639 if (!gtk_text_iter_equal (start, end))
2641 gtk_text_buffer_real_insert_range (request_data->buffer,
2645 request_data->interactive);
2648 post_paste_cleanup (request_data);
2650 g_object_unref (G_OBJECT (src_buffer));
2654 clipboard_clipboard_buffer_received (GtkClipboard *clipboard,
2655 GtkSelectionData *selection_data,
2658 ClipboardRequest *request_data = data;
2659 GtkTextBuffer *src_buffer;
2661 src_buffer = selection_data_get_buffer (selection_data, request_data);
2665 GtkTextIter start, end;
2667 gtk_text_buffer_get_bounds (src_buffer, &start, &end);
2668 /* There's an extra newline on clipboard_contents */
2669 gtk_text_iter_backward_char (&end);
2671 paste_from_buffer (request_data, src_buffer,
2676 /* Request the text selection instead */
2677 gtk_clipboard_request_text (clipboard,
2678 clipboard_text_received,
2684 clipboard_selection_buffer_received (GtkClipboard *clipboard,
2685 GtkSelectionData *selection_data,
2688 ClipboardRequest *request_data = data;
2689 GtkTextBuffer *src_buffer;
2691 src_buffer = selection_data_get_buffer (selection_data, request_data);
2695 GtkTextIter start, end;
2697 if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
2698 paste_from_buffer (request_data, src_buffer,
2703 /* Request the text selection instead */
2704 gtk_clipboard_request_text (clipboard,
2705 clipboard_text_received,
2710 static const GtkTargetEntry targets[] = {
2711 { "STRING", 0, TARGET_STRING },
2712 { "TEXT", 0, TARGET_TEXT },
2713 { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
2714 { "UTF8_STRING", 0, TARGET_UTF8_STRING },
2715 { "GTK_TEXT_BUFFER_CONTENTS", 0, TARGET_TEXT_BUFFER_CONTENTS }
2719 gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
2724 GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2726 /* Determine whether we have a selection and adjust X selection
2730 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2732 if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
2733 gtk_clipboard_clear (clipboard);
2737 /* Even if we already have the selection, we need to update our
2740 if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
2741 clipboard_get_selection_cb,
2742 clipboard_clear_selection_cb,
2744 clipboard_clear_selection_cb (clipboard, buffer);
2749 paste (GtkTextBuffer *buffer,
2750 gboolean is_clipboard,
2751 gboolean interactive,
2752 gboolean default_editable)
2754 ClipboardRequest *data = g_new (ClipboardRequest, 1);
2755 GtkTextIter paste_point;
2756 GtkTextIter start, end;
2758 data->buffer = buffer;
2759 g_object_ref (G_OBJECT (buffer));
2760 data->interactive = interactive;
2761 data->default_editable = default_editable;
2763 /* When pasting with the cursor inside the selection area, you
2764 * replace the selection with the new text, otherwise, you
2765 * simply insert the new text at the point where the click
2766 * occured, unselecting any selected text. The replace_selection
2767 * flag toggles this behavior.
2769 data->replace_selection = FALSE;
2771 get_paste_point (buffer, &paste_point, FALSE);
2772 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end) &&
2773 (gtk_text_iter_in_range (&paste_point, &start, &end) ||
2774 gtk_text_iter_equal (&paste_point, &end)))
2775 data->replace_selection = TRUE;
2778 gtk_clipboard_request_contents (gtk_clipboard_get (GDK_NONE),
2780 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2781 clipboard_clipboard_buffer_received, data);
2783 gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
2785 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2786 clipboard_selection_buffer_received, data);
2790 * gtk_text_buffer_paste_primary:
2791 * @buffer: a #GtkTextBuffer
2792 * @override_location: location to insert pasted text, or %NULL for at the cursor
2793 * @default_editable: whether the buffer is editable by default
2795 * Pastes the primary selection at the insertion point, or at @override_location.
2796 * (Note: pasting is asynchronous, that is, we'll ask for the paste data
2797 * and return, and at some point later after the main loop runs, the paste
2798 * data will be inserted.)
2801 gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
2802 const GtkTextIter *override_location,
2803 gboolean default_editable)
2805 if (override_location != NULL)
2806 gtk_text_buffer_create_mark (buffer,
2807 "gtk_paste_point_override",
2808 override_location, FALSE);
2810 paste (buffer, FALSE, TRUE, default_editable);
2814 * gtk_text_buffer_paste_clipboard:
2815 * @buffer: a #GtkTextBuffer
2816 * @default_editable: whether the buffer is editable by default
2818 * Pastes the clipboard contents at the insertion point. (Note:
2819 * pasting is asynchronous, that is, we'll ask for the paste data and
2820 * return, and at some point later after the main loop runs, the paste
2821 * data will be inserted.)
2825 gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
2826 gboolean default_editable)
2828 paste (buffer, TRUE, TRUE, default_editable);
2832 * gtk_text_buffer_delete_selection:
2833 * @buffer: a #GtkTextBuffer
2834 * @interactive: whether the deletion is caused by user interaction
2835 * @default_editable: whether the buffer is editable by default
2837 * Deletes the range between the "insert" and "selection_bound" marks,
2838 * that is, the currently-selected text. If @interactive is %TRUE,
2839 * the editability of the selection will be considered (users can't delete
2842 * Return value: whether there was a non-empty selection to delete
2845 gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
2846 gboolean interactive,
2847 gboolean default_editable)
2852 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2854 return FALSE; /* No selection */
2860 gtk_text_buffer_begin_user_action (buffer);
2861 gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable);
2862 gtk_text_buffer_end_user_action (buffer);
2865 gtk_text_buffer_delete (buffer, &start, &end);
2867 return TRUE; /* We deleted stuff */
2872 cut_or_copy (GtkTextBuffer *buffer,
2873 gboolean delete_region_after,
2874 gboolean interactive,
2875 gboolean default_editable)
2877 /* We prefer to cut the selected region between selection_bound and
2878 * insertion point. If that region is empty, then we cut the region
2879 * between the "anchor" and the insertion point (this is for
2880 * C-space and M-w and other Emacs-style copy/yank keys). Note that
2881 * insert and selection_bound are guaranteed to exist, but the
2882 * anchor only exists sometimes.
2887 if (buffer->clipboard_contents)
2889 g_object_unref (G_OBJECT (buffer->clipboard_contents));
2890 buffer->clipboard_contents = NULL;
2893 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2895 /* Let's try the anchor thing */
2896 GtkTextMark * anchor = gtk_text_buffer_get_mark (buffer, "anchor");
2902 gtk_text_buffer_get_iter_at_mark (buffer, &end, anchor);
2903 gtk_text_iter_reorder (&start, &end);
2907 if (!gtk_text_iter_equal (&start, &end))
2909 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
2912 buffer->clipboard_contents =
2913 gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
2915 gtk_text_buffer_get_iter_at_offset (buffer->clipboard_contents,
2918 gtk_text_buffer_insert_range (buffer->clipboard_contents,
2923 if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
2924 clipboard_get_contents_cb,
2925 clipboard_clear_contents_cb,
2927 clipboard_clear_contents_cb (clipboard, buffer);
2929 if (delete_region_after)
2932 gtk_text_buffer_delete_interactive (buffer, &start, &end,
2935 gtk_text_buffer_delete (buffer, &start, &end);
2941 * gtk_text_buffer_cut_clipboard:
2942 * @buffer: a #GtkTextBuffer
2943 * @default_editable: default editability of the buffer
2945 * Copies the currently-selected text to the clipboard, then deletes
2946 * said text if it's editable.
2950 gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
2951 gboolean default_editable)
2953 gtk_text_buffer_begin_user_action (buffer);
2954 cut_or_copy (buffer, TRUE, TRUE, default_editable);
2955 gtk_text_buffer_end_user_action (buffer);
2959 * gtk_text_buffer_copy_clipboard:
2960 * @buffer: a #GtkTextBuffer
2962 * Copies the currently-selected text to the clipboard.
2966 gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer)
2968 gtk_text_buffer_begin_user_action (buffer);
2969 cut_or_copy (buffer, FALSE, TRUE, TRUE);
2970 gtk_text_buffer_end_user_action (buffer);
2975 * gtk_text_buffer_get_selection_bounds:
2976 * @buffer: a #GtkTextBuffer a #GtkTextBuffer
2977 * @start: iterator to initialize with selection start
2978 * @end: iterator to initialize with selection end
2980 * Returns %TRUE if some text is selected; places the bounds
2981 * of the selection in @start and @end (if the selection has length 0,
2982 * then @start and @end are filled in with the same value).
2983 * @start and @end will be in ascending order. If @start and @end are
2984 * NULL, then they are not filled in, but the return value still indicates
2985 * whether text is selected.
2987 * Return value: whether the selection has nonzero length
2990 gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
2994 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2996 return _gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
3000 * gtk_text_buffer_begin_user_action:
3001 * @buffer: a #GtkTextBuffer
3003 * Called to indicate that the buffer operations between here and a
3004 * call to gtk_text_buffer_end_user_action() are part of a single
3005 * user-visible operation. The operations between
3006 * gtk_text_buffer_begin_user_action() and
3007 * gtk_text_buffer_end_user_action() can then be grouped when creating
3008 * an undo stack. #GtkTextBuffer maintains a count of calls to
3009 * gtk_text_buffer_begin_user_action() that have not been closed with
3010 * a call to gtk_text_buffer_end_user_action(), and emits the "begin_user_action"
3011 * and "end_user_action" signals only for the outermost pair of calls.
3012 * This allows you to build user actions from other user actions.
3014 * The "interactive" buffer mutation functions, such as
3015 * gtk_text_buffer_insert_interactive(), automatically call begin/end
3016 * user action around the buffer operations they perform, so there's
3017 * no need to add extra calls if you user action consists solely of a
3018 * single call to one of those functions.
3021 gtk_text_buffer_begin_user_action (GtkTextBuffer *buffer)
3023 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
3025 buffer->user_action_count += 1;
3027 if (buffer->user_action_count == 1)
3029 /* Outermost nested user action begin emits the signal */
3030 g_signal_emit (G_OBJECT (buffer), signals[BEGIN_USER_ACTION], 0);
3035 * gtk_text_buffer_end_user_action:
3036 * @buffer: a #GtkTextBuffer
3038 * Should be paired with a call to gtk_text_buffer_begin_user_action().
3039 * See that function for a full explanation.
3042 gtk_text_buffer_end_user_action (GtkTextBuffer *buffer)
3044 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
3045 g_return_if_fail (buffer->user_action_count > 0);
3047 buffer->user_action_count -= 1;
3049 if (buffer->user_action_count == 0)
3051 /* Ended the outermost-nested user action end, so emit the signal */
3052 g_signal_emit (G_OBJECT (buffer), signals[END_USER_ACTION], 0);
3057 * Logical attribute cache
3060 #define ATTR_CACHE_SIZE 2
3062 typedef struct _CacheEntry CacheEntry;
3067 PangoLogAttr *attrs;
3071 struct _GtkTextLogAttrCache
3073 gint chars_changed_stamp;
3074 CacheEntry entries[ATTR_CACHE_SIZE];
3078 free_log_attr_cache (GtkTextLogAttrCache *cache)
3081 while (i < ATTR_CACHE_SIZE)
3083 g_free (cache->entries[i].attrs);
3090 clear_log_attr_cache (GtkTextLogAttrCache *cache)
3093 while (i < ATTR_CACHE_SIZE)
3095 g_free (cache->entries[i].attrs);
3096 cache->entries[i].attrs = NULL;
3101 static PangoLogAttr*
3102 compute_log_attrs (const GtkTextIter *iter,
3108 gint char_len, byte_len;
3109 PangoLogAttr *attrs = NULL;
3115 gtk_text_iter_set_line_offset (&start, 0);
3116 gtk_text_iter_forward_line (&end);
3118 paragraph = gtk_text_iter_get_slice (&start, &end);
3119 char_len = g_utf8_strlen (paragraph, -1);
3120 byte_len = strlen (paragraph);
3122 g_assert (char_len > 0);
3125 *char_lenp = char_len;
3127 attrs = g_new (PangoLogAttr, char_len);
3129 lang = gtk_text_iter_get_language (&start);
3131 pango_get_log_attrs (paragraph, byte_len, -1,
3142 /* The return value from this is valid until you call this a second time.
3145 _gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer,
3146 const GtkTextIter *anywhere_in_line,
3150 GtkTextLogAttrCache *cache;
3153 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
3154 g_return_val_if_fail (anywhere_in_line != NULL, NULL);
3155 g_return_val_if_fail (!gtk_text_iter_is_end (anywhere_in_line), NULL);
3157 /* FIXME we also need to recompute log attrs if the language tag at
3158 * the start of a paragraph changes
3161 if (buffer->log_attr_cache == NULL)
3163 buffer->log_attr_cache = g_new0 (GtkTextLogAttrCache, 1);
3164 buffer->log_attr_cache->chars_changed_stamp =
3165 _gtk_text_btree_get_chars_changed_stamp (get_btree (buffer));
3167 else if (buffer->log_attr_cache->chars_changed_stamp !=
3168 _gtk_text_btree_get_chars_changed_stamp (get_btree (buffer)))
3170 clear_log_attr_cache (buffer->log_attr_cache);
3173 cache = buffer->log_attr_cache;
3174 line = gtk_text_iter_get_line (anywhere_in_line);
3177 while (i < ATTR_CACHE_SIZE)
3179 if (cache->entries[i].attrs &&
3180 cache->entries[i].line == line)
3183 *char_len = cache->entries[i].char_len;
3184 return cache->entries[i].attrs;
3189 /* Not in cache; open up the first cache entry */
3190 if (cache->entries[ATTR_CACHE_SIZE-1].attrs)
3191 g_free (cache->entries[ATTR_CACHE_SIZE-1].attrs);
3193 g_memmove (cache->entries + 1, cache->entries,
3194 sizeof (CacheEntry) * (ATTR_CACHE_SIZE - 1));
3196 cache->entries[0].line = line;
3197 cache->entries[0].attrs = compute_log_attrs (anywhere_in_line,
3198 &cache->entries[0].char_len);
3201 *char_len = cache->entries[0].char_len;
3203 return cache->entries[0].attrs;
3211 _gtk_text_buffer_spew (GtkTextBuffer *buffer)
3213 _gtk_text_btree_spew (get_btree (buffer));