[pygtk] Undoing apply_tag in gtk.TextBuffer

Samuel Abels newsgroups at debain.org
Sat Jul 5 07:49:55 WST 2008


Hi,

Given the following code:

------------
import gtk, pango

def on_apply_tag(buffer, tag, start, end):
    print "apply"

def on_remove_tag(buffer, tag, start, end):
    print "remove"

buffer = gtk.TextBuffer()
bold   = buffer.create_tag('bold', weight = pango.WEIGHT_BOLD)
buffer.connect('apply-tag',  on_apply_tag)
buffer.connect('remove-tag', on_remove_tag)

start = buffer.get_start_iter()
buffer.insert(start, "one two three")

# Make the first seven chars bold.
# ** STEP 1 **
start = buffer.get_start_iter()
end   = buffer.get_iter_at_offset(7)
buffer.apply_tag(bold, start, end)

# Make more chars bold; note that the range intersects with the
# already-bold chars.
# ** STEP 2 **
start = buffer.get_iter_at_offset(4)
end   = buffer.get_end_iter()
buffer.apply_tag(bold, start, end)
------------

The code produces the following output:

------------
apply
apply
------------
(A more complete widget that does the same thing is here:
http://code.google.com/p/spiff-gtkwidgets/source/browse/trunk/src/SpiffGtkWidgets/TextEditor/TextBuffer.py
)

In other words, there is no signal to indicate the removal of the
end-tag that was inserted at STEP 1.

The problem when implementing undo is that when STEP 2 is reverted,
calling remove_tag() will also remove the style from characters 4 to 7,
so gtk.TextView did not keep the tag internally; it was actually
implicitly (re)moved.

Even working around this by trying to find the style that is currently
applied in a specific region does not seem do work; both, the get_text()
and get_slice() methods do not seem to include the information in the
return value.

Is there any way for an undo function to determine the tags (or styles)
that are applied in a specific region? Is there a less painful way to
implement undo for the text view? I know I could monitor all tag events
and build my own tag database in parallel, but that seems silly when the
information has to be present somewhere. Also, somebody must have done
this before.

Any ideas?

-Samuel




More information about the pygtk mailing list