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/.
30 #include "gtkclipboard.h"
31 #include "gtkinvisible.h"
32 #include "gtksignal.h"
33 #include "gtktextbuffer.h"
34 #include "gtktextbtree.h"
35 #include "gtktextiterprivate.h"
38 typedef struct _ClipboardRequest ClipboardRequest;
40 struct _ClipboardRequest
42 GtkTextBuffer *buffer;
44 gboolean default_editable;
45 gboolean is_clipboard;
46 gboolean replace_selection;
75 TARGET_TEXT_BUFFER_CONTENTS
78 static void gtk_text_buffer_init (GtkTextBuffer *tkxt_buffer);
79 static void gtk_text_buffer_class_init (GtkTextBufferClass *klass);
80 static void gtk_text_buffer_finalize (GObject *object);
83 static void gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer);
84 static void gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
88 static void gtk_text_buffer_real_insert_pixbuf (GtkTextBuffer *buffer,
91 static void gtk_text_buffer_real_insert_anchor (GtkTextBuffer *buffer,
93 GtkTextChildAnchor *anchor);
94 static void gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
97 static void gtk_text_buffer_real_apply_tag (GtkTextBuffer *buffer,
99 const GtkTextIter *start_char,
100 const GtkTextIter *end_char);
101 static void gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
103 const GtkTextIter *start_char,
104 const GtkTextIter *end_char);
105 static void gtk_text_buffer_real_changed (GtkTextBuffer *buffer);
107 static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
108 static void free_log_attr_cache (GtkTextLogAttrCache *cache);
110 static GtkObjectClass *parent_class = NULL;
111 static guint signals[LAST_SIGNAL] = { 0 };
114 gtk_text_buffer_get_type (void)
116 static GType our_type = 0;
120 static const GTypeInfo our_info =
122 sizeof (GtkTextBufferClass),
123 (GBaseInitFunc) NULL,
124 (GBaseFinalizeFunc) NULL,
125 (GClassInitFunc) gtk_text_buffer_class_init,
126 NULL, /* class_finalize */
127 NULL, /* class_data */
128 sizeof (GtkTextBuffer),
130 (GInstanceInitFunc) gtk_text_buffer_init
133 our_type = g_type_register_static (G_TYPE_OBJECT,
143 gtk_text_buffer_class_init (GtkTextBufferClass *klass)
145 GObjectClass *object_class = G_OBJECT_CLASS (klass);
147 parent_class = g_type_class_peek_parent (klass);
149 object_class->finalize = gtk_text_buffer_finalize;
151 klass->insert_text = gtk_text_buffer_real_insert_text;
152 klass->insert_pixbuf = gtk_text_buffer_real_insert_pixbuf;
153 klass->delete_range = gtk_text_buffer_real_delete_range;
154 klass->apply_tag = gtk_text_buffer_real_apply_tag;
155 klass->remove_tag = gtk_text_buffer_real_remove_tag;
156 klass->changed = gtk_text_buffer_real_changed;
158 signals[INSERT_TEXT] =
159 g_signal_newc ("insert_text",
160 G_TYPE_FROM_CLASS (object_class),
162 G_STRUCT_OFFSET (GtkTextBufferClass, insert_text),
164 gtk_marshal_VOID__BOXED_STRING_INT,
176 signals[INSERT_PIXBUF] =
177 g_signal_newc ("insert_pixbuf",
178 G_TYPE_FROM_CLASS (object_class),
180 G_STRUCT_OFFSET (GtkTextBufferClass, insert_pixbuf),
182 gtk_marshal_VOID__BOXED_OBJECT,
192 signals[INSERT_CHILD_ANCHOR] =
193 g_signal_newc ("insert_child_anchor",
194 G_TYPE_FROM_CLASS (object_class),
196 G_STRUCT_OFFSET (GtkTextBufferClass, insert_child_anchor),
198 gtk_marshal_VOID__BOXED_OBJECT,
206 GTK_TYPE_TEXT_CHILD_ANCHOR);
208 signals[DELETE_RANGE] =
209 g_signal_newc ("delete_range",
210 G_TYPE_FROM_CLASS (object_class),
212 G_STRUCT_OFFSET (GtkTextBufferClass, delete_range),
214 gtk_marshal_VOID__BOXED_BOXED,
226 g_signal_newc ("changed",
227 G_TYPE_FROM_CLASS (object_class),
229 G_STRUCT_OFFSET (GtkTextBufferClass, changed),
231 gtk_marshal_VOID__VOID,
235 signals[MODIFIED_CHANGED] =
236 g_signal_newc ("modified_changed",
237 G_TYPE_FROM_CLASS (object_class),
239 G_STRUCT_OFFSET (GtkTextBufferClass, modified_changed),
241 gtk_marshal_VOID__VOID,
246 g_signal_newc ("mark_set",
247 G_TYPE_FROM_CLASS (object_class),
249 G_STRUCT_OFFSET (GtkTextBufferClass, mark_set),
251 gtk_marshal_VOID__BOXED_OBJECT,
257 signals[MARK_DELETED] =
258 g_signal_newc ("mark_deleted",
259 G_TYPE_FROM_CLASS (object_class),
261 G_STRUCT_OFFSET (GtkTextBufferClass, mark_deleted),
263 gtk_marshal_VOID__OBJECT,
269 g_signal_newc ("apply_tag",
270 G_TYPE_FROM_CLASS (object_class),
272 G_STRUCT_OFFSET (GtkTextBufferClass, apply_tag),
274 gtk_marshal_VOID__OBJECT_BOXED_BOXED,
281 signals[REMOVE_TAG] =
282 g_signal_newc ("remove_tag",
283 G_TYPE_FROM_CLASS (object_class),
285 G_STRUCT_OFFSET (GtkTextBufferClass, remove_tag),
287 gtk_marshal_VOID__OBJECT_BOXED_BOXED,
294 signals[BEGIN_USER_ACTION] =
295 g_signal_newc ("begin_user_action",
296 G_TYPE_FROM_CLASS (object_class),
298 G_STRUCT_OFFSET (GtkTextBufferClass, begin_user_action),
300 gtk_marshal_VOID__VOID,
304 signals[END_USER_ACTION] =
305 g_signal_newc ("end_user_action",
306 G_TYPE_FROM_CLASS (object_class),
308 G_STRUCT_OFFSET (GtkTextBufferClass, end_user_action),
310 gtk_marshal_VOID__VOID,
316 gtk_text_buffer_init (GtkTextBuffer *buffer)
318 buffer->clipboard_contents = NULL;
322 * gtk_text_buffer_new:
323 * @table: a tag table, or NULL to create a new one
325 * Creates a new text buffer.
327 * Return value: a new text buffer
330 gtk_text_buffer_new (GtkTextTagTable *table)
332 GtkTextBuffer *text_buffer;
334 text_buffer = GTK_TEXT_BUFFER (g_object_new (gtk_text_buffer_get_type (), NULL));
338 text_buffer->tag_table = table;
340 g_object_ref (G_OBJECT (text_buffer->tag_table));
343 g_object_ref (G_OBJECT (text_buffer));
349 gtk_text_buffer_finalize (GObject *object)
351 GtkTextBuffer *buffer;
353 buffer = GTK_TEXT_BUFFER (object);
355 if (buffer->clipboard_contents)
357 g_object_unref (G_OBJECT (buffer->clipboard_contents));
358 buffer->clipboard_contents = NULL;
361 if (buffer->tag_table)
363 g_object_unref (G_OBJECT (buffer->tag_table));
364 buffer->tag_table = NULL;
369 _gtk_text_btree_unref (buffer->btree);
370 buffer->btree = NULL;
373 if (buffer->log_attr_cache)
374 free_log_attr_cache (buffer->log_attr_cache);
376 buffer->log_attr_cache = NULL;
378 G_OBJECT_CLASS (parent_class)->finalize (object);
381 static GtkTextTagTable*
382 get_table (GtkTextBuffer *buffer)
384 if (buffer->tag_table == NULL)
385 buffer->tag_table = gtk_text_tag_table_new ();
387 return buffer->tag_table;
391 get_btree (GtkTextBuffer *buffer)
393 if (buffer->btree == NULL)
394 buffer->btree = _gtk_text_btree_new (gtk_text_buffer_get_tag_table (buffer),
397 return buffer->btree;
401 _gtk_text_buffer_get_btree (GtkTextBuffer *buffer)
403 return get_btree (buffer);
407 * gtk_text_buffer_get_tag_table:
408 * @buffer: a #GtkTextBuffer
410 * Get the #GtkTextTagTable associated with this buffer.
412 * Return value: the buffer's tag table
415 gtk_text_buffer_get_tag_table (GtkTextBuffer *buffer)
417 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
419 return get_table (buffer);
423 * gtk_text_buffer_set_text:
424 * @buffer: a #GtkTextBuffer
425 * @text: UTF-8 text to insert
426 * @len: length of @text in bytes
428 * Deletes current contents of @buffer, and inserts @text instead. If
429 * @text doesn't end with a newline, a newline is added;
430 * #GtkTextBuffer contents must always end with a newline. If @text
431 * ends with a newline, the new buffer contents will be exactly
432 * @text. If @len is -1, @text must be nul-terminated.
435 gtk_text_buffer_set_text (GtkTextBuffer *buffer,
439 GtkTextIter start, end;
441 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
442 g_return_if_fail (text != NULL);
447 /* Chop newline, since the buffer will already have one
450 if (len > 0 && text[len-1] == '\n')
453 gtk_text_buffer_get_bounds (buffer, &start, &end);
455 gtk_text_buffer_delete (buffer, &start, &end);
459 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
460 gtk_text_buffer_insert (buffer, &start, text, len);
470 gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
475 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
476 g_return_if_fail (iter != NULL);
478 _gtk_text_btree_insert (iter, text, len);
480 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
484 gtk_text_buffer_emit_insert (GtkTextBuffer *buffer,
489 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
490 g_return_if_fail (iter != NULL);
491 g_return_if_fail (text != NULL);
496 g_assert (g_utf8_validate (text, len, NULL));
500 g_signal_emit (G_OBJECT (buffer), signals[INSERT_TEXT], 0,
506 * gtk_text_buffer_insert:
507 * @buffer: a #GtkTextBuffer
508 * @iter: a position in the buffer
509 * @text: UTF-8 format text to insert
510 * @len: length of text in bytes, or -1
512 * Inserts @len bytes of @text at position @iter. If @len is -1,
513 * @text must be nul-terminated and will be inserted in its
514 * entirety. Emits the "insert_text" signal; insertion actually occurs
515 * in the default handler for the signal. @iter is invalidated when
516 * insertion occurs (because the buffer contents change), but the
517 * default signal handler revalidates it to point to the end of the
522 gtk_text_buffer_insert (GtkTextBuffer *buffer,
527 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
528 g_return_if_fail (iter != NULL);
529 g_return_if_fail (text != NULL);
531 gtk_text_buffer_emit_insert (buffer, iter, text, len);
535 * gtk_text_buffer_insert_at_cursor:
536 * @buffer: a #GtkTextBuffer
537 * @text: some text in UTF-8 format
538 * @len: length of text, in bytes
540 * Simply calls gtk_text_buffer_insert (), using the current
541 * cursor position as the insertion point.
544 gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buffer,
550 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
551 g_return_if_fail (text != NULL);
553 gtk_text_buffer_get_iter_at_mark (buffer, &iter,
554 gtk_text_buffer_get_mark (buffer,
557 gtk_text_buffer_insert (buffer, &iter, text, len);
561 * gtk_text_buffer_insert_interactive:
562 * @buffer: a #GtkTextBuffer
563 * @iter: a position in @buffer
564 * @text: some UTF-8 text
565 * @len: length of text in bytes, or -1
566 * @default_editable: default editability of buffer
568 * Like gtk_text_buffer_insert (), but the insertion will not occur if
569 * @iter is at a non-editable location in the buffer. Usually you
570 * want to prevent insertions at ineditable locations if the insertion
571 * results from a user action (is interactive).
573 * @default_editable indicates the editability of text that doesn't
574 * have a tag affecting editability applied to it. Typically the
575 * result of gtk_text_view_get_editable() is appropriate here.
577 * Return value: whether text was actually inserted
580 gtk_text_buffer_insert_interactive (GtkTextBuffer *buffer,
584 gboolean default_editable)
586 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
587 g_return_val_if_fail (text != NULL, FALSE);
589 if (gtk_text_iter_editable (iter, default_editable))
591 gtk_text_buffer_begin_user_action (buffer);
592 gtk_text_buffer_emit_insert (buffer, iter, text, len);
593 gtk_text_buffer_end_user_action (buffer);
601 * gtk_text_buffer_insert_interactive_at_cursor:
602 * @buffer: a #GtkTextBuffer
603 * @text: text in UTF-8 format
604 * @len: length of text in bytes, or -1
605 * @default_editable: default editability of buffer
607 * Calls gtk_text_buffer_insert_interactive () at the cursor
610 * @default_editable indicates the editability of text that doesn't
611 * have a tag affecting editability applied to it. Typically the
612 * result of gtk_text_view_get_editable() is appropriate here.
614 * Return value: whether text was actually inserted
617 gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
620 gboolean default_editable)
624 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
625 g_return_val_if_fail (text != NULL, FALSE);
627 gtk_text_buffer_get_iter_at_mark (buffer, &iter,
628 gtk_text_buffer_get_mark (buffer,
631 return gtk_text_buffer_insert_interactive (buffer, &iter, text, len,
636 possibly_not_text (gunichar ch,
639 return ch == GTK_TEXT_UNKNOWN_CHAR;
643 insert_text_range (GtkTextBuffer *buffer,
645 const GtkTextIter *orig_start,
646 const GtkTextIter *orig_end,
647 gboolean interactive)
651 text = gtk_text_iter_get_text (orig_start, orig_end);
653 gtk_text_buffer_emit_insert (buffer, iter, text, -1);
658 typedef struct _Range Range;
661 GtkTextBuffer *buffer;
662 GtkTextMark *start_mark;
663 GtkTextMark *end_mark;
664 GtkTextMark *whole_end_mark;
665 GtkTextIter *range_start;
666 GtkTextIter *range_end;
667 GtkTextIter *whole_end;
671 save_range (GtkTextIter *range_start,
672 GtkTextIter *range_end,
673 GtkTextIter *whole_end)
677 r = g_new (Range, 1);
679 r->buffer = gtk_text_iter_get_buffer (range_start);
680 g_object_ref (G_OBJECT (r->buffer));
683 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
688 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
694 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
699 r->range_start = range_start;
700 r->range_end = range_end;
701 r->whole_end = whole_end;
707 restore_range (Range *r)
709 gtk_text_buffer_get_iter_at_mark (r->buffer,
713 gtk_text_buffer_get_iter_at_mark (r->buffer,
717 gtk_text_buffer_get_iter_at_mark (r->buffer,
721 gtk_text_buffer_delete_mark (r->buffer, r->start_mark);
722 gtk_text_buffer_delete_mark (r->buffer, r->end_mark);
723 gtk_text_buffer_delete_mark (r->buffer, r->whole_end_mark);
725 g_object_unref (G_OBJECT (r->buffer));
730 insert_range_untagged (GtkTextBuffer *buffer,
732 const GtkTextIter *orig_start,
733 const GtkTextIter *orig_end,
734 gboolean interactive)
736 GtkTextIter range_start;
737 GtkTextIter range_end;
738 GtkTextIter start, end;
739 GtkTextBuffer *src_buffer;
742 if (gtk_text_iter_equal (orig_start, orig_end))
748 src_buffer = gtk_text_iter_get_buffer (&start);
755 if (gtk_text_iter_equal (&range_start, &range_end))
757 /* Figure out how to move forward */
759 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
761 if (gtk_text_iter_equal (&range_end, &end))
763 /* nothing left to do */
766 else if (gtk_text_iter_get_char (&range_end) == GTK_TEXT_UNKNOWN_CHAR)
768 GdkPixbuf *pixbuf = NULL;
769 GtkTextChildAnchor *anchor = NULL;
770 pixbuf = gtk_text_iter_get_pixbuf (&range_end);
771 anchor = gtk_text_iter_get_child_anchor (&range_end);
775 r = save_range (&range_start,
779 gtk_text_buffer_insert_pixbuf (buffer,
786 gtk_text_iter_forward_char (&range_end);
788 range_start = range_end;
792 /* Just skip anchors */
794 gtk_text_iter_forward_char (&range_end);
795 range_start = range_end;
799 /* The GTK_TEXT_UNKNOWN_CHAR was in a text segment, so
802 gtk_text_iter_forward_find_char (&range_end,
803 possibly_not_text, NULL,
806 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
811 /* Text segment starts here, so forward search to
812 * find its possible endpoint
814 gtk_text_iter_forward_find_char (&range_end,
815 possibly_not_text, NULL,
818 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
823 r = save_range (&range_start,
827 insert_text_range (buffer,
836 range_start = range_end;
842 gtk_text_buffer_real_insert_range (GtkTextBuffer *buffer,
844 const GtkTextIter *orig_start,
845 const GtkTextIter *orig_end,
846 gboolean interactive)
848 /* Find each range of uniformly-tagged text, insert it,
849 * then apply the tags.
851 GtkTextIter start = *orig_start;
852 GtkTextIter end = *orig_end;
853 GtkTextIter range_start;
854 GtkTextIter range_end;
855 GtkTextBuffer *src_buffer;
858 if (gtk_text_iter_equal (orig_start, orig_end))
862 gtk_text_buffer_begin_user_action (buffer);
864 src_buffer = gtk_text_iter_get_buffer (orig_start);
866 gtk_text_iter_reorder (&start, &end);
874 GtkTextIter start_iter;
878 if (gtk_text_iter_equal (&range_start, &end))
879 break; /* All done */
881 g_assert (gtk_text_iter_compare (&range_start, &end) < 0);
883 gtk_text_iter_forward_to_tag_toggle (&range_end, NULL);
885 g_assert (!gtk_text_iter_equal (&range_start, &range_end));
887 /* Clamp to the end iterator */
888 if (gtk_text_iter_compare (&range_end, &end) > 0)
891 /* We have a range with unique tags; insert it, and
894 start_offset = gtk_text_iter_get_offset (iter);
896 r = save_range (&range_start, &range_end, &end);
898 insert_range_untagged (buffer, iter, &range_start, &range_end, interactive);
903 gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start_offset);
905 tags = gtk_text_iter_get_tags (&range_start);
907 while (tmp_list != NULL)
909 gtk_text_buffer_apply_tag (buffer,
914 tmp_list = g_slist_next (tmp_list);
918 range_start = range_end;
922 gtk_text_buffer_end_user_action (buffer);
926 * gtk_text_buffer_insert_range:
927 * @buffer: a #GtkTextBuffer
928 * @iter: a position in @buffer
929 * @start: a position in a #GtkTextBuffer
930 * @end: another position in the same buffer as @start
932 * Copies text, tags, and pixbufs between @start and @end (the order
933 * of @start and @end doesn't matter) and inserts the copy at @iter.
934 * Used instead of simply getting/inserting text because it preserves
935 * images and tags. If @start and @end are in a different buffer from
936 * @buffer, the two buffers must share the same tag table.
938 * Implemented via emissions of the insert_text and apply_tag signals,
942 gtk_text_buffer_insert_range (GtkTextBuffer *buffer,
944 const GtkTextIter *start,
945 const GtkTextIter *end)
947 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
948 g_return_if_fail (iter != NULL);
949 g_return_if_fail (start != NULL);
950 g_return_if_fail (end != NULL);
951 g_return_if_fail (gtk_text_iter_get_buffer (start) ==
952 gtk_text_iter_get_buffer (end));
953 g_return_if_fail (gtk_text_iter_get_buffer (start)->tag_table ==
956 gtk_text_buffer_real_insert_range (buffer, iter, start, end, FALSE);
960 * gtk_text_buffer_insert_range_interactive:
961 * @buffer: a #GtkTextBuffer
962 * @iter: a position in @buffer
963 * @start: a position in a #GtkTextBuffer
964 * @end: another position in the same buffer as @start
965 * @default_editable: default editability of the buffer
967 * Same as gtk_text_buffer_insert_range(), but does nothing if the
968 * insertion point isn't editable. The @default_editable parameter
969 * indicates whether the text is editable at @iter if no tags
970 * enclosing @iter affect editability. Typically the result of
971 * gtk_text_view_get_editable() is appropriate here.
973 * Returns: whether an insertion was possible at @iter
976 gtk_text_buffer_insert_range_interactive (GtkTextBuffer *buffer,
978 const GtkTextIter *start,
979 const GtkTextIter *end,
980 gboolean default_editable)
982 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
983 g_return_val_if_fail (iter != NULL, FALSE);
984 g_return_val_if_fail (start != NULL, FALSE);
985 g_return_val_if_fail (end != NULL, FALSE);
986 g_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
987 gtk_text_iter_get_buffer (end), FALSE);
988 g_return_val_if_fail (gtk_text_iter_get_buffer (start)->tag_table ==
989 buffer->tag_table, FALSE);
992 if (gtk_text_iter_editable (iter, default_editable))
994 gtk_text_buffer_real_insert_range (buffer, iter, start, end, TRUE);
1002 * gtk_text_buffer_insert_with_tags:
1003 * @buffer: a #GtkTextBuffer
1004 * @iter: an iterator in @buffer
1006 * @len: length of @text, or -1
1007 * @first_tag: first tag to apply to @text
1008 * @Varargs: NULL-terminated list of tags to apply
1010 * Inserts @text into @buffer at @iter, applying the list of tags to
1011 * the newly-inserted text. The last tag specified must be NULL to
1012 * terminate the list. Equivalent to calling gtk_text_buffer_insert (),
1013 * then gtk_text_buffer_apply_tag () on the inserted text;
1014 * gtk_text_buffer_insert_with_tags () is just a convenience function.
1017 gtk_text_buffer_insert_with_tags (GtkTextBuffer *buffer,
1021 GtkTextTag *first_tag,
1029 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1030 g_return_if_fail (iter != NULL);
1031 g_return_if_fail (text != NULL);
1033 start_offset = gtk_text_iter_get_offset (iter);
1035 gtk_text_buffer_insert (buffer, iter, text, len);
1037 if (first_tag == NULL)
1040 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1042 va_start (args, first_tag);
1046 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
1048 tag = va_arg (args, GtkTextTag*);
1055 * gtk_text_buffer_insert_with_tags_by_name:
1056 * @buffer: a #GtkTextBuffer
1057 * @iter: position in @buffer
1059 * @len: length of @text, or -1
1060 * @first_tag_name: name of a tag to apply to @text
1061 * @Varargs: more tag names
1063 * Same as gtk_text_buffer_insert_with_tags (), but allows you
1064 * to pass in tag names instead of tag objects.
1067 gtk_text_buffer_insert_with_tags_by_name (GtkTextBuffer *buffer,
1071 const gchar *first_tag_name,
1077 const gchar *tag_name;
1079 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1080 g_return_if_fail (iter != NULL);
1081 g_return_if_fail (text != NULL);
1083 start_offset = gtk_text_iter_get_offset (iter);
1085 gtk_text_buffer_insert (buffer, iter, text, len);
1087 if (first_tag_name == NULL)
1090 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1092 va_start (args, first_tag_name);
1093 tag_name = first_tag_name;
1098 tag = gtk_text_tag_table_lookup (buffer->tag_table,
1103 g_warning ("%s: no tag with name '%s'!", G_STRLOC, tag_name);
1107 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
1109 tag_name = va_arg (args, const gchar*);
1121 gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
1125 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1126 g_return_if_fail (start != NULL);
1127 g_return_if_fail (end != NULL);
1129 _gtk_text_btree_delete (start, end);
1131 /* may have deleted the selection... */
1132 gtk_text_buffer_update_primary_selection (buffer);
1134 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1138 gtk_text_buffer_emit_delete (GtkTextBuffer *buffer,
1142 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1143 g_return_if_fail (start != NULL);
1144 g_return_if_fail (end != NULL);
1146 if (gtk_text_iter_equal (start, end))
1149 gtk_text_iter_reorder (start, end);
1151 /* Somewhat annoyingly, if you try to delete the final newline
1152 * the BTree will put it back; which means you can't deduce the
1153 * final contents of the buffer purely by monitoring insert/delete
1154 * signals on the buffer. But if you delete the final newline, any
1155 * tags on the newline will go away, oddly. See comment in
1156 * gtktextbtree.c. This is all sort of annoying, but really hard
1159 g_signal_emit (G_OBJECT (buffer),
1160 signals[DELETE_RANGE],
1166 * gtk_text_buffer_delete:
1167 * @buffer: a #GtkTextBuffer
1168 * @start: a position in @buffer
1169 * @end: another position in @buffer
1171 * Deletes text between @start and @end. The order of @start and @end
1172 * is not actually relevant; gtk_text_buffer_delete () will reorder
1173 * them. This function actually emits the "delete_range" signal, and
1174 * the default handler of that signal deletes the text. Because the
1175 * buffer is modified, all outstanding iterators become invalid after
1176 * calling this function; however, the @start and @end will be
1177 * re-initialized to point to the location where text was deleted.
1179 * Note that the final newline in the buffer may not be deleted; a
1180 * #GtkTextBuffer always contains at least one newline. You can
1181 * safely include the final newline in the range [@start,@end) but it
1182 * won't be affected by the deletion.
1186 gtk_text_buffer_delete (GtkTextBuffer *buffer,
1190 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1191 g_return_if_fail (start != NULL);
1192 g_return_if_fail (end != NULL);
1194 gtk_text_buffer_emit_delete (buffer, start, end);
1198 * gtk_text_buffer_delete_interactive:
1199 * @buffer: a #GtkTextBuffer
1200 * @start_iter: start of range to delete
1201 * @end_iter: end of range
1202 * @default_editable: whether the buffer is editable by default
1204 * Deletes all <emphasis>editable</emphasis> text in the given range.
1205 * Calls gtk_text_buffer_delete () for each editable sub-range of
1206 * [@start,@end). @start and @end are revalidated to point to
1207 * the location of the last deleted range, or left untouched if
1208 * no text was deleted.
1210 * Return value: whether some text was actually deleted
1213 gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
1214 GtkTextIter *start_iter,
1215 GtkTextIter *end_iter,
1216 gboolean default_editable)
1218 GtkTextMark *end_mark;
1219 GtkTextMark *start_mark;
1221 gboolean current_state;
1222 gboolean deleted_stuff = FALSE;
1224 /* Delete all editable text in the range start_iter, end_iter */
1226 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1227 g_return_val_if_fail (start_iter != NULL, FALSE);
1228 g_return_val_if_fail (end_iter != NULL, FALSE);
1230 gtk_text_buffer_begin_user_action (buffer);
1232 gtk_text_iter_reorder (start_iter, end_iter);
1234 start_mark = gtk_text_buffer_create_mark (buffer, NULL,
1236 end_mark = gtk_text_buffer_create_mark (buffer, NULL,
1240 current_state = gtk_text_iter_editable (&iter, default_editable);
1245 gboolean done = FALSE;
1248 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
1250 gtk_text_buffer_get_iter_at_mark (buffer, &end, end_mark);
1252 if (gtk_text_iter_compare (&iter, &end) >= 0)
1255 iter = end; /* clamp to the last boundary */
1258 new_state = gtk_text_iter_editable (&iter, default_editable);
1260 if (current_state == new_state)
1266 /* We're ending an editable region. Delete said region. */
1269 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
1271 gtk_text_buffer_emit_delete (buffer, &start, &iter);
1273 deleted_stuff = TRUE;
1275 /* revalidate user's iterators. */
1276 *start_iter = start;
1286 if (current_state && !new_state)
1288 /* End of an editable region. Delete it. */
1291 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
1293 gtk_text_buffer_emit_delete (buffer, &start, &iter);
1295 current_state = FALSE;
1296 deleted_stuff = TRUE;
1298 /* revalidate user's iterators. */
1299 *start_iter = start;
1304 /* We are at the start of an editable region. We won't be deleting
1305 * the previous region. Move start mark to start of this region.
1308 g_assert (!current_state && new_state);
1310 gtk_text_buffer_move_mark (buffer, start_mark,
1314 current_state = TRUE;
1322 gtk_text_buffer_delete_mark (buffer, start_mark);
1323 gtk_text_buffer_delete_mark (buffer, end_mark);
1325 gtk_text_buffer_end_user_action (buffer);
1327 return deleted_stuff;
1331 * Extracting textual buffer contents
1335 * gtk_text_buffer_get_text:
1336 * @buffer: a #GtkTextBuffer
1337 * @start: start of a range
1338 * @end: end of a range
1339 * @include_hidden_chars: whether to include invisible text
1341 * Returns the text in the range [@start,@end). Excludes undisplayed
1342 * text (text marked with tags that set the invisibility attribute) if
1343 * @include_hidden_chars is FALSE. Does not include characters
1344 * representing embedded images, so byte and character indexes into
1345 * the returned string do <emphasis>not</emphasis> correspond to byte
1346 * and character indexes into the buffer. Contrast with
1347 * gtk_text_buffer_get_slice ().
1349 * Return value: an allocated UTF-8 string
1352 gtk_text_buffer_get_text (GtkTextBuffer *buffer,
1353 const GtkTextIter *start,
1354 const GtkTextIter *end,
1355 gboolean include_hidden_chars)
1357 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1358 g_return_val_if_fail (start != NULL, NULL);
1359 g_return_val_if_fail (end != NULL, NULL);
1361 if (include_hidden_chars)
1362 return gtk_text_iter_get_text (start, end);
1364 return gtk_text_iter_get_visible_text (start, end);
1368 * gtk_text_buffer_get_slice:
1369 * @buffer: a #GtkTextBuffer
1370 * @start: start of a range
1371 * @end: end of a range
1372 * @include_hidden_chars: whether to include invisible text
1374 * Returns the text in the range [@start,@end). Excludes undisplayed
1375 * text (text marked with tags that set the invisibility attribute) if
1376 * @include_hidden_chars is FALSE. The returned string includes a
1377 * 0xFFFC character whenever the buffer contains
1378 * embedded images, so byte and character indexes into
1379 * the returned string <emphasis>do</emphasis> correspond to byte
1380 * and character indexes into the buffer. Contrast with
1381 * gtk_text_buffer_get_text (). Note that 0xFFFC can occur in normal
1382 * text as well, so it is not a reliable indicator that a pixbuf or
1383 * widget is in the buffer.
1385 * Return value: an allocated UTF-8 string
1388 gtk_text_buffer_get_slice (GtkTextBuffer *buffer,
1389 const GtkTextIter *start,
1390 const GtkTextIter *end,
1391 gboolean include_hidden_chars)
1393 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1394 g_return_val_if_fail (start != NULL, NULL);
1395 g_return_val_if_fail (end != NULL, NULL);
1397 if (include_hidden_chars)
1398 return gtk_text_iter_get_slice (start, end);
1400 return gtk_text_iter_get_visible_slice (start, end);
1408 gtk_text_buffer_real_insert_pixbuf (GtkTextBuffer *buffer,
1412 _gtk_text_btree_insert_pixbuf (iter, pixbuf);
1414 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1418 * gtk_text_buffer_insert_pixbuf:
1419 * @buffer: a #GtkTextBuffer
1420 * @iter: location to insert the pixbuf
1421 * @pixbuf: a #GdkPixbuf
1423 * Inserts an image into the text buffer at @iter. The image will be
1424 * counted as one character in character counts, and when obtaining
1425 * the buffer contents as a string, will be represented by the Unicode
1426 * "object replacement character" 0xFFFC. Note that the "slice"
1427 * variants for obtaining portions of the buffer as a string include
1428 * this character for pixbufs, but the "text" variants do
1429 * not. e.g. see gtk_text_buffer_get_slice() and
1430 * gtk_text_buffer_get_text().
1434 gtk_text_buffer_insert_pixbuf (GtkTextBuffer *buffer,
1438 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1439 g_return_if_fail (iter != NULL);
1440 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
1442 g_signal_emit (G_OBJECT (buffer), signals[INSERT_PIXBUF], 0,
1452 gtk_text_buffer_real_insert_anchor (GtkTextBuffer *buffer,
1454 GtkTextChildAnchor *anchor)
1456 _gtk_text_btree_insert_child_anchor (iter, anchor);
1458 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1462 * gtk_text_buffer_insert_child_anchor:
1463 * @buffer: a #GtkTextBuffer
1464 * @iter: location to insert the anchor
1465 * @anchor: a #GtkTextChildAnchor
1467 * Inserts a child widget anchor into the text buffer at @iter. The
1468 * anchor will be counted as one character in character counts, and
1469 * when obtaining the buffer contents as a string, will be represented
1470 * by the Unicode "object replacement character" 0xFFFC. Note that the
1471 * "slice" variants for obtaining portions of the buffer as a string
1472 * include this character for pixbufs, but the "text" variants do
1473 * not. e.g. see gtk_text_buffer_get_slice() and
1474 * gtk_text_buffer_get_text(). Consider
1475 * gtk_text_buffer_create_child_anchor() as a more convenient
1476 * alternative to this function. The buffer will add a reference to
1477 * the anchor, so you can unref it after insertion.
1481 gtk_text_buffer_insert_child_anchor (GtkTextBuffer *buffer,
1483 GtkTextChildAnchor *anchor)
1485 GtkTextChildAnchor *anchor;
1487 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1488 g_return_val_if_fail (iter != NULL, NULL);
1489 g_return_val_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor), NULL);
1491 g_signal_emit (G_OBJECT (buffer), signals[INSERT_CHILD_ANCHOR], 0,
1497 * gtk_text_buffer_create_child_anchor:
1498 * @buffer: a #GtkTextBuffer
1499 * @iter: location in the buffer
1501 * This is a convenience function which simply creates a child anchor
1502 * with gtk_text_child_anchor_new() and inserts it into the buffer
1503 * with gtk_text_buffer_insert_child_anchor().
1505 * Return value: the created child anchor
1508 gtk_text_buffer_create_child_anchor (GtkTextBuffer *buffer,
1511 GtkTextChildAnchor *anchor;
1513 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1514 g_return_val_if_fail (iter != NULL, NULL);
1516 anchor = gtk_text_child_anchor_new ();
1518 gtk_text_buffer_insert_child_anchor (buffer, iter, anchor);
1520 g_object_unref (G_OBJECT (anchor));
1530 gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
1531 const GtkTextIter *location,
1534 /* IMO this should NOT work like insert_text and delete_range,
1535 where the real action happens in the default handler.
1537 The reason is that the default handler would be _required_,
1538 i.e. the whole widget would start breaking and segfaulting
1539 if the default handler didn't get run. So you can't really
1540 override the default handler or stop the emission; that is,
1541 this signal is purely for notification, and not to allow users
1542 to modify the default behavior. */
1544 g_object_ref (G_OBJECT (mark));
1546 g_signal_emit (G_OBJECT (buffer),
1552 g_object_unref (G_OBJECT (mark));
1556 * gtk_text_buffer_set_mark:
1557 * @buffer: a #GtkTextBuffer
1558 * @mark_name: name of the mark
1559 * @iter: location for the mark.
1560 * @left_gravity: if the mark is created by this function, gravity for the new
1562 * @should_exist: if %TRUE, warn if the mark does not exist, and return
1565 * Move the mark to the given position, if not @should_exist, create the mark.
1567 * Return value: mark
1570 gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
1571 GtkTextMark *existing_mark,
1572 const gchar *mark_name,
1573 const GtkTextIter *iter,
1574 gboolean left_gravity,
1575 gboolean should_exist)
1577 GtkTextIter location;
1580 mark = _gtk_text_btree_set_mark (get_btree (buffer),
1587 if (_gtk_text_btree_mark_is_insert (get_btree (buffer), mark) ||
1588 _gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
1590 gtk_text_buffer_update_primary_selection (buffer);
1593 _gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1597 gtk_text_buffer_mark_set (buffer, &location, mark);
1603 * gtk_text_buffer_create_mark:
1604 * @buffer: a #GtkTextBuffer
1605 * @mark_name: name for mark, or %NULL
1606 * @where: location to place mark
1607 * @left_gravity: whether the mark has left gravity
1609 * Creates a mark at position @where. If @mark_name is %NULL, the mark
1610 * is anonymous; otherwise, the mark can be retrieved by name using
1611 * gtk_text_buffer_get_mark (). If a mark has left gravity, and text is
1612 * inserted at the mark's current location, the mark will be moved to
1613 * the left of the newly-inserted text. If the mark has right gravity
1614 * (@left_gravity = %FALSE), the mark will end up on the right of
1615 * newly-inserted text. The standard left-to-right cursor is a mark
1616 * with right gravity (when you type, the cursor stays on the right
1617 * side of the text you're typing).
1619 * The caller of this function does <emphasis>not</emphasis> own a reference
1620 * to the returned #GtkTextMark, so you can ignore the return value
1621 * if you like. Marks are owned by the buffer and go away when the
1624 * Emits the "mark_set" signal as notification of the mark's initial
1627 * Return value: the new #GtkTextMark object
1630 gtk_text_buffer_create_mark (GtkTextBuffer *buffer,
1631 const gchar *mark_name,
1632 const GtkTextIter *where,
1633 gboolean left_gravity)
1635 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1637 return gtk_text_buffer_set_mark (buffer, NULL, mark_name, where,
1638 left_gravity, FALSE);
1642 * gtk_text_buffer_move_mark:
1643 * @buffer: a #GtkTextBuffer
1644 * @mark: a #GtkTextMark
1645 * @where: new location for @mark in @buffer
1647 * Moves @mark to the new location @where. Emits the "mark_set" signal
1648 * as notification of the move.
1651 gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
1653 const GtkTextIter *where)
1655 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1656 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1657 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1659 gtk_text_buffer_set_mark (buffer, mark, NULL, where, FALSE, TRUE);
1663 * gtk_text_buffer_get_iter_at_mark:
1664 * @buffer: a #GtkTextBuffer
1665 * @iter: iterator to initialize
1666 * @mark: a #GtkTextMark in @buffer
1668 * Initializes @iter with the current position of @mark.
1671 gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
1675 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1676 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1677 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1679 _gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1685 * gtk_text_buffer_delete_mark:
1686 * @buffer: a #GtkTextBuffer
1687 * @mark: a #GtkTextMark in @buffer
1689 * Deletes @mark, so that it's no longer located anywhere in the
1690 * buffer. Removes the reference the buffer holds to the mark, so if
1691 * you haven't called g_object_ref () on the mark, it will be freed. Even
1692 * if the mark isn't freed, most operations on @mark become
1693 * invalid. There is no way to undelete a
1694 * mark. gtk_text_mark_get_deleted () will return TRUE after this
1695 * function has been called on a mark; gtk_text_mark_get_deleted ()
1696 * indicates that a mark no longer belongs to a buffer. The "mark_deleted"
1697 * signal will be emitted as notification after the mark is deleted.
1700 gtk_text_buffer_delete_mark (GtkTextBuffer *buffer,
1703 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1704 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1705 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1707 g_object_ref (G_OBJECT (mark));
1709 _gtk_text_btree_remove_mark (get_btree (buffer), mark);
1711 /* See rationale above for MARK_SET on why we emit this after
1712 * removing the mark, rather than removing the mark in a default
1715 g_signal_emit (G_OBJECT (buffer), signals[MARK_DELETED],
1719 g_object_unref (G_OBJECT (mark));
1723 * gtk_text_buffer_get_mark:
1724 * @buffer: a #GtkTextBuffer
1725 * @name: a mark name
1727 * Returns the mark named @name in buffer @buffer, or NULL if no such
1728 * mark exists in the buffer.
1730 * Return value: a #GtkTextMark, or NULL
1733 gtk_text_buffer_get_mark (GtkTextBuffer *buffer,
1738 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1739 g_return_val_if_fail (name != NULL, NULL);
1741 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1748 * gtk_text_buffer_move_mark_by_name:
1749 * @buffer: a #GtkTextBuffer
1750 * @name: name of a mark
1751 * @where: new location for mark
1753 * Moves the mark named @name (which must exist) to location @where.
1754 * See gtk_text_buffer_move_mark () for details.
1757 gtk_text_buffer_move_mark_by_name (GtkTextBuffer *buffer,
1759 const GtkTextIter *where)
1763 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1764 g_return_if_fail (name != NULL);
1766 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1770 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1774 gtk_text_buffer_move_mark (buffer, mark, where);
1778 * gtk_text_buffer_delete_mark_by_name:
1779 * @buffer: a #GtkTextBuffer
1780 * @name: name of a mark in @buffer
1782 * Deletes the mark named @name; the mark must exist. See
1783 * gtk_text_buffer_delete_mark () for details.
1786 gtk_text_buffer_delete_mark_by_name (GtkTextBuffer *buffer,
1791 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1792 g_return_if_fail (name != NULL);
1794 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1798 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1802 gtk_text_buffer_delete_mark (buffer, mark);
1806 * gtk_text_buffer_get_insert:
1807 * @buffer: a #GtkTextBuffer
1809 * Returns the mark that represents the cursor (insertion point).
1810 * Equivalent to calling gtk_text_buffer_get_mark () to get the mark
1811 * name "insert," but very slightly more efficient, and involves less
1814 * Return value: insertion point mark
1817 gtk_text_buffer_get_insert (GtkTextBuffer *buffer)
1819 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1821 /* FIXME use struct member in btree */
1822 return gtk_text_buffer_get_mark (buffer, "insert");
1826 * gtk_text_buffer_get_selection_bound:
1827 * @buffer: a #GtkTextBuffer
1829 * Returns the mark that represents the selection bound. Equivalent
1830 * to calling gtk_text_buffer_get_mark () to get the mark name
1831 * "selection_bound," but very slightly more efficient, and involves
1834 * The currently-selected text in @buffer is the region between the
1835 * "selection_bound" and "insert" marks. If "selection_bound" and
1836 * "insert" are in the same place, then there is no current selection.
1837 * gtk_text_buffer_get_selection_bounds () is another convenient function
1838 * for handling the selection, if you just want to know whether there's a
1839 * selection and what its bounds are.
1841 * Return value: selection bound mark
1844 gtk_text_buffer_get_selection_bound (GtkTextBuffer *buffer)
1846 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1848 /* FIXME use struct member in btree */
1849 return gtk_text_buffer_get_mark (buffer, "selection_bound");
1853 gtk_text_buffer_get_iter_at_child_anchor (GtkTextBuffer *buffer,
1855 GtkTextChildAnchor *anchor)
1857 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1858 g_return_if_fail (iter != NULL);
1859 g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor));
1860 g_return_if_fail (!gtk_text_child_anchor_get_deleted (anchor));
1862 _gtk_text_btree_get_iter_at_child_anchor (get_btree (buffer),
1868 * gtk_text_buffer_place_cursor:
1869 * @buffer: a #GtkTextBuffer
1870 * @where: where to put the cursor
1872 * This function moves the "insert" and "selection_bound" marks
1873 * simultaneously. If you move them to the same place in two steps
1874 * with gtk_text_buffer_move_mark (), you will temporarily select a
1875 * region in between their old and new locations, which can be pretty
1876 * inefficient since the temporarily-selected region will force stuff
1877 * to be recalculated. This function moves them as a unit, which can
1881 gtk_text_buffer_place_cursor (GtkTextBuffer *buffer,
1882 const GtkTextIter *where)
1886 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1890 if (gtk_text_iter_is_end (&real))
1891 gtk_text_iter_backward_char (&real);
1893 _gtk_text_btree_place_cursor (get_btree (buffer), &real);
1894 gtk_text_buffer_mark_set (buffer, &real,
1895 gtk_text_buffer_get_mark (buffer,
1897 gtk_text_buffer_mark_set (buffer, &real,
1898 gtk_text_buffer_get_mark (buffer,
1899 "selection_bound"));
1907 * gtk_text_buffer_create_tag:
1908 * @buffer: a #GtkTextBuffer
1909 * @tag_name: name of the new tag, or %NULL
1911 * Creates a tag and adds it to the tag table for @buffer.
1912 * Equivalent to calling gtk_text_tag_new () and then adding the
1913 * tag to the buffer's tag table. The returned tag has its refcount
1914 * incremented, as if you'd called gtk_text_tag_new ().
1916 * If @tag_name is %NULL, the tag is anonymous.
1918 * Return value: a new tag
1921 gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
1922 const gchar *tag_name)
1926 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1928 tag = gtk_text_tag_new (tag_name);
1930 gtk_text_tag_table_add (get_table (buffer), tag);
1936 gtk_text_buffer_real_apply_tag (GtkTextBuffer *buffer,
1938 const GtkTextIter *start,
1939 const GtkTextIter *end)
1941 _gtk_text_btree_tag (start, end, tag, TRUE);
1945 gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
1947 const GtkTextIter *start,
1948 const GtkTextIter *end)
1950 _gtk_text_btree_tag (start, end, tag, FALSE);
1954 gtk_text_buffer_real_changed (GtkTextBuffer *buffer)
1956 gtk_text_buffer_set_modified (buffer, TRUE);
1960 gtk_text_buffer_emit_tag (GtkTextBuffer *buffer,
1963 const GtkTextIter *start,
1964 const GtkTextIter *end)
1966 GtkTextIter start_tmp = *start;
1967 GtkTextIter end_tmp = *end;
1969 g_return_if_fail (tag != NULL);
1971 gtk_text_iter_reorder (&start_tmp, &end_tmp);
1974 g_signal_emit (G_OBJECT (buffer), signals[APPLY_TAG],
1976 tag, &start_tmp, &end_tmp);
1978 g_signal_emit (G_OBJECT (buffer), signals[REMOVE_TAG],
1980 tag, &start_tmp, &end_tmp);
1985 * gtk_text_buffer_apply_tag:
1986 * @buffer: a #GtkTextBuffer
1987 * @tag: a #GtkTextTag
1988 * @start: one bound of range to be tagged
1989 * @end: other bound of range to be tagged
1991 * Emits the "apply_tag" signal on @buffer. The default
1992 * handler for the signal applies @tag to the given range.
1993 * @start and @end do not have to be in order.
1997 gtk_text_buffer_apply_tag (GtkTextBuffer *buffer,
1999 const GtkTextIter *start,
2000 const GtkTextIter *end)
2002 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2003 g_return_if_fail (GTK_IS_TEXT_TAG (tag));
2004 g_return_if_fail (start != NULL);
2005 g_return_if_fail (end != NULL);
2007 gtk_text_buffer_emit_tag (buffer, tag, TRUE, start, end);
2011 * gtk_text_buffer_remove_tag:
2012 * @buffer: a #GtkTextBuffer
2013 * @tag: a #GtkTextTag
2014 * @start: one bound of range to be untagged
2015 * @end: other bound of range to be untagged
2017 * Emits the "remove_tag" signal. The default handler for the signal
2018 * removes all occurrences of @tag from the given range. @start and
2019 * @end don't have to be in order.
2023 gtk_text_buffer_remove_tag (GtkTextBuffer *buffer,
2025 const GtkTextIter *start,
2026 const GtkTextIter *end)
2029 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2030 g_return_if_fail (GTK_IS_TEXT_TAG (tag));
2031 g_return_if_fail (start != NULL);
2032 g_return_if_fail (end != NULL);
2034 gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
2039 * gtk_text_buffer_apply_tag_by_name:
2040 * @buffer: a #GtkTextBuffer
2041 * @name: name of a named #GtkTextTag
2042 * @start: one bound of range to be tagged
2043 * @end: other bound of range to be tagged
2045 * Calls gtk_text_tag_table_lookup() on the buffer's tag table to
2046 * get a #GtkTextTag, then calls gtk_text_buffer_apply_tag().
2050 gtk_text_buffer_apply_tag_by_name (GtkTextBuffer *buffer,
2052 const GtkTextIter *start,
2053 const GtkTextIter *end)
2057 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2058 g_return_if_fail (name != NULL);
2059 g_return_if_fail (start != NULL);
2060 g_return_if_fail (end != NULL);
2062 tag = gtk_text_tag_table_lookup (get_table (buffer),
2067 g_warning ("Unknown tag `%s'", name);
2071 gtk_text_buffer_emit_tag (buffer, tag, TRUE, start, end);
2075 * gtk_text_buffer_remove_tag_by_name:
2076 * @buffer: a #GtkTextBuffer
2077 * @name: name of a #GtkTextTag
2078 * @start: one bound of range to be untagged
2079 * @end: other bound of range to be untagged
2081 * Calls gtk_text_tag_table_lookup() on the buffer's tag table to
2082 * get a #GtkTextTag, then calls gtk_text_buffer_remove_tag().
2087 gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
2089 const GtkTextIter *start,
2090 const GtkTextIter *end)
2094 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2095 g_return_if_fail (name != NULL);
2096 g_return_if_fail (start != NULL);
2097 g_return_if_fail (end != NULL);
2099 tag = gtk_text_tag_table_lookup (get_table (buffer),
2104 g_warning ("Unknown tag `%s'", name);
2108 gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
2113 * Obtain various iterators
2117 * gtk_text_buffer_get_iter_at_line_offset:
2118 * @buffer: a #GtkTextBuffer
2119 * @iter: iterator to initialize
2120 * @line_number: line number counting from 0
2121 * @char_offset: char offset from start of line
2123 * Obtains an iterator pointing to @char_offset within the given
2124 * line. The @char_offset must exist, offsets off the end of the line
2125 * are not allowed. Note <emphasis>characters</emphasis>, not bytes;
2126 * UTF-8 may encode one character as multiple bytes.
2130 gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
2135 g_return_if_fail (iter != NULL);
2136 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2138 _gtk_text_btree_get_iter_at_line_char (get_btree (buffer),
2139 iter, line_number, char_offset);
2143 * gtk_text_buffer_get_iter_at_line_index:
2144 * @buffer: a #GtkTextBuffer
2145 * @iter: iterator to initialize
2146 * @line_number: line number counting from 0
2147 * @byte_index: byte index from start of line
2149 * Obtains an iterator pointing to @byte_index within the given line.
2150 * @byte_index must be the start of a UTF-8 character, and must not be
2151 * beyond the end of the line. Note <emphasis>bytes</emphasis>, not
2152 * characters; UTF-8 may encode one character as multiple bytes.
2156 gtk_text_buffer_get_iter_at_line_index (GtkTextBuffer *buffer,
2161 g_return_if_fail (iter != NULL);
2162 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2164 _gtk_text_btree_get_iter_at_line_byte (get_btree (buffer),
2165 iter, line_number, byte_index);
2169 * gtk_text_buffer_get_iter_at_line:
2170 * @buffer: a #GtkTextBuffer
2171 * @iter: iterator to initialize
2172 * @line_number: line number counting from 0
2174 * Initializes @iter to the start of the given line.
2177 gtk_text_buffer_get_iter_at_line (GtkTextBuffer *buffer,
2181 g_return_if_fail (iter != NULL);
2182 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2184 gtk_text_buffer_get_iter_at_line_offset (buffer, iter, line_number, 0);
2188 * gtk_text_buffer_get_iter_at_offset:
2189 * @buffer: a #GtkTextBuffer
2190 * @iter: iterator to initialize
2191 * @char_offset: char offset from start of buffer, counting from 0
2193 * Initializes @iter to a position @char_offset chars from the start
2194 * of the entire buffer.
2198 gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer,
2202 g_return_if_fail (iter != NULL);
2203 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2205 _gtk_text_btree_get_iter_at_char (get_btree (buffer), iter, char_offset);
2209 * gtk_text_buffer_get_end_iter:
2210 * @buffer: a #GtkTextBuffer
2211 * @iter: iterator to initialize
2213 * Initializes @iter with the "end iterator," one past the last valid
2214 * character in the text buffer. If dereferenced with
2215 * gtk_text_iter_get_char(), the end iterator has a character value of
2216 * 0. The entire buffer lies in the range from the first position in
2217 * the buffer (call gtk_text_buffer_get_iter_at_offset() to get
2218 * character position 0) to the end iterator.
2222 gtk_text_buffer_get_end_iter (GtkTextBuffer *buffer,
2225 g_return_if_fail (iter != NULL);
2226 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2228 _gtk_text_btree_get_end_iter (get_btree (buffer), iter);
2232 * gtk_text_buffer_get_bounds:
2233 * @buffer: a #GtkTextBuffer
2234 * @start: iterator to initialize with first position in the buffer
2235 * @end: iterator to initialize with the end iterator
2237 * Retrieves the first and last iterators in the buffer, i.e. the
2238 * entire buffer lies within the range [@start,@end).
2242 gtk_text_buffer_get_bounds (GtkTextBuffer *buffer,
2246 g_return_if_fail (start != NULL);
2247 g_return_if_fail (end != NULL);
2248 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2250 _gtk_text_btree_get_iter_at_char (get_btree (buffer), start, 0);
2251 _gtk_text_btree_get_end_iter (get_btree (buffer), end);
2259 * gtk_text_buffer_get_modified:
2260 * @buffer: a #GtkTextBuffer
2262 * Indicates whether the buffer has been modified since the last call
2263 * to gtk_text_buffer_set_modified() set the modification flag to
2264 * %FALSE. Used for example to enable a "save" function in a text
2267 * Return value: %TRUE if the buffer has been modified
2270 gtk_text_buffer_get_modified (GtkTextBuffer *buffer)
2272 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2274 return buffer->modified;
2278 * gtk_text_buffer_set_modified:
2279 * @buffer: a #GtkTextBuffer
2280 * @setting: modification flag setting
2282 * Used to keep track of whether the buffer has been modified since the
2283 * last time it was saved. Whenever the buffer is saved to disk, call
2284 * gtk_text_buffer_set_modified (@buffer, FALSE). When the buffer is modified,
2285 * it will automatically toggled on the modified bit again. When the modified
2286 * bit flips, the buffer emits a "modified_changed" signal.
2290 gtk_text_buffer_set_modified (GtkTextBuffer *buffer,
2293 gboolean fixed_setting;
2295 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2297 fixed_setting = setting != FALSE;
2299 if (buffer->modified == fixed_setting)
2303 buffer->modified = fixed_setting;
2304 g_signal_emit (G_OBJECT (buffer), signals[MODIFIED_CHANGED], 0);
2310 * Assorted other stuff
2314 * gtk_text_buffer_get_line_count:
2315 * @buffer: a #GtkTextBuffer
2317 * Obtains the number of lines in the buffer. This value is cached, so
2318 * the function is very fast.
2320 * Return value: number of lines in the buffer
2323 gtk_text_buffer_get_line_count (GtkTextBuffer *buffer)
2325 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
2327 return _gtk_text_btree_line_count (get_btree (buffer));
2331 * gtk_text_buffer_get_char_count:
2332 * @buffer: a #GtkTextBuffer
2334 * Gets the number of characters in the buffer; note that characters
2335 * and bytes are not the same, you can't e.g. expect the contents of
2336 * the buffer in string form to be this many bytes long. The character
2337 * count is cached, so this function is very fast.
2339 * Return value: number of characters in the buffer
2342 gtk_text_buffer_get_char_count (GtkTextBuffer *buffer)
2344 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
2346 return _gtk_text_btree_char_count (get_btree (buffer));
2349 /* Called when we lose the primary selection.
2352 clipboard_clear_selection_cb (GtkClipboard *clipboard,
2355 /* Move selection_bound to the insertion point */
2357 GtkTextIter selection_bound;
2358 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2360 gtk_text_buffer_get_iter_at_mark (buffer, &insert,
2361 gtk_text_buffer_get_mark (buffer, "insert"));
2362 gtk_text_buffer_get_iter_at_mark (buffer, &selection_bound,
2363 gtk_text_buffer_get_mark (buffer, "selection_bound"));
2365 if (!gtk_text_iter_equal (&insert, &selection_bound))
2366 gtk_text_buffer_move_mark (buffer,
2367 gtk_text_buffer_get_mark (buffer, "selection_bound"),
2371 /* Called when we have the primary selection and someone else wants our
2372 * data in order to paste it.
2375 clipboard_get_selection_cb (GtkClipboard *clipboard,
2376 GtkSelectionData *selection_data,
2380 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2381 GtkTextIter start, end;
2383 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2385 if (selection_data->target ==
2386 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2388 /* Provide the address of the buffer; this will only be
2389 * used within-process
2391 gtk_selection_data_set (selection_data,
2392 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2401 str = gtk_text_iter_get_visible_text (&start, &end);
2402 gtk_selection_data_set_text (selection_data, str);
2408 /* Provide cut/copied data */
2410 clipboard_get_contents_cb (GtkClipboard *clipboard,
2411 GtkSelectionData *selection_data,
2415 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2416 GtkTextBuffer *contents = buffer->clipboard_contents;
2418 if (selection_data->target ==
2419 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2421 /* Provide the address of the clipboard buffer; this will only
2422 * be used within-process. OK to supply a NULL value for contents.
2424 gtk_selection_data_set (selection_data,
2425 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2432 /* Just provide text from the clipboard buffer */
2433 if (buffer->clipboard_contents)
2436 GtkTextIter start, end;
2438 gtk_text_buffer_get_bounds (contents, &start, &end);
2439 /* strip off the trailing newline, it isn't part of the text that was cut */
2440 gtk_text_iter_backward_char (&end);
2442 str = gtk_text_iter_get_visible_text (&start, &end);
2443 gtk_selection_data_set_text (selection_data, str);
2448 gtk_selection_data_set_text (selection_data, "");
2455 clipboard_clear_contents_cb (GtkClipboard *clipboard,
2458 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2460 if (buffer->clipboard_contents)
2462 g_object_unref (G_OBJECT (buffer->clipboard_contents));
2463 buffer->clipboard_contents = NULL;
2468 get_paste_point (GtkTextBuffer *buffer,
2470 gboolean clear_afterward)
2472 GtkTextIter insert_point;
2473 GtkTextMark *paste_point_override;
2475 paste_point_override = gtk_text_buffer_get_mark (buffer,
2476 "gtk_paste_point_override");
2478 if (paste_point_override != NULL)
2480 gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
2481 paste_point_override);
2482 if (clear_afterward)
2483 gtk_text_buffer_delete_mark (buffer,
2484 gtk_text_buffer_get_mark (buffer,
2485 "gtk_paste_point_override"));
2489 gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
2490 gtk_text_buffer_get_mark (buffer,
2494 *iter = insert_point;
2498 pre_paste_prep (ClipboardRequest *request_data,
2499 GtkTextIter *insert_point)
2501 GtkTextBuffer *buffer = request_data->buffer;
2503 get_paste_point (buffer, insert_point, TRUE);
2505 /* If we're going to replace the selection, we insert before it to
2506 * avoid messing it up, then we delete the selection after inserting.
2508 if (request_data->replace_selection)
2510 GtkTextIter start, end;
2512 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2513 *insert_point = start;
2518 post_paste_cleanup (ClipboardRequest *request_data)
2520 if (request_data->replace_selection)
2522 GtkTextIter start, end;
2524 if (gtk_text_buffer_get_selection_bounds (request_data->buffer,
2527 if (request_data->interactive)
2528 gtk_text_buffer_delete_interactive (request_data->buffer,
2531 request_data->default_editable);
2533 gtk_text_buffer_delete (request_data->buffer, &start, &end);
2538 /* Called when we request a paste and receive the text data
2541 clipboard_text_received (GtkClipboard *clipboard,
2545 ClipboardRequest *request_data = data;
2546 GtkTextBuffer *buffer = request_data->buffer;
2550 GtkTextIter insert_point;
2552 pre_paste_prep (request_data, &insert_point);
2554 if (request_data->interactive)
2555 gtk_text_buffer_insert_interactive (buffer, &insert_point,
2556 str, -1, request_data->default_editable);
2558 gtk_text_buffer_insert (buffer, &insert_point,
2561 post_paste_cleanup (request_data);
2564 g_object_unref (G_OBJECT (buffer));
2565 g_free (request_data);
2568 static GtkTextBuffer*
2569 selection_data_get_buffer (GtkSelectionData *selection_data,
2570 ClipboardRequest *request_data)
2573 GtkTextBuffer *src_buffer = NULL;
2575 /* If we can get the owner, the selection is in-process */
2576 owner = gdk_selection_owner_get (selection_data->selection);
2581 if (selection_data->type != gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2584 if (selection_data->length != sizeof (src_buffer))
2587 memcpy (&src_buffer, selection_data->data, sizeof (src_buffer));
2589 if (src_buffer == NULL)
2592 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (src_buffer), NULL);
2594 if (gtk_text_buffer_get_tag_table (src_buffer) !=
2595 gtk_text_buffer_get_tag_table (request_data->buffer))
2602 /* These are pretty handy functions; maybe something like them
2603 * should be in the public API. Also, there are other places in this
2604 * file where they could be used.
2607 save_iter (const GtkTextIter *iter,
2608 gboolean left_gravity)
2610 return gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (iter),
2617 restore_iter (const GtkTextIter *iter,
2620 gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (save_id),
2621 (GtkTextIter*) iter,
2623 gtk_text_buffer_delete_mark (gtk_text_mark_get_buffer (save_id),
2629 paste_from_buffer (ClipboardRequest *request_data,
2630 GtkTextBuffer *src_buffer,
2631 const GtkTextIter *start,
2632 const GtkTextIter *end)
2634 GtkTextIter insert_point;
2636 /* We're about to emit a bunch of signals, so be safe */
2637 g_object_ref (G_OBJECT (src_buffer));
2639 pre_paste_prep (request_data, &insert_point);
2641 if (!gtk_text_iter_equal (start, end))
2643 gtk_text_buffer_real_insert_range (request_data->buffer,
2647 request_data->interactive);
2650 post_paste_cleanup (request_data);
2652 g_object_unref (G_OBJECT (src_buffer));
2656 clipboard_clipboard_buffer_received (GtkClipboard *clipboard,
2657 GtkSelectionData *selection_data,
2660 ClipboardRequest *request_data = data;
2661 GtkTextBuffer *src_buffer;
2663 src_buffer = selection_data_get_buffer (selection_data, request_data);
2667 GtkTextIter start, end;
2669 gtk_text_buffer_get_bounds (src_buffer, &start, &end);
2670 /* There's an extra newline on clipboard_contents */
2671 gtk_text_iter_backward_char (&end);
2673 paste_from_buffer (request_data, src_buffer,
2678 /* Request the text selection instead */
2679 gtk_clipboard_request_text (clipboard,
2680 clipboard_text_received,
2686 clipboard_selection_buffer_received (GtkClipboard *clipboard,
2687 GtkSelectionData *selection_data,
2690 ClipboardRequest *request_data = data;
2691 GtkTextBuffer *src_buffer;
2693 src_buffer = selection_data_get_buffer (selection_data, request_data);
2697 GtkTextIter start, end;
2699 if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
2700 paste_from_buffer (request_data, src_buffer,
2705 /* Request the text selection instead */
2706 gtk_clipboard_request_text (clipboard,
2707 clipboard_text_received,
2712 static const GtkTargetEntry targets[] = {
2713 { "STRING", 0, TARGET_STRING },
2714 { "TEXT", 0, TARGET_TEXT },
2715 { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
2716 { "UTF8_STRING", 0, TARGET_UTF8_STRING },
2717 { "GTK_TEXT_BUFFER_CONTENTS", 0, TARGET_TEXT_BUFFER_CONTENTS }
2721 gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
2726 GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2728 /* Determine whether we have a selection and adjust X selection
2732 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2734 if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
2735 gtk_clipboard_clear (clipboard);
2739 /* Even if we already have the selection, we need to update our
2742 if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
2743 clipboard_get_selection_cb,
2744 clipboard_clear_selection_cb,
2746 clipboard_clear_selection_cb (clipboard, buffer);
2751 paste (GtkTextBuffer *buffer,
2752 gboolean is_clipboard,
2753 gboolean interactive,
2754 gboolean default_editable)
2756 ClipboardRequest *data = g_new (ClipboardRequest, 1);
2757 GtkTextIter paste_point;
2758 GtkTextIter start, end;
2760 data->buffer = buffer;
2761 g_object_ref (G_OBJECT (buffer));
2762 data->interactive = interactive;
2763 data->default_editable = default_editable;
2765 /* When pasting with the cursor inside the selection area, you
2766 * replace the selection with the new text, otherwise, you
2767 * simply insert the new text at the point where the click
2768 * occured, unselecting any selected text. The replace_selection
2769 * flag toggles this behavior.
2771 data->replace_selection = FALSE;
2773 get_paste_point (buffer, &paste_point, FALSE);
2774 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end) &&
2775 (gtk_text_iter_in_range (&paste_point, &start, &end) ||
2776 gtk_text_iter_equal (&paste_point, &end)))
2777 data->replace_selection = TRUE;
2780 gtk_clipboard_request_contents (gtk_clipboard_get (GDK_NONE),
2782 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2783 clipboard_clipboard_buffer_received, data);
2785 gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
2787 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2788 clipboard_selection_buffer_received, data);
2792 * gtk_text_buffer_paste_primary:
2793 * @buffer: a #GtkTextBuffer
2794 * @override_location: location to insert pasted text, or %NULL for at the cursor
2795 * @default_editable: whether the buffer is editable by default
2797 * Pastes the primary selection at the insertion point, or at @override_location.
2798 * (Note: pasting is asynchronous, that is, we'll ask for the paste data
2799 * and return, and at some point later after the main loop runs, the paste
2800 * data will be inserted.)
2803 gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
2804 const GtkTextIter *override_location,
2805 gboolean default_editable)
2807 if (override_location != NULL)
2808 gtk_text_buffer_create_mark (buffer,
2809 "gtk_paste_point_override",
2810 override_location, FALSE);
2812 paste (buffer, FALSE, TRUE, default_editable);
2816 * gtk_text_buffer_paste_clipboard:
2817 * @buffer: a #GtkTextBuffer
2818 * @default_editable: whether the buffer is editable by default
2820 * Pastes the clipboard contents at the insertion point. (Note:
2821 * pasting is asynchronous, that is, we'll ask for the paste data and
2822 * return, and at some point later after the main loop runs, the paste
2823 * data will be inserted.)
2827 gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
2828 gboolean default_editable)
2830 paste (buffer, TRUE, TRUE, default_editable);
2834 * gtk_text_buffer_delete_selection:
2835 * @buffer: a #GtkTextBuffer
2836 * @interactive: whether the deletion is caused by user interaction
2837 * @default_editable: whether the buffer is editable by default
2839 * Deletes the range between the "insert" and "selection_bound" marks,
2840 * that is, the currently-selected text. If @interactive is %TRUE,
2841 * the editability of the selection will be considered (users can't delete
2844 * Return value: whether there was a non-empty selection to delete
2847 gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
2848 gboolean interactive,
2849 gboolean default_editable)
2854 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2856 return FALSE; /* No selection */
2862 gtk_text_buffer_begin_user_action (buffer);
2863 gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable);
2864 gtk_text_buffer_end_user_action (buffer);
2867 gtk_text_buffer_delete (buffer, &start, &end);
2869 return TRUE; /* We deleted stuff */
2874 cut_or_copy (GtkTextBuffer *buffer,
2875 gboolean delete_region_after,
2876 gboolean interactive,
2877 gboolean default_editable)
2879 /* We prefer to cut the selected region between selection_bound and
2880 * insertion point. If that region is empty, then we cut the region
2881 * between the "anchor" and the insertion point (this is for
2882 * C-space and M-w and other Emacs-style copy/yank keys). Note that
2883 * insert and selection_bound are guaranteed to exist, but the
2884 * anchor only exists sometimes.
2889 if (buffer->clipboard_contents)
2891 g_object_unref (G_OBJECT (buffer->clipboard_contents));
2892 buffer->clipboard_contents = NULL;
2895 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2897 /* Let's try the anchor thing */
2898 GtkTextMark * anchor = gtk_text_buffer_get_mark (buffer, "anchor");
2904 gtk_text_buffer_get_iter_at_mark (buffer, &end, anchor);
2905 gtk_text_iter_reorder (&start, &end);
2909 if (!gtk_text_iter_equal (&start, &end))
2911 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
2914 buffer->clipboard_contents =
2915 gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
2917 gtk_text_buffer_get_iter_at_offset (buffer->clipboard_contents,
2920 gtk_text_buffer_insert_range (buffer->clipboard_contents,
2925 if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
2926 clipboard_get_contents_cb,
2927 clipboard_clear_contents_cb,
2929 clipboard_clear_contents_cb (clipboard, buffer);
2931 if (delete_region_after)
2934 gtk_text_buffer_delete_interactive (buffer, &start, &end,
2937 gtk_text_buffer_delete (buffer, &start, &end);
2943 * gtk_text_buffer_cut_clipboard:
2944 * @buffer: a #GtkTextBuffer
2945 * @default_editable: default editability of the buffer
2947 * Copies the currently-selected text to the clipboard, then deletes
2948 * said text if it's editable.
2952 gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
2953 gboolean default_editable)
2955 gtk_text_buffer_begin_user_action (buffer);
2956 cut_or_copy (buffer, TRUE, TRUE, default_editable);
2957 gtk_text_buffer_end_user_action (buffer);
2961 * gtk_text_buffer_copy_clipboard:
2962 * @buffer: a #GtkTextBuffer
2964 * Copies the currently-selected text to the clipboard.
2968 gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer)
2970 gtk_text_buffer_begin_user_action (buffer);
2971 cut_or_copy (buffer, FALSE, TRUE, TRUE);
2972 gtk_text_buffer_end_user_action (buffer);
2977 * gtk_text_buffer_get_selection_bounds:
2978 * @buffer: a #GtkTextBuffer a #GtkTextBuffer
2979 * @start: iterator to initialize with selection start
2980 * @end: iterator to initialize with selection end
2982 * Returns %TRUE if some text is selected; places the bounds
2983 * of the selection in @start and @end (if the selection has length 0,
2984 * then @start and @end are filled in with the same value).
2985 * @start and @end will be in ascending order. If @start and @end are
2986 * NULL, then they are not filled in, but the return value still indicates
2987 * whether text is selected.
2989 * Return value: whether the selection has nonzero length
2992 gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
2996 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2998 return _gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
3002 * gtk_text_buffer_begin_user_action:
3003 * @buffer: a #GtkTextBuffer
3005 * Called to indicate that the buffer operations between here and a
3006 * call to gtk_text_buffer_end_user_action() are part of a single
3007 * user-visible operation. The operations between
3008 * gtk_text_buffer_begin_user_action() and
3009 * gtk_text_buffer_end_user_action() can then be grouped when creating
3010 * an undo stack. #GtkTextBuffer maintains a count of calls to
3011 * gtk_text_buffer_begin_user_action() that have not been closed with
3012 * a call to gtk_text_buffer_end_user_action(), and emits the "begin_user_action"
3013 * and "end_user_action" signals only for the outermost pair of calls.
3014 * This allows you to build user actions from other user actions.
3016 * The "interactive" buffer mutation functions, such as
3017 * gtk_text_buffer_insert_interactive(), automatically call begin/end
3018 * user action around the buffer operations they perform, so there's
3019 * no need to add extra calls if you user action consists solely of a
3020 * single call to one of those functions.
3023 gtk_text_buffer_begin_user_action (GtkTextBuffer *buffer)
3025 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
3027 buffer->user_action_count += 1;
3029 if (buffer->user_action_count == 1)
3031 /* Outermost nested user action begin emits the signal */
3032 g_signal_emit (G_OBJECT (buffer), signals[BEGIN_USER_ACTION], 0);
3037 * gtk_text_buffer_end_user_action:
3038 * @buffer: a #GtkTextBuffer
3040 * Should be paired with a call to gtk_text_buffer_begin_user_action().
3041 * See that function for a full explanation.
3044 gtk_text_buffer_end_user_action (GtkTextBuffer *buffer)
3046 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
3047 g_return_if_fail (buffer->user_action_count > 0);
3049 buffer->user_action_count -= 1;
3051 if (buffer->user_action_count == 0)
3053 /* Ended the outermost-nested user action end, so emit the signal */
3054 g_signal_emit (G_OBJECT (buffer), signals[END_USER_ACTION], 0);
3059 * Logical attribute cache
3062 #define ATTR_CACHE_SIZE 2
3064 typedef struct _CacheEntry CacheEntry;
3069 PangoLogAttr *attrs;
3073 struct _GtkTextLogAttrCache
3075 gint chars_changed_stamp;
3076 CacheEntry entries[ATTR_CACHE_SIZE];
3080 free_log_attr_cache (GtkTextLogAttrCache *cache)
3083 while (i < ATTR_CACHE_SIZE)
3085 g_free (cache->entries[i].attrs);
3092 clear_log_attr_cache (GtkTextLogAttrCache *cache)
3095 while (i < ATTR_CACHE_SIZE)
3097 g_free (cache->entries[i].attrs);
3098 cache->entries[i].attrs = NULL;
3103 static PangoLogAttr*
3104 compute_log_attrs (const GtkTextIter *iter,
3110 gint char_len, byte_len;
3111 PangoLogAttr *attrs = NULL;
3117 gtk_text_iter_set_line_offset (&start, 0);
3118 gtk_text_iter_forward_line (&end);
3120 paragraph = gtk_text_iter_get_slice (&start, &end);
3121 char_len = g_utf8_strlen (paragraph, -1);
3122 byte_len = strlen (paragraph);
3124 g_assert (char_len > 0);
3127 *char_lenp = char_len;
3129 attrs = g_new (PangoLogAttr, char_len);
3131 lang = gtk_text_iter_get_language (&start);
3133 pango_get_log_attrs (paragraph, byte_len, -1,
3144 /* The return value from this is valid until you call this a second time.
3147 _gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer,
3148 const GtkTextIter *anywhere_in_line,
3152 GtkTextLogAttrCache *cache;
3155 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
3156 g_return_val_if_fail (anywhere_in_line != NULL, NULL);
3157 g_return_val_if_fail (!gtk_text_iter_is_end (anywhere_in_line), NULL);
3159 /* FIXME we also need to recompute log attrs if the language tag at
3160 * the start of a paragraph changes
3163 if (buffer->log_attr_cache == NULL)
3165 buffer->log_attr_cache = g_new0 (GtkTextLogAttrCache, 1);
3166 buffer->log_attr_cache->chars_changed_stamp =
3167 _gtk_text_btree_get_chars_changed_stamp (get_btree (buffer));
3169 else if (buffer->log_attr_cache->chars_changed_stamp !=
3170 _gtk_text_btree_get_chars_changed_stamp (get_btree (buffer)))
3172 clear_log_attr_cache (buffer->log_attr_cache);
3175 cache = buffer->log_attr_cache;
3176 line = gtk_text_iter_get_line (anywhere_in_line);
3179 while (i < ATTR_CACHE_SIZE)
3181 if (cache->entries[i].attrs &&
3182 cache->entries[i].line == line)
3185 *char_len = cache->entries[i].char_len;
3186 return cache->entries[i].attrs;
3191 /* Not in cache; open up the first cache entry */
3192 if (cache->entries[ATTR_CACHE_SIZE-1].attrs)
3193 g_free (cache->entries[ATTR_CACHE_SIZE-1].attrs);
3195 g_memmove (cache->entries + 1, cache->entries,
3196 sizeof (CacheEntry) * (ATTR_CACHE_SIZE - 1));
3198 cache->entries[0].line = line;
3199 cache->entries[0].attrs = compute_log_attrs (anywhere_in_line,
3200 &cache->entries[0].char_len);
3203 *char_len = cache->entries[0].char_len;
3205 return cache->entries[0].attrs;
3213 _gtk_text_buffer_spew (GtkTextBuffer *buffer)
3215 _gtk_text_btree_spew (get_btree (buffer));