13.3. Text Buffers

A TextBuffer is the core component of the PyGTK text editing system. It contains the text, the TextTags in a TextTagTable and the TextMarks which together describe how the text is to be displayed and allow a user to interactively modify the text and text display. As noted in the previous section a TextBuffer is associated with one or more TextViews which display the TextBuffer contents.

A TextBuffer can be created automatically when a TextView is created or it can be created with the function:

  textbuffer = TextBuffer(table=None)

where table is a TextTagTable. If table is not specified (or is None) a TextTagTable will be created for the TextBuffer.

There are a large number of methods that can be used to:

13.3.1. TextBuffer Status Information

You can retrieve the number of lines in a textbuffer by using the method:

  line_count = textbuffer.get_line_count()

Likewise you can get the number of characters in the textbuffer using:

  char_count = textbuffer.get_char_count()

When the textbuffer contents are changed the modified flag in the textbuffer is set. The status of the modified flag can be retrieved using the method:

  modified = textbuffer.get_modified()

If the program saves the contents of the textbuffer the following method can be used to reset the modified flag:

  textbuffer.set_modified(setting)

13.3.2. Creating TextIters

A TextIter is used to specify a location within a TextBuffer between two characters. TextBuffer methods that manipulate text use TextIters to specify where the method is to be applied. TextIters have a large number of methods that will be described in the >TextIters section.

The basic TextBuffer methods used to create TextIters are:

  iter = textbuffer.get_iter_at_offset(char_offset)

  iter = textbuffer_get_iter_at_line(line_number)

  iter = textbuffer.get_iter_at_line_offset(line_number, line_offset)

  iter = textbuffer.get_iter_at_mark(mark)

get_iter_at_offset() creates an iter that is just after char_offset chars from the start of the textbuffer.

get_iter_at_line() creates an iter that is just before the first character in line_number.

get_iter_at_line_offset() creates an iter that is just after the line_offset character in line_number.

get_iter_at_mark() creates an iter that is at the same position as the given mark.

The following methods create one or more TextIters at specific buffer locations:

  startiter = textbuffer.get_start_iter()

  enditer = textbuffer_get_end_iter()

  startiter, enditer = textbuffer.get_bounds()

  start, end = textbuffer.get_selection_bounds()

get_start_iter() creates an iter that is just before the first character in the textbuffer.

get_end_iter() creates an iter that is just after the last character in the textbuffer.

get_bounds() creates a tuple of two iters that are just before the first character and just after the last character in the textbuffer respectively.

get_selection_bounds() creates a tuple of two iters that have the same location as the insert and selection_bound marks in the textbuffer.

13.3.3. Text Insertion, Retrieval and Deletion

The text in a TextBuffer can be set using the method:

  textbuffer.set_text(text)

This method replaces the current contents of textbuffer with text.

The most general method to insert characters in a textbuffer is:

  textbuffer.insert(iter, text)

which inserts text at the textbuffer location specified by iter.

If you want to simulate the insertion of text by an interactive user use the method:

  result = textbuffer.insert_interactive(iter, text, default_editable)

which inserts text in the textbuffer at the location specified by iter but only if the location is editable (i.e. does not have a tag that specifies the text is non-editable) and the default_editable value is TRUE. The result indicates whether the text was inserted.

default_editable indicates the editability of text that doesn't have a tag affecting editability; default_editable is usually determined by a call to the TextView get_editable() method.

Other methods that insert text are:

  textbuffer.insert_at_cursor(text)

  result = textbuffer.insert_at_cursor_interactive(text, default_editable)

  textbuffer.insert_range(iter, start, end)

  result = textbuffer.insert_range_interactive(iter, start, end, default_editable)

insert_at_cursor() is a convenience method that inserts text at the current cursor (insert) location.

insert_range() copies text, pixbufs and tags between start and end from a TextBuffer (if different from textbuffer the tag table must be the same) and inserts the copy into textbuffer at iter's location.

The interactive versions of these methods operate the same way except they will only insert if the location is editable.

Finally, text can be inserted and have tags applied at the same time using the methods:

  textbuffer.insert_with_tags(iter, text, tag1, tag2, ...)
  
  textbuffer.insert_with_tags_by_name(iter, text, tagname1, tagname2, ...)

insert_with_tags() inserts the text in the textbuffer at the location specified by iter and applies the given tags.

insert_with_tags_by_name() does that same thing but allows you to specify the tags using the tag name.

The text in a textbuffer can be deleted by using the methods:

  textbuffer.delete(start, end)
  
  result = textbuffer.delete_interactive(start, end, default_editable)

delete() removes the text between the start and end TextIter locations in textbuffer.

delete_interactive() removes all the editable (as determined by the applicable text tags and the default_editable argument) text between start and end.

You can retrieve a copy of the text from a textbuffer by using the methods:

  text = textbuffer.get_text(start, end, include_hidden_chars=TRUE)

  text = textbuffer.get_slice(start, end, include_hidden_chars=TRUE)

get_text() returns a copy of the text in textbuffer between start and end; undisplayed text is excluded if include_hidden_chars is FALSE. Characters which represent embedded images or widgets are excluded.

get_slice() is the same as get_text() except that the returned text includes a 0xFFFC character for each embedded image or widget.

13.3.4. TextMarks

TextMarks are similar to TextIters in that they specify a location in a TextBuffer between two characters. However, TextMarks maintain their location information across buffer modifications. The TextMark methods will be described in the TextMarks section.

A textbuffer contains two built-in marks: the insert (cursor) mark and the selection_bound mark. The insert mark is the default location for the insertion of text and the selection_bound mark combines with the insert mark to define a selection range.

The built-in marks can be retrieved by using the methods:

  insertmark = textbuffer.get_insert()

  selection_boundmark = textbuffer.get_selection_bound()

The insert and selection_bound marks can be placed simultaneously at a location by using the method:

  textbuffer.place_cursor(where)

where is a textiter specifying the location. The place_cursor() method is needed to avoid temporarily creating a selection if the marks were moved individually.

TextMarks are created by using the method:

  mark = textbuffer.create_mark(mark_name, where, left_gravity=FALSE)

where mark_name is the name assigned to the created mark (can be None to create an anonymous mark), where is the textiter specifying the location of the mark in textbuffer and left_gravity indicates where the mark will be located after text is inserted at the mark (left if TRUE or right if FALSE).

A mark can be moved in the textbuffer by using the methods:

  textbuffer.move_mark(mark, where)

  textbuffer.move_mark_by_name(name, where)

mark specifies the mark to be moved. name specifies the name of the mark to be moved. where is a textiter specifying the new location.

A mark can be deleted from a textbuffer by using the methods:

  textbuffer.delete_mark(mark)

  textbuffer.delete_mark_by_name(name)

A mark can be retrieved by name using the method:

  mark = textbuffer.get_mark(name)

13.3.5. Creating and Applying TextTags

TextTags contain one or more attributes (e.g. foreground and background colors, font, editability) that can be applied to one or more ranges of text in a TextBuffer. The attributes that can be specified by TextTag properties will be described in Section 13.6.1, “Text Tags”.

A TextTag can be created with attributes and installed in the TextTagTable of a TextBuffer by using the convenience method:

  tag = textbuffer.create_tag(name=None, attr1=val1, attr2=val2, ...)

where name is a string specifying the name of the tag or None if the tag is an anonymous tag and the keyword-value pairs specify the attributes that the tag will have. See the TextTag> section for information on what attributes can be set by the TextTag properties.

A tag can be applied to a range of text in a textbuffer by using the methods:

  textbuffer.apply_tag(tag, start, end)

  textbuffer.apply_tag_by_name(name, start, end)

tag is the tag to be applied to the text. name is the name of the tag to be applied. start and end are textiters that specify the range of text that the tag is to be applied to.

A tag can be removed from a range of text by using the methods:

  textbuffer.remove_tag(tag, start, end)

  textbuffer.remove_tag_by_name(name, start, end)

All tags for a range of text can be removed by using the method:

  textbuffer.remove_all_tags(start, end)

13.3.6. Inserting Images and Widgets

In addition to text a TextBuffer can contain pixbuf images and an anchor location for widgets. A widget can be added to a TextView at an anchor location. A different widget can be added in each TextView which displays a buffer with an anchor.

A pixbuf can be inserted by using the method:

  textbuffer.insert_pixbuf(iter, pixbuf)

where iter specifies the location in the textbuffer to insert the pixbuf. The image will be counted as one character and will be represented in a get_slice() return (but left out of a get_text() return) as the Unicode character "0xFFFC".

A GTK+ widget can be inserted in a TextView at a buffer location specified with a TextChildAnchor. The TextChildAnchor will be counted as one character and represented as "0xFFFC" similar to a pixbuf.

The TextChildAnchor can be created and inserted in the buffer by using the convenience method:

  anchor = text_buffer.create_child_anchor(iter)

where iter is the location for the child_anchor.

A TextChildAnchor can also be created and inserted in two operations as:

  anchor = gtk.TextChildAnchor()

  text_buffer.insert_child_anchor(iter, anchor)

Then the widget can be added to the TextView at an anchor location using the method:

  text_view.add_child_at_anchor(child, anchor)

The list of widgets at a particular buffer anchor can be retrieved using the method:

  widget_list = anchor.get_widgets()

A widget can also be added to a TextView using the method:

  text_view.add_child_in_window(child, which_window, xpos, ypos)

where the child widget is placed in which_window at the location specified by xpos and ypos. which_window indicates in which of the windows that make up the TextView the widget is to be placed:

  gtk.TEXT_WINDOW_TOP
  gtk.TEXT_WINDOW_BOTTOM
  gtk.TEXT_WINDOW_LEFT
  gtk.TEXT_WINDOW_RIGHT
  gtk.TEXT_WINDOW_TEXT
  gtk.TEXT_WINDOW_WIDGET