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;
72 static void gtk_text_buffer_init (GtkTextBuffer *tkxt_buffer);
73 static void gtk_text_buffer_class_init (GtkTextBufferClass *klass);
74 static void gtk_text_buffer_destroy (GtkObject *object);
75 static void gtk_text_buffer_finalize (GObject *object);
78 static void gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer);
79 static void gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
83 gboolean interactive);
84 static void gtk_text_buffer_real_delete_text (GtkTextBuffer *buffer,
87 gboolean interactive);
88 static void gtk_text_buffer_real_apply_tag (GtkTextBuffer *buffer,
90 const GtkTextIter *start_char,
91 const GtkTextIter *end_char);
92 static void gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
94 const GtkTextIter *start_char,
95 const GtkTextIter *end_char);
97 static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
99 static GtkObjectClass *parent_class = NULL;
100 static guint signals[LAST_SIGNAL] = { 0 };
103 gtk_text_buffer_get_type (void)
105 static GtkType our_type = 0;
109 static const GtkTypeInfo our_info =
112 sizeof (GtkTextBuffer),
113 sizeof (GtkTextBufferClass),
114 (GtkClassInitFunc) gtk_text_buffer_class_init,
115 (GtkObjectInitFunc) gtk_text_buffer_init,
116 /* reserved_1 */ NULL,
117 /* reserved_2 */ NULL,
118 (GtkClassInitFunc) NULL
121 our_type = gtk_type_unique (GTK_TYPE_OBJECT, &our_info);
128 gtk_text_buffer_class_init (GtkTextBufferClass *klass)
130 GtkObjectClass *object_class = (GtkObjectClass*) klass;
131 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
133 parent_class = gtk_type_class (GTK_TYPE_OBJECT);
135 signals[INSERT_TEXT] =
136 gtk_signal_new ("insert_text",
138 GTK_CLASS_TYPE (object_class),
139 GTK_SIGNAL_OFFSET (GtkTextBufferClass, insert_text),
140 gtk_marshal_VOID__POINTER_POINTER_INT_INT,
148 signals[DELETE_TEXT] =
149 gtk_signal_new ("delete_text",
151 GTK_CLASS_TYPE (object_class),
152 GTK_SIGNAL_OFFSET (GtkTextBufferClass, delete_text),
153 gtk_marshal_VOID__POINTER_POINTER_INT,
161 gtk_signal_new ("changed",
163 GTK_CLASS_TYPE (object_class),
164 GTK_SIGNAL_OFFSET (GtkTextBufferClass, changed),
165 gtk_marshal_VOID__VOID,
169 signals[MODIFIED_CHANGED] =
170 gtk_signal_new ("modified_changed",
172 GTK_CLASS_TYPE (object_class),
173 GTK_SIGNAL_OFFSET (GtkTextBufferClass, modified_changed),
174 gtk_marshal_VOID__VOID,
179 gtk_signal_new ("mark_set",
181 GTK_CLASS_TYPE (object_class),
182 GTK_SIGNAL_OFFSET (GtkTextBufferClass, mark_set),
183 gtk_marshal_VOID__POINTER_POINTER,
189 signals[MARK_DELETED] =
190 gtk_signal_new ("mark_deleted",
192 GTK_CLASS_TYPE (object_class),
193 GTK_SIGNAL_OFFSET (GtkTextBufferClass, mark_deleted),
194 gtk_marshal_VOID__POINTER,
200 gtk_signal_new ("apply_tag",
202 GTK_CLASS_TYPE (object_class),
203 GTK_SIGNAL_OFFSET (GtkTextBufferClass, apply_tag),
204 gtk_marshal_VOID__POINTER_POINTER_POINTER,
211 signals[REMOVE_TAG] =
212 gtk_signal_new ("remove_tag",
214 GTK_CLASS_TYPE (object_class),
215 GTK_SIGNAL_OFFSET (GtkTextBufferClass, remove_tag),
216 gtk_marshal_VOID__POINTER_POINTER_POINTER,
223 gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
225 object_class->destroy = gtk_text_buffer_destroy;
227 gobject_class->finalize = gtk_text_buffer_finalize;
229 klass->insert_text = gtk_text_buffer_real_insert_text;
230 klass->delete_text = gtk_text_buffer_real_delete_text;
231 klass->apply_tag = gtk_text_buffer_real_apply_tag;
232 klass->remove_tag = gtk_text_buffer_real_remove_tag;
236 gtk_text_buffer_init (GtkTextBuffer *buffer)
241 * gtk_text_buffer_new:
242 * @table: a tag table, or NULL to create a new one
244 * Creates a new text buffer.
246 * Return value: a new text buffer
249 gtk_text_buffer_new (GtkTextTagTable *table)
251 GtkTextBuffer *text_buffer;
253 text_buffer = GTK_TEXT_BUFFER (gtk_type_new (gtk_text_buffer_get_type ()));
257 text_buffer->tag_table = table;
259 gtk_object_ref (GTK_OBJECT(text_buffer->tag_table));
260 gtk_object_sink (GTK_OBJECT(text_buffer->tag_table));
267 gtk_text_buffer_destroy (GtkObject *object)
269 GtkTextBuffer *buffer;
271 buffer = GTK_TEXT_BUFFER (object);
273 if (buffer->tag_table)
275 gtk_object_unref(GTK_OBJECT(buffer->tag_table));
276 buffer->tag_table = NULL;
281 gtk_text_btree_unref(buffer->btree);
282 buffer->btree = NULL;
285 (* parent_class->destroy) (object);
289 gtk_text_buffer_finalize (GObject *object)
291 GtkTextBuffer *tkxt_buffer;
293 tkxt_buffer = GTK_TEXT_BUFFER (object);
295 G_OBJECT_CLASS (parent_class)->finalize (object);
298 static GtkTextTagTable*
299 get_table (GtkTextBuffer *buffer)
301 if (buffer->tag_table == NULL)
303 buffer->tag_table = gtk_text_tag_table_new ();
305 gtk_object_ref (GTK_OBJECT(buffer->tag_table));
306 gtk_object_sink (GTK_OBJECT(buffer->tag_table));
309 return buffer->tag_table;
313 get_btree (GtkTextBuffer *buffer)
315 if (buffer->btree == NULL)
316 buffer->btree = gtk_text_btree_new(gtk_text_buffer_get_tag_table (buffer),
319 return buffer->btree;
323 _gtk_text_buffer_get_btree (GtkTextBuffer *buffer)
325 return get_btree (buffer);
329 * gtk_text_buffer_get_tag_table:
330 * @buffer: a #GtkTextBuffer
332 * Get the #GtkTextTagTable associated with this buffer.
334 * Return value: the buffer's tag table
337 gtk_text_buffer_get_tag_table (GtkTextBuffer *buffer)
339 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
341 return get_table (buffer);
345 * gtk_text_buffer_set_text:
346 * @buffer: a #GtkTextBuffer
347 * @text: UTF-8 text to insert
348 * @len: length of @text in bytes
350 * Deletes current contents of @buffer, and inserts @text instead. If
351 * @text doesn't end with a newline, a newline is added;
352 * #GtkTextBuffer contents must always end with a newline. If @text
353 * ends with a newline, the new buffer contents will be exactly
354 * @text. If @len is -1, @text must be nul-terminated.
357 gtk_text_buffer_set_text (GtkTextBuffer *buffer,
361 GtkTextIter start, end;
363 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
364 g_return_if_fail (text != NULL);
369 /* Chop newline, since the buffer will already have one
372 if (len > 0 && text[len-1] == '\n')
375 gtk_text_buffer_get_bounds (buffer, &start, &end);
377 gtk_text_buffer_delete (buffer, &start, &end);
381 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
382 gtk_text_buffer_insert (buffer, &start, text, len);
391 gtk_text_buffer_real_insert_text(GtkTextBuffer *buffer,
395 gboolean interactive)
397 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
398 g_return_if_fail(iter != NULL);
400 gtk_text_btree_insert(iter, text, len);
402 gtk_signal_emit(GTK_OBJECT(buffer), signals[CHANGED]);
404 gtk_text_buffer_set_modified(buffer, TRUE);
408 gtk_text_buffer_emit_insert(GtkTextBuffer *buffer,
412 gboolean interactive)
414 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
415 g_return_if_fail(iter != NULL);
416 g_return_if_fail(text != NULL);
423 gtk_signal_emit(GTK_OBJECT(buffer), signals[INSERT_TEXT],
424 iter, text, len, interactive);
429 * gtk_text_buffer_insert:
430 * @buffer: a #GtkTextBuffer
431 * @iter: a position in the buffer
432 * @text: UTF-8 format text to insert
433 * @len: length of text in bytes, or -1
435 * Inserts @len bytes of @text at position @iter. If @len is -1,
436 * @text must be nul-terminated and will be inserted in its
437 * entirety. Emits the "insert_text" signal; insertion actually occurs
438 * in the default handler for the signal. @iter is invalidated when
439 * insertion occurs (because the buffer contents change), but the
440 * default signal handler revalidates it to point to the end of the
445 gtk_text_buffer_insert (GtkTextBuffer *buffer,
450 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
451 g_return_if_fail(iter != NULL);
452 g_return_if_fail(text != NULL);
454 gtk_text_buffer_emit_insert(buffer, iter, text, len, FALSE);
458 * gtk_text_buffer_insert_at_cursor:
459 * @buffer: a #GtkTextBuffer
460 * @text: some text in UTF-8 format
461 * @len: length of text, in bytes
463 * Simply calls gtk_text_buffer_insert(), using the current
464 * cursor position as the insertion point.
467 gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buffer,
473 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
474 g_return_if_fail(text != NULL);
476 gtk_text_buffer_get_iter_at_mark(buffer, &iter,
477 gtk_text_buffer_get_mark (buffer,
480 gtk_text_buffer_insert(buffer, &iter, text, len);
484 * gtk_text_buffer_insert_interactive:
485 * @buffer: a #GtkTextBuffer
486 * @iter: a position in @buffer
487 * @text: some UTF-8 text
488 * @len: length of text in bytes, or -1
489 * @default_editable: default editability of buffer
491 * Like gtk_text_buffer_insert(), but the insertion will not occur if
492 * @iter is at a non-editable location in the buffer. Usually you
493 * want to prevent insertions at ineditable locations if the insertion
494 * results from a user action (is interactive).
496 * Return value: whether text was actually inserted
499 gtk_text_buffer_insert_interactive(GtkTextBuffer *buffer,
503 gboolean default_editable)
505 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
506 g_return_val_if_fail(text != NULL, FALSE);
508 if (gtk_text_iter_editable (iter, default_editable))
510 gtk_text_buffer_emit_insert (buffer, iter, text, len, TRUE);
518 * gtk_text_buffer_insert_interactive_at_cursor:
519 * @buffer: a #GtkTextBuffer
520 * @text: text in UTF-8 format
521 * @len: length of text in bytes, or -1
522 * @default_editable: default editability of buffer
524 * Calls gtk_text_buffer_insert_interactive() at the cursor
527 * Return value: whether text was actually inserted
530 gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
533 gboolean default_editable)
537 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
538 g_return_val_if_fail(text != NULL, FALSE);
540 gtk_text_buffer_get_iter_at_mark(buffer, &iter,
541 gtk_text_buffer_get_mark (buffer,
544 return gtk_text_buffer_insert_interactive (buffer, &iter, text, len,
550 * gtk_text_buffer_insert_range:
551 * @buffer: a #GtkTextBuffer
552 * @iter: a position in @buffer
553 * @start: a position in a #GtkTextBuffer
554 * @end: another position in the same buffer as @start
556 * Copies text, tags, and pixbufs between @start and @end (the order
557 * of @start and @end doesn't matter) and inserts the copy at @iter.
558 * Used instead of simply getting/inserting text because it preserves
559 * images and tags. If @start and @end are in a different buffer
560 * from @buffer, the two buffers must share the same tag table.
562 * Implemented via multiple emissions of the insert_text and
563 * apply_tag signals, so expect those.
566 gtk_text_buffer_insert_range (GtkTextBuffer *buffer,
568 const GtkTextIter *start,
569 const GtkTextIter *end)
571 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
572 g_return_if_fail (iter != NULL);
573 g_return_if_fail (start != NULL);
574 g_return_if_fail (end != NULL);
575 g_return_if_fail (gtk_text_iter_get_buffer (start) !=
576 gtk_text_iter_get_buffer (end));
577 g_return_if_fail (gtk_text_iter_get_buffer (start)->tag_table !=
584 gtk_text_buffer_insert_range_interactive (GtkTextBuffer *buffer,
586 const GtkTextIter *start,
587 const GtkTextIter *end,
588 gboolean default_editable)
590 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
591 g_return_val_if_fail (iter != NULL, FALSE);
592 g_return_val_if_fail (start != NULL, FALSE);
593 g_return_val_if_fail (end != NULL, FALSE);
594 g_return_val_if_fail (gtk_text_iter_get_buffer (start) !=
595 gtk_text_iter_get_buffer (end), FALSE);
596 g_return_val_if_fail (gtk_text_iter_get_buffer (start)->tag_table !=
597 buffer->tag_table, FALSE);
606 * gtk_text_buffer_insert_with_tags:
607 * @buffer: a #GtkTextBuffer
608 * @iter: an iterator in @buffer
610 * @len: length of @text, or -1
611 * @first_tag: first tag to apply to @text
612 * @Varargs: NULL-terminated list of tags to apply
614 * Inserts @text into @buffer at @iter, applying the list of tags to
615 * the newly-inserted text. The last tag specified must be NULL to
616 * terminate the list. Equivalent to calling gtk_text_buffer_insert(),
617 * then gtk_text_buffer_apply_tag() on the inserted text;
618 * gtk_text_buffer_insert_with_tags() is just a convenience function.
621 gtk_text_buffer_insert_with_tags (GtkTextBuffer *buffer,
625 GtkTextTag *first_tag,
633 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
634 g_return_if_fail (iter != NULL);
635 g_return_if_fail (text != NULL);
637 start_offset = gtk_text_iter_get_offset (iter);
639 gtk_text_buffer_insert (buffer, iter, text, len);
641 if (first_tag == NULL)
644 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
646 va_start (args, first_tag);
650 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
652 tag = va_arg (args, GtkTextTag*);
659 * gtk_text_buffer_insert_with_tags_by_name:
660 * @buffer: a #GtkTextBuffer
661 * @iter: position in @buffer
663 * @len: length of @text, or -1
664 * @first_tag_name: name of a tag to apply to @text
665 * @Varargs: more tag names
667 * Same as gtk_text_buffer_insert_with_tags(), but allows you
668 * to pass in tag names instead of tag objects.
671 gtk_text_buffer_insert_with_tags_by_name (GtkTextBuffer *buffer,
675 const gchar *first_tag_name,
681 const gchar *tag_name;
683 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
684 g_return_if_fail (iter != NULL);
685 g_return_if_fail (text != NULL);
687 start_offset = gtk_text_iter_get_offset (iter);
689 gtk_text_buffer_insert (buffer, iter, text, len);
691 if (first_tag_name == NULL)
694 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
696 va_start (args, first_tag_name);
697 tag_name = first_tag_name;
702 tag = gtk_text_tag_table_lookup (buffer->tag_table,
707 g_warning ("%s: no tag with name '%s'!", G_STRLOC, tag_name);
711 gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
713 tag_name = va_arg (args, const gchar*);
725 gtk_text_buffer_real_delete_text(GtkTextBuffer *buffer,
728 gboolean interactive)
730 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
731 g_return_if_fail(start != NULL);
732 g_return_if_fail(end != NULL);
734 gtk_text_btree_delete(start, end);
736 /* may have deleted the selection... */
737 gtk_text_buffer_update_primary_selection(buffer);
739 gtk_signal_emit(GTK_OBJECT(buffer), signals[CHANGED]);
741 gtk_text_buffer_set_modified(buffer, TRUE);
745 gtk_text_buffer_emit_delete (GtkTextBuffer *buffer,
748 gboolean interactive)
750 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
751 g_return_if_fail(start != NULL);
752 g_return_if_fail(end != NULL);
754 if (gtk_text_iter_equal(start, end))
757 gtk_text_iter_reorder (start, end);
759 /* Somewhat annoyingly, if you try to delete the final newline
760 * the BTree will put it back; which means you can't deduce the
761 * final contents of the buffer purely by monitoring insert/delete
762 * signals on the buffer. But if you delete the final newline, any
763 * tags on the newline will go away, oddly. See comment in
764 * gtktextbtree.c. This is all sort of annoying, but really hard
767 gtk_signal_emit(GTK_OBJECT(buffer),
768 signals[DELETE_TEXT],
774 * gtk_text_buffer_delete:
775 * @buffer: a #GtkTextBuffer
776 * @start: a position in @buffer
777 * @end: another position in @buffer
779 * Deletes text between @start and @end. The order of @start and @end
780 * is not actually relevant; gtk_text_buffer_delete() will reorder
781 * them. This function actually emits the "delete_text" signal, and
782 * the default handler of that signal deletes the text. Because the
783 * buffer is modified, all outstanding iterators become invalid after
784 * calling this function; however, the @start and @end will be
785 * re-initialized to point to the location where text was deleted.
787 * Note that the final newline in the buffer may not be deleted; a
788 * #GtkTextBuffer always contains at least one newline. You can
789 * safely include the final newline in the range [@start,@end) but it
790 * won't be affected by the deletion.
794 gtk_text_buffer_delete (GtkTextBuffer *buffer,
798 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
799 g_return_if_fail(start != NULL);
800 g_return_if_fail(end != NULL);
802 gtk_text_buffer_emit_delete(buffer, start, end, FALSE);
806 * gtk_text_buffer_delete_interactive:
807 * @buffer: a #GtkTextBuffer
808 * @start_iter: start of range to delete
809 * @end_iter: end of range
810 * @default_editable: whether the buffer is editable by default
812 * Deletes all <emphasis>editable</emphasis> text in the given range.
813 * Calls gtk_text_buffer_delete() for each editable sub-range of
814 * [@start,@end). @start and @end are revalidated to point to
815 * the location of the last deleted range, or left untouched if
816 * no text was deleted.
818 * Return value: whether some text was actually deleted
821 gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
822 GtkTextIter *start_iter,
823 GtkTextIter *end_iter,
824 gboolean default_editable)
826 GtkTextMark *end_mark;
827 GtkTextMark *start_mark;
829 gboolean current_state;
830 gboolean deleted_stuff = FALSE;
832 /* Delete all editable text in the range start_iter, end_iter */
834 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
835 g_return_val_if_fail (start_iter != NULL, FALSE);
836 g_return_val_if_fail (end_iter != NULL, FALSE);
838 gtk_text_iter_reorder (start_iter, end_iter);
840 start_mark = gtk_text_buffer_create_mark (buffer, NULL,
842 end_mark = gtk_text_buffer_create_mark (buffer, NULL,
846 current_state = gtk_text_iter_editable (&iter, default_editable);
851 gboolean done = FALSE;
854 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
856 gtk_text_buffer_get_iter_at_mark (buffer, &end, end_mark);
858 if (gtk_text_iter_compare (&iter, &end) >= 0)
861 iter = end; /* clamp to the last boundary */
864 new_state = gtk_text_iter_editable (&iter, default_editable);
866 if (current_state == new_state)
872 /* We're ending an editable region. Delete said region. */
875 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
877 gtk_text_buffer_emit_delete (buffer, &start, &iter, TRUE);
879 deleted_stuff = TRUE;
881 /* revalidate user's iterators. */
892 if (current_state && !new_state)
894 /* End of an editable region. Delete it. */
897 gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
899 gtk_text_buffer_emit_delete (buffer, &start, &iter, TRUE);
901 current_state = FALSE;
902 deleted_stuff = TRUE;
904 /* revalidate user's iterators. */
910 /* We are at the start of an editable region. We won't be deleting
911 * the previous region. Move start mark to start of this region.
914 g_assert (!current_state && new_state);
916 gtk_text_buffer_move_mark (buffer, start_mark,
920 current_state = TRUE;
928 gtk_text_buffer_delete_mark (buffer, start_mark);
929 gtk_text_buffer_delete_mark (buffer, end_mark);
931 return deleted_stuff;
935 * Extracting textual buffer contents
939 * gtk_text_buffer_get_text:
940 * @buffer: a #GtkTextBuffer
941 * @start: start of a range
942 * @end: end of a range
943 * @include_hidden_chars: whether to include invisible text
945 * Returns the text in the range [@start,@end). Excludes undisplayed
946 * text (text marked with tags that set the invisibility attribute) if
947 * @include_hidden_chars is FALSE. Does not include characters
948 * representing embedded images, so byte and character indexes into
949 * the returned string do <emphasis>not</emphasis> correspond to byte
950 * and character indexes into the buffer. Contrast with
951 * gtk_text_buffer_get_slice().
953 * Return value: an allocated UTF-8 string
956 gtk_text_buffer_get_text (GtkTextBuffer *buffer,
957 const GtkTextIter *start,
958 const GtkTextIter *end,
959 gboolean include_hidden_chars)
961 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
962 g_return_val_if_fail(start != NULL, NULL);
963 g_return_val_if_fail(end != NULL, NULL);
965 if (include_hidden_chars)
966 return gtk_text_iter_get_text(start, end);
968 return gtk_text_iter_get_visible_text(start, end);
972 * gtk_text_buffer_get_slice:
973 * @buffer: a #GtkTextBuffer
974 * @start: start of a range
975 * @end: end of a range
976 * @include_hidden_chars: whether to include invisible text
978 * Returns the text in the range [@start,@end). Excludes undisplayed
979 * text (text marked with tags that set the invisibility attribute) if
980 * @include_hidden_chars is FALSE. The returned string includes a
981 * 0xFFFD character whenever the buffer contains
982 * embedded images, so byte and character indexes into
983 * the returned string <emphasis>do</emphasis> correspond to byte
984 * and character indexes into the buffer. Contrast with
985 * gtk_text_buffer_get_text().
987 * Return value: an allocated UTF-8 string
990 gtk_text_buffer_get_slice (GtkTextBuffer *buffer,
991 const GtkTextIter *start,
992 const GtkTextIter *end,
993 gboolean include_hidden_chars)
995 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
996 g_return_val_if_fail(start != NULL, NULL);
997 g_return_val_if_fail(end != NULL, NULL);
999 if (include_hidden_chars)
1000 return gtk_text_iter_get_slice(start, end);
1002 return gtk_text_iter_get_visible_slice(start, end);
1010 gtk_text_buffer_insert_pixbuf (GtkTextBuffer *buffer,
1014 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
1015 g_return_if_fail (iter != NULL);
1016 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
1018 gtk_text_btree_insert_pixbuf (iter, pixbuf);
1020 /* FIXME pixbuf-specific signal like insert_text */
1022 gtk_signal_emit (GTK_OBJECT(buffer), signals[CHANGED]);
1024 gtk_text_buffer_set_modified (buffer, TRUE);
1032 gtk_text_buffer_mark_set (GtkTextBuffer *buffer,
1033 const GtkTextIter *location,
1036 /* IMO this should NOT work like insert_text and delete_text,
1037 where the real action happens in the default handler.
1039 The reason is that the default handler would be _required_,
1040 i.e. the whole widget would start breaking and segfaulting
1041 if the default handler didn't get run. So you can't really
1042 override the default handler or stop the emission; that is,
1043 this signal is purely for notification, and not to allow users
1044 to modify the default behavior. */
1046 g_object_ref (G_OBJECT (mark));
1048 gtk_signal_emit(GTK_OBJECT(buffer),
1053 g_object_unref (G_OBJECT (mark));
1057 * gtk_text_buffer_set_mark:
1058 * @buffer: a #GtkTextBuffer
1059 * @mark_name: name of the mark
1060 * @iter: location for the mark.
1061 * @left_gravity: if the mark is created by this function, gravity for the new
1063 * @should_exist: if %TRUE, warn if the mark does not exist, and return
1066 * Move the mark to the given position, if not @should_exist, create the mark.
1068 * Return value: mark
1071 gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
1072 GtkTextMark *existing_mark,
1073 const gchar *mark_name,
1074 const GtkTextIter *iter,
1075 gboolean left_gravity,
1076 gboolean should_exist)
1078 GtkTextIter location;
1081 mark = gtk_text_btree_set_mark (get_btree (buffer),
1088 if (gtk_text_btree_mark_is_insert(get_btree (buffer), mark) ||
1089 gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
1091 gtk_text_buffer_update_primary_selection (buffer);
1094 gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1098 gtk_text_buffer_mark_set (buffer, &location, mark);
1104 * gtk_text_buffer_create_mark:
1105 * @buffer: a #GtkTextBuffer
1106 * @mark_name: name for mark, or %NULL
1107 * @where: location to place mark
1108 * @left_gravity: whether the mark has left gravity
1110 * Creates a mark at position @where. If @mark_name is %NULL, the mark
1111 * is anonymous; otherwise, the mark can be retrieved by name using
1112 * gtk_text_buffer_get_mark(). If a mark has left gravity, and text is
1113 * inserted at the mark's current location, the mark will be moved to
1114 * the left of the newly-inserted text. If the mark has right gravity
1115 * (@left_gravity = %FALSE), the mark will end up on the right of
1116 * newly-inserted text. The standard left-to-right cursor is a mark
1117 * with right gravity (when you type, the cursor stays on the right
1118 * side of the text you're typing).
1120 * The caller of this function does <emphasis>not</emphasis> own a reference
1121 * to the returned #GtkTextMark, so you can ignore the return value
1122 * if you like. Marks are owned by the buffer and go away when the
1125 * Emits the "mark_set" signal as notification of the mark's initial
1128 * Return value: the new #GtkTextMark object
1131 gtk_text_buffer_create_mark(GtkTextBuffer *buffer,
1132 const gchar *mark_name,
1133 const GtkTextIter *where,
1134 gboolean left_gravity)
1136 g_return_val_if_fail (GTK_IS_TEXT_BUFFER(buffer), NULL);
1138 return gtk_text_buffer_set_mark (buffer, NULL, mark_name, where,
1139 left_gravity, FALSE);
1143 * gtk_text_buffer_move_mark:
1144 * @buffer: a #GtkTextBuffer
1145 * @mark: a #GtkTextMark
1146 * @where: new location for @mark in @buffer
1148 * Moves @mark to the new location @where. Emits the "mark_set" signal
1149 * as notification of the move.
1152 gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
1154 const GtkTextIter *where)
1156 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1157 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1158 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
1160 gtk_text_buffer_set_mark (buffer, mark, NULL, where, FALSE, TRUE);
1164 * gtk_text_buffer_get_iter_at_mark:
1165 * @buffer: a #GtkTextBuffer
1166 * @iter: iterator to initialize
1167 * @mark: a #GtkTextMark in @buffer
1169 * Initializes @iter with the current position of @mark.
1172 gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
1176 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1177 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1178 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
1180 gtk_text_btree_get_iter_at_mark (get_btree (buffer),
1186 * gtk_text_buffer_delete_mark:
1187 * @buffer: a #GtkTextBuffer
1188 * @mark: a #GtkTextMark in @buffer
1190 * Deletes @mark, so that it's no longer located anywhere in the
1191 * buffer. Removes the reference the buffer holds to the mark, so if
1192 * you haven't called g_object_ref() on the mark, it will be freed. Even
1193 * if the mark isn't freed, most operations on @mark become
1194 * invalid. There is no way to undelete a
1195 * mark. gtk_text_mark_get_deleted() will return TRUE after this
1196 * function has been called on a mark; gtk_text_mark_get_deleted()
1197 * indicates that a mark no longer belongs to a buffer. The "mark_deleted"
1198 * signal will be emitted as notification after the mark is deleted.
1201 gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
1204 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
1205 g_return_if_fail (!gtk_text_mark_get_deleted (mark));
1206 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1208 g_object_ref (G_OBJECT (mark));
1210 gtk_text_btree_remove_mark (get_btree (buffer), mark);
1212 /* See rationale above for MARK_SET on why we emit this after
1213 * removing the mark, rather than removing the mark in a default
1216 gtk_signal_emit (GTK_OBJECT(buffer), signals[MARK_DELETED],
1219 g_object_unref (G_OBJECT (mark));
1223 * gtk_text_buffer_get_mark:
1224 * @buffer: a #GtkTextBuffer
1225 * @name: a mark name
1227 * Returns the mark named @name in buffer @buffer, or NULL if no such
1228 * mark exists in the buffer.
1230 * Return value: a #GtkTextMark, or NULL
1233 gtk_text_buffer_get_mark (GtkTextBuffer *buffer,
1238 g_return_val_if_fail (GTK_IS_TEXT_BUFFER(buffer), NULL);
1239 g_return_val_if_fail (name != NULL, NULL);
1241 mark = gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1248 * gtk_text_buffer_move_mark_by_name:
1249 * @buffer: a #GtkTextBuffer
1250 * @name: name of a mark
1251 * @where: new location for mark
1253 * Moves the mark named @name (which must exist) to location @where.
1254 * See gtk_text_buffer_move_mark() for details.
1257 gtk_text_buffer_move_mark_by_name (GtkTextBuffer *buffer,
1259 const GtkTextIter *where)
1263 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
1264 g_return_if_fail (name != NULL);
1266 mark = gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1270 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1274 gtk_text_buffer_move_mark (buffer, mark, where);
1278 * gtk_text_buffer_delete_mark_by_name:
1279 * @buffer: a #GtkTextBuffer
1280 * @name: name of a mark in @buffer
1282 * Deletes the mark named @name; the mark must exist. See
1283 * gtk_text_buffer_delete_mark() for details.
1286 gtk_text_buffer_delete_mark_by_name (GtkTextBuffer *buffer,
1291 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
1292 g_return_if_fail (name != NULL);
1294 mark = gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
1298 g_warning ("%s: no mark named '%s'", G_STRLOC, name);
1302 gtk_text_buffer_delete_mark (buffer, mark);
1306 * gtk_text_buffer_get_insert:
1307 * @buffer: a #GtkTextBuffer
1309 * Returns the mark that represents the cursor (insertion point).
1310 * Equivalent to calling gtk_text_buffer_get_mark() to get the mark
1311 * name "insert," but very slightly more efficient, and involves less
1314 * Return value: insertion point mark
1317 gtk_text_buffer_get_insert (GtkTextBuffer *buffer)
1319 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
1321 /* FIXME use struct member in btree */
1322 return gtk_text_buffer_get_mark (buffer, "insert");
1326 * gtk_text_buffer_get_selection_bound:
1327 * @buffer: a #GtkTextBuffer
1329 * Returns the mark that represents the selection bound. Equivalent
1330 * to calling gtk_text_buffer_get_mark() to get the mark name
1331 * "selection_bound," but very slightly more efficient, and involves
1334 * The currently-selected text in @buffer is the region between the
1335 * "selection_bound" and "insert" marks. If "selection_bound" and
1336 * "insert" are in the same place, then there is no current selection.
1337 * gtk_text_buffer_get_selection_bounds() is another convenient function
1338 * for handling the selection, if you just want to know whether there's a
1339 * selection and what its bounds are.
1341 * Return value: selection bound mark
1344 gtk_text_buffer_get_selection_bound (GtkTextBuffer *buffer)
1346 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
1348 /* FIXME use struct member in btree */
1349 return gtk_text_buffer_get_mark (buffer, "selection_bound");
1354 gtk_text_buffer_create_child_anchor (GtkTextBuffer *buffer,
1355 const GtkTextIter *where)
1357 /* FIXME: Implement? */
1363 gtk_text_buffer_move_child_anchor (GtkTextBuffer *buffer,
1364 GtkTextChildAnchor *anchor,
1372 gtk_text_buffer_delete_child_anchor (GtkTextBuffer *buffer,
1373 GtkTextChildAnchor *anchor)
1381 gtk_text_buffer_get_iter_at_child_anchor (GtkTextBuffer *buffer,
1383 GtkTextChildAnchor *anchor)
1390 * gtk_text_buffer_place_cursor:
1391 * @buffer: a #GtkTextBuffer
1392 * @where: where to put the cursor
1394 * This function moves the "insert" and "selection_bound" marks
1395 * simultaneously. If you move them to the same place in two steps
1396 * with gtk_text_buffer_move_mark(), you will temporarily select a
1397 * region in between their old and new locations, which can be pretty
1398 * inefficient since the temporarily-selected region will force stuff
1399 * to be recalculated. This function moves them as a unit, which can
1403 gtk_text_buffer_place_cursor (GtkTextBuffer *buffer,
1404 const GtkTextIter *where)
1408 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1412 if (gtk_text_iter_is_last (&real))
1413 gtk_text_iter_prev_char (&real);
1415 gtk_text_btree_place_cursor (get_btree (buffer), &real);
1416 gtk_text_buffer_mark_set (buffer, &real,
1417 gtk_text_buffer_get_mark (buffer,
1419 gtk_text_buffer_mark_set (buffer, &real,
1420 gtk_text_buffer_get_mark (buffer,
1421 "selection_bound"));
1429 * gtk_text_buffer_create_tag:
1430 * @buffer: a #GtkTextBuffer
1431 * @tag_name: name of the new tag, or %NULL
1433 * Creates a tag and adds it to the tag table for @buffer.
1434 * Equivalent to calling gtk_text_tag_new() and then adding the
1435 * tag to the buffer's tag table. The returned tag has its refcount
1436 * incremented, as if you'd called gtk_text_tag_new().
1438 * If @tag_name is %NULL, the tag is anonymous.
1440 * Return value: a new tag
1443 gtk_text_buffer_create_tag(GtkTextBuffer *buffer,
1444 const gchar *tag_name)
1448 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
1450 tag = gtk_text_tag_new(tag_name);
1452 gtk_text_tag_table_add(get_table (buffer), tag);
1458 gtk_text_buffer_real_apply_tag (GtkTextBuffer *buffer,
1460 const GtkTextIter *start,
1461 const GtkTextIter *end)
1463 gtk_text_btree_tag (start, end, tag, TRUE);
1467 gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
1469 const GtkTextIter *start,
1470 const GtkTextIter *end)
1472 gtk_text_btree_tag (start, end, tag, FALSE);
1477 gtk_text_buffer_emit_tag(GtkTextBuffer *buffer,
1480 const GtkTextIter *start,
1481 const GtkTextIter *end)
1483 GtkTextIter start_tmp = *start;
1484 GtkTextIter end_tmp = *end;
1486 g_return_if_fail(tag != NULL);
1488 gtk_text_iter_reorder (&start_tmp, &end_tmp);
1491 gtk_signal_emit (GTK_OBJECT(buffer), signals[APPLY_TAG],
1492 tag, &start_tmp, &end_tmp);
1494 gtk_signal_emit (GTK_OBJECT(buffer), signals[REMOVE_TAG],
1495 tag, &start_tmp, &end_tmp);
1500 gtk_text_buffer_apply_tag(GtkTextBuffer *buffer,
1502 const GtkTextIter *start,
1503 const GtkTextIter *end)
1505 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1506 g_return_if_fail(GTK_IS_TEXT_TAG (tag));
1507 g_return_if_fail(start != NULL);
1508 g_return_if_fail(end != NULL);
1510 gtk_text_buffer_emit_tag(buffer, tag, TRUE, start, end);
1514 gtk_text_buffer_remove_tag(GtkTextBuffer *buffer,
1516 const GtkTextIter *start,
1517 const GtkTextIter *end)
1520 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1521 g_return_if_fail(GTK_IS_TEXT_TAG (tag));
1522 g_return_if_fail(start != NULL);
1523 g_return_if_fail(end != NULL);
1525 gtk_text_buffer_emit_tag(buffer, tag, FALSE, start, end);
1530 gtk_text_buffer_apply_tag_by_name (GtkTextBuffer *buffer,
1532 const GtkTextIter *start,
1533 const GtkTextIter *end)
1537 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1538 g_return_if_fail(name != NULL);
1539 g_return_if_fail(start != NULL);
1540 g_return_if_fail(end != NULL);
1542 tag = gtk_text_tag_table_lookup(get_table (buffer),
1547 g_warning("Unknown tag `%s'", name);
1551 gtk_text_buffer_emit_tag(buffer, tag, TRUE, start, end);
1555 gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
1557 const GtkTextIter *start,
1558 const GtkTextIter *end)
1562 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1563 g_return_if_fail(name != NULL);
1564 g_return_if_fail(start != NULL);
1565 g_return_if_fail(end != NULL);
1567 tag = gtk_text_tag_table_lookup(get_table (buffer),
1572 g_warning("Unknown tag `%s'", name);
1576 gtk_text_buffer_emit_tag(buffer, tag, FALSE, start, end);
1581 * Obtain various iterators
1585 gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
1590 g_return_if_fail (iter != NULL);
1591 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
1593 gtk_text_btree_get_iter_at_line_char (get_btree (buffer),
1594 iter, line_number, char_offset);
1598 gtk_text_buffer_get_iter_at_line_index (GtkTextBuffer *buffer,
1603 g_return_if_fail (iter != NULL);
1604 g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
1606 gtk_text_btree_get_iter_at_line_byte (get_btree (buffer),
1607 iter, line_number, byte_index);
1611 gtk_text_buffer_get_iter_at_line (GtkTextBuffer *buffer,
1615 g_return_if_fail(iter != NULL);
1616 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1618 gtk_text_buffer_get_iter_at_line_offset (buffer, iter, line_number, 0);
1622 gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer,
1626 g_return_if_fail(iter != NULL);
1627 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1629 gtk_text_btree_get_iter_at_char(get_btree (buffer), iter, char_offset);
1633 gtk_text_buffer_get_last_iter (GtkTextBuffer *buffer,
1636 g_return_if_fail(iter != NULL);
1637 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1639 gtk_text_btree_get_last_iter(get_btree (buffer), iter);
1643 gtk_text_buffer_get_bounds (GtkTextBuffer *buffer,
1647 g_return_if_fail(start != NULL);
1648 g_return_if_fail(end != NULL);
1649 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1651 gtk_text_btree_get_iter_at_char(get_btree (buffer), start, 0);
1652 gtk_text_btree_get_last_iter(get_btree (buffer), end);
1660 gtk_text_buffer_modified (GtkTextBuffer *buffer)
1662 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
1664 return buffer->modified;
1668 gtk_text_buffer_set_modified (GtkTextBuffer *buffer,
1671 gboolean fixed_setting;
1673 g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
1675 fixed_setting = setting != FALSE;
1677 if (buffer->modified == fixed_setting)
1681 buffer->modified = fixed_setting;
1682 gtk_signal_emit(GTK_OBJECT(buffer), signals[MODIFIED_CHANGED]);
1688 * Assorted other stuff
1692 gtk_text_buffer_get_line_count(GtkTextBuffer *buffer)
1694 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), 0);
1696 return gtk_text_btree_line_count(get_btree (buffer));
1700 gtk_text_buffer_get_char_count(GtkTextBuffer *buffer)
1702 g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), 0);
1704 return gtk_text_btree_char_count(get_btree (buffer));
1708 gtk_text_buffer_get_tags (GtkTextBuffer *buffer,
1709 const GtkTextIter *iter)
1711 GSList *retval = NULL;
1715 tags = gtk_text_btree_get_tags(iter, &count);
1721 gtk_text_tag_array_sort(tags, count);
1726 retval = g_slist_prepend(retval, tags[i]);
1730 retval = g_slist_reverse(retval);
1739 /* Called when we lose the primary selection.
1742 clipboard_clear_cb (GtkClipboard *clipboard,
1745 /* Move selection_bound to the insertion point */
1747 GtkTextIter selection_bound;
1748 GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
1750 gtk_text_buffer_get_iter_at_mark(buffer, &insert,
1751 gtk_text_buffer_get_mark (buffer, "insert"));
1752 gtk_text_buffer_get_iter_at_mark(buffer, &selection_bound,
1753 gtk_text_buffer_get_mark (buffer, "selection_bound"));
1755 if (!gtk_text_iter_equal(&insert, &selection_bound))
1756 gtk_text_buffer_move_mark(buffer,
1757 gtk_text_buffer_get_mark (buffer, "selection_bound"),
1761 /* Called when we have the primary selection and someone else wants our
1762 * data in order to paste it.
1765 clipboard_get_cb (GtkClipboard *clipboard,
1766 GtkSelectionData *selection_data,
1770 GtkTextBuffer *buffer = GTK_TEXT_BUFFER(data);
1772 GtkTextIter start, end;
1774 if (gtk_text_buffer_get_selection_bounds(buffer, &start, &end))
1776 /* Extract the selected text */
1777 str = gtk_text_iter_get_visible_text(&start, &end);
1778 gtk_selection_data_set_text (selection_data, str);
1783 /* Called when we request a paste and receive the data
1786 clipboard_received (GtkClipboard *clipboard,
1790 ClipboardRequest *request_data = data;
1791 GtkTextBuffer *buffer = request_data->buffer;
1796 GtkTextIter insert_point;
1797 GtkTextMark *paste_point_override;
1799 paste_point_override = gtk_text_buffer_get_mark (buffer,
1800 "gtk_paste_point_override");
1802 if (paste_point_override != NULL)
1804 gtk_text_buffer_get_iter_at_mark(buffer, &insert_point,
1805 paste_point_override);
1806 gtk_text_buffer_delete_mark(buffer,
1807 gtk_text_buffer_get_mark (buffer,
1808 "gtk_paste_point_override"));
1812 gtk_text_buffer_get_iter_at_mark(buffer, &insert_point,
1813 gtk_text_buffer_get_mark (buffer,
1819 /* FIXME ALL OF THIS - I think that the "best method" is that when pasting
1820 * with the cursor inside the selection area, you replace the selection
1821 * with the new text, otherwise, you simply insert the new text at
1822 * the point where the click occured, unselecting any selected text.
1824 * This probably is best implemented as a "replace_selection" flag in
1828 if ((TRUE/* Text is selected FIXME */) &&
1829 (!buffer->have_selection || request_data->is_clipboard))
1833 if (buffer->have_selection)
1835 /* FIXME Delete currently-selected chars but don't give up X
1836 selection since we'll use the newly-pasted stuff as
1837 a new X selection */
1841 ; /* FIXME Delete selected chars and give up X selection */
1845 if (request_data->interactive)
1846 gtk_text_buffer_insert_interactive (buffer, &insert_point,
1847 str, -1, request_data->default_editable);
1849 gtk_text_buffer_insert (buffer, &insert_point,
1853 ; /* FIXME Select the region of text we just inserted */
1856 g_object_unref (G_OBJECT (buffer));
1857 g_free (request_data);
1861 gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
1863 static const GtkTargetEntry targets[] = {
1864 { "STRING", 0, TARGET_STRING },
1865 { "TEXT", 0, TARGET_TEXT },
1866 { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
1867 { "UTF8_STRING", 0, TARGET_UTF8_STRING }
1873 GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1875 /* Determine whether we have a selection and adjust X selection
1879 if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1881 if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
1882 gtk_clipboard_clear (clipboard);
1886 /* Even if we already have the selection, we need to update our
1889 if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
1890 clipboard_get_cb, clipboard_clear_cb, G_OBJECT (buffer)))
1891 clipboard_clear_cb (clipboard, buffer);
1896 paste (GtkTextBuffer *buffer,
1897 gboolean is_clipboard,
1898 gboolean interactive,
1899 gboolean default_editable)
1901 ClipboardRequest *data = g_new (ClipboardRequest, 1);
1903 data->buffer = buffer;
1904 g_object_ref (G_OBJECT (buffer));
1905 data->interactive = interactive;
1906 data->default_editable = default_editable;
1908 gtk_clipboard_request_text (gtk_clipboard_get (is_clipboard ? GDK_NONE : GDK_SELECTION_PRIMARY),
1909 clipboard_received, data);
1913 gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
1914 GtkTextIter *override_location,
1915 gboolean default_editable)
1917 if (override_location != NULL)
1918 gtk_text_buffer_create_mark(buffer,
1919 "gtk_paste_point_override",
1920 override_location, FALSE);
1922 paste (buffer, FALSE, TRUE, default_editable);
1926 gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
1927 gboolean default_editable)
1929 paste (buffer, TRUE, TRUE, default_editable);
1933 gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
1934 gboolean interactive,
1935 gboolean default_editable)
1940 if (!gtk_text_buffer_get_selection_bounds(buffer, &start, &end))
1942 return FALSE; /* No selection */
1947 gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable);
1949 gtk_text_buffer_delete (buffer, &start, &end);
1951 return TRUE; /* We deleted stuff */
1956 cut_or_copy(GtkTextBuffer *buffer,
1957 gboolean delete_region_after,
1958 gboolean interactive,
1959 gboolean default_editable)
1961 /* We prefer to cut the selected region between selection_bound and
1962 insertion point. If that region is empty, then we cut the region
1963 between the "anchor" and the insertion point (this is for C-space
1964 and M-w and other Emacs-style copy/yank keys). Note that insert
1965 and selection_bound are guaranteed to exist, but the anchor only
1966 exists sometimes. */
1970 if (!gtk_text_buffer_get_selection_bounds(buffer, &start, &end))
1972 /* Let's try the anchor thing */
1973 GtkTextMark * anchor = gtk_text_buffer_get_mark (buffer, "anchor");
1979 gtk_text_buffer_get_iter_at_mark(buffer, &end, anchor);
1980 gtk_text_iter_reorder(&start, &end);
1984 if (!gtk_text_iter_equal(&start, &end))
1986 GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
1989 text = gtk_text_iter_get_visible_text (&start, &end);
1990 gtk_clipboard_set_text (clipboard, text, -1);
1993 if (delete_region_after)
1996 gtk_text_buffer_delete_interactive (buffer, &start, &end,
1999 gtk_text_buffer_delete (buffer, &start, &end);
2005 gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
2006 gboolean default_editable)
2008 cut_or_copy (buffer, TRUE, TRUE, default_editable);
2012 gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer)
2014 cut_or_copy (buffer, FALSE, TRUE, TRUE);
2019 * gtk_text_buffer_get_selection_bounds:
2020 * @buffer: a #GtkTextBuffer
2021 * @start: iterator to initialize with selection start
2022 * @end: iterator to initialize with selection end
2024 * Returns %TRUE if some text is selected; places the bounds
2025 * of the selection in @start and @end (if the selection has length 0,
2026 * then @start and @end are filled in with the same value).
2027 * @start and @end will be in ascending order. If @start and @end are
2028 * NULL, then they are not filled in, but the return value still indicates
2029 * whether text is selected.
2031 * Return value: whether the selection has nonzero length
2034 gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
2038 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2040 return gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
2049 _gtk_text_buffer_spew(GtkTextBuffer *buffer)
2051 gtk_text_btree_spew(get_btree (buffer));