<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2001/XInclude" type="guide" style="task" id="textview.py" xml:lang="sv">
  <info>
    <title type="text">TextView (Python)</title>
    <link type="guide" xref="beginner.py#multiline"/>
    <link type="seealso" xref="strings.py"/>
    <link type="seealso" xref="scrolledwindow.py"/>
    <link type="next" xref="dialog.py"/>
    <revision version="0.2" date="2012-06-19" status="draft"/>

    <credit type="author copyright">
      <name>Sebastian Pölsterl</name>
      <email its:translate="no">sebp@k-d-w.org</email>
      <years>2011</years>
    </credit>

    <credit type="author copyright editor">
      <name>Marta Maria Casetti</name>
      <email its:translate="no">mmcasetti@gmail.com</email>
      <years>2012</years>
    </credit>

    <desc>Widget that displays a GtkTextBuffer</desc>
  
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
      <mal:name>Anders Jonsson</mal:name>
      <mal:email>anders.jonsson@norsjovallen.se</mal:email>
      <mal:years>2018</mal:years>
    </mal:credit>
  </info>

  <title>TextView</title>

  <note style="sidebar"><p>This is an example of Gtk.TextView.</p>
  <p>If we press "enter", we have a new line.</p>
  <p>But we can also have a new line if we write a long sentence (the text will wrap breaking lines between words).</p>
  <p>If we have a loooooooooooooooooooooooooooooooooooong</p>
  <p>(that was long)</p>
  <p>word, an horizontal scrollbar will appear.</p></note>

  <media type="image" mime="image/png" src="media/textview.png"/>

  <links type="section"/>

  <section id="code">
  <title>Code used to generate this example</title>

  <code mime="text/x-python" style="numbered">from gi.repository import Gtk
import sys


class MyWindow(Gtk.ApplicationWindow):

    def __init__(self, app):
        Gtk.Window.__init__(self, title="TextView Example", application=app)
        self.set_default_size(300, 450)

        # a scrollbar for the child widget (that is going to be the textview)
        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.set_border_width(5)
        # we scroll only if needed
        scrolled_window.set_policy(
            Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)

        # a text buffer (stores text)
        buffer1 = Gtk.TextBuffer()

        # a textview (displays the buffer)
        textview = Gtk.TextView(buffer=buffer1)
        # wrap the text, if needed, breaking lines in between words
        textview.set_wrap_mode(Gtk.WrapMode.WORD)

        # textview is scrolled
        scrolled_window.add(textview)

        self.add(scrolled_window)


class MyApplication(Gtk.Application):

    def __init__(self):
        Gtk.Application.__init__(self)

    def do_activate(self):
        win = MyWindow(self)
        win.show_all()

    def do_startup(self):
        Gtk.Application.do_startup(self)

app = MyApplication()
exit_status = app.run(sys.argv)
sys.exit(exit_status)
</code>
  </section>

  <section id="methods">
  <title>Useful methods for a TextView widget</title>
  <p>A <code>Gtk.TextView</code> displays the text stored in a <code>Gtk.TextBuffer</code>. However, most text manipulation is accomplished with iterators, represented by a <code>Gtk.TextIter</code> - a position between two characters in the text buffer. Iterators are not valid indefinitely; whenever the buffer is modified in a way that affects the contents of the buffer, all outstanding iterators become invalid. Because of this, iterators can’t be used to preserve positions across buffer modifications. To preserve a position, we use a <code>Gtk.TextMark</code>, that can be set visible with <code>visible(True)</code>. A text buffer contains two built-in marks; an "insert" mark (the position of the cursor) and the "selection_bound" mark.</p>
  <p>Methods for a TextView widget:</p>
  <list>
    <item><p>The TextView widget is by default editable. If you prefer otherwise, use <code>set_editable(False)</code>. If the buffer has no editable text, it might be a good idea to use <code>set_cursor_visible(False)</code> as well.</p></item>
    <item><p>The justification of the text is set with <code>set_justification(Gtk.Justification.JUSTIFICATION)</code> where <code>JUSTIFICATION</code> is one of <code>LEFT, RIGHT, CENTER, FILL</code>.</p></item>
    <item><p>The line wrapping of the text is set with <code>set_wrap_mode(Gtk.WrapMode.WRAP)</code> where <code>WRAP</code> is one of <code>NONE</code> (the text area is made wider), <code>CHAR</code> (break lines anywhere the cursor can appear), <code>WORD</code> (break lines between words), <code>WORD_CHAR</code> (break lines between words, but if that is not enough between characters).</p></item>
  </list>
  <p>Methods for a TextBuffer widget:</p>
  <list>
    <item><p><code>get_insert()</code> returns the <code>Gtk.TextMark</code> that represents the cursor, that is the insertion point.</p></item>
    <item><p><code>get_selection_bound()</code> returns the <code>Gtk.TextMark</code> that represents the selection bound.</p></item>
    <item><p><code>set_text("some text", length)</code> where <code>length</code> is a positive integer or <code>-1</code>, sets the content of the buffer as the first <code>length</code> characters of the <code>"some text"</code> text. If <code>length</code> is omitted or <code>-1</code>, the text is inserted completely. The content of the buffer, if there is any, is destroyed.</p></item>
    <item><p><code>insert(iter, "some text", length)</code> where <code>iter</code> is a text iterator and <code>length</code> is a positive integer or <code>-1</code>, inserts in the buffer at <code>iter</code> the first <code>length</code> characters of the <code>"some text"</code> text. If <code>length</code> is omitted or <code>-1</code>, the text is inserted completely.</p></item>
    <item><p><code>insert_at_cursor("some text", length)</code> does the same as <code>insert(iter, "some text", length)</code>, with the current cursor taken as <code>iter</code>.</p></item>
    <item><p><code>create_mark("mark_name", iter, left_gravity)</code> where <code>iter</code> is a <code>Gtk.TextIter</code> and <code>left_gravity</code> is a boolean, creates a <code>Gtk.TextMark</code> at the position of <code>iter</code>. If <code>"mark_name"</code> is <code>None</code>, the mark is anonymous; otherwise, the mark can be retrieved by name using <code>get_mark()</code>. If a mark has left gravity, and text is inserted at the mark’s current location, the mark will be moved to the left of the newly-inserted text. If <code>left_gravity</code> is omitted, it defaults to <code>False</code>.
</p></item>
    <item><p>To specify that some text in the buffer should have specific formatting, you must define a tag to hold that formatting information, and then apply that tag to the region of text using <code>create_tag("tag name", property)</code> and <code>apply_tag(tag, start_iter, end_iter)</code> as in, for instance:</p>
      <code>
tag = textbuffer.create_tag("orange_bg", background="orange")
textbuffer.apply_tag(tag, start_iter, end_iter)</code>
     <p>The following are some of the common styles applied to text:</p>
      <list>
        <item><p>Background colour ("background" property)</p></item>
        <item><p>Foreground colour ("foreground" property)</p></item>
        <item><p>Underline ("underline" property)</p></item>
        <item><p>Bold ("weight" property)</p></item>
        <item><p>Italics ("style" property)</p></item>
        <item><p>Strikethrough ("strikethrough" property)</p></item>
        <item><p>Justification ("justification" property)</p></item>
        <item><p>Size ("size" and "size-points" properties)</p></item>
        <item><p>Text wrapping ("wrap-mode" property)</p></item>
      </list>
    <p>You can also delete particular tags later using <code>remove_tag()</code> or delete all tags in a given region by calling <code>remove_all_tags()</code>.</p></item>
  </list>
  <p>Methods for a TextIter widget</p>
  <list>
    <item><p><code>forward_search(needle, flags, limit)</code> searches forward for <code>needle</code>. The search will not continue past the <code>Gtk.TextIter</code> limit. The <code>flags</code> can be set to one of the following, or any combination of it by concatenating them with the bitwise-OR operator <code>|</code>: <code>0</code> (the match must be exact); <code>Gtk.TextSearchFlags.VISIBLE_ONLY</code> (the match may have invisible text interspersed in needle); <code>Gtk.TextSearchFlags.TEXT_ONLY</code> (the match may have pixbufs or child widgets mixed inside the matched range); <code>Gtk.TextSearchFlags.CASE_INSENSITIVE</code> (the text will be matched regardless of what case it is in). The method returns a tuple containing a <code>Gtk.TextIter</code> pointing to the start and to the first character after the match; if no match is found, <code>None</code> is returned.</p></item>
    <item><p><code>backward_search(needle, flags, limit)</code> does the same as <code>forward_search()</code>, but moving backwards.</p></item>
  </list>
  </section>

  <section id="references">
  <title>API-referenser</title>
  <p>In this sample we used the following:</p>
  <list>
    <item><p><link href="http://developer.gnome.org/gtk3/unstable/GtkTextView.html">GtkTextView</link></p></item>
    <item><p><link href="http://developer.gnome.org/gtk3/unstable/GtkTextBuffer.html">GtkTextBuffer</link></p></item>
    <item><p><link href="http://developer.gnome.org/gtk3/unstable/GtkTextTag.html">GtkTextTag</link></p></item>
    <item><p><link href="http://developer.gnome.org/gtk3/unstable/GtkScrolledWindow.html">GtkScrolledWindow</link></p></item>
    <item><p><link href="http://developer.gnome.org/gtk3/unstable/gtk3-Standard-Enumerations.html">Standard Enumerations</link></p></item>
  </list>
  </section>
</page>
