If you try it, use shift/ctrl/alt + return/keypad enter for linebreaking while editing the text in a cell.
It seems to work well. However, since I'm new to python and pygtk, any corrections or suggestions will be apprechiated.
Osmo
#!/usr/bin/env python # -*- coding: utf8 -*-
import pygtk import gtk import gobject import pango
class CellTextView(gtk.TextView, gtk.CellEditable):
def set_text(self, text):
text_buffer = self.get_buffer()
text_buffer.set_text(text)
def get_text(self, *args):
text_buffer = self.get_buffer()
start = text_buffer.get_start_iter()
end = text_buffer.get_end_iter()
return text_buffer.get_text(start, end, True)
def do_editing_done(*args): pass def do_remove_widget(*args): pass def do_start_editing(*args): pass
class CellRendererMultilineText(gtk.GenericCellRenderer):
__gproperties__ = { 'text': (gobject.TYPE_STRING, 'text', 'text displayed', '', gobject.PARAM_READWRITE) }
__gsignals__ = {
'edited': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
(gobject.TYPE_STRING, gobject.TYPE_STRING))
}property_names = __gproperties__.keys()
def __init__(self):
self.__gobject_init__()
self.set_property('mode', gtk.CELL_RENDERER_MODE_EDITABLE)
def __getattr__(self, name):
try:
return self.get_property(name)
except TypeError:
raise AttributeError
def __setattr__(self, name, value):
try:
self.set_property(name, value)
except TypeError:
self.__dict__[name] = value
def do_get_property(self, property):
if property.name not in self.property_names:
raise TypeError('No property named %s' % (property.name,))
return self.__dict__[property.name]
def do_set_property(self, property, value):
if property.name not in self.property_names:
raise TypeError('No property named %s' % (property.name,))
self.__dict__[property.name] = value
def on_render(self, window, widget, bg_area, cell_area, exp_area, flags):
x_offset, y_offset, width, height = self.on_get_size(widget, cell_area)
layout = self.get_layout(widget) # Determine state to get text color right.
if flags & gtk.CELL_RENDERER_SELECTED:
if widget.get_property('has-focus'):
state = gtk.STATE_SELECTED
else:
state = gtk.STATE_ACTIVE
else:
state = gtk.STATE_NORMAL widget.style.paint_layout(
window, state, True, cell_area, widget, 'foo',
cell_area.x + x_offset, cell_area.y + y_offset, layout
)
def get_layout(self, widget): '''Gets the Pango layout used in the cell in a TreeView widget.'''
layout = pango.Layout(widget.get_pango_context())
layout.set_width(-1) # Do not wrap text. if self.text:
layout.set_text(self.text)
else:
layout.set_text('')return layout
def on_get_size(self, widget, cell_area):
# The following size calculations have tested so that the TextView
# will fully fit in the cell when editing and it will be the same
# size as a CellRendererText cell with same amount or rows. xpad = 2
ypad = 2 xalign = 0
yalign = 0.5 layout = self.get_layout(widget)
width, height = layout.get_pixel_size() x_offset = xpad
y_offset = ypadif cell_area:
x_offset = xalign * (cell_area.width - width)
x_offset = max(x_offset, xpad)
x_offset = int(round(x_offset, 0)) y_offset = yalign * (cell_area.height - height)
y_offset = max(y_offset, ypad)
y_offset = int(round(y_offset, 0)) width = width + (xpad * 2)
height = height + (ypad * 2)return x_offset, y_offset, width, height
def on_start_editing(self, event, widget, path, bg_area, cell_area, flags):
editor = CellTextView()
editor.set_wrap_mode(gtk.WRAP_NONE)
editor.connect('key-press-event', self.on_key_press_event, path) if self.text:
editor.set_text(self.text) editor.grab_focus()
editor.show()return editor
def on_key_press_event(self, widget, event, path): '''Catch pressing Enter keys.
Shift, Ctrl or Alt combined with Return or Keypad Enter can be used
for linebreaking. Pressing Return or Keypad Enter alone will finish
editing.''' mask = event.state
keyname = gtk.gdk.keyval_name(event.keyval) accel_masks = (gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK | \
gtk.gdk.MOD1_MASK)
enter_keynames = ('Return', 'KP_Enter') if (keyname in enter_keynames) and not (mask & accel_masks):
self.emit('edited', path, widget.get_text())
widget.destroy()
gobject.type_register(CellTextView) gobject.type_register(CellRendererMultilineText)
def on_edited(widget, path, new_value, store, column):
iter = store.get_iter(str(path))
store.set(iter, column, new_value)
if __name__ == '__main__':
store = gtk.ListStore(str, str)
tree = gtk.TreeView()
tree.set_model(store) tree.set_size_request(360, 140)
tree.set_headers_visible(True) cr = gtk.CellRendererText()
cr.connect('edited', on_edited, store, 0)
cr.set_property('editable', True)
column = gtk.TreeViewColumn('gtk.CellRendererText', cr, text = 0)
tree.append_column(column) cr = CellRendererMultilineText()
cr.connect('edited', on_edited, store, 1)
column = gtk.TreeViewColumn('CellRendererMultilineText', cr, text = 1)
tree.append_column(column) store.append(['Phou flou\nghou fhou.', 'Phou flou\nghou fhou.'])
store.append(['Bhuu fvou\nghaa neff.', 'Bhuu fvou\nghaa neff.']) window = gtk.Window()
window.set_position(gtk.WIN_POS_CENTER)
window.connect('delete-event', gtk.main_quit)
window.add(tree) window.show_all()
gtk.main()
_______________________________________________ pygtk mailing list [email protected] http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
