pgtextview API documentation

# Module `pgtextview`

Expand source code

    #!/usr/bin/env python

    import os, sys, getopt, signal, random, time, warnings

    #from pgutil import  *
    #from pgui import  *

    import pgutils

    import gi
    gi.require_version("Gtk", "3.0")
    from gi.repository import Gtk
    from gi.repository import Gdk
    from gi.repository import GLib
    from gi.repository import GObject
    from gi.repository import Pango

    import pgbox

    # Colors for editor selection. Use X11 color names.

    font_colors =   \
            (
                # Color name; RGBA for display
                ("Black",       "#000000ff"),  ("White",       "#ffffffff"),
                ("Red",         "#ff0000ff"),  ("Green",       "#00ff00ff"),
                ("Blue",        "#0000ffff"),  ("Orange",      "#ff8800ff"),
                ("Yellow",      "#ffff00ff"),  ("Brown",       "#885500ff"),
                ("Cyan"   ,     "#00ffffff"),  ("Purple",      "#ff00ffff"),
                ("OrangeRed",    "#ff8888ff"), ("LightBlue",   "#8888ffff"),
                ("LightGreen",  "#88ff88ff"),  ("Gray",        "#888888ff"),
                ("LightGray",   "#aaaaaaff"),  ("Gold",        "#FFD700FF"),
                ("LightYellow", "#aaaaaa99ff"),  ("Gold",        "#FFD700FF"),
            )

    font_sizes =      \
                (
                "7", "8", "9", "10", "12", "14", "18", "22", "24", "32", "36", "48", "64"
                )

    class pgTextView(Gtk.VBox):

        def __init__(self, status = False):

            self.statstr = None
            Gtk.VBox.__init__(self)

            self.tagtablex = []
            self.callb = None
            self.grid = Gtk.Grid()
            self.add(self.grid)

            self._create_textview()
            self._create_toolbar()
            self._create_toolbar2()
            self._create_buttons()

            # Status bar
            self.statstr = Gtk.Label.new("Idle")
            self.statstr.set_halign(Gtk.Align.START)

            if  status:
                hstat = Gtk.HBox()
                hstat.pack_start(Gtk.Label.new("  Status:  "), 0, 0, 0)
                hstat.pack_start(Gtk.Label.new(" "), 0, 0, 0)
                hstat.pack_start(self.statstr, 1, 1, 0)

                self.grid.attach(hstat, 0, 4, 3, 1)

            self.textview.connect("key-press-event", self.area_key)
            self.textview.connect("move-cursor", self.area_curs)
            self.connect("button-press-event", self.area_button)
            #self.textview.connect("focus-out-event", self.focus_out)
            self.findcall = None;

        def  area_curs(self, ext_view, step, count, extend_selection):
            #print("step", step, "count", count)
            pass

        def _create_toolbar(self):

            nnn = 0
            toolbar = Gtk.Toolbar()
            self.grid.attach(toolbar, 0, 1, 3, 1)

            button_norm = Gtk.ToolButton()
            button_norm.set_icon_name("format-text-none-symbolic")
            button_norm.set_tooltip_text("Remove ALL Formatting")
            toolbar.insert(button_norm, nnn) ; nnn += 1

            button_bold = Gtk.ToolButton()
            button_bold.set_icon_name("format-text-bold-symbolic")
            button_bold.set_tooltip_text("Set Bold")
            toolbar.insert(button_bold, nnn)  ; nnn += 1

            button_italic = Gtk.ToolButton()
            button_italic.set_icon_name("format-text-italic-symbolic")
            button_italic.set_tooltip_text("Set Italic")
            toolbar.insert(button_italic, nnn)   ; nnn += 1

            button_underline = Gtk.ToolButton()
            button_underline.set_icon_name("format-text-underline-symbolic")
            button_underline.set_tooltip_text("Set Underline")
            toolbar.insert(button_underline, nnn)   ; nnn += 1

            button_sel = Gtk.ToolItem()

            combo = pgbox.ComboBox(font_sizes, self.combo_sel)
            #combo.sel_text("12")
            #print("str(self.mysize)", str(self.mysize))
            combo.sel_text(str(int(self.mysize)))
            combo.set_tooltip_text("Set Font Size")

            #hb = Gtk.HBox()
            #hb.pack_start(Gtk.Label.new("Font Size:"), 0, 0, 2)
            #hb.pack_start(combo, 0, 0, 0)
            button_sel.add(combo)
            toolbar.insert(button_sel, nnn)  ; nnn += 1

            button_sel2 = Gtk.ToolItem()

            #print("mmm", mmm)
            #hb2 = Gtk.HBox()
            combo2 = pgbox.ColorCombo(font_colors, self.combo_sel2)
            combo2.sel_text("Black")
            combo2.set_tooltip_text("Set Font Color")

            #hb2.pack_start(Gtk.Label.new("Font Color:"), 0, 0, 2)
            #hb2.pack_start(combo2, 0, 0, 0)
            button_sel2.add(combo2)
            toolbar.insert(button_sel2, nnn)  ; nnn += 1

            # ----------------------------------------------------------------

            button_sel3 = Gtk.ToolItem()
            #hb3 = Gtk.HBox()
            combo3 = pgbox.ColorCombo(font_colors, self.combo_sel3)
            combo3.sel_text("White")
            combo3.set_tooltip_text("Set Background Color")
            #hb3.pack_start(Gtk.Label.new("Font Back:"), 0, 0, 2)
            #hb3.pack_start(combo3, 0, 0, 0)
            button_sel3.add(combo3)
            toolbar.insert(button_sel3, nnn)  ; nnn += 1

            button_color = Gtk.ToolButton()
            button_color.set_icon_name("preferences-desktop-theme")
            button_color.set_tooltip_text("Remove Color Attributes")
            button_color.connect("clicked", self.on_rm_color)
            toolbar.insert(button_color, nnn)  ; nnn += 1

            button_norm.connect("clicked", self.on_rm_clicked, self.tag_norm)
            button_bold.connect("clicked", self.on_button_clicked, self.tag_bold)
            button_italic.connect("clicked", self.on_button_clicked, self.tag_italic)
            button_underline.connect("clicked", self.on_button_clicked, self.tag_underline)

            #toolbar.insert(Gtk.SeparatorToolItem(), nnn)  ; nnn += 1

        def _create_toolbar2(self):

            nnn = 0
            toolbar = Gtk.Toolbar()
            self.grid.attach(toolbar, 0, 0, 3, 1)

            radio_justifyleft = Gtk.RadioToolButton()
            radio_justifyleft.set_icon_name("format-justify-left-symbolic")
            toolbar.insert(radio_justifyleft, nnn)   ; nnn += 1

            radio_justifycenter = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
            radio_justifycenter.set_icon_name("format-justify-center-symbolic")
            toolbar.insert(radio_justifycenter, nnn)   ; nnn += 1

            radio_justifyright = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
            radio_justifyright.set_icon_name("format-justify-right-symbolic")
            toolbar.insert(radio_justifyright, nnn)   ; nnn += 1

            radio_justifyfill = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
            radio_justifyfill.set_icon_name("format-justify-fill-symbolic")
            toolbar.insert(radio_justifyfill, nnn)   ; nnn += 1

            radio_justifyleft.connect(
                #"toggled", self.on_justify_toggled, Gtk.Justification.LEFT
                "toggled", self.on_justify_toggled, self.tag_left
            )
            radio_justifycenter.connect(
                #"toggled", self.on_justify_toggled, Gtk.Justification.CENTER
                "toggled", self.on_justify_toggled, self.tag_center
            )
            radio_justifyright.connect(
                "toggled", self.on_justify_toggled, self.tag_right
            )

            radio_justifyfill.connect(
                "toggled", self.on_justify_toggled, self.tag_fill
            )

            button_big = Gtk.ToolButton()
            button_big.set_icon_name("format-text-larger-symbolic")
            button_big.set_tooltip_text("Set Superscript")
            button_big.connect("clicked", self.on_super_button, self.tag_super)
            toolbar.insert(button_big, nnn)  ; nnn += 1

            button_big = Gtk.ToolButton()
            button_big.set_icon_name("format-text-smaller-symbolic")
            button_big.set_tooltip_text("Set Subscript")
            button_big.connect("clicked", self.on_super_button, self.tag_sub)
            toolbar.insert(button_big, nnn)  ; nnn += 1

            button_big = Gtk.ToolButton()
            button_big.set_icon_name("tools-check-spelling")
            button_big.set_tooltip_text("Set XX Large font")
            button_big.connect("clicked", self.on_button_clicked, self.tag_xbig)
            toolbar.insert(button_big, nnn)   ; nnn += 1

            button_color = Gtk.ToolButton()
            button_color.set_icon_name("font-x-generic")
            button_color.set_tooltip_text("Set Font")
            #button_color.connect("clicked", self.on_color_clicked, 0)
            toolbar.insert(button_color, nnn)  ; nnn += 1

            toolbar.insert(Gtk.SeparatorToolItem(), nnn)   ; nnn += 1

            button_clear = Gtk.ToolButton()
            button_clear.set_icon_name("edit-clear-symbolic")
            button_clear.set_tooltip_text("Remove ALL formatting")
            button_clear.connect("clicked", self.on_clear_clicked)
            toolbar.insert(button_clear, nnn)    ; nnn += 1

            toolbar.insert(Gtk.SeparatorToolItem(), nnn)   ; nnn += 1

            button_search = Gtk.ToolButton()
            button_search.set_icon_name("system-search-symbolic")
            button_search.set_tooltip_text("Search current text")
            button_search.connect("clicked", self.on_search_clicked)
            toolbar.insert(button_search, nnn)   ; nnn += 1

            button_mag = Gtk.ToolButton()
            button_mag.set_icon_name("zoom-fit-best")
            button_mag.set_tooltip_text("Magnify Font")
            button_mag.connect("clicked", self.on_zoom_clicked)
            toolbar.insert(button_mag, nnn)  ; nnn += 1

            button_mag = Gtk.ToolButton()
            button_mag.set_icon_name("zoom-in-symbolic")
            button_mag.set_tooltip_text("Set larger font")
            button_mag.connect("clicked", self.on_zoom_clicked)
            toolbar.insert(button_mag, nnn)   ; nnn += 1

            button_mag2 = Gtk.ToolButton()
            button_mag2.set_icon_name("zoom-out-symbolic")
            button_mag2.set_tooltip_text("Set smaller Font")
            button_mag2.connect("clicked", self.on_unzoom_clicked)
            toolbar.insert(button_mag2, nnn)   ; nnn += 1

        def area_key(self, widget, event):
            #print("TextViewWin keypress", event.string, event.keyval)
            if event.state & Gdk.ModifierType.CONTROL_MASK:
                print("TextViewWin control keypress", event.string, event.keyval)

                if event.keyval == 102:
                    #print("control find")
                    if self.findcall:
                        # Call with object argument
                        self.findcall[0](self.findcall[1])

        def area_button(self, but, event):
            #print("click", event.x, event.y)
            # textview
            endd = self.textbuffer.get_end_iter()
            isx, iter = self.textview.get_iter_at_location(event.x, event.y)
            if isx:
                txt =  self.textbuffer.get_text(iter, endd, False)
                #print("[", txt[:4], "]")

                #defvals = self.textview.get_default_attributes()
                #print(defvals.appearance.rise)

                #ixy, attr = iter.get_attributes()
                #if ixy:
                #    #attr.ref()
                #    #print(attr.refcount)
                #    print(dir(attr))
                #    #print(attr.refcount)
                #    #print(attr.appearance.rise)
                #    attr.unref()
                #else:
                #    print("no artt")

                #attr.unref()

        def on_rm_color(self, arg1):
            print(  "on_rm_color", arg1)

            bounds = self.textbuffer.get_selection_bounds()

            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                start, end = bounds

                # Clear out old colors
                for cc in range(len(font_colors)):
                    rrr = "backgr%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                for cc in range(len(font_colors)):
                    rrr = "color%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                self.textbuffer.set_modified(1)

        def on_combo_clicked(self, arg1, arg2):
            #print("on_combo_clicked")
            #cont = ("12", "32", "64")
            #combo_box = pgbox.ComboBox(cont)
            #combo_box.show()
            pass

        def combo_sel(self, sel):
            #print("combo_sel", sel)
            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                nnn = "size%d" % int(sel);
                start, end = bounds

                # Femove size tags from here
                for aa in font_sizes:
                    rrr = "size%d" % int(aa);
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)
                try:
                    self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                    self.textbuffer.set_modified(1)
                except:
                    print("Cannot apply size tag ", nnn, sys.exc_info())

        def combo_sel2(self, sel):
            #print("combo_sel2", sel)
            bounds = self.textbuffer.get_selection_bounds()

            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                # Clear out old colors
                start, end = bounds
                for cc in range(len(font_colors)):
                    rrr = "color%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                # Find out the offset:
                cnt = 0
                for aa, bb in font_colors:
                    if aa == sel:
                        break
                    cnt += 1
                nnn = "color%d" % cnt
                #print("nnn", nnn)
                start, end = bounds
                try:
                    self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                    self.textbuffer.set_modified(1)
                except:
                    print("Cannot apply size tag ", nnn, sys.exc_info())

        def combo_sel3(self, sel):
            #print("combo_sel3", sel)
            bounds = self.textbuffer.get_selection_bounds()

            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                start, end = bounds

                # Clear out old colors
                for cc in range(len(font_colors)):
                    rrr = "backgr%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                # Find out the offset:
                cnt = 0
                for aa, bb in font_colors:
                    if aa == sel:
                        break
                    cnt += 1

                nnn = "backgr%d" % cnt
                #print("nnn", nnn)

                try:
                    self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                    self.textbuffer.set_modified(1)
                except:
                    print("Cannot apply size tag ", nnn, sys.exc_info())

        def on_zoom_clicked(self, arg1):

            pg = Gtk.Widget.create_pango_context(self.textview)
            myfd = pg.get_font_description()
            mysize = myfd.get_size() / Pango.SCALE

            fd = Pango.FontDescription()
            fd.set_size((mysize + 1) * Pango.SCALE)
            self.textview.modify_font(fd)

        def on_unzoom_clicked(self, arg1):

            pg = Gtk.Widget.create_pango_context(self.textview)
            myfd = pg.get_font_description()
            mysize = myfd.get_size() / Pango.SCALE

            fd = Pango.FontDescription()
            fd.set_size((mysize - 1) * Pango.SCALE)
            self.textview.modify_font(fd)

        def _create_textview(self):

            self.textview = Gtk.TextView()
            self.textbuffer = self.textview.get_buffer()

            scrolledwindow = Gtk.ScrolledWindow()
            scrolledwindow.set_hexpand(True)
            scrolledwindow.set_vexpand(True)
            self.grid.attach(scrolledwindow, 0, 2, 3, 1)

            scrolledwindow.add(self.textview)

            self.fd = Pango.FontDescription()
            pg = Gtk.Widget.create_pango_context(self.textview)
            myfd = pg.get_font_description()
            self.mysize = myfd.get_size() / Pango.SCALE
            self.myfam = myfd.get_family()
            #print(self.mysize)

            #self.textview.set_has_window(True)

            #self.set_events(Gdk.EventMask.ALL_EVENTS_MASK )

            self.tag_regular = self.textbuffer.create_tag("regular", size=self.mysize * Pango.SCALE)
            self.tag_super   = self.textbuffer.create_tag("super", rise=5 * Pango.SCALE)
            self.tag_sub     = self.textbuffer.create_tag("sub",   rise=-5 * Pango.SCALE)
            self.tag_norm    = self.textbuffer.create_tag("norm", weight=14*Pango.SCALE)
            self.tag_xbig    = self.textbuffer.create_tag("xbig", size=30*Pango.SCALE)
            self.tag_big     = self.textbuffer.create_tag("big", size=20*Pango.SCALE)
            #self.tag_red     = self.textbuffer.create_tag("red", foreground="red")
            #self.tag_redbg   = self.textbuffer.create_tag("redbg", background="red")
            self.tag_norm    = self.textbuffer.create_tag("normal", style=Pango.Style.NORMAL)
            self.tag_bold    = self.textbuffer.create_tag("bold", weight=Pango.Weight.BOLD)
            self.tag_italic     = self.textbuffer.create_tag("italic", style=Pango.Style.ITALIC)
            self.tag_underline  = self.textbuffer.create_tag("underline", underline=Pango.Underline.SINGLE)
            self.tag_found      = self.textbuffer.create_tag("found", background="yellow")
            self.tag_left       = self.textbuffer.create_tag("justleft", justification=Gtk.Justification.LEFT)
            self.tag_center     = self.textbuffer.create_tag("justcent", justification=Gtk.Justification.CENTER)
            self.tag_right      = self.textbuffer.create_tag("justright", justification=Gtk.Justification.RIGHT)
            self.tag_fill       = self.textbuffer.create_tag("justfill",  justification=Gtk.Justification.FILL)

            self.textview.set_wrap_mode(Gtk.WrapMode.WORD)

            # We create the attributes for all possible size tags
            for aa in font_sizes:
                nnn = "size%d" % int(aa);
                ttt = self.textbuffer.create_tag(nnn, size=int(aa) * Pango.SCALE)
                setattr(self, nnn, ttt)

            # We create the attributes for all possible color tags
            cnt = 0
            for aa, bb in font_colors:
                print
                nnn = "color%d" % cnt;
                ttt = self.textbuffer.create_tag(nnn, foreground=aa)
                setattr(self, nnn, ttt)
                cnt += 1

            cnt = 0
            for aa, bb in font_colors:
                nnn = "backgr%d" % int(cnt);
                ttt = self.textbuffer.create_tag(nnn, background=aa)
                setattr(self, nnn, ttt)
                cnt += 1

            #print(dir(self))

        def _create_buttons(self):

            #check_editable = Gtk.CheckButton(label="Editable")
            #check_editable.set_active(True)
            #check_editable.connect("toggled", self.on_editable_toggled)
            #self.grid.attach(check_editable, 0, 2, 1, 1)
            ##
            #check_cursor = Gtk.CheckButton(label="Cursor Visible")
            #check_cursor.set_active(True)
            #check_editable.connect("toggled", self.on_cursor_toggled)
            #self.grid.attach_next_to(
            #    check_cursor, check_editable, Gtk.PositionType.RIGHT, 1, 1)

            # ---------------------------------------------------------------------------------

            radio_wrapword =  Gtk.RadioButton.new_with_label_from_widget(None, "Word")
            self.grid.attach(radio_wrapword, 0, 3, 1, 1)

            radio_wrapchar =  Gtk.RadioButton.new_with_label_from_widget(radio_wrapword, "Character")
            self.grid.attach_next_to(
                radio_wrapchar, radio_wrapword, Gtk.PositionType.RIGHT, 1, 1)

            radio_wrapnone = Gtk.RadioButton.new_with_label_from_widget(radio_wrapword, "None")
            self.grid.attach_next_to(
                    radio_wrapnone, radio_wrapchar, Gtk.PositionType.RIGHT, 1, 1)

            radio_wrapnone.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.NONE)
            radio_wrapchar.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.CHAR)
            radio_wrapword.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.WORD)

        def get_text(self):
            startt = self.textbuffer.get_start_iter()
            endd = self.textbuffer.get_end_iter()
            txt = self.textbuffer.get_text(startt, endd, False)
            return txt

        #def get_all(self):
        #    print("Get_all called")
        #    startt = self.buffer.get_start_iter()
        #    endd = self.buffer.get_end_iter()
        #    return self.buffer.get_text(startt, endd, True)

        def  get_modified(self):
            return self.textbuffer.get_modified()

        def  set_modified(self, valx):
            return self.textbuffer.set_modified(valx)

        def set_text(self, txt):
            if self.textbuffer.get_modified():
                startt = self.textbuffer.get_start_iter()
                endd = self.textbuffer.get_end_iter()
                old = self.textbuffer.get_text(startt, endd, False)
                if self.callb:
                    self.callb(old)
                #print("old_content", old)
            self.textbuffer.set_text(txt)

        def on_rm_clicked(self, widget, tag):
            bounds = self.textbuffer.get_selection_bounds()
            if len(bounds) != 0:
                start, end = bounds
                self.textbuffer.remove_all_tags(start, end)
                self.textbuffer.set_modified(1)

                # This was the old clear -- now clearing ALL
                #self.textbuffer.remove_tag(self.tag_bold, start, end)
                #self.textbuffer.remove_tag(self.tag_italic, start, end)
                #self.textbuffer.remove_tag(self.tag_underline, start, end)
                #self.textbuffer.remove_tag(self.tag_red, start, end)
                #self.textbuffer.remove_tag(self.tag_redbg, start, end)
                #self.textbuffer.remove_tag(self.tag_big, start, end)
                #self.textbuffer.remove_tag(self.tag_xbig, start, end)
                #self.textbuffer.remove_tag(self.tag_regular, start, end)

        def on_button_clicked(self, widget, tag):

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No style selection.")
            else:
                start, end = bounds
                #print("Apply Tag", tag, start, end)
                self.textbuffer.apply_tag(tag, start, end)
                self.textbuffer.set_modified(1)

        def on_super_button(self, widget, tag):

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No style selection.")
            else:
                start, end = bounds

                self.textbuffer.remove_tag(self.tag_super, start, end)
                self.textbuffer.remove_tag(self.tag_sub, start, end)

                #print("Apply Tag", tag, start, end)
                self.textbuffer.apply_tag(tag, start, end)
                self.textbuffer.set_modified(1)

        def on_size_button(self, widget, tag):

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No style selection.")
            else:
                start, end = bounds

                self.textbuffer.remove_tag(self.tag_super, start, end)
                self.textbuffer.remove_tag(self.tag_sub, start, end)

                #print("Apply Tag", tag, start, end)
                self.textbuffer.apply_tag(tag, start, end)
                self.textbuffer.set_modified(1)

        def on_clear_clicked(self, widget):
            start = self.textbuffer.get_start_iter()
            end = self.textbuffer.get_end_iter()
            self.textbuffer.remove_all_tags(start, end)
            self.textbuffer.set_modified(1)

        def on_editable_toggled(self, widget):
            self.textview.set_editable(widget.get_active())
            self.textbuffer.set_modified(1)

        def on_cursor_toggled(self, widget):
            self.textview.set_cursor_visible(widget.get_active())

        def on_wrap_toggled(self, widget, mode):
            self.textview.set_wrap_mode(mode)

        def on_justify_toggled(self, widget, justification):
            #print("on_justify_toggled", justification)
            #self.textview.set_justification(justification)
            #start = self.textbuffer.get_start_iter()
            #end = self.textbuffer.get_end_iter()

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection.")
            else:
                start, end = bounds
                #print("Apply Just Tag", justification, start, end)

                # Remove old justification
                self.textbuffer.remove_tag(self.tag_left, start, end)
                self.textbuffer.remove_tag(self.tag_center, start, end)
                self.textbuffer.remove_tag(self.tag_right, start, end)
                self.textbuffer.remove_tag(self.tag_fill, start, end)

                self.textbuffer.apply_tag(justification, start, end)
                self.textbuffer.set_modified(1)

        def on_search_clicked(self, widget):

            if self.findcall:
                # Call with object argument
                self.findcall[0](self.findcall[1])

            dialog.destroy()

        def search_and_mark(self, text, start):
            end = self.textbuffer.get_end_iter()
            match = start.forward_search(text, 0, end)

            if match is not None:
                match_start, match_end = match
                self.textbuffer.apply_tag(self.tag_found, match_start, match_end)
                self.search_and_mark(text, match_end)

        # --------------------------------------------------------------------
        # Load it here

        def deser_buff(self, buffx):

            if not buffx:
                return

            #print("UnSer buff")

            fmt = self.textbuffer.register_deserialize_tagset()
            self.textbuffer.deserialize_set_can_create_tags(fmt, True)
            self.textbuffer.deserialize(self.textbuffer, fmt,
                                    self.textbuffer.get_start_iter(), buffx)
            self.textbuffer.set_modified(0)

        # --------------------------------------------------------------------
        # Save it here

        def ser_buff(self):

            #print("Ser buff")

            startt = self.textbuffer.get_start_iter()
            endd = self.textbuffer.get_end_iter()

            fmt = self.textbuffer.register_serialize_tagset()
            sss = self.textbuffer.serialize(self.textbuffer, fmt, startt, endd)
            if not sss: sss = b""
            return sss

        # Print TextTag  (testing)
        def ptag(self, ttt, tt):

            global cnt              # Print only one
            if cnt: return
            cnt += 1

            print(ttt)
            #print(dir(ttt))
            ll = ttt.list_properties()
            for aa in ll:
                #print(nnnn, end= " ")
                try:
                    nn = tt.lookup(aa.name)
                    if nn:
                        #nnn = nn.get_property("size")
                        #print("size", nnn)

                        lll = nn.list_properties()
                        for bb in lll:
                            nnn = bb.name   #get_property("name")
                            try:
                                pp = nn.get_property(nnn)
                            except:
                                pass
                            print(aa.name, "prop", "'" + nnn + "'" , "val =", pp)
                        print()

                except:
                    print(sys.exc_info())
                    pass
                #print()

            return

        # --------------------------------------------------------------------

        def print_tags(self):

            #startt = self.textbuffer.get_start_iter()
            #endd = self.textbuffer.get_end_iter()

            # TagTable
            #tt = self.textbuffer.get_property("tag-table")
            #print("table", tt)

            tt = self.textbuffer.get_tag_table()
            print("table", tt)
            tt.foreach(self.ptag, tt)
            print()

            return

            txt = self.textbuffer.get_text(startt, endd, False)
            lc =  self.textbuffer.get_char_count()
            for aa in range(lc):
                iii = self.textbuffer.get_iter_at_offset(aa)
                eee = self.textbuffer.get_iter_at_offset(aa+1)
                ccc = self.textbuffer.get_text(iii, eee, False)
                #print("aa", ccc)

            return txt

            #all = self.edview.get_all()
            #print("serialize", self.edview.textbuffer.get_deserialize_formats())
            #print("str", self.edview.serial_str())
            #print("serialize", self.edview.textbuffer.get_deserialize_formats())

            #vv = self.edview.textbuffer
            #startt = vv.get_start_iter(); endd = vv.get_end_iter()
            #while True:
            #    prev = startt.copy()
            #    nextok = startt.forward_line()
            #    ttt = vv.get_text(prev, startt, False)
            #    prevc = prev.copy()
            #    while True:
            #        sss = prevc.get_toggled_tags(True)
            #        if sss:
            #            print("tags on toggle", sss)
            #            for cc in sss:
            #                print("cc", cc.get_property("name"))
            #            print("pos", prevc.get_line(), prevc.get_line_offset())
            #        beg = prevc.copy()
            #        nextokc = prevc.forward_char()
            #        if not nextokc:
            #            break
            #        if startt == prevc:
            #            break
            #        chh = vv.get_text(beg, prevc, False)
            #        print(chh, end="")
            #
            #    #print("tags", prev.get_tags())
            #    #print("line:", ttt, end="")
            #    if not nextok:
            #        break
            #
            ##print("tags:", self.edview.textbuffer.get_tags())

## Classes

`class pgTextView (status=False)`

  :Constructors:

  ::

      VBox(**properties)
      new(homogeneous:bool, spacing:int) -> Gtk.Widget

  Initializer for a GObject based classes with support for property sets through the use of explicit keyword arguments.

  Expand source code

      class pgTextView(Gtk.VBox):

          def __init__(self, status = False):

              self.statstr = None
              Gtk.VBox.__init__(self)

              self.tagtablex = []
              self.callb = None
              self.grid = Gtk.Grid()
              self.add(self.grid)

              self._create_textview()
              self._create_toolbar()
              self._create_toolbar2()
              self._create_buttons()

              # Status bar
              self.statstr = Gtk.Label.new("Idle")
              self.statstr.set_halign(Gtk.Align.START)

              if  status:
                  hstat = Gtk.HBox()
                  hstat.pack_start(Gtk.Label.new("  Status:  "), 0, 0, 0)
                  hstat.pack_start(Gtk.Label.new(" "), 0, 0, 0)
                  hstat.pack_start(self.statstr, 1, 1, 0)

                  self.grid.attach(hstat, 0, 4, 3, 1)

              self.textview.connect("key-press-event", self.area_key)
              self.textview.connect("move-cursor", self.area_curs)
              self.connect("button-press-event", self.area_button)
              #self.textview.connect("focus-out-event", self.focus_out)
              self.findcall = None;

          def  area_curs(self, ext_view, step, count, extend_selection):
              #print("step", step, "count", count)
              pass

          def _create_toolbar(self):

              nnn = 0
              toolbar = Gtk.Toolbar()
              self.grid.attach(toolbar, 0, 1, 3, 1)

              button_norm = Gtk.ToolButton()
              button_norm.set_icon_name("format-text-none-symbolic")
              button_norm.set_tooltip_text("Remove ALL Formatting")
              toolbar.insert(button_norm, nnn) ; nnn += 1

              button_bold = Gtk.ToolButton()
              button_bold.set_icon_name("format-text-bold-symbolic")
              button_bold.set_tooltip_text("Set Bold")
              toolbar.insert(button_bold, nnn)  ; nnn += 1

              button_italic = Gtk.ToolButton()
              button_italic.set_icon_name("format-text-italic-symbolic")
              button_italic.set_tooltip_text("Set Italic")
              toolbar.insert(button_italic, nnn)   ; nnn += 1

              button_underline = Gtk.ToolButton()
              button_underline.set_icon_name("format-text-underline-symbolic")
              button_underline.set_tooltip_text("Set Underline")
              toolbar.insert(button_underline, nnn)   ; nnn += 1

              button_sel = Gtk.ToolItem()

              combo = pgbox.ComboBox(font_sizes, self.combo_sel)
              #combo.sel_text("12")
              #print("str(self.mysize)", str(self.mysize))
              combo.sel_text(str(int(self.mysize)))
              combo.set_tooltip_text("Set Font Size")

              #hb = Gtk.HBox()
              #hb.pack_start(Gtk.Label.new("Font Size:"), 0, 0, 2)
              #hb.pack_start(combo, 0, 0, 0)
              button_sel.add(combo)
              toolbar.insert(button_sel, nnn)  ; nnn += 1

              button_sel2 = Gtk.ToolItem()

              #print("mmm", mmm)
              #hb2 = Gtk.HBox()
              combo2 = pgbox.ColorCombo(font_colors, self.combo_sel2)
              combo2.sel_text("Black")
              combo2.set_tooltip_text("Set Font Color")

              #hb2.pack_start(Gtk.Label.new("Font Color:"), 0, 0, 2)
              #hb2.pack_start(combo2, 0, 0, 0)
              button_sel2.add(combo2)
              toolbar.insert(button_sel2, nnn)  ; nnn += 1

              # ----------------------------------------------------------------

              button_sel3 = Gtk.ToolItem()
              #hb3 = Gtk.HBox()
              combo3 = pgbox.ColorCombo(font_colors, self.combo_sel3)
              combo3.sel_text("White")
              combo3.set_tooltip_text("Set Background Color")
              #hb3.pack_start(Gtk.Label.new("Font Back:"), 0, 0, 2)
              #hb3.pack_start(combo3, 0, 0, 0)
              button_sel3.add(combo3)
              toolbar.insert(button_sel3, nnn)  ; nnn += 1

              button_color = Gtk.ToolButton()
              button_color.set_icon_name("preferences-desktop-theme")
              button_color.set_tooltip_text("Remove Color Attributes")
              button_color.connect("clicked", self.on_rm_color)
              toolbar.insert(button_color, nnn)  ; nnn += 1

              button_norm.connect("clicked", self.on_rm_clicked, self.tag_norm)
              button_bold.connect("clicked", self.on_button_clicked, self.tag_bold)
              button_italic.connect("clicked", self.on_button_clicked, self.tag_italic)
              button_underline.connect("clicked", self.on_button_clicked, self.tag_underline)

              #toolbar.insert(Gtk.SeparatorToolItem(), nnn)  ; nnn += 1

          def _create_toolbar2(self):

              nnn = 0
              toolbar = Gtk.Toolbar()
              self.grid.attach(toolbar, 0, 0, 3, 1)

              radio_justifyleft = Gtk.RadioToolButton()
              radio_justifyleft.set_icon_name("format-justify-left-symbolic")
              toolbar.insert(radio_justifyleft, nnn)   ; nnn += 1

              radio_justifycenter = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
              radio_justifycenter.set_icon_name("format-justify-center-symbolic")
              toolbar.insert(radio_justifycenter, nnn)   ; nnn += 1

              radio_justifyright = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
              radio_justifyright.set_icon_name("format-justify-right-symbolic")
              toolbar.insert(radio_justifyright, nnn)   ; nnn += 1

              radio_justifyfill = Gtk.RadioToolButton.new_from_widget(radio_justifyleft)
              radio_justifyfill.set_icon_name("format-justify-fill-symbolic")
              toolbar.insert(radio_justifyfill, nnn)   ; nnn += 1

              radio_justifyleft.connect(
                  #"toggled", self.on_justify_toggled, Gtk.Justification.LEFT
                  "toggled", self.on_justify_toggled, self.tag_left
              )
              radio_justifycenter.connect(
                  #"toggled", self.on_justify_toggled, Gtk.Justification.CENTER
                  "toggled", self.on_justify_toggled, self.tag_center
              )
              radio_justifyright.connect(
                  "toggled", self.on_justify_toggled, self.tag_right
              )

              radio_justifyfill.connect(
                  "toggled", self.on_justify_toggled, self.tag_fill
              )

              button_big = Gtk.ToolButton()
              button_big.set_icon_name("format-text-larger-symbolic")
              button_big.set_tooltip_text("Set Superscript")
              button_big.connect("clicked", self.on_super_button, self.tag_super)
              toolbar.insert(button_big, nnn)  ; nnn += 1

              button_big = Gtk.ToolButton()
              button_big.set_icon_name("format-text-smaller-symbolic")
              button_big.set_tooltip_text("Set Subscript")
              button_big.connect("clicked", self.on_super_button, self.tag_sub)
              toolbar.insert(button_big, nnn)  ; nnn += 1

              button_big = Gtk.ToolButton()
              button_big.set_icon_name("tools-check-spelling")
              button_big.set_tooltip_text("Set XX Large font")
              button_big.connect("clicked", self.on_button_clicked, self.tag_xbig)
              toolbar.insert(button_big, nnn)   ; nnn += 1

              button_color = Gtk.ToolButton()
              button_color.set_icon_name("font-x-generic")
              button_color.set_tooltip_text("Set Font")
              #button_color.connect("clicked", self.on_color_clicked, 0)
              toolbar.insert(button_color, nnn)  ; nnn += 1

              toolbar.insert(Gtk.SeparatorToolItem(), nnn)   ; nnn += 1

              button_clear = Gtk.ToolButton()
              button_clear.set_icon_name("edit-clear-symbolic")
              button_clear.set_tooltip_text("Remove ALL formatting")
              button_clear.connect("clicked", self.on_clear_clicked)
              toolbar.insert(button_clear, nnn)    ; nnn += 1

              toolbar.insert(Gtk.SeparatorToolItem(), nnn)   ; nnn += 1

              button_search = Gtk.ToolButton()
              button_search.set_icon_name("system-search-symbolic")
              button_search.set_tooltip_text("Search current text")
              button_search.connect("clicked", self.on_search_clicked)
              toolbar.insert(button_search, nnn)   ; nnn += 1

              button_mag = Gtk.ToolButton()
              button_mag.set_icon_name("zoom-fit-best")
              button_mag.set_tooltip_text("Magnify Font")
              button_mag.connect("clicked", self.on_zoom_clicked)
              toolbar.insert(button_mag, nnn)  ; nnn += 1

              button_mag = Gtk.ToolButton()
              button_mag.set_icon_name("zoom-in-symbolic")
              button_mag.set_tooltip_text("Set larger font")
              button_mag.connect("clicked", self.on_zoom_clicked)
              toolbar.insert(button_mag, nnn)   ; nnn += 1

              button_mag2 = Gtk.ToolButton()
              button_mag2.set_icon_name("zoom-out-symbolic")
              button_mag2.set_tooltip_text("Set smaller Font")
              button_mag2.connect("clicked", self.on_unzoom_clicked)
              toolbar.insert(button_mag2, nnn)   ; nnn += 1

          def area_key(self, widget, event):
              #print("TextViewWin keypress", event.string, event.keyval)
              if event.state & Gdk.ModifierType.CONTROL_MASK:
                  print("TextViewWin control keypress", event.string, event.keyval)

                  if event.keyval == 102:
                      #print("control find")
                      if self.findcall:
                          # Call with object argument
                          self.findcall[0](self.findcall[1])

          def area_button(self, but, event):
              #print("click", event.x, event.y)
              # textview
              endd = self.textbuffer.get_end_iter()
              isx, iter = self.textview.get_iter_at_location(event.x, event.y)
              if isx:
                  txt =  self.textbuffer.get_text(iter, endd, False)
                  #print("[", txt[:4], "]")

                  #defvals = self.textview.get_default_attributes()
                  #print(defvals.appearance.rise)

                  #ixy, attr = iter.get_attributes()
                  #if ixy:
                  #    #attr.ref()
                  #    #print(attr.refcount)
                  #    print(dir(attr))
                  #    #print(attr.refcount)
                  #    #print(attr.appearance.rise)
                  #    attr.unref()
                  #else:
                  #    print("no artt")

                  #attr.unref()

          def on_rm_color(self, arg1):
              print(  "on_rm_color", arg1)

              bounds = self.textbuffer.get_selection_bounds()

              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No selection")
                  #print("No selection")
                  return
              else:
                  start, end = bounds

                  # Clear out old colors
                  for cc in range(len(font_colors)):
                      rrr = "backgr%d" % cc
                      self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                  for cc in range(len(font_colors)):
                      rrr = "color%d" % cc
                      self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                  self.textbuffer.set_modified(1)

          def on_combo_clicked(self, arg1, arg2):
              #print("on_combo_clicked")
              #cont = ("12", "32", "64")
              #combo_box = pgbox.ComboBox(cont)
              #combo_box.show()
              pass

          def combo_sel(self, sel):
              #print("combo_sel", sel)
              bounds = self.textbuffer.get_selection_bounds()
              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No selection")
                  #print("No selection")
                  return
              else:
                  nnn = "size%d" % int(sel);
                  start, end = bounds

                  # Femove size tags from here
                  for aa in font_sizes:
                      rrr = "size%d" % int(aa);
                      self.textbuffer.remove_tag(getattr(self, rrr), start, end)
                  try:
                      self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                      self.textbuffer.set_modified(1)
                  except:
                      print("Cannot apply size tag ", nnn, sys.exc_info())

          def combo_sel2(self, sel):
              #print("combo_sel2", sel)
              bounds = self.textbuffer.get_selection_bounds()

              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No selection")
                  #print("No selection")
                  return
              else:
                  # Clear out old colors
                  start, end = bounds
                  for cc in range(len(font_colors)):
                      rrr = "color%d" % cc
                      self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                  # Find out the offset:
                  cnt = 0
                  for aa, bb in font_colors:
                      if aa == sel:
                          break
                      cnt += 1
                  nnn = "color%d" % cnt
                  #print("nnn", nnn)
                  start, end = bounds
                  try:
                      self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                      self.textbuffer.set_modified(1)
                  except:
                      print("Cannot apply size tag ", nnn, sys.exc_info())

          def combo_sel3(self, sel):
              #print("combo_sel3", sel)
              bounds = self.textbuffer.get_selection_bounds()

              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No selection")
                  #print("No selection")
                  return
              else:
                  start, end = bounds

                  # Clear out old colors
                  for cc in range(len(font_colors)):
                      rrr = "backgr%d" % cc
                      self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                  # Find out the offset:
                  cnt = 0
                  for aa, bb in font_colors:
                      if aa == sel:
                          break
                      cnt += 1

                  nnn = "backgr%d" % cnt
                  #print("nnn", nnn)

                  try:
                      self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                      self.textbuffer.set_modified(1)
                  except:
                      print("Cannot apply size tag ", nnn, sys.exc_info())

          def on_zoom_clicked(self, arg1):

              pg = Gtk.Widget.create_pango_context(self.textview)
              myfd = pg.get_font_description()
              mysize = myfd.get_size() / Pango.SCALE

              fd = Pango.FontDescription()
              fd.set_size((mysize + 1) * Pango.SCALE)
              self.textview.modify_font(fd)

          def on_unzoom_clicked(self, arg1):

              pg = Gtk.Widget.create_pango_context(self.textview)
              myfd = pg.get_font_description()
              mysize = myfd.get_size() / Pango.SCALE

              fd = Pango.FontDescription()
              fd.set_size((mysize - 1) * Pango.SCALE)
              self.textview.modify_font(fd)

          def _create_textview(self):

              self.textview = Gtk.TextView()
              self.textbuffer = self.textview.get_buffer()

              scrolledwindow = Gtk.ScrolledWindow()
              scrolledwindow.set_hexpand(True)
              scrolledwindow.set_vexpand(True)
              self.grid.attach(scrolledwindow, 0, 2, 3, 1)

              scrolledwindow.add(self.textview)

              self.fd = Pango.FontDescription()
              pg = Gtk.Widget.create_pango_context(self.textview)
              myfd = pg.get_font_description()
              self.mysize = myfd.get_size() / Pango.SCALE
              self.myfam = myfd.get_family()
              #print(self.mysize)

              #self.textview.set_has_window(True)

              #self.set_events(Gdk.EventMask.ALL_EVENTS_MASK )

              self.tag_regular = self.textbuffer.create_tag("regular", size=self.mysize * Pango.SCALE)
              self.tag_super   = self.textbuffer.create_tag("super", rise=5 * Pango.SCALE)
              self.tag_sub     = self.textbuffer.create_tag("sub",   rise=-5 * Pango.SCALE)
              self.tag_norm    = self.textbuffer.create_tag("norm", weight=14*Pango.SCALE)
              self.tag_xbig    = self.textbuffer.create_tag("xbig", size=30*Pango.SCALE)
              self.tag_big     = self.textbuffer.create_tag("big", size=20*Pango.SCALE)
              #self.tag_red     = self.textbuffer.create_tag("red", foreground="red")
              #self.tag_redbg   = self.textbuffer.create_tag("redbg", background="red")
              self.tag_norm    = self.textbuffer.create_tag("normal", style=Pango.Style.NORMAL)
              self.tag_bold    = self.textbuffer.create_tag("bold", weight=Pango.Weight.BOLD)
              self.tag_italic     = self.textbuffer.create_tag("italic", style=Pango.Style.ITALIC)
              self.tag_underline  = self.textbuffer.create_tag("underline", underline=Pango.Underline.SINGLE)
              self.tag_found      = self.textbuffer.create_tag("found", background="yellow")
              self.tag_left       = self.textbuffer.create_tag("justleft", justification=Gtk.Justification.LEFT)
              self.tag_center     = self.textbuffer.create_tag("justcent", justification=Gtk.Justification.CENTER)
              self.tag_right      = self.textbuffer.create_tag("justright", justification=Gtk.Justification.RIGHT)
              self.tag_fill       = self.textbuffer.create_tag("justfill",  justification=Gtk.Justification.FILL)

              self.textview.set_wrap_mode(Gtk.WrapMode.WORD)

              # We create the attributes for all possible size tags
              for aa in font_sizes:
                  nnn = "size%d" % int(aa);
                  ttt = self.textbuffer.create_tag(nnn, size=int(aa) * Pango.SCALE)
                  setattr(self, nnn, ttt)

              # We create the attributes for all possible color tags
              cnt = 0
              for aa, bb in font_colors:
                  print
                  nnn = "color%d" % cnt;
                  ttt = self.textbuffer.create_tag(nnn, foreground=aa)
                  setattr(self, nnn, ttt)
                  cnt += 1

              cnt = 0
              for aa, bb in font_colors:
                  nnn = "backgr%d" % int(cnt);
                  ttt = self.textbuffer.create_tag(nnn, background=aa)
                  setattr(self, nnn, ttt)
                  cnt += 1

              #print(dir(self))

          def _create_buttons(self):

              #check_editable = Gtk.CheckButton(label="Editable")
              #check_editable.set_active(True)
              #check_editable.connect("toggled", self.on_editable_toggled)
              #self.grid.attach(check_editable, 0, 2, 1, 1)
              ##
              #check_cursor = Gtk.CheckButton(label="Cursor Visible")
              #check_cursor.set_active(True)
              #check_editable.connect("toggled", self.on_cursor_toggled)
              #self.grid.attach_next_to(
              #    check_cursor, check_editable, Gtk.PositionType.RIGHT, 1, 1)

              # ---------------------------------------------------------------------------------

              radio_wrapword =  Gtk.RadioButton.new_with_label_from_widget(None, "Word")
              self.grid.attach(radio_wrapword, 0, 3, 1, 1)

              radio_wrapchar =  Gtk.RadioButton.new_with_label_from_widget(radio_wrapword, "Character")
              self.grid.attach_next_to(
                  radio_wrapchar, radio_wrapword, Gtk.PositionType.RIGHT, 1, 1)

              radio_wrapnone = Gtk.RadioButton.new_with_label_from_widget(radio_wrapword, "None")
              self.grid.attach_next_to(
                      radio_wrapnone, radio_wrapchar, Gtk.PositionType.RIGHT, 1, 1)

              radio_wrapnone.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.NONE)
              radio_wrapchar.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.CHAR)
              radio_wrapword.connect("toggled", self.on_wrap_toggled, Gtk.WrapMode.WORD)

          def get_text(self):
              startt = self.textbuffer.get_start_iter()
              endd = self.textbuffer.get_end_iter()
              txt = self.textbuffer.get_text(startt, endd, False)
              return txt

          #def get_all(self):
          #    print("Get_all called")
          #    startt = self.buffer.get_start_iter()
          #    endd = self.buffer.get_end_iter()
          #    return self.buffer.get_text(startt, endd, True)

          def  get_modified(self):
              return self.textbuffer.get_modified()

          def  set_modified(self, valx):
              return self.textbuffer.set_modified(valx)

          def set_text(self, txt):
              if self.textbuffer.get_modified():
                  startt = self.textbuffer.get_start_iter()
                  endd = self.textbuffer.get_end_iter()
                  old = self.textbuffer.get_text(startt, endd, False)
                  if self.callb:
                      self.callb(old)
                  #print("old_content", old)
              self.textbuffer.set_text(txt)

          def on_rm_clicked(self, widget, tag):
              bounds = self.textbuffer.get_selection_bounds()
              if len(bounds) != 0:
                  start, end = bounds
                  self.textbuffer.remove_all_tags(start, end)
                  self.textbuffer.set_modified(1)

                  # This was the old clear -- now clearing ALL
                  #self.textbuffer.remove_tag(self.tag_bold, start, end)
                  #self.textbuffer.remove_tag(self.tag_italic, start, end)
                  #self.textbuffer.remove_tag(self.tag_underline, start, end)
                  #self.textbuffer.remove_tag(self.tag_red, start, end)
                  #self.textbuffer.remove_tag(self.tag_redbg, start, end)
                  #self.textbuffer.remove_tag(self.tag_big, start, end)
                  #self.textbuffer.remove_tag(self.tag_xbig, start, end)
                  #self.textbuffer.remove_tag(self.tag_regular, start, end)

          def on_button_clicked(self, widget, tag):

              bounds = self.textbuffer.get_selection_bounds()
              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No style selection.")
              else:
                  start, end = bounds
                  #print("Apply Tag", tag, start, end)
                  self.textbuffer.apply_tag(tag, start, end)
                  self.textbuffer.set_modified(1)

          def on_super_button(self, widget, tag):

              bounds = self.textbuffer.get_selection_bounds()
              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No style selection.")
              else:
                  start, end = bounds

                  self.textbuffer.remove_tag(self.tag_super, start, end)
                  self.textbuffer.remove_tag(self.tag_sub, start, end)

                  #print("Apply Tag", tag, start, end)
                  self.textbuffer.apply_tag(tag, start, end)
                  self.textbuffer.set_modified(1)

          def on_size_button(self, widget, tag):

              bounds = self.textbuffer.get_selection_bounds()
              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No style selection.")
              else:
                  start, end = bounds

                  self.textbuffer.remove_tag(self.tag_super, start, end)
                  self.textbuffer.remove_tag(self.tag_sub, start, end)

                  #print("Apply Tag", tag, start, end)
                  self.textbuffer.apply_tag(tag, start, end)
                  self.textbuffer.set_modified(1)

          def on_clear_clicked(self, widget):
              start = self.textbuffer.get_start_iter()
              end = self.textbuffer.get_end_iter()
              self.textbuffer.remove_all_tags(start, end)
              self.textbuffer.set_modified(1)

          def on_editable_toggled(self, widget):
              self.textview.set_editable(widget.get_active())
              self.textbuffer.set_modified(1)

          def on_cursor_toggled(self, widget):
              self.textview.set_cursor_visible(widget.get_active())

          def on_wrap_toggled(self, widget, mode):
              self.textview.set_wrap_mode(mode)

          def on_justify_toggled(self, widget, justification):
              #print("on_justify_toggled", justification)
              #self.textview.set_justification(justification)
              #start = self.textbuffer.get_start_iter()
              #end = self.textbuffer.get_end_iter()

              bounds = self.textbuffer.get_selection_bounds()
              if not len(bounds):
                  if self.statstr:
                      self.statstr.set_text("No selection.")
              else:
                  start, end = bounds
                  #print("Apply Just Tag", justification, start, end)

                  # Remove old justification
                  self.textbuffer.remove_tag(self.tag_left, start, end)
                  self.textbuffer.remove_tag(self.tag_center, start, end)
                  self.textbuffer.remove_tag(self.tag_right, start, end)
                  self.textbuffer.remove_tag(self.tag_fill, start, end)

                  self.textbuffer.apply_tag(justification, start, end)
                  self.textbuffer.set_modified(1)

          def on_search_clicked(self, widget):

              if self.findcall:
                  # Call with object argument
                  self.findcall[0](self.findcall[1])

              dialog.destroy()

          def search_and_mark(self, text, start):
              end = self.textbuffer.get_end_iter()
              match = start.forward_search(text, 0, end)

              if match is not None:
                  match_start, match_end = match
                  self.textbuffer.apply_tag(self.tag_found, match_start, match_end)
                  self.search_and_mark(text, match_end)

          # --------------------------------------------------------------------
          # Load it here

          def deser_buff(self, buffx):

              if not buffx:
                  return

              #print("UnSer buff")

              fmt = self.textbuffer.register_deserialize_tagset()
              self.textbuffer.deserialize_set_can_create_tags(fmt, True)
              self.textbuffer.deserialize(self.textbuffer, fmt,
                                      self.textbuffer.get_start_iter(), buffx)
              self.textbuffer.set_modified(0)

          # --------------------------------------------------------------------
          # Save it here

          def ser_buff(self):

              #print("Ser buff")

              startt = self.textbuffer.get_start_iter()
              endd = self.textbuffer.get_end_iter()

              fmt = self.textbuffer.register_serialize_tagset()
              sss = self.textbuffer.serialize(self.textbuffer, fmt, startt, endd)
              if not sss: sss = b""
              return sss

          # Print TextTag  (testing)
          def ptag(self, ttt, tt):

              global cnt              # Print only one
              if cnt: return
              cnt += 1

              print(ttt)
              #print(dir(ttt))
              ll = ttt.list_properties()
              for aa in ll:
                  #print(nnnn, end= " ")
                  try:
                      nn = tt.lookup(aa.name)
                      if nn:
                          #nnn = nn.get_property("size")
                          #print("size", nnn)

                          lll = nn.list_properties()
                          for bb in lll:
                              nnn = bb.name   #get_property("name")
                              try:
                                  pp = nn.get_property(nnn)
                              except:
                                  pass
                              print(aa.name, "prop", "'" + nnn + "'" , "val =", pp)
                          print()

                  except:
                      print(sys.exc_info())
                      pass
                  #print()

              return

          # --------------------------------------------------------------------

          def print_tags(self):

              #startt = self.textbuffer.get_start_iter()
              #endd = self.textbuffer.get_end_iter()

              # TagTable
              #tt = self.textbuffer.get_property("tag-table")
              #print("table", tt)

              tt = self.textbuffer.get_tag_table()
              print("table", tt)
              tt.foreach(self.ptag, tt)
              print()

              return

              txt = self.textbuffer.get_text(startt, endd, False)
              lc =  self.textbuffer.get_char_count()
              for aa in range(lc):
                  iii = self.textbuffer.get_iter_at_offset(aa)
                  eee = self.textbuffer.get_iter_at_offset(aa+1)
                  ccc = self.textbuffer.get_text(iii, eee, False)
                  #print("aa", ccc)

              return txt

              #all = self.edview.get_all()
              #print("serialize", self.edview.textbuffer.get_deserialize_formats())
              #print("str", self.edview.serial_str())
              #print("serialize", self.edview.textbuffer.get_deserialize_formats())

              #vv = self.edview.textbuffer
              #startt = vv.get_start_iter(); endd = vv.get_end_iter()
              #while True:
              #    prev = startt.copy()
              #    nextok = startt.forward_line()
              #    ttt = vv.get_text(prev, startt, False)
              #    prevc = prev.copy()
              #    while True:
              #        sss = prevc.get_toggled_tags(True)
              #        if sss:
              #            print("tags on toggle", sss)
              #            for cc in sss:
              #                print("cc", cc.get_property("name"))
              #            print("pos", prevc.get_line(), prevc.get_line_offset())
              #        beg = prevc.copy()
              #        nextokc = prevc.forward_char()
              #        if not nextokc:
              #            break
              #        if startt == prevc:
              #            break
              #        chh = vv.get_text(beg, prevc, False)
              #        print(chh, end="")
              #
              #    #print("tags", prev.get_tags())
              #    #print("line:", ttt, end="")
              #    if not nextok:
              #        break
              #
              ##print("tags:", self.edview.textbuffer.get_tags())

  ### Ancestors

  - gi.repository.Gtk.VBox
  - gi.overrides.Gtk.Box
  - gi.repository.Gtk.Box
  - gi.overrides.Gtk.Container
  - gi.repository.Gtk.Container
  - gi.overrides.Gtk.Widget
  - gi.repository.Gtk.Widget
  - gi.repository.GObject.InitiallyUnowned
  - gi.overrides.GObject.Object
  - gi.repository.GObject.Object
  - gi._gi.GObject
  - gi.repository.Atk.ImplementorIface
  - gi.repository.Gtk.Buildable
  - gi.repository.Gtk.Orientable
  - gobject.GInterface

  ### Methods

  `def area_button(self, but, event)`
    Expand source code

        def area_button(self, but, event):
            #print("click", event.x, event.y)
            # textview
            endd = self.textbuffer.get_end_iter()
            isx, iter = self.textview.get_iter_at_location(event.x, event.y)
            if isx:
                txt =  self.textbuffer.get_text(iter, endd, False)
                #print("[", txt[:4], "]")

                #defvals = self.textview.get_default_attributes()
                #print(defvals.appearance.rise)

                #ixy, attr = iter.get_attributes()
                #if ixy:
                #    #attr.ref()
                #    #print(attr.refcount)
                #    print(dir(attr))
                #    #print(attr.refcount)
                #    #print(attr.appearance.rise)
                #    attr.unref()
                #else:
                #    print("no artt")

                #attr.unref()

  `def area_curs(self, ext_view, step, count, extend_selection)`
    Expand source code

        def  area_curs(self, ext_view, step, count, extend_selection):
            #print("step", step, "count", count)
            pass

  `def area_key(self, widget, event)`
    Expand source code

        def area_key(self, widget, event):
            #print("TextViewWin keypress", event.string, event.keyval)
            if event.state & Gdk.ModifierType.CONTROL_MASK:
                print("TextViewWin control keypress", event.string, event.keyval)

                if event.keyval == 102:
                    #print("control find")
                    if self.findcall:
                        # Call with object argument
                        self.findcall[0](self.findcall[1])

  `def combo_sel(self, sel)`
    Expand source code

        def combo_sel(self, sel):
            #print("combo_sel", sel)
            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                nnn = "size%d" % int(sel);
                start, end = bounds

                # Femove size tags from here
                for aa in font_sizes:
                    rrr = "size%d" % int(aa);
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)
                try:
                    self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                    self.textbuffer.set_modified(1)
                except:
                    print("Cannot apply size tag ", nnn, sys.exc_info())

  `def combo_sel2(self, sel)`
    Expand source code

        def combo_sel2(self, sel):
            #print("combo_sel2", sel)
            bounds = self.textbuffer.get_selection_bounds()

            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                # Clear out old colors
                start, end = bounds
                for cc in range(len(font_colors)):
                    rrr = "color%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                # Find out the offset:
                cnt = 0
                for aa, bb in font_colors:
                    if aa == sel:
                        break
                    cnt += 1
                nnn = "color%d" % cnt
                #print("nnn", nnn)
                start, end = bounds
                try:
                    self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                    self.textbuffer.set_modified(1)
                except:
                    print("Cannot apply size tag ", nnn, sys.exc_info())

  `def combo_sel3(self, sel)`
    Expand source code

        def combo_sel3(self, sel):
            #print("combo_sel3", sel)
            bounds = self.textbuffer.get_selection_bounds()

            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                start, end = bounds

                # Clear out old colors
                for cc in range(len(font_colors)):
                    rrr = "backgr%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                # Find out the offset:
                cnt = 0
                for aa, bb in font_colors:
                    if aa == sel:
                        break
                    cnt += 1

                nnn = "backgr%d" % cnt
                #print("nnn", nnn)

                try:
                    self.textbuffer.apply_tag(getattr(self, nnn), start, end)
                    self.textbuffer.set_modified(1)
                except:
                    print("Cannot apply size tag ", nnn, sys.exc_info())

  `def deser_buff(self, buffx)`
    Expand source code

        def deser_buff(self, buffx):

            if not buffx:
                return

            #print("UnSer buff")

            fmt = self.textbuffer.register_deserialize_tagset()
            self.textbuffer.deserialize_set_can_create_tags(fmt, True)
            self.textbuffer.deserialize(self.textbuffer, fmt,
                                    self.textbuffer.get_start_iter(), buffx)
            self.textbuffer.set_modified(0)

  `def get_modified(self)`
    Expand source code

        def  get_modified(self):
            return self.textbuffer.get_modified()

  `def get_text(self)`
    Expand source code

        def get_text(self):
            startt = self.textbuffer.get_start_iter()
            endd = self.textbuffer.get_end_iter()
            txt = self.textbuffer.get_text(startt, endd, False)
            return txt

  `def on_button_clicked(self, widget, tag)`
    Expand source code

        def on_button_clicked(self, widget, tag):

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No style selection.")
            else:
                start, end = bounds
                #print("Apply Tag", tag, start, end)
                self.textbuffer.apply_tag(tag, start, end)
                self.textbuffer.set_modified(1)

  `def on_clear_clicked(self, widget)`
    Expand source code

        def on_clear_clicked(self, widget):
            start = self.textbuffer.get_start_iter()
            end = self.textbuffer.get_end_iter()
            self.textbuffer.remove_all_tags(start, end)
            self.textbuffer.set_modified(1)

  `def on_combo_clicked(self, arg1, arg2)`
    Expand source code

        def on_combo_clicked(self, arg1, arg2):
            #print("on_combo_clicked")
            #cont = ("12", "32", "64")
            #combo_box = pgbox.ComboBox(cont)
            #combo_box.show()
            pass

  `def on_cursor_toggled(self, widget)`
    Expand source code

        def on_cursor_toggled(self, widget):
            self.textview.set_cursor_visible(widget.get_active())

  `def on_editable_toggled(self, widget)`
    Expand source code

        def on_editable_toggled(self, widget):
            self.textview.set_editable(widget.get_active())
            self.textbuffer.set_modified(1)

  `def on_justify_toggled(self, widget, justification)`
    Expand source code

        def on_justify_toggled(self, widget, justification):
            #print("on_justify_toggled", justification)
            #self.textview.set_justification(justification)
            #start = self.textbuffer.get_start_iter()
            #end = self.textbuffer.get_end_iter()

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection.")
            else:
                start, end = bounds
                #print("Apply Just Tag", justification, start, end)

                # Remove old justification
                self.textbuffer.remove_tag(self.tag_left, start, end)
                self.textbuffer.remove_tag(self.tag_center, start, end)
                self.textbuffer.remove_tag(self.tag_right, start, end)
                self.textbuffer.remove_tag(self.tag_fill, start, end)

                self.textbuffer.apply_tag(justification, start, end)
                self.textbuffer.set_modified(1)

  `def on_rm_clicked(self, widget, tag)`
    Expand source code

        def on_rm_clicked(self, widget, tag):
            bounds = self.textbuffer.get_selection_bounds()
            if len(bounds) != 0:
                start, end = bounds
                self.textbuffer.remove_all_tags(start, end)
                self.textbuffer.set_modified(1)

                # This was the old clear -- now clearing ALL
                #self.textbuffer.remove_tag(self.tag_bold, start, end)
                #self.textbuffer.remove_tag(self.tag_italic, start, end)
                #self.textbuffer.remove_tag(self.tag_underline, start, end)
                #self.textbuffer.remove_tag(self.tag_red, start, end)
                #self.textbuffer.remove_tag(self.tag_redbg, start, end)
                #self.textbuffer.remove_tag(self.tag_big, start, end)
                #self.textbuffer.remove_tag(self.tag_xbig, start, end)
                #self.textbuffer.remove_tag(self.tag_regular, start, end)

  `def on_rm_color(self, arg1)`
    Expand source code

        def on_rm_color(self, arg1):
            print(  "on_rm_color", arg1)

            bounds = self.textbuffer.get_selection_bounds()

            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No selection")
                #print("No selection")
                return
            else:
                start, end = bounds

                # Clear out old colors
                for cc in range(len(font_colors)):
                    rrr = "backgr%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                for cc in range(len(font_colors)):
                    rrr = "color%d" % cc
                    self.textbuffer.remove_tag(getattr(self, rrr), start, end)

                self.textbuffer.set_modified(1)

  `def on_search_clicked(self, widget)`
    Expand source code

        def on_search_clicked(self, widget):

            if self.findcall:
                # Call with object argument
                self.findcall[0](self.findcall[1])

            dialog.destroy()

  `def on_size_button(self, widget, tag)`
    Expand source code

        def on_size_button(self, widget, tag):

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No style selection.")
            else:
                start, end = bounds

                self.textbuffer.remove_tag(self.tag_super, start, end)
                self.textbuffer.remove_tag(self.tag_sub, start, end)

                #print("Apply Tag", tag, start, end)
                self.textbuffer.apply_tag(tag, start, end)
                self.textbuffer.set_modified(1)

  `def on_super_button(self, widget, tag)`
    Expand source code

        def on_super_button(self, widget, tag):

            bounds = self.textbuffer.get_selection_bounds()
            if not len(bounds):
                if self.statstr:
                    self.statstr.set_text("No style selection.")
            else:
                start, end = bounds

                self.textbuffer.remove_tag(self.tag_super, start, end)
                self.textbuffer.remove_tag(self.tag_sub, start, end)

                #print("Apply Tag", tag, start, end)
                self.textbuffer.apply_tag(tag, start, end)
                self.textbuffer.set_modified(1)

  `def on_unzoom_clicked(self, arg1)`
    Expand source code

        def on_unzoom_clicked(self, arg1):

            pg = Gtk.Widget.create_pango_context(self.textview)
            myfd = pg.get_font_description()
            mysize = myfd.get_size() / Pango.SCALE

            fd = Pango.FontDescription()
            fd.set_size((mysize - 1) * Pango.SCALE)
            self.textview.modify_font(fd)

  `def on_wrap_toggled(self, widget, mode)`
    Expand source code

        def on_wrap_toggled(self, widget, mode):
            self.textview.set_wrap_mode(mode)

  `def on_zoom_clicked(self, arg1)`
    Expand source code

        def on_zoom_clicked(self, arg1):

            pg = Gtk.Widget.create_pango_context(self.textview)
            myfd = pg.get_font_description()
            mysize = myfd.get_size() / Pango.SCALE

            fd = Pango.FontDescription()
            fd.set_size((mysize + 1) * Pango.SCALE)
            self.textview.modify_font(fd)

  `def print_tags(self)`
    Expand source code

        def print_tags(self):

            #startt = self.textbuffer.get_start_iter()
            #endd = self.textbuffer.get_end_iter()

            # TagTable
            #tt = self.textbuffer.get_property("tag-table")
            #print("table", tt)

            tt = self.textbuffer.get_tag_table()
            print("table", tt)
            tt.foreach(self.ptag, tt)
            print()

            return

            txt = self.textbuffer.get_text(startt, endd, False)
            lc =  self.textbuffer.get_char_count()
            for aa in range(lc):
                iii = self.textbuffer.get_iter_at_offset(aa)
                eee = self.textbuffer.get_iter_at_offset(aa+1)
                ccc = self.textbuffer.get_text(iii, eee, False)
                #print("aa", ccc)

            return txt

            #all = self.edview.get_all()
            #print("serialize", self.edview.textbuffer.get_deserialize_formats())
            #print("str", self.edview.serial_str())
            #print("serialize", self.edview.textbuffer.get_deserialize_formats())

            #vv = self.edview.textbuffer
            #startt = vv.get_start_iter(); endd = vv.get_end_iter()
            #while True:
            #    prev = startt.copy()
            #    nextok = startt.forward_line()
            #    ttt = vv.get_text(prev, startt, False)
            #    prevc = prev.copy()
            #    while True:
            #        sss = prevc.get_toggled_tags(True)
            #        if sss:
            #            print("tags on toggle", sss)
            #            for cc in sss:
            #                print("cc", cc.get_property("name"))
            #            print("pos", prevc.get_line(), prevc.get_line_offset())
            #        beg = prevc.copy()
            #        nextokc = prevc.forward_char()
            #        if not nextokc:
            #            break
            #        if startt == prevc:
            #            break
            #        chh = vv.get_text(beg, prevc, False)
            #        print(chh, end="")
            #
            #    #print("tags", prev.get_tags())
            #    #print("line:", ttt, end="")
            #    if not nextok:
            #        break
            #
            ##print("tags:", self.edview.textbuffer.get_tags())

  `def ptag(self, ttt, tt)`
    Expand source code

        def ptag(self, ttt, tt):

            global cnt              # Print only one
            if cnt: return
            cnt += 1

            print(ttt)
            #print(dir(ttt))
            ll = ttt.list_properties()
            for aa in ll:
                #print(nnnn, end= " ")
                try:
                    nn = tt.lookup(aa.name)
                    if nn:
                        #nnn = nn.get_property("size")
                        #print("size", nnn)

                        lll = nn.list_properties()
                        for bb in lll:
                            nnn = bb.name   #get_property("name")
                            try:
                                pp = nn.get_property(nnn)
                            except:
                                pass
                            print(aa.name, "prop", "'" + nnn + "'" , "val =", pp)
                        print()

                except:
                    print(sys.exc_info())
                    pass
                #print()

            return

  `def search_and_mark(self, text, start)`
    Expand source code

        def search_and_mark(self, text, start):
            end = self.textbuffer.get_end_iter()
            match = start.forward_search(text, 0, end)

            if match is not None:
                match_start, match_end = match
                self.textbuffer.apply_tag(self.tag_found, match_start, match_end)
                self.search_and_mark(text, match_end)

  `def ser_buff(self)`
    Expand source code

        def ser_buff(self):

            #print("Ser buff")

            startt = self.textbuffer.get_start_iter()
            endd = self.textbuffer.get_end_iter()

            fmt = self.textbuffer.register_serialize_tagset()
            sss = self.textbuffer.serialize(self.textbuffer, fmt, startt, endd)
            if not sss: sss = b""
            return sss

  `def set_modified(self, valx)`
    Expand source code

        def  set_modified(self, valx):
            return self.textbuffer.set_modified(valx)

  `def set_text(self, txt)`
    Expand source code

        def set_text(self, txt):
            if self.textbuffer.get_modified():
                startt = self.textbuffer.get_start_iter()
                endd = self.textbuffer.get_end_iter()
                old = self.textbuffer.get_text(startt, endd, False)
                if self.callb:
                    self.callb(old)
                #print("old_content", old)
            self.textbuffer.set_text(txt)