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_return_if_fail (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);
514 g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
516 gtk_text_buffer_emit_insert (buffer, iter, text, len);
520 * gtk_text_buffer_insert_at_cursor:
521 * @buffer: a #GtkTextBuffer
522 * @text: some text in UTF-8 format
523 * @len: length of text, in bytes
525 * Simply calls gtk_text_buffer_insert (), using the current
526 * cursor position as the insertion point.
529 gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buffer,
535 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
536 g_return_if_fail (text != NULL);
538 gtk_text_buffer_get_iter_at_mark (buffer, &iter,
539 gtk_text_buffer_get_mark (buffer,
542 gtk_text_buffer_insert (buffer, &iter, text, len);
546 * gtk_text_buffer_insert_interactive:
547 * @buffer: a #GtkTextBuffer
548 * @iter: a position in @buffer
549 * @text: some UTF-8 text
550 * @len: length of text in bytes, or -1
551 * @default_editable: default editability of buffer
553 * Like gtk_text_buffer_insert (), but the insertion will not occur if
554 * @iter is at a non-editable location in the buffer. Usually you
555 * want to prevent insertions at ineditable locations if the insertion
556 * results from a user action (is interactive).
558 * @default_editable indicates the editability of text that doesn't
559 * have a tag affecting editability applied to it. Typically the
560 * result of gtk_text_view_get_editable() is appropriate here.
562 * Return value: whether text was actually inserted
565 gtk_text_buffer_insert_interactive (GtkTextBuffer *buffer,
569 gboolean default_editable)
571 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
572 g_return_val_if_fail (text != NULL, FALSE);
573 g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == buffer, FALSE);
575 if (gtk_text_iter_editable (iter, default_editable))
577 gtk_text_buffer_begin_user_action (buffer);
578 gtk_text_buffer_emit_insert (buffer, iter, text, len);
579 gtk_text_buffer_end_user_action (buffer);
587 * gtk_text_buffer_insert_interactive_at_cursor:
588 * @buffer: a #GtkTextBuffer
589 * @text: text in UTF-8 format
590 * @len: length of text in bytes, or -1
591 * @default_editable: default editability of buffer
593 * Calls gtk_text_buffer_insert_interactive () at the cursor
596 * @default_editable indicates the editability of text that doesn't
597 * have a tag affecting editability applied to it. Typically the
598 * result of gtk_text_view_get_editable() is appropriate here.
600 * Return value: whether text was actually inserted
603 gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
606 gboolean default_editable)
610 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
611 g_return_val_if_fail (text != NULL, FALSE);
613 gtk_text_buffer_get_iter_at_mark (buffer, &iter,
614 gtk_text_buffer_get_mark (buffer,
617 return gtk_text_buffer_insert_interactive (buffer, &iter, text, len,
622 possibly_not_text (gunichar ch,
625 return ch == GTK_TEXT_UNKNOWN_CHAR;
629 insert_text_range (GtkTextBuffer *buffer,
631 const GtkTextIter *orig_start,
632 const GtkTextIter *orig_end,
633 gboolean interactive)
637 text = gtk_text_iter_get_text (orig_start, orig_end);
639 gtk_text_buffer_emit_insert (buffer, iter, text, -1);
644 typedef struct _Range Range;
647 GtkTextBuffer *buffer;
648 GtkTextMark *start_mark;
649 GtkTextMark *end_mark;
650 GtkTextMark *whole_end_mark;
651 GtkTextIter *range_start;
652 GtkTextIter *range_end;
653 GtkTextIter *whole_end;
657 save_range (GtkTextIter *range_start,
658 GtkTextIter *range_end,
659 GtkTextIter *whole_end)
663 r = g_new (Range, 1);
665 r->buffer = gtk_text_iter_get_buffer (range_start);
666 g_object_ref (G_OBJECT (r->buffer));
669 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
674 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
680 gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (range_start),
685 r->range_start = range_start;
686 r->range_end = range_end;
687 r->whole_end = whole_end;
693 restore_range (Range *r)
695 gtk_text_buffer_get_iter_at_mark (r->buffer,
699 gtk_text_buffer_get_iter_at_mark (r->buffer,
703 gtk_text_buffer_get_iter_at_mark (r->buffer,
707 gtk_text_buffer_delete_mark (r->buffer, r->start_mark);
708 gtk_text_buffer_delete_mark (r->buffer, r->end_mark);
709 gtk_text_buffer_delete_mark (r->buffer, r->whole_end_mark);
711 g_object_unref (G_OBJECT (r->buffer));
716 insert_range_untagged (GtkTextBuffer *buffer,
718 const GtkTextIter *orig_start,
719 const GtkTextIter *orig_end,
720 gboolean interactive)
722 GtkTextIter range_start;
723 GtkTextIter range_end;
724 GtkTextIter start, end;
725 GtkTextBuffer *src_buffer;
728 if (gtk_text_iter_equal (orig_start, orig_end))
734 src_buffer = gtk_text_iter_get_buffer (&start);
741 if (gtk_text_iter_equal (&range_start, &range_end))
743 /* Figure out how to move forward */
745 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
747 if (gtk_text_iter_equal (&range_end, &end))
749 /* nothing left to do */
752 else if (gtk_text_iter_get_char (&range_end) == GTK_TEXT_UNKNOWN_CHAR)
754 GdkPixbuf *pixbuf = NULL;
755 GtkTextChildAnchor *anchor = NULL;
756 pixbuf = gtk_text_iter_get_pixbuf (&range_end);
757 anchor = gtk_text_iter_get_child_anchor (&range_end);
761 r = save_range (&range_start,
765 gtk_text_buffer_insert_pixbuf (buffer,
772 gtk_text_iter_forward_char (&range_end);
774 range_start = range_end;
778 /* Just skip anchors */
780 gtk_text_iter_forward_char (&range_end);
781 range_start = range_end;
785 /* The GTK_TEXT_UNKNOWN_CHAR was in a text segment, so
788 gtk_text_iter_forward_find_char (&range_end,
789 possibly_not_text, NULL,
792 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
797 /* Text segment starts here, so forward search to
798 * find its possible endpoint
800 gtk_text_iter_forward_find_char (&range_end,
801 possibly_not_text, NULL,
804 g_assert (gtk_text_iter_compare (&range_end, &end) <= 0);
809 r = save_range (&range_start,
813 insert_text_range (buffer,
822 range_start = range_end;
828 gtk_text_buffer_real_insert_range (GtkTextBuffer *buffer,
830 const GtkTextIter *orig_start,
831 const GtkTextIter *orig_end,
832 gboolean interactive)
834 /* Find each range of uniformly-tagged text, insert it,
835 * then apply the tags.
837 GtkTextIter start = *orig_start;
838 GtkTextIter end = *orig_end;
839 GtkTextIter range_start;
840 GtkTextIter range_end;
841 GtkTextBuffer *src_buffer;
844 if (gtk_text_iter_equal (orig_start, orig_end))
848 gtk_text_buffer_begin_user_action (buffer);
850 src_buffer = gtk_text_iter_get_buffer (orig_start);
852 gtk_text_iter_order (&start, &end);
860 GtkTextIter start_iter;
864 if (gtk_text_iter_equal (&range_start, &end))
865 break; /* All done */
867 g_assert (gtk_text_iter_compare (&range_start, &end) < 0);
869 gtk_text_iter_forward_to_tag_toggle (&range_end, NULL);
871 g_assert (!gtk_text_iter_equal (&range_start, &range_end));
873 /* Clamp to the end iterator */
874 if (gtk_text_iter_compare (&range_end, &end) > 0)
877 /* We have a range with unique tags; insert it, and
880 start_offset = gtk_text_iter_get_offset (iter);
882 r = save_range (&range_start, &range_end, &end);
884 insert_range_untagged (buffer, iter, &range_start, &range_end, interactive);
889 gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start_offset);
891 tags = gtk_text_iter_get_tags (&range_start);
893 while (tmp_list != NULL)
895 gtk_text_buffer_apply_tag (buffer,
900 tmp_list = g_slist_next (tmp_list);
904 range_start = range_end;
908 gtk_text_buffer_end_user_action (buffer);
912 * gtk_text_buffer_insert_range:
913 * @buffer: a #GtkTextBuffer
914 * @iter: a position in @buffer
915 * @start: a position in a #GtkTextBuffer
916 * @end: another position in the same buffer as @start
918 * Copies text, tags, and pixbufs between @start and @end (the order
919 * of @start and @end doesn't matter) and inserts the copy at @iter.
920 * Used instead of simply getting/inserting text because it preserves
921 * images and tags. If @start and @end are in a different buffer from
922 * @buffer, the two buffers must share the same tag table.
924 * Implemented via emissions of the insert_text and apply_tag signals,
928 gtk_text_buffer_insert_range (GtkTextBuffer *buffer,
930 const GtkTextIter *start,
931 const GtkTextIter *end)
933 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
934 g_return_if_fail (iter != NULL);
935 g_return_if_fail (start != NULL);
936 g_return_if_fail (end != NULL);
937 g_return_if_fail (gtk_text_iter_get_buffer (start) ==
938 gtk_text_iter_get_buffer (end));
939 g_return_if_fail (gtk_text_iter_get_buffer (start)->tag_table ==
941 g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
943 gtk_text_buffer_real_insert_range (buffer, iter, start, end, FALSE);
947 * gtk_text_buffer_insert_range_interactive:
948 * @buffer: a #GtkTextBuffer
949 * @iter: a position in @buffer
950 * @start: a position in a #GtkTextBuffer
951 * @end: another position in the same buffer as @start
952 * @default_editable: default editability of the buffer
954 * Same as gtk_text_buffer_insert_range(), but does nothing if the
955 * insertion point isn't editable. The @default_editable parameter
956 * indicates whether the text is editable at @iter if no tags
957 * enclosing @iter affect editability. Typically the result of
958 * gtk_text_view_get_editable() is appropriate here.
960 * Returns: whether an insertion was possible at @iter
963 gtk_text_buffer_insert_range_interactive (GtkTextBuffer *buffer,
965 const GtkTextIter *start,
966 const GtkTextIter *end,
967 gboolean default_editable)
969 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
970 g_return_val_if_fail (iter != NULL, FALSE);
971 g_return_val_if_fail (start != NULL, FALSE);
972 g_return_val_if_fail (end != NULL, FALSE);
973 g_return_val_if_fail (gtk_text_iter_get_buffer (start) ==
974 gtk_text_iter_get_buffer (end), FALSE);
975 g_return_val_if_fail (gtk_text_iter_get_buffer (start)->tag_table ==
976 buffer->tag_table, FALSE);
979 if (gtk_text_iter_editable (iter, default_editable))
981 gtk_text_buffer_real_insert_range (buffer, iter, start, end, TRUE);
989 * gtk_text_buffer_insert_with_tags:
990 * @buffer: a #GtkTextBuffer
991 * @iter: an iterator in @buffer
993 * @len: length of @text, or -1
994 * @first_tag: first tag to apply to @text
995 * @Varargs: NULL-terminated list of tags to apply
997 * Inserts @text into @buffer at @iter, applying the list of tags to
998 * the newly-inserted text. The last tag specified must be NULL to
999 * terminate the list. Equivalent to calling gtk_text_buffer_insert (),
1000 * then gtk_text_buffer_apply_tag () on the inserted text;
1001 * gtk_text_buffer_insert_with_tags () is just a convenience function.
1004 gtk_text_buffer_insert_with_tags (GtkTextBuffer *buffer,
1008 GtkTextTag *first_tag,
1016 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1017 g_return_if_fail (iter != NULL);
1018 g_return_if_fail (text != NULL);
1019 g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
1021 start_offset = gtk_text_iter_get_offset (iter);
1023 gtk_text_buffer_insert (buffer, iter, text, len);
1025 if (first_tag == NULL)
1028 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1030 va_start (args, first_tag);
1034 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
1036 tag = va_arg (args, GtkTextTag*);
1043 * gtk_text_buffer_insert_with_tags_by_name:
1044 * @buffer: a #GtkTextBuffer
1045 * @iter: position in @buffer
1047 * @len: length of @text, or -1
1048 * @first_tag_name: name of a tag to apply to @text
1049 * @Varargs: more tag names
1051 * Same as gtk_text_buffer_insert_with_tags (), but allows you
1052 * to pass in tag names instead of tag objects.
1055 gtk_text_buffer_insert_with_tags_by_name (GtkTextBuffer *buffer,
1059 const gchar *first_tag_name,
1065 const gchar *tag_name;
1067 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1068 g_return_if_fail (iter != NULL);
1069 g_return_if_fail (text != NULL);
1070 g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
1072 start_offset = gtk_text_iter_get_offset (iter);
1074 gtk_text_buffer_insert (buffer, iter, text, len);
1076 if (first_tag_name == NULL)
1079 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1081 va_start (args, first_tag_name);
1082 tag_name = first_tag_name;
1087 tag = gtk_text_tag_table_lookup (buffer->tag_table,
1092 g_warning ("%s: no tag with name '%s'!", G_STRLOC, tag_name);
1096 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
1098 tag_name = va_arg (args, const gchar*);
1110 gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
1114 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1115 g_return_if_fail (start != NULL);
1116 g_return_if_fail (end != NULL);
1118 _gtk_text_btree_delete (start, end);
1120 /* may have deleted the selection... */
1121 gtk_text_buffer_update_primary_selection (buffer);
1123 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1127 gtk_text_buffer_emit_delete (GtkTextBuffer *buffer,
1131 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1132 g_return_if_fail (start != NULL);
1133 g_return_if_fail (end != NULL);
1135 if (gtk_text_iter_equal (start, end))
1138 gtk_text_iter_order (start, end);
1140 /* Somewhat annoyingly, if you try to delete the final newline
1141 * the BTree will put it back; which means you can't deduce the
1142 * final contents of the buffer purely by monitoring insert/delete
1143 * signals on the buffer. But if you delete the final newline, any
1144 * tags on the newline will go away, oddly. See comment in
1145 * gtktextbtree.c. This is all sort of annoying, but really hard
1148 g_signal_emit (G_OBJECT (buffer),
1149 signals[DELETE_RANGE],
1155 * gtk_text_buffer_delete:
1156 * @buffer: a #GtkTextBuffer
1157 * @start: a position in @buffer
1158 * @end: another position in @buffer
1160 * Deletes text between @start and @end. The order of @start and @end
1161 * is not actually relevant; gtk_text_buffer_delete () will reorder
1162 * them. This function actually emits the "delete_range" signal, and
1163 * the default handler of that signal deletes the text. Because the
1164 * buffer is modified, all outstanding iterators become invalid after
1165 * calling this function; however, the @start and @end will be
1166 * re-initialized to point to the location where text was deleted.
1168 * Note that the final newline in the buffer may not be deleted; a
1169 * #GtkTextBuffer always contains at least one newline. You can
1170 * safely include the final newline in the range [@start,@end) but it
1171 * won't be affected by the deletion.
1175 gtk_text_buffer_delete (GtkTextBuffer *buffer,
1179 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1180 g_return_if_fail (start != NULL);
1181 g_return_if_fail (end != NULL);
1182 g_return_if_fail (gtk_text_iter_get_buffer (start) == buffer);
1183 g_return_if_fail (gtk_text_iter_get_buffer (end) == buffer);
1185 gtk_text_buffer_emit_delete (buffer, start, end);
1189 * gtk_text_buffer_delete_interactive:
1190 * @buffer: a #GtkTextBuffer
1191 * @start_iter: start of range to delete
1192 * @end_iter: end of range
1193 * @default_editable: whether the buffer is editable by default
1195 * Deletes all <emphasis>editable</emphasis> text in the given range.
1196 * Calls gtk_text_buffer_delete () for each editable sub-range of
1197 * [@start,@end). @start and @end are revalidated to point to
1198 * the location of the last deleted range, or left untouched if
1199 * no text was deleted.
1201 * Return value: whether some text was actually deleted
1204 gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
1205 GtkTextIter *start_iter,
1206 GtkTextIter *end_iter,
1207 gboolean default_editable)
1209 GtkTextMark *end_mark;
1210 GtkTextMark *start_mark;
1212 gboolean current_state;
1213 gboolean deleted_stuff = FALSE;
1215 /* Delete all editable text in the range start_iter, end_iter */
1217 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1218 g_return_val_if_fail (start_iter != NULL, FALSE);
1219 g_return_val_if_fail (end_iter != NULL, FALSE);
1220 g_return_val_if_fail (gtk_text_iter_get_buffer (start_iter) == buffer, FALSE);
1221 g_return_val_if_fail (gtk_text_iter_get_buffer (end_iter) == buffer, FALSE);
1224 gtk_text_buffer_begin_user_action (buffer);
1226 gtk_text_iter_order (start_iter, end_iter);
1228 start_mark = gtk_text_buffer_create_mark (buffer, NULL,
1230 end_mark = gtk_text_buffer_create_mark (buffer, NULL,
1234 current_state = gtk_text_iter_editable (&iter, default_editable);
1239 gboolean done = FALSE;
1242 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
1244 gtk_text_buffer_get_iter_at_mark (buffer, &end, end_mark);
1246 if (gtk_text_iter_compare (&iter, &end) >= 0)
1249 iter = end; /* clamp to the last boundary */
1252 new_state = gtk_text_iter_editable (&iter, default_editable);
1254 if (current_state == new_state)
1260 /* We're ending an editable region. Delete said region. */
1263 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
1265 gtk_text_buffer_emit_delete (buffer, &start, &iter);
1267 deleted_stuff = TRUE;
1269 /* revalidate user's iterators. */
1270 *start_iter = start;
1280 if (current_state && !new_state)
1282 /* End of an editable region. Delete it. */
1285 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
1287 gtk_text_buffer_emit_delete (buffer, &start, &iter);
1289 current_state = FALSE;
1290 deleted_stuff = TRUE;
1292 /* revalidate user's iterators. */
1293 *start_iter = start;
1298 /* We are at the start of an editable region. We won't be deleting
1299 * the previous region. Move start mark to start of this region.
1302 g_assert (!current_state && new_state);
1304 gtk_text_buffer_move_mark (buffer, start_mark,
1308 current_state = TRUE;
1316 gtk_text_buffer_delete_mark (buffer, start_mark);
1317 gtk_text_buffer_delete_mark (buffer, end_mark);
1319 gtk_text_buffer_end_user_action (buffer);
1321 return deleted_stuff;
1325 * Extracting textual buffer contents
1329 * gtk_text_buffer_get_text:
1330 * @buffer: a #GtkTextBuffer
1331 * @start: start of a range
1332 * @end: end of a range
1333 * @include_hidden_chars: whether to include invisible text
1335 * Returns the text in the range [@start,@end). Excludes undisplayed
1336 * text (text marked with tags that set the invisibility attribute) if
1337 * @include_hidden_chars is FALSE. Does not include characters
1338 * representing embedded images, so byte and character indexes into
1339 * the returned string do <emphasis>not</emphasis> correspond to byte
1340 * and character indexes into the buffer. Contrast with
1341 * gtk_text_buffer_get_slice ().
1343 * Return value: an allocated UTF-8 string
1346 gtk_text_buffer_get_text (GtkTextBuffer *buffer,
1347 const GtkTextIter *start,
1348 const GtkTextIter *end,
1349 gboolean include_hidden_chars)
1351 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1352 g_return_val_if_fail (start != NULL, NULL);
1353 g_return_val_if_fail (end != NULL, NULL);
1354 g_return_val_if_fail (gtk_text_iter_get_buffer (start) == buffer, NULL);
1355 g_return_val_if_fail (gtk_text_iter_get_buffer (end) == buffer, NULL);
1357 if (include_hidden_chars)
1358 return gtk_text_iter_get_text (start, end);
1360 return gtk_text_iter_get_visible_text (start, end);
1364 * gtk_text_buffer_get_slice:
1365 * @buffer: a #GtkTextBuffer
1366 * @start: start of a range
1367 * @end: end of a range
1368 * @include_hidden_chars: whether to include invisible text
1370 * Returns the text in the range [@start,@end). Excludes undisplayed
1371 * text (text marked with tags that set the invisibility attribute) if
1372 * @include_hidden_chars is FALSE. The returned string includes a
1373 * 0xFFFC character whenever the buffer contains
1374 * embedded images, so byte and character indexes into
1375 * the returned string <emphasis>do</emphasis> correspond to byte
1376 * and character indexes into the buffer. Contrast with
1377 * gtk_text_buffer_get_text (). Note that 0xFFFC can occur in normal
1378 * text as well, so it is not a reliable indicator that a pixbuf or
1379 * widget is in the buffer.
1381 * Return value: an allocated UTF-8 string
1384 gtk_text_buffer_get_slice (GtkTextBuffer *buffer,
1385 const GtkTextIter *start,
1386 const GtkTextIter *end,
1387 gboolean include_hidden_chars)
1389 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1390 g_return_val_if_fail (start != NULL, NULL);
1391 g_return_val_if_fail (end != NULL, NULL);
1392 g_return_val_if_fail (gtk_text_iter_get_buffer (start) == buffer, NULL);
1393 g_return_val_if_fail (gtk_text_iter_get_buffer (end) == buffer, NULL);
1395 if (include_hidden_chars)
1396 return gtk_text_iter_get_slice (start, end);
1398 return gtk_text_iter_get_visible_slice (start, end);
1406 gtk_text_buffer_real_insert_pixbuf (GtkTextBuffer *buffer,
1410 _gtk_text_btree_insert_pixbuf (iter, pixbuf);
1412 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1416 * gtk_text_buffer_insert_pixbuf:
1417 * @buffer: a #GtkTextBuffer
1418 * @iter: location to insert the pixbuf
1419 * @pixbuf: a #GdkPixbuf
1421 * Inserts an image into the text buffer at @iter. The image will be
1422 * counted as one character in character counts, and when obtaining
1423 * the buffer contents as a string, will be represented by the Unicode
1424 * "object replacement character" 0xFFFC. Note that the "slice"
1425 * variants for obtaining portions of the buffer as a string include
1426 * this character for pixbufs, but the "text" variants do
1427 * not. e.g. see gtk_text_buffer_get_slice() and
1428 * gtk_text_buffer_get_text().
1432 gtk_text_buffer_insert_pixbuf (GtkTextBuffer *buffer,
1436 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1437 g_return_if_fail (iter != NULL);
1438 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
1439 g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
1441 g_signal_emit (G_OBJECT (buffer), signals[INSERT_PIXBUF], 0,
1451 gtk_text_buffer_real_insert_anchor (GtkTextBuffer *buffer,
1453 GtkTextChildAnchor *anchor)
1455 _gtk_text_btree_insert_child_anchor (iter, anchor);
1457 g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
1461 * gtk_text_buffer_insert_child_anchor:
1462 * @buffer: a #GtkTextBuffer
1463 * @iter: location to insert the anchor
1464 * @anchor: a #GtkTextChildAnchor
1466 * Inserts a child widget anchor into the text buffer at @iter. The
1467 * anchor will be counted as one character in character counts, and
1468 * when obtaining the buffer contents as a string, will be represented
1469 * by the Unicode "object replacement character" 0xFFFC. Note that the
1470 * "slice" variants for obtaining portions of the buffer as a string
1471 * include this character for pixbufs, but the "text" variants do
1472 * not. e.g. see gtk_text_buffer_get_slice() and
1473 * gtk_text_buffer_get_text(). Consider
1474 * gtk_text_buffer_create_child_anchor() as a more convenient
1475 * alternative to this function. The buffer will add a reference to
1476 * the anchor, so you can unref it after insertion.
1480 gtk_text_buffer_insert_child_anchor (GtkTextBuffer *buffer,
1482 GtkTextChildAnchor *anchor)
1484 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1485 g_return_if_fail (iter != NULL);
1486 g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor));
1487 g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
1489 g_signal_emit (G_OBJECT (buffer), signals[INSERT_CHILD_ANCHOR], 0,
1495 * gtk_text_buffer_create_child_anchor:
1496 * @buffer: a #GtkTextBuffer
1497 * @iter: location in the buffer
1499 * This is a convenience function which simply creates a child anchor
1500 * with gtk_text_child_anchor_new() and inserts it into the buffer
1501 * with gtk_text_buffer_insert_child_anchor().
1503 * Return value: the created child anchor
1506 gtk_text_buffer_create_child_anchor (GtkTextBuffer *buffer,
1509 GtkTextChildAnchor *anchor;
1511 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1512 g_return_val_if_fail (iter != NULL, NULL);
1513 g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == buffer, NULL);
1515 anchor = gtk_text_child_anchor_new ();
1517 gtk_text_buffer_insert_child_anchor (buffer, iter, anchor);
1519 g_object_unref (G_OBJECT (anchor));
1529 gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
1530 const GtkTextIter *location,
1533 /* IMO this should NOT work like insert_text and delete_range,
1534 where the real action happens in the default handler.
1536 The reason is that the default handler would be _required_,
1537 i.e. the whole widget would start breaking and segfaulting
1538 if the default handler didn't get run. So you can't really
1539 override the default handler or stop the emission; that is,
1540 this signal is purely for notification, and not to allow users
1541 to modify the default behavior. */
1543 g_object_ref (G_OBJECT (mark));
1545 g_signal_emit (G_OBJECT (buffer),
1551 g_object_unref (G_OBJECT (mark));
1555 * gtk_text_buffer_set_mark:
1556 * @buffer: a #GtkTextBuffer
1557 * @mark_name: name of the mark
1558 * @iter: location for the mark.
1559 * @left_gravity: if the mark is created by this function, gravity for the new
1561 * @should_exist: if %TRUE, warn if the mark does not exist, and return
1564 * Move the mark to the given position, if not @should_exist, create the mark.
1566 * Return value: mark
1569 gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
1570 GtkTextMark *existing_mark,
1571 const gchar *mark_name,
1572 const GtkTextIter *iter,
1573 gboolean left_gravity,
1574 gboolean should_exist)
1576 GtkTextIter location;
1579 g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == buffer, NULL);
1581 mark = _gtk_text_btree_set_mark (get_btree (buffer),
1588 if (_gtk_text_btree_mark_is_insert (get_btree (buffer), mark) ||
1589 _gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
1591 gtk_text_buffer_update_primary_selection (buffer);
1594 _gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1598 gtk_text_buffer_mark_set (buffer, &location, mark);
1604 * gtk_text_buffer_create_mark:
1605 * @buffer: a #GtkTextBuffer
1606 * @mark_name: name for mark, or %NULL
1607 * @where: location to place mark
1608 * @left_gravity: whether the mark has left gravity
1610 * Creates a mark at position @where. If @mark_name is %NULL, the mark
1611 * is anonymous; otherwise, the mark can be retrieved by name using
1612 * gtk_text_buffer_get_mark (). If a mark has left gravity, and text is
1613 * inserted at the mark's current location, the mark will be moved to
1614 * the left of the newly-inserted text. If the mark has right gravity
1615 * (@left_gravity = %FALSE), the mark will end up on the right of
1616 * newly-inserted text. The standard left-to-right cursor is a mark
1617 * with right gravity (when you type, the cursor stays on the right
1618 * side of the text you're typing).
1620 * The caller of this function does <emphasis>not</emphasis> own a reference
1621 * to the returned #GtkTextMark, so you can ignore the return value
1622 * if you like. Marks are owned by the buffer and go away when the
1625 * Emits the "mark_set" signal as notification of the mark's initial
1628 * Return value: the new #GtkTextMark object
1631 gtk_text_buffer_create_mark (GtkTextBuffer *buffer,
1632 const gchar *mark_name,
1633 const GtkTextIter *where,
1634 gboolean left_gravity)
1636 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1638 return gtk_text_buffer_set_mark (buffer, NULL, mark_name, where,
1639 left_gravity, FALSE);
1643 * gtk_text_buffer_move_mark:
1644 * @buffer: a #GtkTextBuffer
1645 * @mark: a #GtkTextMark
1646 * @where: new location for @mark in @buffer
1648 * Moves @mark to the new location @where. Emits the "mark_set" signal
1649 * as notification of the move.
1652 gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
1654 const GtkTextIter *where)
1656 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1657 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1658 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1660 gtk_text_buffer_set_mark (buffer, mark, NULL, where, FALSE, TRUE);
1664 * gtk_text_buffer_get_iter_at_mark:
1665 * @buffer: a #GtkTextBuffer
1666 * @iter: iterator to initialize
1667 * @mark: a #GtkTextMark in @buffer
1669 * Initializes @iter with the current position of @mark.
1672 gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
1676 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1677 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1678 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1680 _gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1686 * gtk_text_buffer_delete_mark:
1687 * @buffer: a #GtkTextBuffer
1688 * @mark: a #GtkTextMark in @buffer
1690 * Deletes @mark, so that it's no longer located anywhere in the
1691 * buffer. Removes the reference the buffer holds to the mark, so if
1692 * you haven't called g_object_ref () on the mark, it will be freed. Even
1693 * if the mark isn't freed, most operations on @mark become
1694 * invalid. There is no way to undelete a
1695 * mark. gtk_text_mark_get_deleted () will return TRUE after this
1696 * function has been called on a mark; gtk_text_mark_get_deleted ()
1697 * indicates that a mark no longer belongs to a buffer. The "mark_deleted"
1698 * signal will be emitted as notification after the mark is deleted.
1701 gtk_text_buffer_delete_mark (GtkTextBuffer *buffer,
1704 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1705 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1706 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1708 g_object_ref (G_OBJECT (mark));
1710 _gtk_text_btree_remove_mark (get_btree (buffer), mark);
1712 /* See rationale above for MARK_SET on why we emit this after
1713 * removing the mark, rather than removing the mark in a default
1716 g_signal_emit (G_OBJECT (buffer), signals[MARK_DELETED],
1720 g_object_unref (G_OBJECT (mark));
1724 * gtk_text_buffer_get_mark:
1725 * @buffer: a #GtkTextBuffer
1726 * @name: a mark name
1728 * Returns the mark named @name in buffer @buffer, or NULL if no such
1729 * mark exists in the buffer.
1731 * Return value: a #GtkTextMark, or NULL
1734 gtk_text_buffer_get_mark (GtkTextBuffer *buffer,
1739 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1740 g_return_val_if_fail (name != NULL, NULL);
1742 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1749 * gtk_text_buffer_move_mark_by_name:
1750 * @buffer: a #GtkTextBuffer
1751 * @name: name of a mark
1752 * @where: new location for mark
1754 * Moves the mark named @name (which must exist) to location @where.
1755 * See gtk_text_buffer_move_mark () for details.
1758 gtk_text_buffer_move_mark_by_name (GtkTextBuffer *buffer,
1760 const GtkTextIter *where)
1764 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1765 g_return_if_fail (name != NULL);
1767 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1771 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1775 gtk_text_buffer_move_mark (buffer, mark, where);
1779 * gtk_text_buffer_delete_mark_by_name:
1780 * @buffer: a #GtkTextBuffer
1781 * @name: name of a mark in @buffer
1783 * Deletes the mark named @name; the mark must exist. See
1784 * gtk_text_buffer_delete_mark () for details.
1787 gtk_text_buffer_delete_mark_by_name (GtkTextBuffer *buffer,
1792 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1793 g_return_if_fail (name != NULL);
1795 mark = _gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1799 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1803 gtk_text_buffer_delete_mark (buffer, mark);
1807 * gtk_text_buffer_get_insert:
1808 * @buffer: a #GtkTextBuffer
1810 * Returns the mark that represents the cursor (insertion point).
1811 * Equivalent to calling gtk_text_buffer_get_mark () to get the mark
1812 * name "insert," but very slightly more efficient, and involves less
1815 * Return value: insertion point mark
1818 gtk_text_buffer_get_insert (GtkTextBuffer *buffer)
1820 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1822 /* FIXME use struct member in btree */
1823 return gtk_text_buffer_get_mark (buffer, "insert");
1827 * gtk_text_buffer_get_selection_bound:
1828 * @buffer: a #GtkTextBuffer
1830 * Returns the mark that represents the selection bound. Equivalent
1831 * to calling gtk_text_buffer_get_mark () to get the mark name
1832 * "selection_bound," but very slightly more efficient, and involves
1835 * The currently-selected text in @buffer is the region between the
1836 * "selection_bound" and "insert" marks. If "selection_bound" and
1837 * "insert" are in the same place, then there is no current selection.
1838 * gtk_text_buffer_get_selection_bounds () is another convenient function
1839 * for handling the selection, if you just want to know whether there's a
1840 * selection and what its bounds are.
1842 * Return value: selection bound mark
1845 gtk_text_buffer_get_selection_bound (GtkTextBuffer *buffer)
1847 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1849 /* FIXME use struct member in btree */
1850 return gtk_text_buffer_get_mark (buffer, "selection_bound");
1854 gtk_text_buffer_get_iter_at_child_anchor (GtkTextBuffer *buffer,
1856 GtkTextChildAnchor *anchor)
1858 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1859 g_return_if_fail (iter != NULL);
1860 g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor));
1861 g_return_if_fail (!gtk_text_child_anchor_get_deleted (anchor));
1863 _gtk_text_btree_get_iter_at_child_anchor (get_btree (buffer),
1869 * gtk_text_buffer_place_cursor:
1870 * @buffer: a #GtkTextBuffer
1871 * @where: where to put the cursor
1873 * This function moves the "insert" and "selection_bound" marks
1874 * simultaneously. If you move them to the same place in two steps
1875 * with gtk_text_buffer_move_mark (), you will temporarily select a
1876 * region in between their old and new locations, which can be pretty
1877 * inefficient since the temporarily-selected region will force stuff
1878 * to be recalculated. This function moves them as a unit, which can
1882 gtk_text_buffer_place_cursor (GtkTextBuffer *buffer,
1883 const GtkTextIter *where)
1887 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1891 if (gtk_text_iter_is_end (&real))
1892 gtk_text_iter_backward_char (&real);
1894 _gtk_text_btree_place_cursor (get_btree (buffer), &real);
1895 gtk_text_buffer_mark_set (buffer, &real,
1896 gtk_text_buffer_get_mark (buffer,
1898 gtk_text_buffer_mark_set (buffer, &real,
1899 gtk_text_buffer_get_mark (buffer,
1900 "selection_bound"));
1908 * gtk_text_buffer_create_tag:
1909 * @buffer: a #GtkTextBuffer
1910 * @tag_name: name of the new tag, or %NULL
1911 * @first_property_name: name of first property to set, or %NULL
1912 * @Varargs: %NULL-terminated list of property names and values
1915 * Creates a tag and adds it to the tag table for @buffer.
1916 * Equivalent to calling gtk_text_tag_new () and then adding the
1917 * tag to the buffer's tag table. The returned tag has its refcount
1918 * incremented, as if you'd called gtk_text_tag_new ().
1920 * If @tag_name is %NULL, the tag is anonymous.
1922 * If @tag_name is non-%NULL, a tag called @tag_name must not already
1923 * exist in the tag table for this buffer.
1925 * The @first_property_name argument and subsequent arguments are a list
1926 * of properties to set on the tag, as with g_object_set().
1928 * Return value: a new tag
1931 gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
1932 const gchar *tag_name,
1933 const gchar *first_property_name,
1939 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1941 tag = gtk_text_tag_new (tag_name);
1943 gtk_text_tag_table_add (get_table (buffer), tag);
1945 if (first_property_name)
1947 va_start (list, first_property_name);
1948 g_object_set_valist (G_OBJECT (tag), first_property_name, list);
1956 gtk_text_buffer_real_apply_tag (GtkTextBuffer *buffer,
1958 const GtkTextIter *start,
1959 const GtkTextIter *end)
1961 if (tag->table != buffer->tag_table)
1963 g_warning ("Can only apply tags that are in the tag table for the buffer");
1967 _gtk_text_btree_tag (start, end, tag, TRUE);
1971 gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
1973 const GtkTextIter *start,
1974 const GtkTextIter *end)
1976 if (tag->table != buffer->tag_table)
1978 g_warning ("Can only remove tags that are in the tag table for the buffer");
1982 _gtk_text_btree_tag (start, end, tag, FALSE);
1986 gtk_text_buffer_real_changed (GtkTextBuffer *buffer)
1988 gtk_text_buffer_set_modified (buffer, TRUE);
1992 gtk_text_buffer_emit_tag (GtkTextBuffer *buffer,
1995 const GtkTextIter *start,
1996 const GtkTextIter *end)
1998 GtkTextIter start_tmp = *start;
1999 GtkTextIter end_tmp = *end;
2001 g_return_if_fail (tag != NULL);
2003 gtk_text_iter_order (&start_tmp, &end_tmp);
2006 g_signal_emit (G_OBJECT (buffer), signals[APPLY_TAG],
2008 tag, &start_tmp, &end_tmp);
2010 g_signal_emit (G_OBJECT (buffer), signals[REMOVE_TAG],
2012 tag, &start_tmp, &end_tmp);
2017 * gtk_text_buffer_apply_tag:
2018 * @buffer: a #GtkTextBuffer
2019 * @tag: a #GtkTextTag
2020 * @start: one bound of range to be tagged
2021 * @end: other bound of range to be tagged
2023 * Emits the "apply_tag" signal on @buffer. The default
2024 * handler for the signal applies @tag to the given range.
2025 * @start and @end do not have to be in order.
2029 gtk_text_buffer_apply_tag (GtkTextBuffer *buffer,
2031 const GtkTextIter *start,
2032 const GtkTextIter *end)
2034 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2035 g_return_if_fail (GTK_IS_TEXT_TAG (tag));
2036 g_return_if_fail (start != NULL);
2037 g_return_if_fail (end != NULL);
2038 g_return_if_fail (gtk_text_iter_get_buffer (start) == buffer);
2039 g_return_if_fail (gtk_text_iter_get_buffer (end) == buffer);
2040 g_return_if_fail (tag->table == buffer->tag_table);
2042 gtk_text_buffer_emit_tag (buffer, tag, TRUE, start, end);
2046 * gtk_text_buffer_remove_tag:
2047 * @buffer: a #GtkTextBuffer
2048 * @tag: a #GtkTextTag
2049 * @start: one bound of range to be untagged
2050 * @end: other bound of range to be untagged
2052 * Emits the "remove_tag" signal. The default handler for the signal
2053 * removes all occurrences of @tag from the given range. @start and
2054 * @end don't have to be in order.
2058 gtk_text_buffer_remove_tag (GtkTextBuffer *buffer,
2060 const GtkTextIter *start,
2061 const GtkTextIter *end)
2064 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2065 g_return_if_fail (GTK_IS_TEXT_TAG (tag));
2066 g_return_if_fail (start != NULL);
2067 g_return_if_fail (end != NULL);
2068 g_return_if_fail (gtk_text_iter_get_buffer (start) == buffer);
2069 g_return_if_fail (gtk_text_iter_get_buffer (end) == buffer);
2070 g_return_if_fail (tag->table == buffer->tag_table);
2072 gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
2077 * gtk_text_buffer_apply_tag_by_name:
2078 * @buffer: a #GtkTextBuffer
2079 * @name: name of a named #GtkTextTag
2080 * @start: one bound of range to be tagged
2081 * @end: other bound of range to be tagged
2083 * Calls gtk_text_tag_table_lookup() on the buffer's tag table to
2084 * get a #GtkTextTag, then calls gtk_text_buffer_apply_tag().
2088 gtk_text_buffer_apply_tag_by_name (GtkTextBuffer *buffer,
2090 const GtkTextIter *start,
2091 const GtkTextIter *end)
2095 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2096 g_return_if_fail (name != NULL);
2097 g_return_if_fail (start != NULL);
2098 g_return_if_fail (end != NULL);
2099 g_return_if_fail (gtk_text_iter_get_buffer (start) == buffer);
2100 g_return_if_fail (gtk_text_iter_get_buffer (end) == buffer);
2102 tag = gtk_text_tag_table_lookup (get_table (buffer),
2107 g_warning ("Unknown tag `%s'", name);
2111 gtk_text_buffer_emit_tag (buffer, tag, TRUE, start, end);
2115 * gtk_text_buffer_remove_tag_by_name:
2116 * @buffer: a #GtkTextBuffer
2117 * @name: name of a #GtkTextTag
2118 * @start: one bound of range to be untagged
2119 * @end: other bound of range to be untagged
2121 * Calls gtk_text_tag_table_lookup() on the buffer's tag table to
2122 * get a #GtkTextTag, then calls gtk_text_buffer_remove_tag().
2127 gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
2129 const GtkTextIter *start,
2130 const GtkTextIter *end)
2134 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2135 g_return_if_fail (name != NULL);
2136 g_return_if_fail (start != NULL);
2137 g_return_if_fail (end != NULL);
2138 g_return_if_fail (gtk_text_iter_get_buffer (start) == buffer);
2139 g_return_if_fail (gtk_text_iter_get_buffer (end) == buffer);
2141 tag = gtk_text_tag_table_lookup (get_table (buffer),
2146 g_warning ("Unknown tag `%s'", name);
2150 gtk_text_buffer_emit_tag (buffer, tag, FALSE, start, end);
2154 pointer_cmp (gconstpointer a,
2166 * gtk_text_buffer_remove_all_tags:
2167 * @buffer: a #GtkTextBuffer
2168 * @start: one bound of range to be untagged
2169 * @end: other bound of range to be untagged
2171 * Removes all tags in the range between @start and @end. Be careful
2172 * with this function; it could remove tags added in code unrelated to
2173 * the code you're currently writing. That is, using this function is
2174 * probably a bad idea if you have two or more unrelated code sections
2178 gtk_text_buffer_remove_all_tags (GtkTextBuffer *buffer,
2179 const GtkTextIter *start,
2180 const GtkTextIter *end)
2182 GtkTextIter first, second, tmp;
2188 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2189 g_return_if_fail (start != NULL);
2190 g_return_if_fail (end != NULL);
2191 g_return_if_fail (gtk_text_iter_get_buffer (start) == buffer);
2192 g_return_if_fail (gtk_text_iter_get_buffer (end) == buffer);
2197 gtk_text_iter_order (&first, &second);
2199 /* Get all tags turned on at the start */
2200 tags = gtk_text_iter_get_tags (&first);
2202 /* Find any that are toggled on within the range */
2204 while (gtk_text_iter_forward_to_tag_toggle (&tmp, NULL))
2209 if (gtk_text_iter_compare (&tmp, &second) >= 0)
2210 break; /* past the end of the range */
2212 toggled = gtk_text_iter_get_toggled_tags (&tmp, TRUE);
2214 /* We could end up with a really big-ass list here.
2217 tmp_list2 = toggled;
2218 while (tmp_list2 != NULL)
2220 tags = g_slist_prepend (tags, tmp_list2->data);
2222 tmp_list2 = g_slist_next (tmp_list2);
2225 g_slist_free (toggled);
2229 tags = g_slist_sort (tags, pointer_cmp);
2231 /* Strip duplicates */
2235 while (tmp_list != NULL)
2237 if (tag == tmp_list->data)
2241 prev->next = tmp_list->next;
2243 tmp_list->next = NULL;
2245 g_slist_free (tmp_list);
2247 tmp_list = prev->next;
2248 /* prev is unchanged */
2252 /* not a duplicate */
2253 tag = GTK_TEXT_TAG (tmp_list->data);
2255 tmp_list = tmp_list->next;
2259 g_slist_foreach (tags, (GFunc) g_object_ref, NULL);
2262 while (tmp_list != NULL)
2264 tag = GTK_TEXT_TAG (tmp_list->data);
2266 gtk_text_buffer_remove_tag (buffer, tag, &first, &second);
2268 tmp_list = tmp_list->next;
2271 g_slist_foreach (tags, (GFunc) g_object_unref, NULL);
2273 g_slist_free (tags);
2278 * Obtain various iterators
2282 * gtk_text_buffer_get_iter_at_line_offset:
2283 * @buffer: a #GtkTextBuffer
2284 * @iter: iterator to initialize
2285 * @line_number: line number counting from 0
2286 * @char_offset: char offset from start of line
2288 * Obtains an iterator pointing to @char_offset within the given
2289 * line. The @char_offset must exist, offsets off the end of the line
2290 * are not allowed. Note <emphasis>characters</emphasis>, not bytes;
2291 * UTF-8 may encode one character as multiple bytes.
2295 gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
2300 g_return_if_fail (iter != NULL);
2301 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2303 _gtk_text_btree_get_iter_at_line_char (get_btree (buffer),
2304 iter, line_number, char_offset);
2308 * gtk_text_buffer_get_iter_at_line_index:
2309 * @buffer: a #GtkTextBuffer
2310 * @iter: iterator to initialize
2311 * @line_number: line number counting from 0
2312 * @byte_index: byte index from start of line
2314 * Obtains an iterator pointing to @byte_index within the given line.
2315 * @byte_index must be the start of a UTF-8 character, and must not be
2316 * beyond the end of the line. Note <emphasis>bytes</emphasis>, not
2317 * characters; UTF-8 may encode one character as multiple bytes.
2321 gtk_text_buffer_get_iter_at_line_index (GtkTextBuffer *buffer,
2326 g_return_if_fail (iter != NULL);
2327 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2329 _gtk_text_btree_get_iter_at_line_byte (get_btree (buffer),
2330 iter, line_number, byte_index);
2334 * gtk_text_buffer_get_iter_at_line:
2335 * @buffer: a #GtkTextBuffer
2336 * @iter: iterator to initialize
2337 * @line_number: line number counting from 0
2339 * Initializes @iter to the start of the given line.
2342 gtk_text_buffer_get_iter_at_line (GtkTextBuffer *buffer,
2346 g_return_if_fail (iter != NULL);
2347 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2349 gtk_text_buffer_get_iter_at_line_offset (buffer, iter, line_number, 0);
2353 * gtk_text_buffer_get_iter_at_offset:
2354 * @buffer: a #GtkTextBuffer
2355 * @iter: iterator to initialize
2356 * @char_offset: char offset from start of buffer, counting from 0
2358 * Initializes @iter to a position @char_offset chars from the start
2359 * of the entire buffer.
2363 gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer,
2367 g_return_if_fail (iter != NULL);
2368 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2370 _gtk_text_btree_get_iter_at_char (get_btree (buffer), iter, char_offset);
2374 * gtk_text_buffer_get_start_iter:
2375 * @buffer: a #GtkTextBuffer
2376 * @iter: iterator to initialize
2378 * Initialized @iter with the first position in the text buffer. This
2379 * is the same as using gtk_text_buffer_get_iter_at_offset() to get
2380 * the iter at character offset 0.
2384 gtk_text_buffer_get_start_iter (GtkTextBuffer *buffer,
2387 g_return_if_fail (iter != NULL);
2388 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2390 _gtk_text_btree_get_iter_at_char (get_btree (buffer), iter, 0);
2394 * gtk_text_buffer_get_end_iter:
2395 * @buffer: a #GtkTextBuffer
2396 * @iter: iterator to initialize
2398 * Initializes @iter with the "end iterator," one past the last valid
2399 * character in the text buffer. If dereferenced with
2400 * gtk_text_iter_get_char(), the end iterator has a character value of
2401 * 0. The entire buffer lies in the range from the first position in
2402 * the buffer (call gtk_text_buffer_get_start_iter() to get
2403 * character position 0) to the end iterator.
2407 gtk_text_buffer_get_end_iter (GtkTextBuffer *buffer,
2410 g_return_if_fail (iter != NULL);
2411 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2413 _gtk_text_btree_get_end_iter (get_btree (buffer), iter);
2417 * gtk_text_buffer_get_bounds:
2418 * @buffer: a #GtkTextBuffer
2419 * @start: iterator to initialize with first position in the buffer
2420 * @end: iterator to initialize with the end iterator
2422 * Retrieves the first and last iterators in the buffer, i.e. the
2423 * entire buffer lies within the range [@start,@end).
2427 gtk_text_buffer_get_bounds (GtkTextBuffer *buffer,
2431 g_return_if_fail (start != NULL);
2432 g_return_if_fail (end != NULL);
2433 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2435 _gtk_text_btree_get_iter_at_char (get_btree (buffer), start, 0);
2436 _gtk_text_btree_get_end_iter (get_btree (buffer), end);
2444 * gtk_text_buffer_get_modified:
2445 * @buffer: a #GtkTextBuffer
2447 * Indicates whether the buffer has been modified since the last call
2448 * to gtk_text_buffer_set_modified() set the modification flag to
2449 * %FALSE. Used for example to enable a "save" function in a text
2452 * Return value: %TRUE if the buffer has been modified
2455 gtk_text_buffer_get_modified (GtkTextBuffer *buffer)
2457 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2459 return buffer->modified;
2463 * gtk_text_buffer_set_modified:
2464 * @buffer: a #GtkTextBuffer
2465 * @setting: modification flag setting
2467 * Used to keep track of whether the buffer has been modified since the
2468 * last time it was saved. Whenever the buffer is saved to disk, call
2469 * gtk_text_buffer_set_modified (@buffer, FALSE). When the buffer is modified,
2470 * it will automatically toggled on the modified bit again. When the modified
2471 * bit flips, the buffer emits a "modified_changed" signal.
2475 gtk_text_buffer_set_modified (GtkTextBuffer *buffer,
2478 gboolean fixed_setting;
2480 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
2482 fixed_setting = setting != FALSE;
2484 if (buffer->modified == fixed_setting)
2488 buffer->modified = fixed_setting;
2489 g_signal_emit (G_OBJECT (buffer), signals[MODIFIED_CHANGED], 0);
2495 * Assorted other stuff
2499 * gtk_text_buffer_get_line_count:
2500 * @buffer: a #GtkTextBuffer
2502 * Obtains the number of lines in the buffer. This value is cached, so
2503 * the function is very fast.
2505 * Return value: number of lines in the buffer
2508 gtk_text_buffer_get_line_count (GtkTextBuffer *buffer)
2510 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
2512 return _gtk_text_btree_line_count (get_btree (buffer));
2516 * gtk_text_buffer_get_char_count:
2517 * @buffer: a #GtkTextBuffer
2519 * Gets the number of characters in the buffer; note that characters
2520 * and bytes are not the same, you can't e.g. expect the contents of
2521 * the buffer in string form to be this many bytes long. The character
2522 * count is cached, so this function is very fast.
2524 * Return value: number of characters in the buffer
2527 gtk_text_buffer_get_char_count (GtkTextBuffer *buffer)
2529 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), 0);
2531 return _gtk_text_btree_char_count (get_btree (buffer));
2534 /* Called when we lose the primary selection.
2537 clipboard_clear_selection_cb (GtkClipboard *clipboard,
2540 /* Move selection_bound to the insertion point */
2542 GtkTextIter selection_bound;
2543 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2545 gtk_text_buffer_get_iter_at_mark (buffer, &insert,
2546 gtk_text_buffer_get_mark (buffer, "insert"));
2547 gtk_text_buffer_get_iter_at_mark (buffer, &selection_bound,
2548 gtk_text_buffer_get_mark (buffer, "selection_bound"));
2550 if (!gtk_text_iter_equal (&insert, &selection_bound))
2551 gtk_text_buffer_move_mark (buffer,
2552 gtk_text_buffer_get_mark (buffer, "selection_bound"),
2556 /* Called when we have the primary selection and someone else wants our
2557 * data in order to paste it.
2560 clipboard_get_selection_cb (GtkClipboard *clipboard,
2561 GtkSelectionData *selection_data,
2565 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2566 GtkTextIter start, end;
2568 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2570 if (selection_data->target ==
2571 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2573 /* Provide the address of the buffer; this will only be
2574 * used within-process
2576 gtk_selection_data_set (selection_data,
2577 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2586 str = gtk_text_iter_get_visible_text (&start, &end);
2587 gtk_selection_data_set_text (selection_data, str);
2593 /* Provide cut/copied data */
2595 clipboard_get_contents_cb (GtkClipboard *clipboard,
2596 GtkSelectionData *selection_data,
2600 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2601 GtkTextBuffer *contents = buffer->clipboard_contents;
2603 if (selection_data->target ==
2604 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2606 /* Provide the address of the clipboard buffer; this will only
2607 * be used within-process. OK to supply a NULL value for contents.
2609 gtk_selection_data_set (selection_data,
2610 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2617 /* Just provide text from the clipboard buffer */
2618 if (buffer->clipboard_contents)
2621 GtkTextIter start, end;
2623 gtk_text_buffer_get_bounds (contents, &start, &end);
2624 /* strip off the trailing newline, it isn't part of the text that was cut */
2625 gtk_text_iter_backward_char (&end);
2627 str = gtk_text_iter_get_visible_text (&start, &end);
2628 gtk_selection_data_set_text (selection_data, str);
2633 gtk_selection_data_set_text (selection_data, "");
2640 clipboard_clear_contents_cb (GtkClipboard *clipboard,
2643 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
2645 if (buffer->clipboard_contents)
2647 g_object_unref (G_OBJECT (buffer->clipboard_contents));
2648 buffer->clipboard_contents = NULL;
2653 get_paste_point (GtkTextBuffer *buffer,
2655 gboolean clear_afterward)
2657 GtkTextIter insert_point;
2658 GtkTextMark *paste_point_override;
2660 paste_point_override = gtk_text_buffer_get_mark (buffer,
2661 "gtk_paste_point_override");
2663 if (paste_point_override != NULL)
2665 gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
2666 paste_point_override);
2667 if (clear_afterward)
2668 gtk_text_buffer_delete_mark (buffer,
2669 gtk_text_buffer_get_mark (buffer,
2670 "gtk_paste_point_override"));
2674 gtk_text_buffer_get_iter_at_mark (buffer, &insert_point,
2675 gtk_text_buffer_get_mark (buffer,
2679 *iter = insert_point;
2683 pre_paste_prep (ClipboardRequest *request_data,
2684 GtkTextIter *insert_point)
2686 GtkTextBuffer *buffer = request_data->buffer;
2688 get_paste_point (buffer, insert_point, TRUE);
2690 /* If we're going to replace the selection, we insert before it to
2691 * avoid messing it up, then we delete the selection after inserting.
2693 if (request_data->replace_selection)
2695 GtkTextIter start, end;
2697 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2698 *insert_point = start;
2703 post_paste_cleanup (ClipboardRequest *request_data)
2705 if (request_data->replace_selection)
2707 GtkTextIter start, end;
2709 if (gtk_text_buffer_get_selection_bounds (request_data->buffer,
2712 if (request_data->interactive)
2713 gtk_text_buffer_delete_interactive (request_data->buffer,
2716 request_data->default_editable);
2718 gtk_text_buffer_delete (request_data->buffer, &start, &end);
2723 /* Called when we request a paste and receive the text data
2726 clipboard_text_received (GtkClipboard *clipboard,
2730 ClipboardRequest *request_data = data;
2731 GtkTextBuffer *buffer = request_data->buffer;
2735 GtkTextIter insert_point;
2737 pre_paste_prep (request_data, &insert_point);
2739 if (request_data->interactive)
2740 gtk_text_buffer_insert_interactive (buffer, &insert_point,
2741 str, -1, request_data->default_editable);
2743 gtk_text_buffer_insert (buffer, &insert_point,
2746 post_paste_cleanup (request_data);
2749 g_object_unref (G_OBJECT (buffer));
2750 g_free (request_data);
2753 static GtkTextBuffer*
2754 selection_data_get_buffer (GtkSelectionData *selection_data,
2755 ClipboardRequest *request_data)
2758 GtkTextBuffer *src_buffer = NULL;
2760 /* If we can get the owner, the selection is in-process */
2761 owner = gdk_selection_owner_get (selection_data->selection);
2766 if (selection_data->type != gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
2769 if (selection_data->length != sizeof (src_buffer))
2772 memcpy (&src_buffer, selection_data->data, sizeof (src_buffer));
2774 if (src_buffer == NULL)
2777 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (src_buffer), NULL);
2779 if (gtk_text_buffer_get_tag_table (src_buffer) !=
2780 gtk_text_buffer_get_tag_table (request_data->buffer))
2787 /* These are pretty handy functions; maybe something like them
2788 * should be in the public API. Also, there are other places in this
2789 * file where they could be used.
2792 save_iter (const GtkTextIter *iter,
2793 gboolean left_gravity)
2795 return gtk_text_buffer_create_mark (gtk_text_iter_get_buffer (iter),
2802 restore_iter (const GtkTextIter *iter,
2805 gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (save_id),
2806 (GtkTextIter*) iter,
2808 gtk_text_buffer_delete_mark (gtk_text_mark_get_buffer (save_id),
2814 paste_from_buffer (ClipboardRequest *request_data,
2815 GtkTextBuffer *src_buffer,
2816 const GtkTextIter *start,
2817 const GtkTextIter *end)
2819 GtkTextIter insert_point;
2821 /* We're about to emit a bunch of signals, so be safe */
2822 g_object_ref (G_OBJECT (src_buffer));
2824 pre_paste_prep (request_data, &insert_point);
2826 if (!gtk_text_iter_equal (start, end))
2828 gtk_text_buffer_real_insert_range (request_data->buffer,
2832 request_data->interactive);
2835 post_paste_cleanup (request_data);
2837 g_object_unref (G_OBJECT (src_buffer));
2841 clipboard_clipboard_buffer_received (GtkClipboard *clipboard,
2842 GtkSelectionData *selection_data,
2845 ClipboardRequest *request_data = data;
2846 GtkTextBuffer *src_buffer;
2848 src_buffer = selection_data_get_buffer (selection_data, request_data);
2852 GtkTextIter start, end;
2854 gtk_text_buffer_get_bounds (src_buffer, &start, &end);
2855 /* There's an extra newline on clipboard_contents */
2856 gtk_text_iter_backward_char (&end);
2858 paste_from_buffer (request_data, src_buffer,
2863 /* Request the text selection instead */
2864 gtk_clipboard_request_text (clipboard,
2865 clipboard_text_received,
2871 clipboard_selection_buffer_received (GtkClipboard *clipboard,
2872 GtkSelectionData *selection_data,
2875 ClipboardRequest *request_data = data;
2876 GtkTextBuffer *src_buffer;
2878 src_buffer = selection_data_get_buffer (selection_data, request_data);
2882 GtkTextIter start, end;
2884 if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
2885 paste_from_buffer (request_data, src_buffer,
2890 /* Request the text selection instead */
2891 gtk_clipboard_request_text (clipboard,
2892 clipboard_text_received,
2897 static const GtkTargetEntry targets[] = {
2898 { "STRING", 0, TARGET_STRING },
2899 { "TEXT", 0, TARGET_TEXT },
2900 { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
2901 { "UTF8_STRING", 0, TARGET_UTF8_STRING },
2902 { "GTK_TEXT_BUFFER_CONTENTS", 0, TARGET_TEXT_BUFFER_CONTENTS }
2906 gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
2911 GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2913 /* Determine whether we have a selection and adjust X selection
2917 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
2919 if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
2920 gtk_clipboard_clear (clipboard);
2924 /* Even if we already have the selection, we need to update our
2927 if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
2928 clipboard_get_selection_cb,
2929 clipboard_clear_selection_cb,
2931 clipboard_clear_selection_cb (clipboard, buffer);
2936 paste (GtkTextBuffer *buffer,
2937 gboolean is_clipboard,
2938 gboolean interactive,
2939 gboolean default_editable)
2941 ClipboardRequest *data = g_new (ClipboardRequest, 1);
2942 GtkTextIter paste_point;
2943 GtkTextIter start, end;
2945 data->buffer = buffer;
2946 g_object_ref (G_OBJECT (buffer));
2947 data->interactive = interactive;
2948 data->default_editable = default_editable;
2950 /* When pasting with the cursor inside the selection area, you
2951 * replace the selection with the new text, otherwise, you
2952 * simply insert the new text at the point where the click
2953 * occured, unselecting any selected text. The replace_selection
2954 * flag toggles this behavior.
2956 data->replace_selection = FALSE;
2958 get_paste_point (buffer, &paste_point, FALSE);
2959 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end) &&
2960 (gtk_text_iter_in_range (&paste_point, &start, &end) ||
2961 gtk_text_iter_equal (&paste_point, &end)))
2962 data->replace_selection = TRUE;
2965 gtk_clipboard_request_contents (gtk_clipboard_get (GDK_NONE),
2967 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2968 clipboard_clipboard_buffer_received, data);
2970 gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
2972 gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
2973 clipboard_selection_buffer_received, data);
2977 * gtk_text_buffer_paste_primary:
2978 * @buffer: a #GtkTextBuffer
2979 * @override_location: location to insert pasted text, or %NULL for at the cursor
2980 * @default_editable: whether the buffer is editable by default
2982 * Pastes the primary selection at the insertion point, or at @override_location.
2983 * (Note: pasting is asynchronous, that is, we'll ask for the paste data
2984 * and return, and at some point later after the main loop runs, the paste
2985 * data will be inserted.)
2988 gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
2989 const GtkTextIter *override_location,
2990 gboolean default_editable)
2992 if (override_location != NULL)
2993 gtk_text_buffer_create_mark (buffer,
2994 "gtk_paste_point_override",
2995 override_location, FALSE);
2997 paste (buffer, FALSE, TRUE, default_editable);
3001 * gtk_text_buffer_paste_clipboard:
3002 * @buffer: a #GtkTextBuffer
3003 * @default_editable: whether the buffer is editable by default
3005 * Pastes the clipboard contents at the insertion point. (Note:
3006 * pasting is asynchronous, that is, we'll ask for the paste data and
3007 * return, and at some point later after the main loop runs, the paste
3008 * data will be inserted.)
3012 gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
3013 gboolean default_editable)
3015 paste (buffer, TRUE, TRUE, default_editable);
3019 * gtk_text_buffer_delete_selection:
3020 * @buffer: a #GtkTextBuffer
3021 * @interactive: whether the deletion is caused by user interaction
3022 * @default_editable: whether the buffer is editable by default
3024 * Deletes the range between the "insert" and "selection_bound" marks,
3025 * that is, the currently-selected text. If @interactive is %TRUE,
3026 * the editability of the selection will be considered (users can't delete
3029 * Return value: whether there was a non-empty selection to delete
3032 gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
3033 gboolean interactive,
3034 gboolean default_editable)
3039 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
3041 return FALSE; /* No selection */
3047 gtk_text_buffer_begin_user_action (buffer);
3048 gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable);
3049 gtk_text_buffer_end_user_action (buffer);
3052 gtk_text_buffer_delete (buffer, &start, &end);
3054 return TRUE; /* We deleted stuff */
3059 cut_or_copy (GtkTextBuffer *buffer,
3060 gboolean delete_region_after,
3061 gboolean interactive,
3062 gboolean default_editable)
3064 /* We prefer to cut the selected region between selection_bound and
3065 * insertion point. If that region is empty, then we cut the region
3066 * between the "anchor" and the insertion point (this is for
3067 * C-space and M-w and other Emacs-style copy/yank keys). Note that
3068 * insert and selection_bound are guaranteed to exist, but the
3069 * anchor only exists sometimes.
3074 if (buffer->clipboard_contents)
3076 g_object_unref (G_OBJECT (buffer->clipboard_contents));
3077 buffer->clipboard_contents = NULL;
3080 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
3082 /* Let's try the anchor thing */
3083 GtkTextMark * anchor = gtk_text_buffer_get_mark (buffer, "anchor");
3089 gtk_text_buffer_get_iter_at_mark (buffer, &end, anchor);
3090 gtk_text_iter_order (&start, &end);
3094 if (!gtk_text_iter_equal (&start, &end))
3096 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
3099 buffer->clipboard_contents =
3100 gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
3102 gtk_text_buffer_get_iter_at_offset (buffer->clipboard_contents,
3105 gtk_text_buffer_insert_range (buffer->clipboard_contents,
3110 if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
3111 clipboard_get_contents_cb,
3112 clipboard_clear_contents_cb,
3114 clipboard_clear_contents_cb (clipboard, buffer);
3116 if (delete_region_after)
3119 gtk_text_buffer_delete_interactive (buffer, &start, &end,
3122 gtk_text_buffer_delete (buffer, &start, &end);
3128 * gtk_text_buffer_cut_clipboard:
3129 * @buffer: a #GtkTextBuffer
3130 * @default_editable: default editability of the buffer
3132 * Copies the currently-selected text to the clipboard, then deletes
3133 * said text if it's editable.
3137 gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
3138 gboolean default_editable)
3140 gtk_text_buffer_begin_user_action (buffer);
3141 cut_or_copy (buffer, TRUE, TRUE, default_editable);
3142 gtk_text_buffer_end_user_action (buffer);
3146 * gtk_text_buffer_copy_clipboard:
3147 * @buffer: a #GtkTextBuffer
3149 * Copies the currently-selected text to the clipboard.
3153 gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer)
3155 gtk_text_buffer_begin_user_action (buffer);
3156 cut_or_copy (buffer, FALSE, TRUE, TRUE);
3157 gtk_text_buffer_end_user_action (buffer);
3162 * gtk_text_buffer_get_selection_bounds:
3163 * @buffer: a #GtkTextBuffer a #GtkTextBuffer
3164 * @start: iterator to initialize with selection start
3165 * @end: iterator to initialize with selection end
3167 * Returns %TRUE if some text is selected; places the bounds
3168 * of the selection in @start and @end (if the selection has length 0,
3169 * then @start and @end are filled in with the same value).
3170 * @start and @end will be in ascending order. If @start and @end are
3171 * NULL, then they are not filled in, but the return value still indicates
3172 * whether text is selected.
3174 * Return value: whether the selection has nonzero length
3177 gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
3181 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
3183 return _gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
3187 * gtk_text_buffer_begin_user_action:
3188 * @buffer: a #GtkTextBuffer
3190 * Called to indicate that the buffer operations between here and a
3191 * call to gtk_text_buffer_end_user_action() are part of a single
3192 * user-visible operation. The operations between
3193 * gtk_text_buffer_begin_user_action() and
3194 * gtk_text_buffer_end_user_action() can then be grouped when creating
3195 * an undo stack. #GtkTextBuffer maintains a count of calls to
3196 * gtk_text_buffer_begin_user_action() that have not been closed with
3197 * a call to gtk_text_buffer_end_user_action(), and emits the "begin_user_action"
3198 * and "end_user_action" signals only for the outermost pair of calls.
3199 * This allows you to build user actions from other user actions.
3201 * The "interactive" buffer mutation functions, such as
3202 * gtk_text_buffer_insert_interactive(), automatically call begin/end
3203 * user action around the buffer operations they perform, so there's
3204 * no need to add extra calls if you user action consists solely of a
3205 * single call to one of those functions.
3208 gtk_text_buffer_begin_user_action (GtkTextBuffer *buffer)
3210 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
3212 buffer->user_action_count += 1;
3214 if (buffer->user_action_count == 1)
3216 /* Outermost nested user action begin emits the signal */
3217 g_signal_emit (G_OBJECT (buffer), signals[BEGIN_USER_ACTION], 0);
3222 * gtk_text_buffer_end_user_action:
3223 * @buffer: a #GtkTextBuffer
3225 * Should be paired with a call to gtk_text_buffer_begin_user_action().
3226 * See that function for a full explanation.
3229 gtk_text_buffer_end_user_action (GtkTextBuffer *buffer)
3231 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
3232 g_return_if_fail (buffer->user_action_count > 0);
3234 buffer->user_action_count -= 1;
3236 if (buffer->user_action_count == 0)
3238 /* Ended the outermost-nested user action end, so emit the signal */
3239 g_signal_emit (G_OBJECT (buffer), signals[END_USER_ACTION], 0);
3244 * Logical attribute cache
3247 #define ATTR_CACHE_SIZE 2
3249 typedef struct _CacheEntry CacheEntry;
3254 PangoLogAttr *attrs;
3258 struct _GtkTextLogAttrCache
3260 gint chars_changed_stamp;
3261 CacheEntry entries[ATTR_CACHE_SIZE];
3265 free_log_attr_cache (GtkTextLogAttrCache *cache)
3268 while (i < ATTR_CACHE_SIZE)
3270 g_free (cache->entries[i].attrs);
3277 clear_log_attr_cache (GtkTextLogAttrCache *cache)
3280 while (i < ATTR_CACHE_SIZE)
3282 g_free (cache->entries[i].attrs);
3283 cache->entries[i].attrs = NULL;
3288 static PangoLogAttr*
3289 compute_log_attrs (const GtkTextIter *iter,
3295 gint char_len, byte_len;
3296 PangoLogAttr *attrs = NULL;
3301 gtk_text_iter_set_line_offset (&start, 0);
3302 gtk_text_iter_forward_line (&end);
3304 paragraph = gtk_text_iter_get_slice (&start, &end);
3305 char_len = g_utf8_strlen (paragraph, -1);
3306 byte_len = strlen (paragraph);
3308 g_assert (char_len > 0);
3311 *char_lenp = char_len;
3313 attrs = g_new (PangoLogAttr, char_len);
3315 pango_get_log_attrs (paragraph, byte_len, -1,
3316 gtk_text_iter_get_language (&start),
3324 /* The return value from this is valid until you call this a second time.
3327 _gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer,
3328 const GtkTextIter *anywhere_in_line,
3332 GtkTextLogAttrCache *cache;
3335 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
3336 g_return_val_if_fail (anywhere_in_line != NULL, NULL);
3337 g_return_val_if_fail (!gtk_text_iter_is_end (anywhere_in_line), NULL);
3339 /* FIXME we also need to recompute log attrs if the language tag at
3340 * the start of a paragraph changes
3343 if (buffer->log_attr_cache == NULL)
3345 buffer->log_attr_cache = g_new0 (GtkTextLogAttrCache, 1);
3346 buffer->log_attr_cache->chars_changed_stamp =
3347 _gtk_text_btree_get_chars_changed_stamp (get_btree (buffer));
3349 else if (buffer->log_attr_cache->chars_changed_stamp !=
3350 _gtk_text_btree_get_chars_changed_stamp (get_btree (buffer)))
3352 clear_log_attr_cache (buffer->log_attr_cache);
3355 cache = buffer->log_attr_cache;
3356 line = gtk_text_iter_get_line (anywhere_in_line);
3359 while (i < ATTR_CACHE_SIZE)
3361 if (cache->entries[i].attrs &&
3362 cache->entries[i].line == line)
3365 *char_len = cache->entries[i].char_len;
3366 return cache->entries[i].attrs;
3371 /* Not in cache; open up the first cache entry */
3372 if (cache->entries[ATTR_CACHE_SIZE-1].attrs)
3373 g_free (cache->entries[ATTR_CACHE_SIZE-1].attrs);
3375 g_memmove (cache->entries + 1, cache->entries,
3376 sizeof (CacheEntry) * (ATTR_CACHE_SIZE - 1));
3378 cache->entries[0].line = line;
3379 cache->entries[0].attrs = compute_log_attrs (anywhere_in_line,
3380 &cache->entries[0].char_len);
3383 *char_len = cache->entries[0].char_len;
3385 return cache->entries[0].attrs;
3393 _gtk_text_buffer_spew (GtkTextBuffer *buffer)
3395 _gtk_text_btree_spew (get_btree (buffer));